98a479f8178f260beb2fc67db771a5e4ada99062
[policy/engine.git] / POLICY-SDK-APP / src / main / java / org / onap / policy / controller / ActionPolicyController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Engine
4  * ================================================================================
5  * Copyright (C) 2017, 2019 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Bell Canada
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.controller;
23
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Map.Entry;
30 import javax.xml.bind.JAXBElement;
31 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
32 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
33 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
34 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
35 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
36 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
37 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
38 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
39 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
42 import org.onap.policy.common.logging.flexlogger.FlexLogger;
43 import org.onap.policy.common.logging.flexlogger.Logger;
44 import org.onap.policy.rest.adapter.PolicyRestAdapter;
45 import org.onap.portalsdk.core.controller.RestrictedBaseController;
46 import org.springframework.stereotype.Controller;
47 import org.springframework.web.bind.annotation.RequestMapping;
48
49 @Controller
50 @RequestMapping({"/"})
51 public class ActionPolicyController extends RestrictedBaseController {
52     private static final Logger LOGGER = FlexLogger.getLogger(ActionPolicyController.class);
53     private static final String PERFORMER_ATTRIBUTE_ID = "performer";
54     private static final String DYNAMIC_RULE_ALGORITHM_FIELD_1 = "dynamicRuleAlgorithmField1";
55     private static final String DYNAMIC_RULE_ALGORITHM_FIELD_2 = "dynamicRuleAlgorithmField2";
56     private LinkedList<Integer> ruleAlgorithmTracker;
57     private Map<String, String> performer = new HashMap<>();
58     private List<Object> ruleAlgorithmList;
59
60     public ActionPolicyController() {
61         // Default Constructor
62     }
63
64     /**
65      * prePopulateActionPolicyData.
66      *
67      * @param policyAdapter PolicyRestAdapter
68      */
69     public void prePopulateActionPolicyData(PolicyRestAdapter policyAdapter) {
70         ruleAlgorithmList = new ArrayList<>();
71         performer.put("PDP", "PDPAction");
72         performer.put("PEP", "PEPAction");
73
74         if (policyAdapter.getPolicyData() instanceof PolicyType) {
75             PolicyType policy = (PolicyType) policyAdapter.getPolicyData();
76
77             // 1. Set policy-name, policy-filename and description to Policy Adapter
78             setPolicyAdapterPolicyNameAndDesc(policyAdapter, policy);
79
80             // 2a. Get the target data under policy for Action.
81             TargetType target = policy.getTarget();
82             if (target == null) {
83                 return;
84             }
85
86             // 2b. Set attributes to Policy Adapter
87             setPolicyAdapterAttributes(policyAdapter, target.getAnyOf());
88
89             List<Object> ruleList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
90             // Under rule we have Condition and obligation.
91             for (Object o : ruleList) {
92                 if (!(o instanceof RuleType)) {
93                     continue;
94                 }
95                 // 3. Set rule-algorithm choices to Policy Adapter
96                 setPolicyAdapterRuleAlgorithmschoices(policyAdapter, (RuleType) o);
97
98                 // 4a. Get the Obligation data under the rule for Form elements.
99                 ObligationExpressionsType obligations = ((RuleType) o).getObligationExpressions();
100
101                 // 4b. Set action attribute-value and action-performer to Policy Adapter
102                 setPolicyAdapterActionData(policyAdapter, obligations);
103             }
104         }
105     }
106
107     private void setPolicyAdapterActionData(PolicyRestAdapter policyAdapter, ObligationExpressionsType obligations) {
108         if (obligations == null) {
109             return;
110         }
111         // Under the obligationExpressions we have obligationExpression.
112         // NOTE: getObligationExpression() will never return NULL.
113         //
114         for (ObligationExpressionType obligation : obligations.getObligationExpression()) {
115             policyAdapter.setActionAttributeValue(obligation.getObligationId());
116             // Under the obligationExpression we have attributeAssignmentExpression.
117             //
118             // NOTE: obligation.getAttributeAssignmentExpression() will NEVER be null
119             // It will always return a list.
120             //
121             for (AttributeAssignmentExpressionType attributeAssignmentExpression :
122                 obligation.getAttributeAssignmentExpression()) {
123                 //
124                 //
125                 //
126                 String attributeID = attributeAssignmentExpression.getAttributeId();
127                 AttributeValueType attributeValue =
128                         (AttributeValueType) attributeAssignmentExpression.getExpression().getValue();
129                 if (!attributeID.equals(PERFORMER_ATTRIBUTE_ID)) {
130                     continue;
131                 }
132                 performer.forEach((key, keyValue) -> {
133                     if (keyValue.equals(attributeValue.getContent().get(0))) {
134                         policyAdapter.setActionPerformer(key);
135                     }
136                 });
137             }
138         }
139     }
140
141     private void setPolicyAdapterPolicyNameAndDesc(PolicyRestAdapter policyAdapter, PolicyType policy) {
142         policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
143         String policyNameValue =
144                 policyAdapter.getPolicyName().substring(policyAdapter.getPolicyName().indexOf('_') + 1);
145         policyAdapter.setPolicyName(policyNameValue);
146         String description;
147         try {
148             description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
149         } catch (Exception e) {
150             LOGGER.error("Error while collecting the description tag in ActionPolicy " + policyNameValue, e);
151             description = policy.getDescription();
152         }
153         policyAdapter.setPolicyDescription(description);
154     }
155
156     private void setPolicyAdapterRuleAlgorithmschoices(PolicyRestAdapter policyAdapter, RuleType ruleType) {
157         if (ruleType.getCondition() != null) {
158             int index = 0;
159             ApplyType actionApply = (ApplyType) ruleType.getCondition().getExpression().getValue();
160             ruleAlgorithmTracker = new LinkedList<>();
161             // Populating Rule Algorithms starting from compound.
162             prePopulateCompoundRuleAlgorithm(index, actionApply);
163         }
164         policyAdapter.setRuleAlgorithmschoices(ruleAlgorithmList);
165     }
166
167     private void setPolicyAdapterAttributes(PolicyRestAdapter policyAdapter, List<AnyOfType> anyOfList) {
168         List<Object> attributeList = new ArrayList<>();
169         //
170         // NOTE: If using xacml3 code and doing a getAnyOf(), the anyOfList will
171         // NEVER be null as that code will create it if it is null.
172         //
173         // Remove the null check as its impossible to cover it.
174         //
175         // under target we have AnyOFType
176         for (AnyOfType anyOf : anyOfList) {
177             // Under AntOfType we have AllOfType
178             //
179             // NOTE: This will NEVER be null as the method call in the
180             // previous line getAllOf() will never return a null. It
181             // always creates it if its empty.
182             //
183             List<AllOfType> allOfList = anyOf.getAllOf();
184             // Under AllOfType we have Match.
185             for (AllOfType allOfType : allOfList) {
186                 //
187                 // NOTE: allOfType.getMatch() will NEVER be null as the method
188                 // call getMatch will always return something. If its
189                 // not there it will create it.
190                 //
191                 //
192                 // Under the match we have attributeValue and
193                 // attributeDesignator. So,finally down to the actual attribute.
194                 //
195                 // Component attributes are saved under Target here we are fetching them back.
196                 // One row is default so we are not adding dynamic component at index 0.
197                 allOfType.getMatch().forEach(match -> {
198                     AttributeValueType attributeValue = match.getAttributeValue();
199                     String value = (String) attributeValue.getContent().get(0);
200                     AttributeDesignatorType designator = match.getAttributeDesignator();
201                     String attributeId = designator.getAttributeId();
202                     Map<String, String> attribute = new HashMap<>();
203                     attribute.put("key", attributeId);
204                     attribute.put("value", value);
205                     attributeList.add(attribute);
206                 });
207                 policyAdapter.setAttributes(attributeList);
208             }
209         }
210     }
211
212     private int prePopulateCompoundRuleAlgorithm(int index, ApplyType actionApply) {
213         boolean isCompoundRule = true;
214         List<JAXBElement<?>> jaxbActionTypes = actionApply.getExpression();
215         for (JAXBElement<?> jaxbElement : jaxbActionTypes) {
216             // If There is Attribute Value under Action Type that means we came to the final child
217             if (LOGGER.isDebugEnabled()) {
218                 LOGGER.debug("Prepopulating rule algoirthm: " + index);
219             }
220             // Check to see if Attribute Value exists, if yes then it is not a compound rule
221             if (jaxbElement.getValue() instanceof AttributeValueType
222                     || jaxbElement.getValue() instanceof AttributeDesignatorType) {
223                 prePopulateRuleAlgorithms(index, actionApply, jaxbActionTypes);
224                 ruleAlgorithmTracker.addLast(index);
225                 isCompoundRule = false;
226                 index++;
227             }
228         }
229         if (isCompoundRule) {
230             // As it's compound rule, Get the Apply types
231             for (JAXBElement<?> jaxbElement : jaxbActionTypes) {
232                 ApplyType innerActionApply = (ApplyType) jaxbElement.getValue();
233                 index = prePopulateCompoundRuleAlgorithm(index, innerActionApply);
234             }
235             // Populate combo box
236             if (LOGGER.isDebugEnabled()) {
237                 LOGGER.debug("Prepopulating Compound rule algorithm: " + index);
238             }
239             Map<String, String> rule = new HashMap<>();
240             for (String key : PolicyController.getDropDownMap().keySet()) {
241                 String keyValue = PolicyController.getDropDownMap().get(key);
242                 if (keyValue.equals(actionApply.getFunctionId())) {
243                     rule.put("dynamicRuleAlgorithmCombo", key);
244                 }
245             }
246             rule.put("id", "A" + (index + 1));
247             // Populate Key and values for Compound Rule
248             rule.put(DYNAMIC_RULE_ALGORITHM_FIELD_1, "A" + (ruleAlgorithmTracker.getLast() + 1));
249             ruleAlgorithmTracker.removeLast();
250             rule.put(DYNAMIC_RULE_ALGORITHM_FIELD_2, "A" + (ruleAlgorithmTracker.getLast() + 1));
251             ruleAlgorithmTracker.removeLast();
252             ruleAlgorithmTracker.addLast(index);
253             ruleAlgorithmList.add(rule);
254             index++;
255         }
256         return index;
257     }
258
259     private void prePopulateRuleAlgorithms(int index, ApplyType actionApply, List<JAXBElement<?>> jaxbActionTypes) {
260         Map<String, String> ruleMap = new HashMap<>();
261         ruleMap.put("id", "A" + (index + 1));
262         // Populate combo box
263         Map<String, String> dropDownMap = PolicyController.getDropDownMap();
264         for (Entry<String, String> entry : dropDownMap.entrySet()) {
265             if (entry.getValue().equals(actionApply.getFunctionId())) {
266                 ruleMap.put("dynamicRuleAlgorithmCombo", entry.getKey());
267             }
268         }
269         // Populate the key and value fields
270         // Rule Attribute added as key
271         if ((jaxbActionTypes.get(0).getValue()) instanceof ApplyType) {
272             // Get from Attribute Designator
273             ApplyType innerActionApply = (ApplyType) jaxbActionTypes.get(0).getValue();
274             List<JAXBElement<?>> jaxbInnerActionTypes = innerActionApply.getExpression();
275             AttributeDesignatorType attributeDesignator =
276                     (AttributeDesignatorType) jaxbInnerActionTypes.get(0).getValue();
277             ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_1, attributeDesignator.getAttributeId());
278
279             // Get from Attribute Value
280             AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbActionTypes.get(1).getValue();
281             String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
282             ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_2, attributeValue);
283         }
284         // Rule Attribute added as value
285         else if ((jaxbActionTypes.get(0).getValue()) instanceof AttributeValueType) {
286             AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbActionTypes.get(0).getValue();
287             String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
288             ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_2, attributeValue);
289
290             //
291             // This is making a BIG assumption here that there exists an innerApply. This IF
292             // statement was added to support JUnit code coverage. For lack of any example of what
293             // this policy should actually look like.
294             //
295             if (jaxbActionTypes.size() > 1) {
296                 ApplyType innerActionApply = (ApplyType) jaxbActionTypes.get(1).getValue();
297                 List<JAXBElement<?>> jaxbInnerActionTypes = innerActionApply.getExpression();
298                 AttributeDesignatorType attributeDesignator =
299                         (AttributeDesignatorType) jaxbInnerActionTypes.get(0).getValue();
300                 ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_1, attributeDesignator.getAttributeId());
301             }
302         }
303         ruleAlgorithmList.add(ruleMap);
304     }
305 }