Started with test decision JSON objects.
[policy/xacml-pdp.git] / applications / guard / src / main / java / org / onap / policy / xacml / pdp / application / guard / GuardPdpApplication.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * SPDX-License-Identifier: Apache-2.0
20  * ============LICENSE_END=========================================================
21  */
22
23 package org.onap.policy.xacml.pdp.application.guard;
24
25 import com.att.research.xacml.api.Request;
26 import com.att.research.xacml.api.Response;
27 import com.att.research.xacml.api.pdp.PDPEngine;
28 import com.att.research.xacml.api.pdp.PDPException;
29 import com.att.research.xacml.util.XACMLPolicyWriter;
30 import com.google.common.collect.Lists;
31
32 import java.io.ByteArrayOutputStream;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.nio.file.Path;
36 import java.util.ArrayList;
37 import java.util.Arrays;
38 import java.util.HashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Map.Entry;
42 import java.util.Properties;
43
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
45
46 import org.onap.policy.models.decisions.concepts.DecisionRequest;
47 import org.onap.policy.models.decisions.concepts.DecisionResponse;
48 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConversionException;
49 import org.onap.policy.pdp.xacml.application.common.ToscaPolicyConverter;
50 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
51 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
54 import org.yaml.snakeyaml.Yaml;
55
56 /**
57  * This class implements the onap.policies.controlloop.Guard policy implementations.
58  *
59  * @author pameladragosh
60  *
61  */
62 public class GuardPdpApplication implements ToscaPolicyConverter, XacmlApplicationServiceProvider {
63
64     private static final Logger LOGGER = LoggerFactory.getLogger(GuardPdpApplication.class);
65     private static final String STRING_VERSION100 = "1.0.0";
66     private Map<String, String> supportedPolicyTypes = new HashMap<>();
67     private Path pathForData;
68     private Properties pdpProperties = null;
69     private PDPEngine pdpEngine = null;
70
71     /** Constructor.
72      *
73      */
74     public GuardPdpApplication() {
75         this.supportedPolicyTypes.put("onap.policies.controlloop.guard.FrequencyLimiter", STRING_VERSION100);
76         this.supportedPolicyTypes.put("onap.policies.controlloop.guard.MinMax", STRING_VERSION100);
77     }
78
79     @Override
80     public String applicationName() {
81         return "Guard Application";
82     }
83
84     @Override
85     public List<String> actionDecisionsSupported() {
86         return Arrays.asList("guard");
87     }
88
89     @Override
90     public void initialize(Path pathForData) {
91         //
92         // Save our path
93         //
94         this.pathForData = pathForData;
95         LOGGER.debug("New Path is {}", this.pathForData.toAbsolutePath());
96         //
97         // Look for and load the properties object
98         //
99         try {
100             pdpProperties = XacmlPolicyUtils.loadXacmlProperties(XacmlPolicyUtils.getPropertiesPath(pathForData));
101             LOGGER.debug("{}", pdpProperties);
102         } catch (IOException e) {
103             LOGGER.error("{}", e);
104         }
105         //
106         // Create an engine
107         //
108         PDPEngine newEngine = XacmlPolicyUtils.createEngine(pdpProperties);
109         if (newEngine != null) {
110             pdpEngine = newEngine;
111         }
112     }
113
114     @Override
115     public List<String> supportedPolicyTypes() {
116         return Lists.newArrayList(supportedPolicyTypes.keySet());
117     }
118
119     @Override
120     public boolean canSupportPolicyType(String policyType, String policyTypeVersion) {
121         //
122         // For the time being, restrict this if the version isn't known.
123         // Could be too difficult to support changing of versions dynamically.
124         //
125         if (! this.supportedPolicyTypes.containsKey(policyType)) {
126             return false;
127         }
128         //
129         // Must match version exactly
130         //
131         return this.supportedPolicyTypes.get(policyType).equals(policyTypeVersion);
132     }
133
134     @Override
135     public void loadPolicies(Map<String, Object> toscaPolicies) {
136         try {
137             //
138             // Convert the policies first
139             //
140             List<PolicyType> listPolicies = this.convertPolicies(toscaPolicies);
141             if (listPolicies.isEmpty()) {
142                 throw new ToscaPolicyConversionException("Converted 0 policies");
143             }
144         } catch (ToscaPolicyConversionException e) {
145             LOGGER.error("Failed to loadPolicies {}", e);
146         }
147     }
148
149     @Override
150     public DecisionResponse makeDecision(DecisionRequest request) {
151         //
152         // Convert to a XacmlRequest
153         //
154         Request xacmlRequest = this.convertRequest(request);
155         //
156         // Now get a decision
157         //
158         Response xacmlResponse = this.xacmlDecision(xacmlRequest);
159         //
160         // Convert to a DecisionResponse
161         //
162         return this.convertResponse(xacmlResponse);
163     }
164
165     @Override
166     public List<PolicyType> convertPolicies(InputStream isToscaPolicy) throws ToscaPolicyConversionException {
167         //
168         // Have snakeyaml parse the object
169         //
170         Yaml yaml = new Yaml();
171         Map<String, Object> toscaObject = yaml.load(isToscaPolicy);
172         //
173         // Return the policies
174         //
175         return scanAndConvertPolicies(toscaObject);
176     }
177
178     @Override
179     public List<PolicyType> convertPolicies(Map<String, Object> toscaObject) throws ToscaPolicyConversionException {
180         //
181         // Return the policies
182         //
183         return scanAndConvertPolicies(toscaObject);
184     }
185
186     @Override
187     public Request convertRequest(DecisionRequest request) {
188         // TODO Auto-generated method stub
189         return null;
190     }
191
192     @Override
193     public DecisionResponse convertResponse(Response response) {
194         // TODO Auto-generated method stub
195         return null;
196     }
197
198     @SuppressWarnings("unchecked")
199     private List<PolicyType> scanAndConvertPolicies(Map<String, Object> toscaObject)
200             throws ToscaPolicyConversionException {
201         //
202         // Our return object
203         //
204         List<PolicyType> scannedPolicies = new ArrayList<>();
205         //
206         // Iterate each of the Policies
207         //
208         List<Object> policies = (List<Object>) toscaObject.get("policies");
209         for (Object policyObject : policies) {
210             //
211             // Get the contents
212             //
213             LOGGER.debug("Found policy {}", policyObject.getClass());
214             Map<String, Object> policyContents = (Map<String, Object>) policyObject;
215             for (Entry<String, Object> entrySet : policyContents.entrySet()) {
216                 LOGGER.debug("Entry set {}", entrySet);
217                 //
218                 // Convert this policy
219                 //
220                 PolicyType policy = this.convertPolicy(entrySet);
221                 try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
222                     XACMLPolicyWriter.writePolicyFile(os, policy);
223                     LOGGER.debug("{}", os);
224                 } catch (IOException e) {
225                     LOGGER.error("Failed to convert {}", e);
226                 }
227                 //
228                 // Convert and add in the new policy
229                 //
230                 scannedPolicies.add(policy);
231             }
232         }
233
234         return scannedPolicies;
235     }
236
237     private PolicyType convertPolicy(Entry<String, Object> entrySet) throws ToscaPolicyConversionException {
238
239         return null;
240     }
241
242     /**
243      * Make a decision call.
244      *
245      * @param request Incoming request object
246      * @return Response object
247      */
248     private synchronized Response xacmlDecision(Request request) {
249         //
250         // This is what we need to return
251         //
252         Response response = null;
253         //
254         // Track some timing
255         //
256         long timeStart = System.currentTimeMillis();
257         try {
258             response = this.pdpEngine.decide(request);
259         } catch (PDPException e) {
260             LOGGER.error("Xacml PDP Engine failed {}", e);
261         } finally {
262             //
263             // Track the end of timing
264             //
265             long timeEnd = System.currentTimeMillis();
266             LOGGER.info("Elapsed Time: {}ms", (timeEnd - timeStart));
267         }
268         return response;
269     }
270
271 }