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