2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2019 AT&T Intellectual Property. All rights reserved.
6 * Modified Copyright (C) 2018 Samsung Electronics Co., Ltd.
7 * Modifications Copyright (C) 2019 Bell Canada
8 * ================================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.controller;
25 import com.fasterxml.jackson.databind.DeserializationFeature;
26 import com.fasterxml.jackson.databind.JsonNode;
27 import com.fasterxml.jackson.databind.ObjectMapper;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.LinkedHashMap;
35 import java.util.List;
37 import java.util.Map.Entry;
38 import java.util.Objects;
40 import java.util.regex.Matcher;
41 import java.util.regex.Pattern;
42 import java.util.stream.Collectors;
44 import javax.servlet.http.HttpServletRequest;
45 import javax.servlet.http.HttpServletResponse;
46 import javax.xml.bind.JAXBElement;
48 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
49 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
52 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
53 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
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.PolicyType;
56 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
59 import org.apache.commons.collections.CollectionUtils;
60 import org.json.JSONObject;
61 import org.onap.policy.common.logging.flexlogger.FlexLogger;
62 import org.onap.policy.common.logging.flexlogger.Logger;
63 import org.onap.policy.rest.adapter.PolicyRestAdapter;
64 import org.onap.policy.rest.dao.CommonClassDao;
65 import org.onap.policy.rest.jpa.BrmsParamTemplate;
66 import org.onap.policy.rest.jpa.PolicyEntity;
67 import org.onap.policy.utils.PolicyUtils;
68 import org.onap.policy.xacml.api.XACMLErrorConstants;
69 import org.onap.portalsdk.core.controller.RestrictedBaseController;
70 import org.springframework.beans.factory.annotation.Autowired;
71 import org.springframework.stereotype.Controller;
72 import org.springframework.web.bind.annotation.RequestMapping;
73 import org.springframework.web.bind.annotation.RequestMethod;
77 public class CreateBRMSParamController extends RestrictedBaseController {
79 private static final Logger policyLogger = FlexLogger.getLogger(CreateBRMSParamController.class);
81 private static CommonClassDao commonClassDao;
83 public static CommonClassDao getCommonClassDao() {
84 return commonClassDao;
87 public static void setCommonClassDao(CommonClassDao commonClassDao) {
88 CreateBRMSParamController.commonClassDao = commonClassDao;
92 private CreateBRMSParamController(CommonClassDao commonClassDao) {
93 CreateBRMSParamController.commonClassDao = commonClassDao;
96 public CreateBRMSParamController() {
100 protected PolicyRestAdapter policyAdapter = null;
102 private HashMap<String, String> dynamicLayoutMap;
104 private static String brmsTemplateVlaue = "<$%BRMSParamTemplate=";
105 private static String string = "String";
108 * getBRMSParamPolicyRuleData.
110 * @param request HttpServletRequest
111 * @param response HttpServletResponse
113 @RequestMapping(value = {"/policyController/getBRMSTemplateData.htm"}, method = {RequestMethod.POST})
114 public void getBRMSParamPolicyRuleData(HttpServletRequest request, HttpServletResponse response) {
116 dynamicLayoutMap = new HashMap<>();
117 ObjectMapper mapper = new ObjectMapper();
118 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
119 JsonNode root = mapper.readTree(request.getReader());
120 String rule = findRule(root.get(PolicyController.getPolicydata()).toString().replaceAll("^\"|\"$", ""));
122 response.setCharacterEncoding(PolicyController.getCharacterencoding());
123 response.setContentType(PolicyController.getContenttype());
124 request.setCharacterEncoding(PolicyController.getCharacterencoding());
126 response.getWriter().write(new JSONObject("{policyData: " + mapper.writeValueAsString(dynamicLayoutMap)
128 } catch (Exception e) {
129 policyLogger.error("Exception Occured while getting BRMS Rule data", e);
133 private String findRule(String ruleTemplate) {
134 List<Object> datas = commonClassDao.getDataById(BrmsParamTemplate.class, "ruleName", ruleTemplate);
135 if (CollectionUtils.isNotEmpty(datas)) {
136 return ((BrmsParamTemplate) datas.get(0)).getRule();
141 private void generateUI(String rule) {
147 } catch (Exception e) {
148 policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
153 private void processRule(String rule) {
154 StringBuilder params = getParamsBuilderFromRule(rule);
155 params = new StringBuilder(
156 params.toString().replace("declare Params", "").replace("end", "").replaceAll("\\s+", ""));
157 String[] components = params.toString().split(":");
159 for (int i = 0; i < components.length; i++) {
162 caption = components[i];
164 if ("".equals(caption)) {
167 String nextComponent;
169 nextComponent = components[i + 1];
170 } catch (Exception e) {
171 policyLogger.info("Error when procesing rule: " + e);
172 nextComponent = components[i];
174 if (nextComponent.startsWith(string)) {
176 createField(caption, type);
177 caption = nextComponent.replace(string, "");
178 } else if (nextComponent.startsWith("int")) {
180 createField(caption, type);
181 caption = nextComponent.replace("int", "");
186 private StringBuilder getParamsBuilderFromRule(final String rule) {
187 StringBuilder params = new StringBuilder();
188 boolean flag = false;
189 boolean comment = false;
190 String[] lines = rule.split("\n");
191 for (String line : lines) {
192 if (line.isEmpty() || line.startsWith("//")) {
195 if (line.startsWith("/*")) {
199 if (line.contains("//")) {
200 line = splitSingleLineComment(line);
202 if (line.contains("/*")) {
204 if (line.contains("*/")) {
206 line = processMultiLineFullComment(line);
208 line = splitMultiLineStartComment(line);
211 if (line.contains("*/")) {
213 line = processEndComment(line);
221 if (line.contains("declare Params")) {
225 if (line.contains("end") && flag) {
232 private String splitMultiLineStartComment(String line) {
233 return line.split("\\/\\*")[0];
236 private String splitMultiLineEndComment(String line) {
237 return line.split("\\*\\/")[1].replace("*/", "");
240 private String splitSingleLineComment(String line) {
241 return line.split("\\/\\/")[0];
244 private void createField(String caption, String type) {
245 dynamicLayoutMap.put(caption, type);
249 * prePopulateBRMSParamPolicyData.
250 * When the User Click Edit or View Policy the following method will get invoked for setting the data to
252 * Which is used to bind the data in GUI.
254 * @param policyAdapter PolicyRestAdapter
255 * @param entity PolicyEntity
257 public void prePopulateBRMSParamPolicyData(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
258 dynamicLayoutMap = new HashMap<>();
259 if (! (policyAdapter.getPolicyData() instanceof PolicyType)) {
262 PolicyType policy = (PolicyType) policyAdapter.getPolicyData();
263 policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
264 // policy name value is the policy name without any prefix and
266 String policyNameValue =
267 policyAdapter.getPolicyName().substring(policyAdapter.getPolicyName().indexOf("BRMS_Param_") + 11);
268 if (policyLogger.isDebugEnabled()) {
270 .debug("Prepopulating form data for BRMS RAW Policy selected:" + policyAdapter.getPolicyName());
272 policyAdapter.setPolicyName(policyNameValue);
275 description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
276 } catch (Exception e) {
277 policyLogger.info("Error getting description: " + e);
278 description = policy.getDescription();
280 policyAdapter.setPolicyDescription(description);
281 setDataAdapterFromAdviceExpressions(policy, policyAdapter);
285 paramUiGenerate(policyAdapter, entity);
286 } catch (Exception e) {
287 policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e);
290 // Get the target data under policy.
291 policyAdapter.setDynamicLayoutMap(dynamicLayoutMap);
292 if (policyAdapter.getDynamicLayoutMap().size() > 0) {
293 LinkedHashMap<String, String> drlRule = policyAdapter.getDynamicLayoutMap().keySet().stream()
294 .collect(Collectors.toMap(String::toString,
295 keyValue -> policyAdapter.getDynamicLayoutMap().get(keyValue), (a, b) -> b,
296 LinkedHashMap::new));
297 policyAdapter.setRuleData(drlRule);
299 TargetType target = policy.getTarget();
300 if (target != null) {
301 setDataToAdapterFromTarget(target, policyAdapter);
305 private void setDataAdapterFromAdviceExpressions(PolicyType policy, PolicyRestAdapter policyAdapter) {
306 ArrayList<Object> attributeList = new ArrayList<>();
308 AdviceExpressionsType expressionTypes =
309 ((RuleType) policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().get(0))
310 .getAdviceExpressions();
311 for (AdviceExpressionType adviceExpression : expressionTypes.getAdviceExpression()) {
312 for (AttributeAssignmentExpressionType attributeAssignment : adviceExpression
313 .getAttributeAssignmentExpression()) {
314 if (attributeAssignment.getAttributeId().startsWith("key:")) {
315 Map<String, String> attribute = new HashMap<>();
316 String key = attributeAssignment.getAttributeId().replace("key:", "");
317 attribute.put("key", key);
318 @SuppressWarnings("unchecked")
319 JAXBElement<AttributeValueType> attributeValue =
320 (JAXBElement<AttributeValueType>) attributeAssignment.getExpression();
321 String value = (String) attributeValue.getValue().getContent().get(0);
322 attribute.put("value", value);
323 attributeList.add(attribute);
324 } else if (attributeAssignment.getAttributeId().startsWith("dependencies:")) {
325 ArrayList<String> dependencies = new ArrayList<>(Arrays
326 .asList(attributeAssignment.getAttributeId().replace("dependencies:", "").split(",")));
327 dependencies.remove("");
328 policyAdapter.setBrmsDependency(dependencies);
329 } else if (attributeAssignment.getAttributeId().startsWith("controller:")) {
330 policyAdapter.setBrmsController(attributeAssignment.getAttributeId().replace("controller:", ""));
333 policyAdapter.setAttributes(attributeList);
337 private void setDataToAdapterFromTarget(TargetType target, PolicyRestAdapter policyAdapter) {
338 // Under target we have AnyOFType
339 if (target.getAnyOf() == null) {
342 target.getAnyOf().stream().map(AnyOfType::getAllOf).filter(Objects::nonNull).flatMap(Collection::stream)
343 .forEach(allOf -> setDataToAdapterFromMatchList(allOf.getMatch(), policyAdapter));
346 private void setDataToAdapterFromMatchList(List<MatchType> matchList, PolicyRestAdapter policyAdapter) {
347 if (matchList == null) {
350 for (final MatchType match : matchList) {
352 // Under the match we have attribute value and
353 // attributeDesignator. So,finally down to the actual attribute.
355 AttributeValueType attributeValue = match.getAttributeValue();
356 String value = (String) attributeValue.getContent().get(0);
357 AttributeDesignatorType designator = match.getAttributeDesignator();
358 String attributeId = designator.getAttributeId();
359 policyAdapter.setupUsingAttribute(attributeId, value);
363 // This method generates the UI from rule configuration
364 private void paramUiGenerate(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
365 String data = entity.getConfigurationData().getConfigBody();
369 StringBuilder params = new StringBuilder();
370 boolean flag = false;
371 boolean comment = false;
372 for (String line : data.split("\n")) {
373 if (line.isEmpty() || line.startsWith("//")) {
376 if (line.contains(brmsTemplateVlaue)) {
377 String value = line.substring(line.indexOf("<$%"), line.indexOf("%$>"));
378 value = value.replace(brmsTemplateVlaue, "");
379 policyAdapter.setRuleName(value);
381 if (line.contains("<%$Values=")) {
382 String value = line.substring(line.indexOf("<%$"), line.indexOf("$%>"));
383 value = value.replaceAll("<%\\$Values=", "");
384 Arrays.stream(value.split(":\\|:")).map(keyValue -> keyValue.split(":-:"))
385 .filter(pair -> pair.length > 0)
386 .forEach(pair -> dynamicLayoutMap.put(pair[0], (pair.length > 1) ? pair[1] : ""));
389 if (line.startsWith("/*")) {
393 if ((line.contains("//")) && (!(line.contains("http://") || line.contains("https://")))) {
394 line = splitSingleLineComment(line);
396 if (line.contains("/*")) {
398 if (line.contains("*/")) {
400 line = processMultiLineFullComment(line);
402 line = splitMultiLineStartComment(line);
405 if (line.contains("*/")) {
407 line = processEndComment(line);
415 if (line.contains("rule") && line.contains(".Params\"")) {
419 if (line.contains("end") && flag) {
423 params = new StringBuilder(params.substring(params.indexOf(".Params\"") + 11));
424 params = new StringBuilder(
425 params.toString().replaceAll("\\s+", "").replace("salience1000whenthenParamsparams=newParams();", "")
426 .replace("insert(params);end", "").replace("params.set", ""));
427 updateCaptionToDynamicLayoutMap(params);
430 private void updateCaptionToDynamicLayoutMap(final StringBuilder params) {
431 String[] components = params.toString().split("\\);");
432 if (components.length > 0) {
433 for (int i = 0; i < components.length; i++) {
435 components[i] = components[i] + ")";
436 String caption = components[i].substring(0, components[i].indexOf('('));
437 caption = caption.substring(0, 1).toLowerCase() + caption.substring(1);
438 if (components[i].contains("(\"")) {
439 value = components[i].substring(components[i].indexOf("(\""), components[i].indexOf("\")"))
440 .replace("(\"", "").replace("\")", "");
442 value = components[i].substring(components[i].indexOf('('), components[i].indexOf(')'))
443 .replace("(", "").replace(")", "");
445 dynamicLayoutMap.put(caption, value);
450 private String processEndComment(String line) {
452 line = splitMultiLineEndComment(line);
453 } catch (Exception e) {
454 policyLogger.info("Just for Logging" + e);
460 private String processMultiLineFullComment(String line) {
462 line = splitMultiLineStartComment(line) + splitMultiLineEndComment(line);
463 } catch (Exception e) {
464 policyLogger.info("Just for Logging" + e);
465 line = splitMultiLineStartComment(line);
473 * @param request HttpServletRequest
474 * @param response HttpServletResponse
476 @SuppressWarnings("unchecked")
477 @RequestMapping(value = {"/policyController/ViewBRMSParamPolicyRule.htm"}, method = {RequestMethod.POST})
478 public void setViewRule(HttpServletRequest request, HttpServletResponse response) {
480 ObjectMapper mapper = new ObjectMapper();
481 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
482 JsonNode root = mapper.readTree(request.getReader());
483 PolicyRestAdapter policyData = mapper.readValue(
484 root.get(PolicyController.getPolicydata()).get("policy").toString(), PolicyRestAdapter.class);
485 policyData.setDomainDir(
486 root.get(PolicyController.getPolicydata()).get("model").get("name").toString().replace("\"", ""));
487 if (root.get(PolicyController.getPolicydata()).get("model").get("type").toString().replace("\"", "")
488 .equals(PolicyController.getFile())) {
489 policyData.setEditPolicy(true);
492 String body = findRule(policyData.getRuleName()) + "\n";
493 StringBuilder generatedMetadata = new StringBuilder().append(
494 "/* Autogenerated Code Please Don't change/remove this comment section. "
495 + "This is for the UI purpose. \n\t ")
496 .append(brmsTemplateVlaue).append(policyData.getRuleName()).append("%$> \n */ \n");
498 if (policyData.getDynamicLayoutMap().size() > 0) {
499 generatedMetadata.append("/* <%$Values=");
500 for (Entry<?, ?> entry : policyData.getRuleData().entrySet()) {
501 String uiKey = (String) entry.getKey();
502 if (!"templateName".equals(uiKey)) {
503 generatedMetadata.append(uiKey).append(":-:").append(entry.getValue()).append(":|:");
506 generatedMetadata.append("$%> \n*/ \n");
508 policyLogger.info("Metadata generated with :" + generatedMetadata.toString());
509 body = generatedMetadata.toString() + body;
511 Map<String, String> copyMap =
512 new HashMap<>((Map<? extends String, ? extends String>) policyData.getRuleData());
513 copyMap.put("policyName",
514 policyData.getDomainDir().replace("\\", ".") + ".Config_BRMS_Param_" + policyData.getPolicyName());
515 copyMap.put("policyScope", policyData.getDomainDir().replace("\\", "."));
516 copyMap.put("policyVersion", "1");
517 // Finding all the keys in the Map data-structure.
518 Set<String> keySet = copyMap.keySet();
519 Iterator<String> iterator = keySet.iterator();
520 while (iterator.hasNext()) {
521 // Converting the first character of the key into a lower case.
522 String input = iterator.next();
523 String output = Character.toLowerCase(input.charAt(0)) + (input.length() > 1 ? input.substring(1) : "");
524 // Searching for a pattern in the String using the key.
525 Pattern pattern = Pattern.compile("\\$\\{" + output + "\\}");
526 Matcher matcher = pattern.matcher(body);
527 // Replacing the value with the inputs provided by the user in the editor.
528 body = matcher.replaceAll(copyMap.get(input));
530 response.setCharacterEncoding(PolicyUtils.CHARACTER_ENCODING);
531 response.setContentType(PolicyUtils.APPLICATION_JSON);
532 request.setCharacterEncoding(PolicyUtils.CHARACTER_ENCODING);
534 response.getWriter().write(new JSONObject("{policyData: " + mapper.writeValueAsString(body)
536 } catch (Exception e) {
537 policyLogger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);