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