Merge "Fix critical sonar for ONAP-PAP-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 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  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.pap.xacml.rest.components;
22
23 import java.io.ByteArrayInputStream;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URI;
27 import java.net.URISyntaxException;
28 import java.nio.charset.StandardCharsets;
29 import java.nio.file.Files;
30 import java.nio.file.Path;
31 import java.nio.file.Paths;
32 import java.util.HashMap;
33 import java.util.Map;
34
35 import javax.json.Json;
36 import javax.json.JsonReader;
37
38 import org.apache.commons.io.FilenameUtils;
39 import org.json.JSONObject;
40 import org.onap.policy.common.logging.eelf.MessageCodes;
41 import org.onap.policy.common.logging.eelf.PolicyLogger;
42 import org.onap.policy.common.logging.flexlogger.FlexLogger;
43 import org.onap.policy.common.logging.flexlogger.Logger;
44 import org.onap.policy.rest.XACMLRestProperties;
45 import org.onap.policy.rest.adapter.PolicyRestAdapter;
46 import org.onap.policy.xacml.util.XACMLPolicyWriter;
47
48 import com.att.research.xacml.api.pap.PAPException;
49 import com.att.research.xacml.std.IdentifierImpl;
50 import com.att.research.xacml.util.XACMLProperties;
51 import com.att.research.xacmlatt.pdp.policy.PolicyDef;
52 import com.att.research.xacmlatt.pdp.policy.dom.DOMPolicyDef;
53
54 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
55 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
58
59 public abstract class Policy {
60         
61         private static final Logger LOGGER      = FlexLogger.getLogger(Policy.class);
62         
63
64         /**
65          * Common Fields
66          */
67         public static final String GET_INT_TYPE = "Integer";
68         public static final String GET_STRING_TYPE = "String";
69
70         public static final String ONAPID = "ONAPName";
71         public static final String CONFIGID = "ConfigName";
72         public static final String CLOSEDLOOPID = "ServiceType";
73
74         public static final String CONFIG_POLICY = "Config";
75         public static final String ACTION_POLICY = "Action";
76         public static final String DECISION_POLICY = "Decision";
77
78         protected String policyName = null;
79
80         protected boolean isValidForm = true;
81
82         private Path finalPolicyPath = null;
83
84         private boolean preparedToSave = false;
85
86         private boolean policyExists = false;
87
88         public Path getFinalPolicyPath() {
89                 return finalPolicyPath;
90         }
91
92         public void setFinalPolicyPath(Path finalPolicyPath) {
93                 this.finalPolicyPath = finalPolicyPath;
94         }
95
96         // Constants Used in XML Creation
97         public static final String CATEGORY_RECIPIENT_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:recipient-subject";
98         public static final String CATEGORY_RESOURCE = "urn:oasis:names:tc:xacml:3.0:attribute-category:resource";
99         public static final String CATEGORY_ACTION = "urn:oasis:names:tc:xacml:3.0:attribute-category:action";
100         public static final String CATEGORY_ACCESS_SUBJECT = "urn:oasis:names:tc:xacml:1.0:subject-category:access-subject";
101         public static final String ACTION_ID = "urn:oasis:names:tc:xacml:1.0:action:action-id";
102         public static final String SUBJECT_ID = "urn:oasis:names:tc:xacml:1.0:subject:subject-id";
103         public static final String RESOURCE_ID = "urn:oasis:names:tc:xacml:1.0:resource:resource-id";
104         public static final String FUNTION_INTEGER_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:integer-one-and-only";
105         public static final String FUNCTION_STRING_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:string-one-and-only";
106         public static final String FUNCTION_BOOLEAN_ONE_AND_ONLY = "urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only";
107         public static final String FUNCTION_STRING_EQUAL = "urn:oasis:names:tc:xacml:1.0:function:string-equal";
108         public static final String FUNCTION_STRING_REGEX_MATCH = "org.onap.function.regex-match";
109         public static final String FUNCTION_STRING_REGEXP_MATCH = "urn:oasis:names:tc:xacml:1.0:function:string-regexp-match";
110         public static final String FUNCTION_STRING_EQUAL_IGNORE = "urn:oasis:names:tc:xacml:3.0:function:string-equal-ignore-case";
111         public static final String INTEGER_DATATYPE = "http://www.w3.org/2001/XMLSchema#integer";
112         public static final String BOOLEAN_DATATYPE = "http://www.w3.org/2001/XMLSchema#boolean";
113         public static final String STRING_DATATYPE = "http://www.w3.org/2001/XMLSchema#string";
114         public static final String URI_DATATYPE = "http://www.w3.org/2001/XMLSchema#anyURI";
115         public static final String RULE_VARIABLE = "var:";
116         public static final String EMPTY_STRING = "";
117         private static final String String = null;
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 adapter when
140         //getting the xml to save the policy. Instead of keep this hardcoded in the save method,
141         //this method makes it usable outside.
142         /**
143          * Return the data field of the PolicyAdapter that will be used when saving this policy
144          * with the savePolicies method.
145          * @return Either the PolicyAdapter.getData() or PolicyAdapter.getPolicyData()
146          */
147         public abstract Object getCorrectPolicyDataObject();
148         public abstract Map<String, String>  savePolicies() throws PAPException;
149
150         //This is the method for preparing the policy for saving.  We have broken it out
151         //separately because the fully configured policy is used for multiple things
152         public abstract boolean prepareToSave() throws PAPException;
153
154
155         // create match for onap and config name
156         protected MatchType createMatch(String key, String value) {
157                 MatchType match = new MatchType();
158
159                 AttributeValueType attributeValue = new AttributeValueType();
160                 attributeValue.setDataType(STRING_DATATYPE);
161                 attributeValue.getContent().add(value);
162                 match.setAttributeValue(attributeValue);
163                 AttributeDesignatorType attributeDesignator = new AttributeDesignatorType();
164                 URI uri = null;
165                 try {
166                         uri = new URI(key);
167                 } catch (URISyntaxException e) {
168                         LOGGER.error("Exception Occured"+e);
169                 }
170                 attributeDesignator.setCategory(CATEGORY_ACCESS_SUBJECT);
171                 attributeDesignator.setDataType(STRING_DATATYPE);
172                 attributeDesignator.setAttributeId(new IdentifierImpl(uri).stringValue());
173                 match.setAttributeDesignator(attributeDesignator);
174                 match.setMatchId(FUNCTION_STRING_REGEX_MATCH);
175                 return match;
176         }
177
178         // Creating the match for dynamically added components.
179         protected MatchType createDynamicMatch(String key, String value) {
180                 MatchType dynamicMatch = new MatchType();
181                 AttributeValueType dynamicAttributeValue = new AttributeValueType();
182                 String dataType = null;
183                 dataType = STRING_DATATYPE;
184                 dynamicAttributeValue.setDataType(dataType);
185                 dynamicAttributeValue.getContent().add(value);
186                 dynamicMatch.setAttributeValue(dynamicAttributeValue);
187
188                 AttributeDesignatorType dynamicAttributeDesignator = new AttributeDesignatorType();
189
190                 URI dynamicURI = null;
191                 try {
192                         dynamicURI = new URI(key);
193                 } catch (URISyntaxException e) {
194                         LOGGER.error("Exception Occured"+e);// log msg
195                 }
196                 dynamicAttributeDesignator.setCategory(CATEGORY_RESOURCE);
197                 dynamicAttributeDesignator.setDataType(dataType);
198                 dynamicAttributeDesignator.setAttributeId(new IdentifierImpl(dynamicURI).stringValue());
199                 dynamicMatch.setAttributeDesignator(dynamicAttributeDesignator);
200                 dynamicMatch.setMatchId(FUNCTION_STRING_REGEX_MATCH);
201
202                 return dynamicMatch;
203         }
204
205         //validation for numeric
206         protected boolean isNumeric(String str){
207                 for (char c : str.toCharArray()){
208                         if (!Character.isDigit(c)) return false;
209                 }
210                 return true;
211         }
212
213         // Validation for json.
214         protected static boolean isJSONValid(String data) {
215                 JsonReader jsonReader = null;
216                 try {
217                     new JSONObject(data);
218                         InputStream stream = new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
219                         jsonReader = Json.createReader(stream);
220                         LOGGER.info("Json Value is: " + jsonReader.read().toString() );
221                 } catch (Exception e) {
222                         LOGGER.error("Exception Occured while reading json"+e);
223                         return false;
224                 }finally{
225                         if(jsonReader != null){
226                                 jsonReader.close();
227                         }
228                 }
229                 return true;
230         }
231
232         //  the Policy Name as Unique One throws error
233         @SuppressWarnings("static-access")
234         protected Path getNextFilename(Path parent, String policyType, String polcyFileName, Integer version) {
235                 policyType = FilenameUtils.removeExtension(policyType);
236                 polcyFileName = FilenameUtils.removeExtension(polcyFileName);
237                 Path newFile = null;
238                 String policyDir = EMPTY_STRING;
239                 String absolutePath = parent.toString();
240                 if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
241                         policyDir = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.length());
242                         if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
243                                 policyDir = absolutePath.substring(absolutePath.lastIndexOf("/") + 1, absolutePath.length());
244                         }
245                 }
246
247                 String fileName = "default";
248                 if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
249                         fileName = policyType + "_" + String.format(polcyFileName) + "." + version + ".xml";
250                 } 
251                 if (fileName != null) {
252                         newFile = Paths.get(parent.toString(), fileName);
253                 }
254                 if (Files.notExists(newFile)) {
255                         return newFile;
256                 }
257                 return null;
258         }
259
260         protected Path getNextLoopFilename(Path parentPath, String policyType, String policyConfigType, String policyFileName, Integer version) {
261                 policyType = FilenameUtils.removeExtension(policyType);
262                 policyConfigType = FilenameUtils.removeExtension(policyConfigType);
263                 policyFileName = FilenameUtils.removeExtension(policyFileName);
264                 Path newFile = null;
265                 String policyDir = EMPTY_STRING;
266                 String absolutePath = parentPath.toString();
267                 if (absolutePath != null && !absolutePath.equals(EMPTY_STRING)) {
268                         policyDir = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.length());
269                         if (policyDir == null || policyDir.equals(EMPTY_STRING)) {
270                                 policyDir = absolutePath.substring(absolutePath.lastIndexOf("/") + 1, absolutePath.length());
271                         }
272                 }
273
274                 String fileName = "default";
275                 if (policyDir != null && !policyDir.equals(EMPTY_STRING)) {
276                         if(policyConfigType.equals("ClosedLoop_PM")){
277                                 fileName = policyType + "_" + "PM" + "_" +java.lang.String.format(policyFileName) + "." +version +".xml";
278                         }else if(policyConfigType.equals("ClosedLoop_Fault")){
279                                 fileName = policyType + "_" + "Fault" + "_" +java.lang.String.format(policyFileName) +  "." + version + ".xml";
280                         }else if(policyConfigType.equals("Micro Service")){
281                                 fileName = policyType + "_" + "MS" + "_" + java.lang.String.format(policyFileName) + "." + version + ".xml";
282                         }
283                 } 
284                 if (fileName != null) {
285                         newFile = Paths.get(parentPath.toString(), fileName);
286                 }
287                 if (Files.notExists(newFile)) {
288                         return newFile;
289                 }
290                 return null;
291         }
292
293
294         //create policy once all the validations are completed
295         protected Map<String, String> createPolicy(final Path policyPath, final Object policyData) {
296                 Map<String, String> success = new HashMap<>(); 
297                 //
298                 // Is the root a PolicySet or Policy?
299                 //
300
301                 if (policyData instanceof PolicyType) {
302                         //
303                         // Write it out
304                         //
305                         //Does not need to be XACMLPolicyWriterWithPapNotify since it is already in the PAP
306                         //and this transaction is intercepted up stream.
307                         InputStream inputStream = null;
308                         try {
309                                 inputStream = XACMLPolicyWriter.getXmlAsInputStream((PolicyType) policyData);
310                                 PolicyDef policyDef = DOMPolicyDef.load(inputStream);
311                                 if (policyDef == null) {
312                                         success.put("validation", "PolicyDef Validation Failed");
313                                 }else{
314                                         success.put("success", "success");
315                                 }
316                         } catch (Exception e) {
317                                 LOGGER.error("PolicyDef Validation failed"+e);
318                                 success.put("error", "Validation Failed");
319                         }finally{
320                                 try {
321                                         if(inputStream != null)
322                                                 inputStream.close();
323                                 } catch (IOException e) {
324                                         LOGGER.error("Exception Occured while closing the input stream"+e);
325                                 }
326                         }
327                 } else {
328                         PolicyLogger.error("Unknown data type sent back.");
329                         return success;
330                 }
331                 return success;
332         }
333
334         public static String getConfigHome(){
335                 try {
336                         loadWebapps();
337                 } catch (Exception e) {
338                         LOGGER.debug(e);
339                         return null;
340                 }
341                 return configHome;
342         }
343
344         public static String getActionHome(){
345                 try {
346                         loadWebapps();
347                 } catch (Exception e) {
348                         LOGGER.debug(e);
349                         return null;
350                 }
351                 return actionHome;
352         }
353
354         private static void loadWebapps() throws PAPException{
355                 if(actionHome == null || configHome == null){
356                         Path webappsPath = Paths.get(XACMLProperties.getProperty(XACMLRestProperties.PROP_PAP_WEBAPPS));
357                         //Sanity Check
358                         if (webappsPath == null) {
359                                 PolicyLogger.error("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
360                                 throw new PAPException("Invalid Webapps Path Location property : " + XACMLRestProperties.PROP_PAP_WEBAPPS);
361                         }
362                         Path webappsPathConfig;
363                         Path webappsPathAction;
364                         if(webappsPath.toString().contains("\\")){
365                                 webappsPathConfig = Paths.get(webappsPath.toString()+"\\Config");
366                                 webappsPathAction = Paths.get(webappsPath.toString()+"\\Action");
367                         }else{
368                                 webappsPathConfig = Paths.get(webappsPath.toString()+"/Config");
369                                 webappsPathAction = Paths.get(webappsPath.toString()+"/Action");
370                         }
371                         if(!webappsPathConfig.toFile().exists()){
372                                 try {
373                                         Files.createDirectories(webappsPathConfig);
374                                 } catch (IOException e) {
375                                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Policy", "Failed to create config directory");
376                                 }
377                         }
378                         if(!webappsPathAction.toFile().exists()){
379                                 try {
380                                         Files.createDirectories(webappsPathAction);
381                                 } catch (IOException e) {
382                                         PolicyLogger.error(MessageCodes.ERROR_PROCESS_FLOW, e, "Policy", "Failed to create config directory");
383                                 }
384                         }
385                         actionHome = webappsPathAction.toString();
386                         configHome = webappsPathConfig.toString();
387                 }
388         }
389         
390         public boolean validateConfigForm() {
391                 return true;
392         }
393
394         /**
395          * @return the preparedToSave
396          */
397         public boolean isPreparedToSave() {
398                 return preparedToSave;
399         }
400
401         /**
402          * @param preparedToSave the preparedToSave to set
403          */
404         protected void setPreparedToSave(boolean preparedToSave) {
405                 this.preparedToSave = preparedToSave;
406         }
407
408         public boolean isPolicyExists() {
409                 return policyExists;
410         }
411
412         public void setPolicyExists(boolean policyExists) {
413                 this.policyExists = policyExists;
414         }
415
416
417 }