2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.openecomp.policy.controller;
25 import java.io.IOException;
26 import java.io.PrintWriter;
27 import java.nio.file.Path;
28 import java.nio.file.Paths;
29 import java.util.ArrayList;
30 import java.util.HashMap;
31 import java.util.Iterator;
32 import java.util.LinkedHashMap;
33 import java.util.LinkedList;
34 import java.util.List;
36 import java.util.UUID;
38 import javax.servlet.http.HttpServletRequest;
39 import javax.servlet.http.HttpServletResponse;
40 import javax.xml.bind.JAXBElement;
42 import org.json.JSONObject;
43 import org.openecomp.policy.adapter.PolicyAdapter;
44 import org.openecomp.policy.admin.PolicyNotificationMail;
45 import org.openecomp.policy.admin.RESTfulPAPEngine;
46 import org.openecomp.policy.dao.PolicyVersionDao;
47 import org.openecomp.policy.dao.RuleAlgorithmsDao;
48 import org.openecomp.policy.dao.WatchPolicyNotificationDao;
49 import org.openecomp.policy.elk.client.PolicyElasticSearchController;
50 import org.openecomp.policy.rest.jpa.PolicyVersion;
51 import org.openecomp.policy.rest.jpa.RuleAlgorithms;
52 import org.openecomp.portalsdk.core.controller.RestrictedBaseController;
53 import org.openecomp.portalsdk.core.web.support.UserUtils;
54 import org.springframework.beans.factory.annotation.Autowired;
55 import org.springframework.stereotype.Controller;
56 import org.springframework.web.bind.annotation.RequestMapping;
57 import org.springframework.web.servlet.ModelAndView;
59 import org.openecomp.policy.common.logging.flexlogger.FlexLogger;
60 import org.openecomp.policy.common.logging.flexlogger.Logger;
62 import com.att.research.xacml.api.XACML3;
63 import org.openecomp.policy.xacml.util.XACMLPolicyScanner;
64 import com.fasterxml.jackson.databind.DeserializationFeature;
65 import com.fasterxml.jackson.databind.JsonNode;
66 import com.fasterxml.jackson.databind.ObjectMapper;
67 import com.google.common.base.Joiner;
69 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
70 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
71 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ApplyType;
72 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
73 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
74 import oasis.names.tc.xacml._3_0.core.schema.wd_17.ConditionType;
75 import oasis.names.tc.xacml._3_0.core.schema.wd_17.EffectType;
76 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
77 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
78 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
79 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
80 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableDefinitionType;
81 import oasis.names.tc.xacml._3_0.core.schema.wd_17.VariableReferenceType;
85 public class DecisionPolicyController extends RestrictedBaseController {
86 private static final Logger logger = FlexLogger.getLogger(DecisionPolicyController.class);
88 private static RuleAlgorithmsDao ruleAlgorithmsDao;
89 private static PolicyVersionDao policyVersionDao;
90 private static WatchPolicyNotificationDao policyNotificationDao;
93 private DecisionPolicyController(RuleAlgorithmsDao ruleAlgorithmsDao, PolicyVersionDao policyVersionDao, WatchPolicyNotificationDao policyNotificationDao){
94 DecisionPolicyController.policyVersionDao = policyVersionDao;
95 DecisionPolicyController.ruleAlgorithmsDao = ruleAlgorithmsDao;
96 DecisionPolicyController.policyNotificationDao = policyNotificationDao;
99 public DecisionPolicyController(){}
101 protected PolicyAdapter policyAdapter = null;
102 private static String ruleID = "";
103 private ArrayList<Object> attributeList;
104 private ArrayList<Object> decisionList;
105 private ArrayList<Object> ruleAlgorithmList;
106 protected LinkedList<Integer> ruleAlgoirthmTracker;
107 public static final String FUNCTION_NOT = "urn:oasis:names:tc:xacml:1.0:function:not";
109 public String newPolicyID() {
110 return Joiner.on(':').skipNulls().join((PolicyController.getDomain().startsWith("urn") ? null: "urn"),
111 PolicyController.getDomain().replaceAll("[/\\\\.]", ":"), "xacml", "policy", "id", UUID.randomUUID());
114 @RequestMapping(value={"/policyController/save_DecisionPolicy.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
115 public ModelAndView saveDecisionPolicy(HttpServletRequest request, HttpServletResponse response) throws Exception{
117 String userId = UserUtils.getUserIdFromCookie(request);
118 RESTfulPAPEngine engine = (RESTfulPAPEngine) PolicyController.getPapEngine();
119 ObjectMapper mapper = new ObjectMapper();
120 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
121 JsonNode root = mapper.readTree(request.getReader());
122 PolicyAdapter policyData = (PolicyAdapter)mapper.readValue(root.get("policyData").get("policy").toString(), PolicyAdapter.class);
123 if(root.get("policyData").get("model").get("type").toString().replace("\"", "").equals("file")){
124 policyData.isEditPolicy = true;
126 if(root.get("policyData").get("model").get("path").size() != 0){
128 for(int i = 0; i < root.get("policyData").get("model").get("path").size(); i++){
129 dirName = dirName.replace("\"", "") + root.get("policyData").get("model").get("path").get(i).toString().replace("\"", "") + File.separator;
131 policyData.setDomainDir(dirName.substring(0, dirName.lastIndexOf(File.separator)));
133 policyData.setDomainDir(root.get("policyData").get("model").get("name").toString().replace("\"", ""));
136 int highestVersion = 0;
137 int descriptionVersion = 0;
138 //get the highest version of policy from policy version table.
139 //getting the sub scope domain where the policy is created or updated
140 String dbCheckPolicyName = policyData.getDomainDir() + File.separator + "Decision_" + policyData.getPolicyName();
141 List<PolicyVersion> policyVersionList = policyVersionDao.getPolicyVersionEntityByName(dbCheckPolicyName);
142 if (policyVersionList.size() > 0) {
143 for(int i = 0; i < policyVersionList.size(); i++) {
144 PolicyVersion entityItem = policyVersionList.get(i);
145 if(entityItem.getPolicyName().equals(dbCheckPolicyName)){
146 highestVersion = entityItem.getHigherVersion();
150 if(highestVersion != 0){
151 version = highestVersion;
152 descriptionVersion = highestVersion +1;
155 descriptionVersion = 1;
158 //set policy adapter values for Building JSON object containing policy data
159 String createdBy = "";
160 String modifiedBy = userId;
161 if(descriptionVersion == 1){
164 String policyName = PolicyController.getGitPath().toAbsolutePath().toString() + File.separator + policyData.getDomainDir() + File.separator + policyData.getOldPolicyFileName() + ".xml";
165 File policyPath = new File(policyName);
167 createdBy = XACMLPolicyScanner.getCreatedBy(policyPath.toPath());
168 } catch (IOException e) {
173 policyData.setPolicyDescription(policyData.getPolicyDescription()+ "@CreatedBy:" +createdBy + "@CreatedBy:" + "@ModifiedBy:" +modifiedBy + "@ModifiedBy:");
174 Map<String, String> successMap = new HashMap<String, String>();
175 Map<String, String> attributeMap = new HashMap<String, String>();
176 Map<String, String> settingsMap = new HashMap<String, String>();
178 List<String> dynamicRuleAlgorithmLabels = new LinkedList<String>();
179 List<String> dynamicRuleAlgorithmCombo = new LinkedList<String>();
180 List<String> dynamicRuleAlgorithmField1 = new LinkedList<String>();
181 List<String> dynamicRuleAlgorithmField2 = new LinkedList<String>();
182 List<Object> dynamicVariableList = new LinkedList<Object>();
183 List<String> dataTypeList = new LinkedList<String>();
185 //set the Rule Combining Algorithm Id to be sent to PAP-REST via JSON
186 List<RuleAlgorithms> ruleAlgorithmsList = ruleAlgorithmsDao.getRuleAlgorithms();
187 for (int i = 0; i < ruleAlgorithmsList.size(); i++) {
188 RuleAlgorithms a = ruleAlgorithmsList.get(i);
189 if (a.getXacmlId().equals(XACML3.ID_RULE_PERMIT_OVERRIDES.stringValue())) {
190 policyData.setRuleCombiningAlgId(a.getXacmlId());
195 if(policyData.getAttributes().size() > 0){
196 for(Object attribute : policyData.getAttributes()){
197 if(attribute instanceof LinkedHashMap<?, ?>){
198 String key = ((LinkedHashMap<?, ?>) attribute).get("option").toString();
199 String value = ((LinkedHashMap<?, ?>) attribute).get("number").toString();
200 attributeMap.put(key, value);
205 if(policyData.getSettings().size() > 0){
206 for(Object settingsData : policyData.getSettings()){
207 if(settingsData instanceof LinkedHashMap<?, ?>){
208 String key = ((LinkedHashMap<?, ?>) settingsData).get("option").toString();
209 String value = ((LinkedHashMap<?, ?>) settingsData).get("number").toString();
210 settingsMap.put(key, value);
215 if(policyData.getRuleAlgorithmschoices().size() > 0){
216 for(Object attribute : policyData.getRuleAlgorithmschoices()){
217 if(attribute instanceof LinkedHashMap<?, ?>){
218 String label = ((LinkedHashMap<?, ?>) attribute).get("id").toString();
219 String key = ((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField1").toString();
220 String rule = ((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmCombo").toString();
221 String value = ((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField2").toString();
222 dynamicRuleAlgorithmLabels.add(label);
223 dynamicRuleAlgorithmField1.add(key);
224 dynamicRuleAlgorithmCombo.add(rule);
225 dynamicRuleAlgorithmField2.add(value);
230 policyData.setDynamicRuleAlgorithmLabels(dynamicRuleAlgorithmLabels);
231 policyData.setDynamicRuleAlgorithmCombo(dynamicRuleAlgorithmCombo);
232 policyData.setDynamicRuleAlgorithmField1(dynamicRuleAlgorithmField1);
233 policyData.setDynamicRuleAlgorithmField2(dynamicRuleAlgorithmField2);
234 policyData.setDynamicVariableList(dynamicVariableList);
235 policyData.setDynamicSettingsMap(settingsMap);
236 policyData.setDynamicFieldConfigAttributes(attributeMap);
237 policyData.setDataTypeList(dataTypeList);
238 if (policyData.isEditPolicy()){
239 //increment the version and set in policyAdapter
240 policyData.setVersion(String.valueOf(version));
241 policyData.setHighestVersion(version);
242 policyData.setPolicyID(this.newPolicyID());
243 policyData.setRuleID(ruleID);
244 successMap = engine.updatePolicyRequest(policyData);
246 //send it for policy creation
247 policyData.setVersion(String.valueOf(version));
248 policyData.setHighestVersion(version);
249 successMap = engine.createPolicyRequest(policyData);
253 if (successMap.containsKey("success")) {
254 // Add it into our tree
255 Path finalPolicyPath = null;
256 finalPolicyPath = Paths.get(successMap.get("success"));
257 PolicyElasticSearchController controller = new PolicyElasticSearchController();
258 controller.updateElk(finalPolicyPath.toString());
259 File file = finalPolicyPath.toFile();
261 String policyName = file.toString();
262 String removePath = policyName.substring(policyName.indexOf("repository")+11);
263 String removeXml = removePath.replace(".xml", "");
264 String removeExtension = removeXml.substring(0, removeXml.indexOf("."));
265 List<PolicyVersion> vesionList = policyVersionDao.getPolicyVersionEntityByName(removeExtension);
266 if (vesionList.size() > 0) {
267 for(int i = 0; i < vesionList.size(); i++) {
268 PolicyVersion entityItem = vesionList.get(i);
269 if(entityItem.getPolicyName().equals(removeExtension)){
270 version = entityItem.getHigherVersion() +1;
271 entityItem.setActiveVersion(version);
272 entityItem.setHigherVersion(version);
273 entityItem.setModifiedBy(userId);
274 policyVersionDao.update(entityItem);
275 if(policyData.isEditPolicy){
276 PolicyNotificationMail email = new PolicyNotificationMail();
277 String mode = "EditPolicy";
278 String policyNameForEmail = policyData.getDomainDir() + File.separator + policyData.getOldPolicyFileName() + ".xml";
279 email.sendMail(entityItem, policyNameForEmail, mode, policyNotificationDao);
284 PolicyVersion entityItem = new PolicyVersion();
285 entityItem.setActiveVersion(version);
286 entityItem.setHigherVersion(version);
287 entityItem.setPolicyName(removeExtension);
288 entityItem.setCreatedBy(userId);
289 entityItem.setModifiedBy(userId);
290 policyVersionDao.Save(entityItem);
295 response.setCharacterEncoding("UTF-8");
296 response.setContentType("application / json");
297 request.setCharacterEncoding("UTF-8");
299 PrintWriter out = response.getWriter();
300 String responseString = mapper.writeValueAsString(successMap);
301 JSONObject j = new JSONObject("{policyData: " + responseString + "}");
302 out.write(j.toString());
306 response.setCharacterEncoding("UTF-8");
307 request.setCharacterEncoding("UTF-8");
308 PrintWriter out = response.getWriter();
309 out.write(e.getMessage());
314 public void PrePopulateDecisionPolicyData(PolicyAdapter policyAdapter) {
315 attributeList = new ArrayList<Object>();
316 decisionList = new ArrayList<Object>();
317 ruleAlgorithmList = new ArrayList<Object>();
318 if (policyAdapter.getPolicyData() instanceof PolicyType) {
319 Object policyData = policyAdapter.getPolicyData();
320 PolicyType policy = (PolicyType) policyData;
321 policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
322 String policyNameValue = policyAdapter.getPolicyName().substring(policyAdapter.getPolicyName().indexOf("_") + 1, policyAdapter.getPolicyName().lastIndexOf("."));
323 policyAdapter.setPolicyName(policyNameValue);
324 String description = "";
326 description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
328 description = policy.getDescription();
330 policyAdapter.setPolicyDescription(description);
331 // Get the target data under policy for Action.
332 TargetType target = policy.getTarget();
333 if (target != null) {
334 // under target we have AnyOFType
335 List<AnyOfType> anyOfList = target.getAnyOf();
336 if (anyOfList != null) {
337 Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
338 while (iterAnyOf.hasNext()) {
339 AnyOfType anyOf = iterAnyOf.next();
340 // Under AntOfType we have AllOfType
341 List<AllOfType> allOfList = anyOf.getAllOf();
342 if (allOfList != null) {
343 Iterator<AllOfType> iterAllOf = allOfList.iterator();
344 while (iterAllOf.hasNext()) {
345 AllOfType allOf = iterAllOf.next();
346 // Under AllOfType we have Mathch.
347 List<MatchType> matchList = allOf.getMatch();
349 if (matchList != null) {
350 Iterator<MatchType> iterMatch = matchList.iterator();
351 while (iterMatch.hasNext()) {
352 MatchType match = iterMatch.next();
354 // Under the match we have attributevalue and
355 // attributeDesignator. So,finally down to the actual attribute.
357 AttributeValueType attributeValue = match.getAttributeValue();
358 String value = (String) attributeValue.getContent().get(0);
359 AttributeDesignatorType designator = match.getAttributeDesignator();
360 String attributeId = designator.getAttributeId();
361 // First match in the target is EcompName, so set that value.
363 policyAdapter.setEcompName(value);
365 // Component attributes are saved under Target here we are fetching them back.
366 // One row is default so we are not adding dynamic componet at index 0.
368 Map<String, String> attribute = new HashMap<String, String>();
369 attribute.put("option", attributeId);
370 attribute.put("number", value);
371 attributeList.add(attribute);
376 policyAdapter.setAttributes(attributeList);
382 List<Object> ruleList = policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition();
384 for (Object object : ruleList) {
385 if (object instanceof VariableDefinitionType) {
386 VariableDefinitionType variableDefinitionType = (VariableDefinitionType) object;
387 Map<String, String> settings = new HashMap<String, String>();
388 settings.put("option", variableDefinitionType.getVariableId());
389 JAXBElement<AttributeValueType> attributeValueTypeElement = (JAXBElement<AttributeValueType>) variableDefinitionType.getExpression();
390 if (attributeValueTypeElement != null) {
391 AttributeValueType attributeValueType = attributeValueTypeElement.getValue();
392 settings.put("number", attributeValueType.getContent().get(0).toString());
394 decisionList.add(settings);
395 } else if (object instanceof RuleType) {
396 // get the condition data under the rule for rule Algorithms.
397 ruleID = ((RuleType) object).getRuleId();
398 if (((RuleType) object).getEffect().equals(EffectType.PERMIT)) {
399 ConditionType condition = ((RuleType) object).getCondition();
400 if (condition != null) {
401 ApplyType decisionApply = (ApplyType) condition.getExpression().getValue();
402 ruleAlgoirthmTracker = new LinkedList<Integer>();
403 // Populating Rule Algorithms starting from compound.
404 prePopulateDecisionCompoundRuleAlgorithm(index, decisionApply);
405 policyAdapter.setRuleAlgorithmschoices(ruleAlgorithmList);
407 }else if(((RuleType) object).getEffect().equals(EffectType.DENY)) {
408 if(((RuleType) object).getAdviceExpressions()!=null){
409 if(((RuleType) object).getAdviceExpressions().getAdviceExpression().get(0).getAdviceId().toString().equalsIgnoreCase("AAF")){
410 policyAdapter.setRuleProvider("AAF");
414 policyAdapter.setRuleProvider("Custom");
420 policyAdapter.setSettings(decisionList);
425 private void prePopulateDecisionRuleAlgorithms(int index, ApplyType decisionApply, List<JAXBElement<?>> jaxbDecisionTypes) {
426 Map<String, String> ruleMap = new HashMap<String, String>();
427 ruleMap.put("id", "A" + (index +1));
428 Map<String, String> dropDownMap = PolicyController.getDropDownMap();
429 for (String key : dropDownMap.keySet()) {
430 String keyValue = dropDownMap.get(key);
431 if (keyValue.equals(decisionApply.getFunctionId())) {
432 ruleMap.put("dynamicRuleAlgorithmCombo", key);
435 // Populate the key and value fields
436 if (((jaxbDecisionTypes.get(0).getValue()) instanceof AttributeValueType)) {
437 ApplyType innerDecisionApply = (ApplyType) jaxbDecisionTypes.get(1).getValue();
438 List<JAXBElement<?>> jaxbInnerDecisionTypes = innerDecisionApply.getExpression();
439 if (jaxbInnerDecisionTypes.get(0).getValue() instanceof AttributeDesignatorType) {
440 AttributeDesignatorType attributeDesignator = (AttributeDesignatorType) jaxbInnerDecisionTypes.get(0).getValue();
441 ruleMap.put("dynamicRuleAlgorithmField1", attributeDesignator.getAttributeId());
443 // Get from Attribute Value
444 AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbDecisionTypes.get(0).getValue();
445 String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
446 ruleMap.put("dynamicRuleAlgorithmField2", attributeValue);
448 } else if ((jaxbDecisionTypes.get(0).getValue()) instanceof VariableReferenceType) {
449 VariableReferenceType variableReference = (VariableReferenceType) jaxbDecisionTypes.get(0).getValue();
450 ruleMap.put("dynamicRuleAlgorithmField1", "S_"+ variableReference.getVariableId());
453 // Get from Attribute Value
454 AttributeValueType actionConditionAttributeValue = (AttributeValueType) jaxbDecisionTypes.get(1).getValue();
455 String attributeValue = (String) actionConditionAttributeValue.getContent().get(0);
456 ruleMap.put("dynamicRuleAlgorithmField2", attributeValue);
458 ruleAlgorithmList.add(ruleMap);
461 private int prePopulateDecisionCompoundRuleAlgorithm(int index, ApplyType decisionApply) {
462 boolean isCompoundRule = true;
463 List<JAXBElement<?>> jaxbDecisionTypes = decisionApply.getExpression();
464 for (JAXBElement<?> jaxbElement : jaxbDecisionTypes) {
465 // If There is Attribute Value under Decision Type that means we came to the final child
466 if (logger.isDebugEnabled()) {
467 logger.debug("Prepopulating rule algoirthm: " + index);
469 // Check to see if Attribute Value exists, if yes then it is not a compound rule
470 if(jaxbElement.getValue() instanceof AttributeValueType) {
471 prePopulateDecisionRuleAlgorithms(index, decisionApply, jaxbDecisionTypes);
472 ruleAlgoirthmTracker.addLast(index);
473 isCompoundRule = false;
477 if (isCompoundRule) {
478 // As it's compound rule, Get the Apply types
479 for (JAXBElement<?> jaxbElement : jaxbDecisionTypes) {
480 ApplyType innerDecisionApply = (ApplyType) jaxbElement.getValue();
481 index = prePopulateDecisionCompoundRuleAlgorithm(index, innerDecisionApply);
483 // Populate combo box
484 if (logger.isDebugEnabled()) {
485 logger.debug("Prepopulating Compound rule algorithm: " + index);
487 Map<String, String> rule = new HashMap<String, String>();
488 for (String key : PolicyController.getDropDownMap().keySet()) {
489 String keyValue = PolicyController.getDropDownMap().get(key);
490 if (keyValue.equals(decisionApply.getFunctionId())) {
491 rule.put("dynamicRuleAlgorithmCombo", key);
495 rule.put("id", "A" + (index +1));
496 // Populate Key and values for Compound Rule
497 rule.put("dynamicRuleAlgorithmField1", "A" + (ruleAlgoirthmTracker.getLast() + 1 ));
498 ruleAlgoirthmTracker.removeLast();
499 rule.put("dynamicRuleAlgorithmField2", "A" + (ruleAlgoirthmTracker.getLast() + 1));
500 ruleAlgoirthmTracker.removeLast();
501 ruleAlgoirthmTracker.addLast(index);
502 ruleAlgorithmList.add(rule);