Test decision from main entry
[policy/xacml-pdp.git] / applications / common / src / main / java / org / onap / policy / pdp / xacml / application / common / std / StdXacmlApplicationServiceProvider.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.pdp.xacml.application.common.std;
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.PDPEngineFactory;
29 import com.att.research.xacml.api.pdp.PDPException;
30 import com.att.research.xacml.util.FactoryException;
31
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.OutputStream;
35 import java.nio.file.Files;
36 import java.nio.file.Path;
37 import java.nio.file.Paths;
38 import java.util.Collections;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Properties;
42
43 import org.onap.policy.models.decisions.concepts.DecisionRequest;
44 import org.onap.policy.models.decisions.concepts.DecisionResponse;
45 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyTypeIdentifier;
46 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationException;
47 import org.onap.policy.pdp.xacml.application.common.XacmlApplicationServiceProvider;
48 import org.onap.policy.pdp.xacml.application.common.XacmlPolicyUtils;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 public class StdXacmlApplicationServiceProvider implements XacmlApplicationServiceProvider {
53
54     private static final Logger LOGGER = LoggerFactory.getLogger(StdXacmlApplicationServiceProvider.class);
55     private Path pathForData = null;
56     private Properties pdpProperties = null;
57     private PDPEngine pdpEngine = null;
58
59     public StdXacmlApplicationServiceProvider() {
60         super();
61     }
62
63     @Override
64     public String applicationName() {
65         return "Please Override";
66     }
67
68     @Override
69     public List<String> actionDecisionsSupported() {
70         return Collections.emptyList();
71     }
72
73     @Override
74     public void initialize(Path pathForData) throws XacmlApplicationException {
75         //
76         // Save our path
77         //
78         this.pathForData = pathForData;
79         LOGGER.info("New Path is {}", this.pathForData.toAbsolutePath());
80         //
81         // Ensure properties exist
82         //
83         Path propertiesPath = XacmlPolicyUtils.getPropertiesPath(pathForData);
84         if (! propertiesPath.toFile().exists()) {
85             LOGGER.info("Copying src/main/resources/xacml.properties to path");
86             //
87             // Properties do not exist, by default we will copy ours over
88             // from src/main/resources
89             //
90             try {
91                 Files.copy(Paths.get("src/main/resources/xacml.properties"), propertiesPath);
92             } catch (IOException e) {
93                 throw new XacmlApplicationException("Failed to copy xacml.propertis", e);
94             }
95         }
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             throw new XacmlApplicationException("Failed to load xacml.propertis", e);
104         }
105         //
106         // Create an engine
107         //
108         createEngine(pdpProperties);
109     }
110
111     @Override
112     public List<ToscaPolicyTypeIdentifier> supportedPolicyTypes() {
113         return Collections.emptyList();
114     }
115
116     @Override
117     public boolean canSupportPolicyType(ToscaPolicyTypeIdentifier policyTypeId) {
118         return false;
119     }
120
121     @Override
122     public void loadPolicies(Map<String, Object> toscaPolicies) throws XacmlApplicationException {
123         throw new UnsupportedOperationException("Please override and implement loadPolicies");
124     }
125
126     @Override
127     public DecisionResponse makeDecision(DecisionRequest request) {
128         //
129         // We should have a standard error response to return
130         //
131         return null;
132     }
133
134     protected synchronized PDPEngine getEngine() {
135         return this.pdpEngine;
136     }
137
138     protected synchronized Properties getProperties() {
139         return new Properties(pdpProperties);
140     }
141
142     protected synchronized Path getDataPath() {
143         return pathForData;
144     }
145
146     /**
147      * Load properties from given file.
148      *
149      * @throws IOException If unable to read file
150      */
151     protected synchronized Properties loadXacmlProperties() throws IOException {
152         LOGGER.debug("Loading xacml properties {}", pathForData);
153         try (InputStream is = Files.newInputStream(pathForData)) {
154             Properties properties = new Properties();
155             properties.load(is);
156             return properties;
157         }
158     }
159
160     /**
161      * Stores the XACML Properties to the given file location.
162      *
163      * @throws IOException If unable to store the file.
164      */
165     protected synchronized void storeXacmlProperties() throws IOException {
166         try (OutputStream os = Files.newOutputStream(pathForData)) {
167             String strComments = "#";
168             pdpProperties.store(os, strComments);
169         }
170     }
171
172     /**
173      * Appends 'xacml.properties' to a root Path object
174      *
175      * @return Path to rootPath/xacml.properties file
176      */
177     protected synchronized Path getPropertiesPath() {
178         return Paths.get(pathForData.toAbsolutePath().toString(), "xacml.properties");
179     }
180
181     /**
182      * Creates an instance of PDP engine given the Properties object.
183      */
184     protected synchronized void createEngine(Properties properties) {
185         //
186         // Now initialize the XACML PDP Engine
187         //
188         try {
189             PDPEngineFactory factory = PDPEngineFactory.newInstance();
190             PDPEngine engine = factory.newEngine(properties);
191             if (engine != null) {
192                 this.pdpEngine = engine;
193                 this.pdpProperties = new Properties(properties);
194             }
195         } catch (FactoryException e) {
196             LOGGER.error("Failed to create XACML PDP Engine {}", e);
197         }
198     }
199
200     /**
201      * Make a decision call.
202      *
203      * @param request Incoming request object
204      * @return Response object
205      */
206     protected synchronized Response xacmlDecision(Request request) {
207         //
208         // This is what we need to return
209         //
210         Response response = null;
211         //
212         // Track some timing
213         //
214         long timeStart = System.currentTimeMillis();
215         try {
216             response = this.pdpEngine.decide(request);
217         } catch (PDPException e) {
218             LOGGER.error("Xacml PDP Engine failed {}", e);
219         } finally {
220             //
221             // Track the end of timing
222             //
223             long timeEnd = System.currentTimeMillis();
224             LOGGER.info("Elapsed Time: {}ms", (timeEnd - timeStart));
225         }
226         return response;
227     }
228
229 }