XACML Platform Enhancements
[policy/engine.git] / POLICY-SDK-APP / src / main / java / org / onap / policy / controller / DecisionPolicyController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Engine
4  * ================================================================================
5  * Copyright (C) 2017-2018 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.controller;
22
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.util.ArrayList;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.LinkedList;
30 import java.util.List;
31 import java.util.Map;
32 import java.util.Map.Entry;
33 import javax.xml.bind.JAXBElement;
34 import org.apache.commons.io.IOUtils;
35 import org.apache.commons.lang3.StringUtils;
36 import org.onap.policy.common.logging.flexlogger.FlexLogger;
37 import org.onap.policy.common.logging.flexlogger.Logger;
38 import org.onap.policy.rest.adapter.PolicyRestAdapter;
39 import org.onap.policy.rest.adapter.RainyDayParams;
40 import org.onap.policy.rest.adapter.YAMLParams;
41 import org.onap.policy.rest.jpa.PolicyEntity;
42 import org.onap.policy.xacml.util.XACMLPolicyWriter;
43 import org.onap.portalsdk.core.controller.RestrictedBaseController;
44 import org.springframework.stereotype.Controller;
45 import org.springframework.web.bind.annotation.RequestMapping;
46 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
47 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
52 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
53 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
54 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
55 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
58 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
59 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
60 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
61
62 @Controller
63 @RequestMapping("/")
64 public class DecisionPolicyController extends RestrictedBaseController {
65     private static final Logger policyLogger = FlexLogger.getLogger(DecisionPolicyController.class);
66
67     public DecisionPolicyController() {
68         // This constructor is empty
69     }
70
71     protected PolicyRestAdapter policyAdapter = null;
72     private ArrayList<Object> attributeList;
73     private ArrayList<Object> decisionList;
74     private ArrayList<Object> ruleAlgorithmList;
75     private ArrayList<Object> treatmentList = null;
76     protected LinkedList<Integer> ruleAlgoirthmTracker;
77     public static final String FUNCTION_NOT = "urn:oasis:names:tc:xacml:1.0:function:not";
78     private static final String blEntry = "@blEntry@";
79     private static final String decisionRawType = "@#RuleProvider@#Decision_Raw@#RuleProvider@#";
80
81     public void rawXACMLPolicy(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
82         try (InputStream policyXmlStream = XACMLPolicyWriter.getXmlAsInputStream(policyAdapter.getPolicyData())) {
83             String name = StringUtils.substringAfter(entity.getPolicyName(), "Decision_");
84             policyAdapter.setPolicyName(name.substring(0, name.indexOf('.')));
85             policyAdapter.setRuleProvider("Raw");
86             policyAdapter.setRawXacmlPolicy(IOUtils.toString(policyXmlStream).replaceAll(decisionRawType, ""));
87         } catch (IOException e) {
88             policyLogger.error("Exception Occured while setting XACML Raw Object" + e);
89         }
90     }
91
92     @SuppressWarnings("unchecked")
93     public void prePopulateDecisionPolicyData(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
94         attributeList = new ArrayList<>();
95         decisionList = new ArrayList<>();
96         ruleAlgorithmList = new ArrayList<>();
97         treatmentList = new ArrayList<>();
98
99         boolean rawPolicyCheck = false;
100         if (policyAdapter.getPolicyData() instanceof PolicySetType) {
101             rawPolicyCheck = ((PolicySetType) policyAdapter.getPolicyData()).getDescription().contains(decisionRawType);
102         } else {
103             rawPolicyCheck = ((PolicyType) policyAdapter.getPolicyData()).getDescription().contains(decisionRawType);
104         }
105
106         if (rawPolicyCheck) {
107             rawXACMLPolicy(policyAdapter, entity);
108         } else {
109             RainyDayParams rainydayParams = new RainyDayParams();
110             Object policyData = policyAdapter.getPolicyData();
111             PolicyType policy = (PolicyType) policyData;
112             policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
113
114             policyAdapter.setPolicyName(StringUtils.substringAfter(policyAdapter.getPolicyName(), "Decision_"));
115             String description = "";
116             String blackListEntryType = "Use Manual Entry";
117             try {
118                 if (policy.getDescription().contains(blEntry)) {
119                     blackListEntryType = policy.getDescription().substring(policy.getDescription().indexOf(blEntry) + 9,
120                             policy.getDescription().lastIndexOf(blEntry));
121                 }
122                 policyAdapter.setBlackListEntryType(blackListEntryType);
123                 description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
124
125             } catch (Exception e) {
126                 policyLogger.info("General error", e);
127                 description = policy.getDescription();
128             }
129             policyAdapter.setPolicyDescription(description);
130             // Get the target data under policy for Action.
131             TargetType target = policy.getTarget();
132             if (target != null) {
133                 // under target we have AnyOFType
134                 List<AnyOfType> anyOfList = target.getAnyOf();
135                 if (anyOfList != null) {
136                     Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
137                     while (iterAnyOf.hasNext()) {
138                         AnyOfType anyOf = iterAnyOf.next();
139                         // Under AntOfType we have AllOfType
140                         List<AllOfType> allOfList = anyOf.getAllOf();
141                         if (allOfList != null) {
142                             Iterator<AllOfType> iterAllOf = allOfList.iterator();
143                             while (iterAllOf.hasNext()) {
144                                 AllOfType allOf = iterAllOf.next();
145                                 // Under AllOfType we have Mathch.
146                                 List<MatchType> matchList = allOf.getMatch();
147                                 int index = 0;
148                                 if (matchList != null) {
149                                     Iterator<MatchType> iterMatch = matchList.iterator();
150                                     while (iterMatch.hasNext()) {
151                                         MatchType match = iterMatch.next();
152                                         //
153                                         // Under the match we have attributevalue and
154                                         // attributeDesignator. So,finally down to the actual attribute.
155                                         //
156                                         AttributeValueType attributeValue = match.getAttributeValue();
157                                         String value = (String) attributeValue.getContent().get(0);
158                                         if (value != null) {
159                                             value = value.replaceAll("\\(\\?i\\)", "");
160                                         }
161                                         AttributeDesignatorType designator = match.getAttributeDesignator();
162                                         String attributeId = designator.getAttributeId();
163                                         // First match in the target is OnapName, so set that value.
164                                         if ("ONAPName".equals(attributeId)) {
165                                             policyAdapter.setOnapName(value);
166                                         }
167                                         // Component attributes are saved under Target here we are fetching them back.
168                                         // One row is default so we are not adding dynamic component at index 0.
169                                         if (index >= 1) {
170                                             Map<String, String> attribute = new HashMap<>();
171                                             attribute.put("key", attributeId);
172                                             attribute.put("value", value);
173                                             attributeList.add(attribute);
174                                         }
175                                         index++;
176                                     }
177                                 }
178                                 policyAdapter.setAttributes(attributeList);
179                             }
180                         }
181                     }
182                     // Setting rainy day attributes to the parameters object if they exist
183                     boolean rainy = false;
184                     if (!attributeList.isEmpty()) {
185                         for (int i = 0; i < attributeList.size(); i++) {
186                             Map<String, String> map = (Map<String, String>) attributeList.get(i);
187                             if ("WorkStep".equals(map.get("key"))) {
188                                 rainydayParams.setWorkstep(map.get("value"));
189                                 rainy = true;
190                             } else if ("BB_ID".equals(map.get("key"))) {
191                                 rainydayParams.setBbid(map.get("value"));
192                                 rainy = true;
193                             } else if ("ServiceType".equals(map.get("key"))) {
194                                 rainydayParams.setServiceType(map.get("value"));
195                                 rainy = true;
196                             } else if ("VNFType".equals(map.get("key"))) {
197                                 rainydayParams.setVnfType(map.get("value"));
198                                 rainy = true;
199                             }
200                         }
201                     }
202                     if (rainy) {
203                         policyAdapter.setRuleProvider("Rainy_Day");
204                     }
205                 }
206
207                 List<Object> ruleList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
208                 int index = 0;
209                 for (Object object : ruleList) {
210                     if (object instanceof VariableDefinitionType) {
211                         VariableDefinitionType variableDefinitionType = (VariableDefinitionType) object;
212                         Map<String, String> settings = new HashMap<>();
213                         settings.put("key", variableDefinitionType.getVariableId());
214                         JAXBElement<AttributeValueType> attributeValueTypeElement =
215                                 (JAXBElement<AttributeValueType>) variableDefinitionType.getExpression();
216                         if (attributeValueTypeElement != null) {
217                             AttributeValueType attributeValueType = attributeValueTypeElement.getValue();
218                             settings.put("value", attributeValueType.getContent().get(0).toString());
219                         }
220                         decisionList.add(settings);
221                     } else if (object instanceof RuleType) {
222                         // get the condition data under the rule for rule Algorithms.
223                         if (((RuleType) object).getEffect().equals(EffectType.DENY)) {
224                             if (((RuleType) object).getAdviceExpressions() != null) {
225                                 if ("AAF".equalsIgnoreCase(((RuleType) object).getAdviceExpressions()
226                                         .getAdviceExpression().get(0).getAdviceId())) {
227                                     policyAdapter.setRuleProvider("AAF");
228                                     break;
229                                 } else if ("GUARD_YAML".equalsIgnoreCase(((RuleType) object).getAdviceExpressions()
230                                         .getAdviceExpression().get(0).getAdviceId())) {
231                                     policyAdapter.setRuleProvider("GUARD_YAML");
232                                 } else if ("GUARD_BL_YAML".equalsIgnoreCase(((RuleType) object).getAdviceExpressions()
233                                         .getAdviceExpression().get(0).getAdviceId())) {
234                                     policyAdapter.setRuleProvider("GUARD_BL_YAML");
235                                 }
236                             } else {
237                                 policyAdapter.setRuleProvider("Custom");
238                             }
239                             ConditionType condition = ((RuleType) object).getCondition();
240                             if (condition != null) {
241                                 ApplyType decisionApply = (ApplyType) condition.getExpression().getValue();
242                                 decisionApply = (ApplyType) decisionApply.getExpression().get(0).getValue();
243                                 ruleAlgoirthmTracker = new LinkedList<>();
244                                 if (policyAdapter.getRuleProvider() != null
245                                         && ("GUARD_YAML".equals(policyAdapter.getRuleProvider())
246                                                 || ("GUARD_BL_YAML".equals(policyAdapter.getRuleProvider())))) {
247                                     YAMLParams yamlParams = new YAMLParams();
248                                     for (int i = 0; i < attributeList.size(); i++) {
249                                         Map<String, String> map = (Map<String, String>) attributeList.get(i);
250                                         if ("actor".equals(map.get("key"))) {
251                                             yamlParams.setActor(map.get("value"));
252                                         } else if ("recipe".equals(map.get("key"))) {
253                                             yamlParams.setRecipe(map.get("value"));
254                                         } else if ("target".equals(map.get("key"))) {
255                                             yamlParams.setTargets(Arrays.asList(map.get("value").split("\\|")));
256                                         } else if ("clname".equals(map.get("key"))) {
257                                             yamlParams.setClname(map.get("value"));
258                                         }
259                                     }
260                                     ApplyType apply =
261                                             (ApplyType) ((ApplyType) decisionApply.getExpression().get(0).getValue())
262                                                     .getExpression().get(0).getValue();
263                                     yamlParams.setGuardActiveStart(
264                                             ((AttributeValueType) apply.getExpression().get(1).getValue()).getContent()
265                                                     .get(0).toString());
266                                     yamlParams.setGuardActiveEnd(
267                                             ((AttributeValueType) apply.getExpression().get(2).getValue()).getContent()
268                                                     .get(0).toString());
269                                     if ("GUARD_BL_YAML".equals(policyAdapter.getRuleProvider())) {
270                                         apply = (ApplyType) ((ApplyType) ((ApplyType) decisionApply.getExpression()
271                                                 .get(0).getValue()).getExpression().get(1).getValue()).getExpression()
272                                                         .get(2).getValue();
273                                         Iterator<JAXBElement<?>> attributes = apply.getExpression().iterator();
274                                         List<String> blackList = new ArrayList<>();
275                                         while (attributes.hasNext()) {
276                                             blackList.add(((AttributeValueType) attributes.next().getValue())
277                                                     .getContent().get(0).toString());
278                                         }
279                                         yamlParams.setBlackList(blackList);
280                                         if ("Use File Upload".equals(policyAdapter.getBlackListEntryType())) {
281                                             policyAdapter.setBlackListEntries(blackList);
282                                         }
283                                     } else {
284                                         ApplyType timeWindowSection = (ApplyType) ((ApplyType) decisionApply
285                                                 .getExpression().get(0).getValue()).getExpression().get(1).getValue();
286                                         yamlParams.setLimit(((AttributeValueType) timeWindowSection.getExpression()
287                                                 .get(1).getValue()).getContent().get(0).toString());
288                                         String timeWindow = ((AttributeDesignatorType) ((ApplyType) timeWindowSection
289                                                 .getExpression().get(0).getValue()).getExpression().get(0).getValue())
290                                                         .getIssuer();
291                                         yamlParams.setTimeUnits(timeWindow.substring(timeWindow.lastIndexOf(':') + 1));
292                                         yamlParams.setTimeWindow(timeWindow.substring(timeWindow.indexOf(":tw:") + 4,
293                                                 timeWindow.lastIndexOf(':')));
294                                     }
295                                     policyAdapter.setYamlparams(yamlParams);
296                                     policyAdapter.setAttributes(new ArrayList<Object>());
297                                     policyAdapter.setRuleAlgorithmschoices(new ArrayList<Object>());
298                                     break;
299                                 }
300                                 // Populating Rule Algorithms starting from compound.
301                                 prePopulateDecisionCompoundRuleAlgorithm(index, decisionApply);
302                                 policyAdapter.setRuleAlgorithmschoices(ruleAlgorithmList);
303                             }
304                         } else if (policyAdapter.getRuleProvider() != null
305                                 && "Rainy_Day".equals(policyAdapter.getRuleProvider())
306                                 && ((RuleType) object).getEffect().equals(EffectType.PERMIT)) {
307
308                             TargetType ruleTarget = ((RuleType) object).getTarget();
309                             AdviceExpressionsType adviceExpression = ((RuleType) object).getAdviceExpressions();
310
311                             String errorcode = ruleTarget.getAnyOf().get(0).getAllOf().get(0).getMatch().get(1)
312                                     .getAttributeValue().getContent().get(0).toString();
313                             JAXBElement<AttributeValueType> tempTreatmentObj =
314                                     (JAXBElement<AttributeValueType>) adviceExpression.getAdviceExpression().get(0)
315                                             .getAttributeAssignmentExpression().get(0).getExpression();
316                             String treatment = tempTreatmentObj.getValue().getContent().get(0).toString();
317
318                             prePopulateRainyDayTreatments(errorcode, treatment);
319
320                         }
321                     }
322                 }
323             }
324
325             rainydayParams.setTreatmentTableChoices(treatmentList);
326             policyAdapter.setRainyday(rainydayParams);
327             policyAdapter.setSettings(decisionList);
328         }
329
330     }
331
332     private void prePopulateRainyDayTreatments(String errorcode, String treatment) {
333         Map<String, String> ruleMap = new HashMap<>();
334
335         ruleMap.put("errorcode", errorcode);
336         ruleMap.put("treatment", treatment);
337         treatmentList.add(ruleMap);
338
339     }
340
341     private void prePopulateDecisionRuleAlgorithms(int index, ApplyType decisionApply,
342             List<JAXBElement<?>> jaxbDecisionTypes) {
343         Map<String, String> ruleMap = new HashMap<>();
344         ruleMap.put("id", "A" + (index + 1));
345         Map<String, String> dropDownMap = PolicyController.getDropDownMap();
346         for (Entry<String, String> entry : dropDownMap.entrySet()) {
347             if (entry.getValue().equals(decisionApply.getFunctionId())) {
348                 ruleMap.put("dynamicRuleAlgorithmCombo", entry.getKey());
349             }
350         }
351         // Populate the key and value fields
352         if ((jaxbDecisionTypes.get(0).getValue() instanceof AttributeValueType)) {
353             ApplyType innerDecisionApply = (ApplyType) jaxbDecisionTypes.get(1).getValue();
354             List<JAXBElement<?>> jaxbInnerDecisionTypes = innerDecisionApply.getExpression();
355             if (jaxbInnerDecisionTypes.get(0).getValue() instanceof AttributeDesignatorType) {
356                 AttributeDesignatorType attributeDesignator =
357                         (AttributeDesignatorType) jaxbInnerDecisionTypes.get(0).getValue();
358                 ruleMap.put("dynamicRuleAlgorithmField1", attributeDesignator.getAttributeId());
359
360                 // Get from Attribute Value
361                 AttributeValueType actionConditionAttributeValue =
362                         (AttributeValueType) jaxbDecisionTypes.get(0).getValue();
363                 String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
364                 ruleMap.put("dynamicRuleAlgorithmField2", attributeValue);
365             }
366         } else if ((jaxbDecisionTypes.get(0).getValue()) instanceof VariableReferenceType) {
367             VariableReferenceType variableReference = (VariableReferenceType) jaxbDecisionTypes.get(0).getValue();
368             ruleMap.put("dynamicRuleAlgorithmField1", "S_" + variableReference.getVariableId());
369
370
371             // Get from Attribute Value
372             AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbDecisionTypes.get(1).getValue();
373             String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
374             ruleMap.put("dynamicRuleAlgorithmField2", attributeValue);
375         }
376         ruleAlgorithmList.add(ruleMap);
377     }
378
379     private int prePopulateDecisionCompoundRuleAlgorithm(int index, ApplyType decisionApply) {
380         boolean isCompoundRule = true;
381         List<JAXBElement<?>> jaxbDecisionTypes = decisionApply.getExpression();
382         for (JAXBElement<?> jaxbElement : jaxbDecisionTypes) {
383             // If There is Attribute Value under Decision Type that means we came to the final child
384             if (policyLogger.isDebugEnabled()) {
385                 policyLogger.debug("Prepopulating rule algoirthm: " + index);
386             }
387             // Check to see if Attribute Value exists, if yes then it is not a compound rule
388             if (jaxbElement.getValue() instanceof AttributeValueType) {
389                 prePopulateDecisionRuleAlgorithms(index, decisionApply, jaxbDecisionTypes);
390                 ruleAlgoirthmTracker.addLast(index);
391                 isCompoundRule = false;
392                 index++;
393             }
394         }
395         if (isCompoundRule) {
396             // As it's compound rule, Get the Apply types
397             for (JAXBElement<?> jaxbElement : jaxbDecisionTypes) {
398                 ApplyType innerDecisionApply = (ApplyType) jaxbElement.getValue();
399                 index = prePopulateDecisionCompoundRuleAlgorithm(index, innerDecisionApply);
400             }
401             // Populate combo box
402             if (policyLogger.isDebugEnabled()) {
403                 policyLogger.debug("Prepopulating Compound rule algorithm: " + index);
404             }
405             Map<String, String> rule = new HashMap<>();
406             for (String key : PolicyController.getDropDownMap().keySet()) {
407                 String keyValue = PolicyController.getDropDownMap().get(key);
408                 if (keyValue.equals(decisionApply.getFunctionId())) {
409                     rule.put("dynamicRuleAlgorithmCombo", key);
410                     break;
411                 }
412             }
413
414             rule.put("id", "A" + (index + 1));
415             // Populate Key and values for Compound Rule
416             rule.put("dynamicRuleAlgorithmField1", "A" + (ruleAlgoirthmTracker.getLast() + 1));
417             ruleAlgoirthmTracker.removeLast();
418             rule.put("dynamicRuleAlgorithmField2", "A" + (ruleAlgoirthmTracker.getLast() + 1));
419             ruleAlgoirthmTracker.removeLast();
420             ruleAlgoirthmTracker.addLast(index);
421             ruleAlgorithmList.add(rule);
422             index++;
423         }
424
425         return index;
426     }
427 }