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