CHeckstyle and JUnit for base package in ONAP-REST
[policy/engine.git] / ONAP-PAP-REST / src / main / java / org / onap / policy / pap / xacml / rest / components / Policy.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP-PAP-REST
4  * ================================================================================
5  * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6  * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.pap.xacml.rest.components;
23
24 import com.att.research.xacml.api.pap.PAPException;
25 import com.att.research.xacml.std.IdentifierImpl;
26 import com.att.research.xacml.util.XACMLProperties;
27 import com.att.research.xacmlatt.pdp.policy.PolicyDef;
28 import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
29
30 import java.io.IOException;
31 import java.io.InputStream;
32 import java.net.URI;
33 import java.net.URISyntaxException;
34 import java.nio.file.Files;
35 import java.nio.file.Path;
36 import java.nio.file.Paths;
37 import java.util.HashMap;
38 import java.util.Map;
39
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
43 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
44 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
45
46 import org.apache.commons.io.FilenameUtils;
47 import org.onap.policy.common.logging.eelf.MessageCodes;
48 import org.onap.policy.common.logging.eelf.PolicyLogger;
49 import org.onap.policy.common.logging.flexlogger.FlexLogger;
50 import org.onap.policy.common.logging.flexlogger.Logger;
51 import org.onap.policy.rest.XacmlRestProperties;
52 import org.onap.policy.rest.adapter.PolicyRestAdapter;
53 import org.onap.policy.xacml.util.XACMLPolicyWriter;
54
55 public abstract class Policy {
56
57     private static final Logger LOGGER = FlexLogger.getLogger(Policy.class);
58
59     /**
60      * Common Fields
61      */
62     public static final String GET_INT_TYPE = "Integer";
63     public static final String GET_STRING_TYPE = "String";
64
65     public static final String ONAPID = "ONAPName";
66     public static final String CONFIGID = "ConfigName";
67     public static final String CLOSEDLOOPID = "ServiceType";
68
69     public static final String CONFIG_POLICY = "Config";
70     public static final String ACTION_POLICY = "Action";
71     public static final String DECISION_POLICY = "Decision";
72
73     protected String policyName = null;
74
75     protected boolean isValidForm = true;
76
77     private Path finalPolicyPath = null;
78
79     private boolean preparedToSave = false;
80
81     private boolean policyExists = false;
82
83     public Path getFinalPolicyPath() {
84         return finalPolicyPath;
85     }
86
87     public void setFinalPolicyPath(Path finalPolicyPath) {
88         this.finalPolicyPath = finalPolicyPath;
89     }
90
91     // Constants Used in XML Creation
92     public static final String CATEGORY_RECIPIENT_SUBJECT =
93             "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
94     public static final String CATEGORY_RESOURCE = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource";
95     public static final String CATEGORY_ACTION = "urn:oasis:names:tc:xacml:3.0:attribute-category:action";
96     public static final String CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
97     public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
98     public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
99     public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
100     public static final String FUNTION_INTEGER_ONE_AND_ONLY =
101             "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only";
102     public static final String FUNCTION_STRING_ONE_AND_ONLY =
103             "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only";
104     public static final String FUNCTION_BOOLEAN_ONE_AND_ONLY =
105             "urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only";
106     public static final String FUNCTION_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
107     public static final String FUNCTION_STRING_REGEX_MATCH = "org.onap.function.regex-match";
108     public static final String FUNCTION_STRING_REGEXP_MATCH =
109             "urn:oasis:names:tc:xacml:1.0:function:string-regexp-match";
110     public static final String FUNCTION_STRING_EQUAL_IGNORE =
111             "urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case";
112     public static final String INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer";
113     public static final String BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean";
114     public static final String STRING_DATATYPE = "http://www.w3.org/2001/XMLSchema#string";
115     public static final String URI_DATATYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
116     public static final String RULE_VARIABLE = "var:";
117     public static final String EMPTY_STRING = "";
118
119     protected static String CONFIG_HOME = null;
120     protected static String ACTION_HOME = null;
121     protected static String CONFIG_URL = null;
122
123     protected Map<String, String> performer = new HashMap<>();
124
125     private static String actionHome = null;
126     private static String configHome = null;
127
128     public PolicyRestAdapter policyAdapter = null;
129     String ruleID = "";
130
131     public Policy() {
132         CONFIG_HOME = getConfigHome();
133         ACTION_HOME = getActionHome();
134         CONFIG_URL = "$URL";
135         performer.put("PDP", "PDPAction");
136         performer.put("PEP", "PEPAction");
137     }
138
139     // Each policy type seems to either use policyData or data field policy
140     // adapter when
141     // getting the xml to save the policy. Instead of keep this hardcoded in the
142     // save method,
143     // this method makes it usable outside.
144     /**
145      * Return the data field of the PolicyAdapter that will be used when saving this policy with the savePolicies
146      * method.
147      *
148      * @return Either the PolicyAdapter.getData() or PolicyAdapter.getPolicyData()
149      */
150     public abstract Object getCorrectPolicyDataObject();
151
152     public abstract Map<String, String> savePolicies() throws PAPException;
153
154     // This is the method for preparing the policy for saving. We have broken it
155     // out
156     // separately because the fully configured policy is used for multiple
157     // things
158     public abstract boolean prepareToSave() throws PAPException;
159
160     // create match for onap and config name
161     protected MatchType createMatch(String key, String value) {
162         MatchType match = new MatchType();
163
164         AttributeValueType attributeValue = new AttributeValueType();
165         attributeValue.setDataType(STRING_DATATYPE);
166         attributeValue.getContent().add(value);
167         match.setAttributeValue(attributeValue);
168         AttributeDesignatorType attributeDesignator = new AttributeDesignatorType();
169         URI uri = null;
170         try {
171             uri = new URI(key.replaceAll("\\s+", ""));
172         } catch (URISyntaxException e) {
173             LOGGER.error("Exception Occured" + e);
174         }
175         attributeDesignator.setCategory(CATEGORY_ACCESS_SUBJECT);
176         attributeDesignator.setDataType(STRING_DATATYPE);
177         attributeDesignator.setAttributeId(new IdentifierImpl(uri).stringValue());
178         match.setAttributeDesignator(attributeDesignator);
179         match.setMatchId(FUNCTION_STRING_REGEX_MATCH);
180         return match;
181     }
182
183     // Creating the match for dynamically added components.
184     protected MatchType createDynamicMatch(String key, String value) {
185         MatchType dynamicMatch = new MatchType();
186         AttributeValueType dynamicAttributeValue = new AttributeValueType();
187         String dataType = null;
188         dataType = STRING_DATATYPE;
189         dynamicAttributeValue.setDataType(dataType);
190         dynamicAttributeValue.getContent().add(value);
191         dynamicMatch.setAttributeValue(dynamicAttributeValue);
192
193         AttributeDesignatorType dynamicAttributeDesignator = new AttributeDesignatorType();
194
195         URI dynamicURI = null;
196         try {
197             dynamicURI = new URI(key.replaceAll("\\s+", ""));
198         } catch (URISyntaxException e) {
199             LOGGER.error("Exception Occured" + e);// log msg
200         }
201         dynamicAttributeDesignator.setCategory(CATEGORY_RESOURCE);
202         dynamicAttributeDesignator.setDataType(dataType);
203         dynamicAttributeDesignator.setAttributeId(new IdentifierImpl(dynamicURI).stringValue());
204         dynamicMatch.setAttributeDesignator(dynamicAttributeDesignator);
205         dynamicMatch.setMatchId(FUNCTION_STRING_REGEX_MATCH);
206
207         return dynamicMatch;
208     }
209
210     // the Policy Name as Unique One throws error
211     protected Path getNextFilename(Path parent, String policyType, String polcyFileName, Integer version) {
212         policyType = FilenameUtils.removeExtension(policyType);
213         polcyFileName = FilenameUtils.removeExtension(polcyFileName);
214         Path newFile = null;
215         String policyDir = EMPTY_STRING;
216         String absolutePath = parent.toString();
217         if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
218             policyDir = absolutePath.substring(absolutePath.lastIndexOf('\\') + 1, absolutePath.length());
219             if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
220                 policyDir = absolutePath.substring(absolutePath.lastIndexOf('/') + 1, absolutePath.length());
221             }
222         }
223
224         String fileName = "default";
225         if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
226             fileName = policyType + "_" + String.format(polcyFileName) + "." + version + ".xml";
227         }
228
229         newFile = Paths.get(parent.toString(), fileName);
230         if (newFile.toFile().exists()) {
231             return newFile;
232         }
233         return null;
234     }
235
236     protected Path getNextLoopFilename(Path parentPath, String policyType, String policyConfigType,
237             String policyFileName, Integer version) {
238         policyType = FilenameUtils.removeExtension(policyType);
239         policyConfigType = FilenameUtils.removeExtension(policyConfigType);
240         policyFileName = FilenameUtils.removeExtension(policyFileName);
241         Path newFile = null;
242         String policyDir = EMPTY_STRING;
243         String absolutePath = parentPath.toString();
244         if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
245             policyDir = absolutePath.substring(absolutePath.lastIndexOf('\\') + 1, absolutePath.length());
246             if (policyDir.equals(EMPTY_STRING)) {
247                 policyDir = absolutePath.substring(absolutePath.lastIndexOf('/') + 1, absolutePath.length());
248             }
249         }
250
251         String fileName = "default";
252         if (!policyDir.equals(EMPTY_STRING)) {
253             if ("ClosedLoop_PM".equals(policyConfigType)) {
254                 fileName = policyType + "_" + "PM" + "_" + java.lang.String.format(policyFileName) + "." + version
255                         + ".xml";
256             } else if ("ClosedLoop_Fault".equals(policyConfigType)) {
257                 fileName = policyType + "_" + "Fault" + "_" + java.lang.String.format(policyFileName) + "." + version
258                         + ".xml";
259             } else if ("Micro Service".equals(policyConfigType)) {
260                 fileName = policyType + "_" + "MS" + "_" + java.lang.String.format(policyFileName) + "." + version
261                         + ".xml";
262             } else if ("Optimization".equals(policyConfigType)) {
263                 fileName = policyType + "_" + "OOF" + "_" + java.lang.String.format(policyFileName) + "." + version
264                         + ".xml";
265             }
266         }
267
268         newFile = Paths.get(parentPath.toString(), fileName);
269
270         if (newFile.toFile().exists()) {
271             return newFile;
272         }
273         return null;
274     }
275
276     // create policy once all the validations are completed
277     protected Map<String, String> createPolicy(final Path policyPath, final Object policyData) {
278         Map<String, String> success = new HashMap<>();
279         //
280         // Is the root a PolicySet or Policy?
281         //
282
283         if (policyData instanceof PolicyType || policyData instanceof PolicySetType) {
284             //
285             // Write it out
286             //
287             // Does not need to be XACMLPolicyWriterWithPapNotify since it is
288             // already in the PAP
289             // and this transaction is intercepted up stream.
290             try (InputStream inputStream = XACMLPolicyWriter.getXmlAsInputStream(policyData)) {
291                 PolicyDef policyDef = DOMPolicyDef.load(inputStream);
292                 if (policyDef == null) {
293                     success.put("validation", "PolicyDef Validation Failed");
294                 } else {
295                     success.put("success", "success");
296                 }
297             } catch (Exception e) {
298                 LOGGER.error("PolicyDef Validation failed" + e);
299                 success.put("error", "Validation Failed");
300             }
301         } else {
302             PolicyLogger.error("Unknown data type sent back.");
303             return success;
304         }
305         return success;
306     }
307
308     public static String getConfigHome() {
309         try {
310             loadWebapps();
311         } catch (Exception e) {
312             LOGGER.debug(e);
313             return null;
314         }
315         return configHome;
316     }
317
318     public static String getActionHome() {
319         try {
320             loadWebapps();
321         } catch (Exception e) {
322             LOGGER.debug(e);
323             return null;
324         }
325         return actionHome;
326     }
327
328     private static void loadWebapps() throws PAPException {
329         if (actionHome == null || configHome == null) {
330             Path webappsPath = Paths.get(XACMLProperties.getProperty(XacmlRestProperties.PROP_PAP_WEBAPPS));
331             // Sanity Check
332             if (webappsPath == null) {
333                 PolicyLogger.error("Invalid Webapps Path Location property : " + XacmlRestProperties.PROP_PAP_WEBAPPS);
334                 throw new PAPException(
335                         "Invalid Webapps Path Location property : " + XacmlRestProperties.PROP_PAP_WEBAPPS);
336             }
337             Path webappsPathConfig;
338             Path webappsPathAction;
339             if (webappsPath.toString().contains("\\")) {
340                 webappsPathConfig = Paths.get(webappsPath.toString() + "\\Config");
341                 webappsPathAction = Paths.get(webappsPath.toString() + "\\Action");
342             } else {
343                 webappsPathConfig = Paths.get(webappsPath.toString() + "/Config");
344                 webappsPathAction = Paths.get(webappsPath.toString() + "/Action");
345             }
346             if (!webappsPathConfig.toFile().exists()) {
347                 try {
348                     Files.createDirectories(webappsPathConfig);
349                 } catch (IOException e) {
350                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Policy",
351                             "Failed to create config directory");
352                 }
353             }
354             if (!webappsPathAction.toFile().exists()) {
355                 try {
356                     Files.createDirectories(webappsPathAction);
357                 } catch (IOException e) {
358                     PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Policy",
359                             "Failed to create config directory");
360                 }
361             }
362             actionHome = webappsPathAction.toString();
363             configHome = webappsPathConfig.toString();
364         }
365     }
366
367     public boolean validateConfigForm() {
368         return true;
369     }
370
371     /**
372      * @return the preparedToSave
373      */
374     public boolean isPreparedToSave() {
375         return preparedToSave;
376     }
377
378     /**
379      * @param preparedToSave the preparedToSave to set
380      */
381     protected void setPreparedToSave(boolean preparedToSave) {
382         this.preparedToSave = preparedToSave;
383     }
384
385     public boolean isPolicyExists() {
386         return policyExists;
387     }
388
389     public void setPolicyExists(boolean policyExists) {
390         this.policyExists = policyExists;
391     }
392
393 }