098055939258ada6b1539c913120d96d4e542479
[policy/xacml-pdp.git] / main / src / main / java / org / onap / policy / pdpx / main / rest / XacmlPdpApplicationManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pdpx.main.rest;
22
23 import java.io.IOException;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.nio.file.Paths;
27 import java.util.ArrayList;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.ServiceLoader;
32 import org.onap.policy.models.decisions.concepts.DecisionRequest;
33 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
34 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyIdentifier;
35 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
36 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
37 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerFactory;
40
41 public class XacmlPdpApplicationManager {
42     private static final Logger LOGGER = LoggerFactory.getLogger(XacmlPdpApplicationManager.class);
43
44     private static boolean needsInit = true;
45     private static ServiceLoader<XacmlApplicationServiceProvider> applicationLoader;
46     private static Map<String, XacmlApplicationServiceProvider> providerActionMap = new HashMap<>();
47     private static List<ToscaPolicyTypeIdentifier> toscaPolicyTypeIdents = new ArrayList<>();
48     private static List<ToscaPolicyIdentifier> toscaPolicies = new ArrayList<>();
49
50     private XacmlPdpApplicationManager() {
51         super();
52     }
53
54     /**
55      * One time to initialize the applications upon startup.
56      */
57     public static void initializeApplications(Path applicationPath) {
58         //
59         // If we have already done this
60         //
61         if (! needsInit) {
62             LOGGER.error("Already initialized the applications");
63             return;
64         }
65         //
66         // Load service
67         //
68         applicationLoader = ServiceLoader.load(XacmlApplicationServiceProvider.class);
69         //
70         // Iterate through the applications for actions and supported policy types
71         //
72         for (XacmlApplicationServiceProvider application : applicationLoader) {
73             LOGGER.info("Application {} supports {}", application.applicationName(),
74                     application.supportedPolicyTypes());
75             //
76             // We are not going to make this available unless the application can
77             // install correctly.
78             //
79             boolean applicationInitialized = false;
80             //
81             // Have it initialize at a path
82             //
83             try {
84                 initializeApplicationPath(applicationPath, application);
85                 //
86                 // We are initialized
87                 //
88                 applicationInitialized = true;
89             } catch (XacmlApplicationException e) {
90                 LOGGER.error("Failed to initialize path for {}", application.applicationName(), e);
91             }
92             if (applicationInitialized) {
93                 //
94                 // Iterate through the actions and save in the providerActionMap
95                 //
96                 for (String action : application.actionDecisionsSupported()) {
97                     //
98                     // Save the actions that it supports
99                     //
100                     providerActionMap.put(action, application);
101                 }
102                 //
103                 // Add all the supported policy types
104                 //
105                 toscaPolicyTypeIdents.addAll(application.supportedPolicyTypes());
106             }
107         }
108         //
109         // we have initialized
110         //
111         needsInit = false;
112     }
113
114     public static XacmlApplicationServiceProvider findApplication(DecisionRequest request) {
115         return providerActionMap.get(request.getAction());
116     }
117
118     public static List<ToscaPolicyTypeIdentifier> getToscaPolicyTypeIdents() {
119         return toscaPolicyTypeIdents;
120     }
121
122     /**
123      * Finds the appropriate application and loads the policy.
124      *
125      * @param policy Incoming policy
126      */
127     public static void loadDeployedPolicy(ToscaPolicy policy) {
128
129         for (XacmlApplicationServiceProvider application : applicationLoader) {
130             try {
131                 //
132                 // There should be only one application per policytype. We can
133                 // put more logic surrounding enforcement of that later. For now,
134                 // just use the first one found.
135                 //
136                 if (application.canSupportPolicyType(policy.getTypeIdentifier())) {
137                     application.loadPolicy(policy);
138                     return;
139                 }
140             } catch (XacmlApplicationException e) {
141                 LOGGER.error("Failed to load the Tosca Policy", e);
142             }
143         }
144     }
145
146     public static List<ToscaPolicyIdentifier> getToscaPolicies() {
147         return toscaPolicies;
148     }
149
150     /**
151      * Returns the current count of policy types supported. This could be misleading a bit
152      * as some applications can support wildcard of policy types. Eg. onap.Monitoring.* as
153      * well as individual types/versions. Nevertheless useful for debugging and testing.
154      *
155      * @return Total count added from all applications
156      */
157     public static long getPolicyTypeCount() {
158         long types = 0;
159         for (XacmlApplicationServiceProvider application : applicationLoader) {
160             types += application.supportedPolicyTypes().size();
161         }
162         return types;
163     }
164
165     private static void initializeApplicationPath(Path basePath, XacmlApplicationServiceProvider application)
166             throws XacmlApplicationException {
167         //
168         // Making an assumption that all application names are unique, and
169         // they can result in a valid directory being created.
170         //
171         Path path = Paths.get(basePath.toAbsolutePath().toString(), application.applicationName());
172         LOGGER.info("initializeApplicationPath {} at this path {}", application.applicationName(), path);
173         //
174         // Create that the directory if it does not exist. Ideally
175         // this is only for testing, but could be used for production
176         // Probably better to have the docker container and/or helm
177         // scripts setup the local directory.
178         //
179         if (! path.toFile().exists()) {
180             try {
181                 //
182                 // Try to create the directory
183                 //
184                 Files.createDirectory(path);
185             } catch (IOException e) {
186                 LOGGER.error("Failed to create application directory", e);
187             }
188         }
189         //
190         // Have the application initialize
191         //
192         application.initialize(path);
193     }
194
195 }