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