2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
22 package org.onap.policy.controller;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.LinkedList;
27 import java.util.List;
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.MatchType;
38 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionType;
39 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ObligationExpressionsType;
40 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
41 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
42 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
43 import org.onap.policy.common.logging.flexlogger.FlexLogger;
44 import org.onap.policy.common.logging.flexlogger.Logger;
45 import org.onap.policy.rest.adapter.PolicyRestAdapter;
46 import org.onap.portalsdk.core.controller.RestrictedBaseController;
47 import org.springframework.stereotype.Controller;
48 import org.springframework.web.bind.annotation.RequestMapping;
51 @RequestMapping({"/"})
52 public class ActionPolicyController extends RestrictedBaseController {
53 private static final Logger LOGGER = FlexLogger.getLogger(ActionPolicyController.class);
54 private static final String PERFORMER_ATTRIBUTE_ID = "performer";
55 private static final String DYNAMIC_RULE_ALGORITHM_FIELD_1 = "dynamicRuleAlgorithmField1";
56 private static final String DYNAMIC_RULE_ALGORITHM_FIELD_2 = "dynamicRuleAlgorithmField2";
57 private LinkedList<Integer> ruleAlgorithmTracker;
58 private Map<String, String> performer = new HashMap<>();
59 private List<Object> ruleAlgorithmList;
61 public ActionPolicyController() {
62 // Default Constructor
66 * prePopulateActionPolicyData.
68 * @param policyAdapter PolicyRestAdapter
70 public void prePopulateActionPolicyData(PolicyRestAdapter policyAdapter) {
71 ruleAlgorithmList = new ArrayList<>();
72 performer.put("PDP", "PDPAction");
73 performer.put("PEP", "PEPAction");
75 if (! (policyAdapter.getPolicyData() instanceof PolicyType)) {
78 PolicyType policy = (PolicyType) policyAdapter.getPolicyData();
80 // 1. Set policy-name, policy-filename and description to Policy Adapter
81 setPolicyAdapterPolicyNameAndDesc(policyAdapter, policy);
83 // 2a. Get the target data under policy for Action.
84 TargetType target = policy.getTarget();
89 // 2b. Set attributes to Policy Adapter
90 setPolicyAdapterAttributes(policyAdapter, target.getAnyOf());
92 List<Object> ruleList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
93 // Under rule we have Condition and obligation.
94 for (Object o : ruleList) {
95 if (!(o instanceof RuleType)) {
98 // 3. Set rule-algorithm choices to Policy Adapter
99 setPolicyAdapterRuleAlgorithmschoices(policyAdapter, (RuleType) o);
101 // 4a. Get the Obligation data under the rule for Form elements.
102 ObligationExpressionsType obligations = ((RuleType) o).getObligationExpressions();
104 // 4b. Set action attribute-value and action-performer to Policy Adapter
105 setPolicyAdapterActionData(policyAdapter, obligations);
109 private void setPolicyAdapterActionData(PolicyRestAdapter policyAdapter, ObligationExpressionsType obligations) {
110 if (obligations == null) {
113 // Under the obligationExpressions we have obligationExpression.
114 // NOTE: getObligationExpression() will never return NULL.
116 for (ObligationExpressionType obligation : obligations.getObligationExpression()) {
117 policyAdapter.setActionAttributeValue(obligation.getObligationId());
118 // Under the obligationExpression we have attributeAssignmentExpression.
120 // NOTE: obligation.getAttributeAssignmentExpression() will NEVER be null
121 // It will always return a list.
123 for (AttributeAssignmentExpressionType attributeAssignmentExpression :
124 obligation.getAttributeAssignmentExpression()) {
128 String attributeID = attributeAssignmentExpression.getAttributeId();
129 AttributeValueType attributeValue =
130 (AttributeValueType) attributeAssignmentExpression.getExpression().getValue();
131 if (!attributeID.equals(PERFORMER_ATTRIBUTE_ID)) {
134 performer.forEach((key, keyValue) -> {
135 if (keyValue.equals(attributeValue.getContent().get(0))) {
136 policyAdapter.setActionPerformer(key);
143 private void setPolicyAdapterPolicyNameAndDesc(PolicyRestAdapter policyAdapter, PolicyType policy) {
144 policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
145 String policyNameValue =
146 policyAdapter.getPolicyName().substring(policyAdapter.getPolicyName().indexOf('_') + 1);
147 policyAdapter.setPolicyName(policyNameValue);
150 description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
151 } catch (Exception e) {
152 LOGGER.error("Error while collecting the description tag in ActionPolicy " + policyNameValue, e);
153 description = policy.getDescription();
155 policyAdapter.setPolicyDescription(description);
158 private void setPolicyAdapterRuleAlgorithmschoices(PolicyRestAdapter policyAdapter, RuleType ruleType) {
159 if (ruleType.getCondition() != null) {
161 ApplyType actionApply = (ApplyType) ruleType.getCondition().getExpression().getValue();
162 ruleAlgorithmTracker = new LinkedList<>();
163 // Populating Rule Algorithms starting from compound.
164 prePopulateCompoundRuleAlgorithm(index, actionApply);
166 policyAdapter.setRuleAlgorithmschoices(ruleAlgorithmList);
169 private void setPolicyAdapterAttributes(PolicyRestAdapter policyAdapter, List<AnyOfType> anyOfList) {
170 List<Object> attributeList = new ArrayList<>();
172 // NOTE: If using xacml3 code and doing a getAnyOf(), the anyOfList will
173 // NEVER be null as that code will create it if it is null.
175 // Remove the null check as its impossible to cover it.
177 // under target we have AnyOFType
178 for (AnyOfType anyOf : anyOfList) {
179 // Under AntOfType we have AllOfType
181 // NOTE: This will NEVER be null as the method call in the
182 // previous line getAllOf() will never return a null. It
183 // always creates it if its empty.
185 List<AllOfType> allOfList = anyOf.getAllOf();
186 // Under AllOfType we have Match.
187 for (AllOfType allOfType : allOfList) {
189 // NOTE: allOfType.getMatch() will NEVER be null as the method
190 // call getMatch will always return something. If its
191 // not there it will create it.
194 // Under the match we have attributeValue and
195 // attributeDesignator. So,finally down to the actual attribute.
197 // Component attributes are saved under Target here we are fetching them back.
198 // One row is default so we are not adding dynamic component at index 0.
199 for (MatchType match : allOfType.getMatch()) {
200 AttributeValueType attributeValue = match.getAttributeValue();
201 String value = (String) attributeValue.getContent().get(0);
202 AttributeDesignatorType designator = match.getAttributeDesignator();
203 String attributeId = designator.getAttributeId();
204 Map<String, String> attribute = new HashMap<>();
205 attribute.put("key", attributeId);
206 attribute.put("value", value);
207 attributeList.add(attribute);
209 policyAdapter.setAttributes(attributeList);
214 private int prePopulateCompoundRuleAlgorithm(int index, ApplyType actionApply) {
215 boolean isCompoundRule = true;
216 List<JAXBElement<?>> jaxbActionTypes = actionApply.getExpression();
217 for (JAXBElement<?> jaxbElement : jaxbActionTypes) {
218 // If There is Attribute Value under Action Type that means we came to the final child
219 if (LOGGER.isDebugEnabled()) {
220 LOGGER.debug("Prepopulating rule algoirthm: " + index);
222 // Check to see if Attribute Value exists, if yes then it is not a compound rule
223 if (jaxbElement.getValue() instanceof AttributeValueType
224 || jaxbElement.getValue() instanceof AttributeDesignatorType) {
225 prePopulateRuleAlgorithms(index, actionApply, jaxbActionTypes);
226 ruleAlgorithmTracker.addLast(index);
227 isCompoundRule = false;
231 if (!isCompoundRule) {
234 // As it's compound rule, Get the Apply types
235 for (JAXBElement<?> jaxbElement : jaxbActionTypes) {
236 ApplyType innerActionApply = (ApplyType) jaxbElement.getValue();
237 index = prePopulateCompoundRuleAlgorithm(index, innerActionApply);
239 // Populate combo box
240 if (LOGGER.isDebugEnabled()) {
241 LOGGER.debug("Prepopulating Compound rule algorithm: " + index);
243 Map<String, String> rule = new HashMap<>();
244 for ( Entry<String, String> entrySet : PolicyController.getDropDownMap().entrySet()) {
245 if (entrySet.getValue().equals(actionApply.getFunctionId())) {
246 rule.put("dynamicRuleAlgorithmCombo", entrySet.getKey());
249 rule.put("id", "A" + (index + 1));
250 // Populate Key and values for Compound Rule
251 rule.put(DYNAMIC_RULE_ALGORITHM_FIELD_1, "A" + (ruleAlgorithmTracker.getLast() + 1));
252 ruleAlgorithmTracker.removeLast();
253 rule.put(DYNAMIC_RULE_ALGORITHM_FIELD_2, "A" + (ruleAlgorithmTracker.getLast() + 1));
254 ruleAlgorithmTracker.removeLast();
255 ruleAlgorithmTracker.addLast(index);
256 ruleAlgorithmList.add(rule);
260 private void prePopulateRuleAlgorithms(int index, ApplyType actionApply, List<JAXBElement<?>> jaxbActionTypes) {
261 Map<String, String> ruleMap = new HashMap<>();
262 ruleMap.put("id", "A" + (index + 1));
263 // Populate combo box
264 Map<String, String> dropDownMap = PolicyController.getDropDownMap();
265 for (Entry<String, String> entry : dropDownMap.entrySet()) {
266 if (entry.getValue().equals(actionApply.getFunctionId())) {
267 ruleMap.put("dynamicRuleAlgorithmCombo", entry.getKey());
270 // Populate the key and value fields
271 // Rule Attribute added as key
272 if ((jaxbActionTypes.get(0).getValue()) instanceof ApplyType) {
273 // Get from Attribute Designator
274 ApplyType innerActionApply = (ApplyType) jaxbActionTypes.get(0).getValue();
275 List<JAXBElement<?>> jaxbInnerActionTypes = innerActionApply.getExpression();
276 AttributeDesignatorType attributeDesignator =
277 (AttributeDesignatorType) jaxbInnerActionTypes.get(0).getValue();
278 ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_1, attributeDesignator.getAttributeId());
280 // Get from Attribute Value
281 AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbActionTypes.get(1).getValue();
282 String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
283 ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_2, attributeValue);
285 // Rule Attribute added as value
286 else if ((jaxbActionTypes.get(0).getValue()) instanceof AttributeValueType) {
287 AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbActionTypes.get(0).getValue();
288 String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
289 ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_2, attributeValue);
292 // This is making a BIG assumption here that there exists an innerApply. This IF
293 // statement was added to support JUnit code coverage. For lack of any example of what
294 // this policy should actually look like.
296 if (jaxbActionTypes.size() > 1) {
297 ApplyType innerActionApply = (ApplyType) jaxbActionTypes.get(1).getValue();
298 List<JAXBElement<?>> jaxbInnerActionTypes = innerActionApply.getExpression();
299 if (! jaxbInnerActionTypes.isEmpty()) {
300 AttributeDesignatorType attributeDesignator =
301 (AttributeDesignatorType) jaxbInnerActionTypes.get(0).getValue();
302 ruleMap.put(DYNAMIC_RULE_ALGORITHM_FIELD_1, attributeDesignator.getAttributeId());
306 ruleAlgorithmList.add(ruleMap);