2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017-2018 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 java.io.PrintWriter;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Collection;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.LinkedHashMap;
32 import java.util.List;
34 import java.util.Map.Entry;
35 import java.util.Objects;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
40 import java.util.stream.Collectors;
41 import javax.servlet.http.HttpServletRequest;
42 import javax.servlet.http.HttpServletResponse;
43 import javax.xml.bind.JAXBElement;
45 import org.apache.commons.collections.CollectionUtils;
46 import org.json.JSONObject;
47 import org.onap.policy.common.logging.flexlogger.FlexLogger;
48 import org.onap.policy.common.logging.flexlogger.Logger;
49 import org.onap.policy.rest.adapter.PolicyRestAdapter;
50 import org.onap.policy.rest.dao.CommonClassDao;
51 import org.onap.policy.rest.jpa.BRMSParamTemplate;
52 import org.onap.policy.rest.jpa.PolicyEntity;
53 import org.onap.policy.xacml.api.XACMLErrorConstants;
54 import org.onap.portalsdk.core.controller.RestrictedBaseController;
55 import org.springframework.beans.factory.annotation.Autowired;
56 import org.springframework.stereotype.Controller;
57 import org.springframework.web.bind.annotation.RequestMapping;
58 import org.springframework.web.bind.annotation.RequestMethod;
60 import com.fasterxml.jackson.databind.DeserializationFeature;
61 import com.fasterxml.jackson.databind.JsonNode;
62 import com.fasterxml.jackson.databind.ObjectMapper;
64 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
65 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
66 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
67 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
68 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
69 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
70 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
71 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
72 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
73 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
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 @RequestMapping(value = {"/policyController/getBRMSTemplateData.htm"}, method = { RequestMethod.POST})
109 public void getBRMSParamPolicyRuleData(HttpServletRequest request, HttpServletResponse response) {
111 dynamicLayoutMap = new HashMap<>();
112 ObjectMapper mapper = new ObjectMapper();
113 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
114 JsonNode root = mapper.readTree(request.getReader());
115 String rule = findRule(root.get(PolicyController.getPolicydata()).toString().replaceAll("^\"|\"$", ""));
117 response.setCharacterEncoding(PolicyController.getCharacterencoding());
118 response.setContentType(PolicyController.getContenttype());
119 request.setCharacterEncoding(PolicyController.getCharacterencoding());
121 PrintWriter out = response.getWriter();
122 String responseString = mapper.writeValueAsString(dynamicLayoutMap);
123 JSONObject j = new JSONObject("{policyData: " + responseString + "}");
124 out.write(j.toString());
125 } catch (Exception e) {
126 policyLogger.error("Exception Occured while getting BRMS Rule data", e);
130 private String findRule(String ruleTemplate) {
131 List<Object> datas = commonClassDao.getDataById(BRMSParamTemplate.class, "ruleName", ruleTemplate);
132 if(CollectionUtils.isNotEmpty(datas)){
133 BRMSParamTemplate bRMSParamTemplate = (BRMSParamTemplate) datas.get(0);
134 return bRMSParamTemplate.getRule();
139 private void generateUI(String rule) {
145 } catch (Exception e) {
146 policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
151 private void processRule(String rule) {
152 StringBuilder params = getParamsBuilderFromRule(rule);
153 params = new StringBuilder(
154 params.toString().replace("declare Params", "").replace("end", "").replaceAll("\\s+", ""));
155 String[] components = params.toString().split(":");
157 for (int i = 0; i < components.length; i++) {
160 caption = components[i];
162 if ("".equals(caption)) {
165 String nextComponent;
167 nextComponent = components[i + 1];
168 } catch (Exception e) {
169 policyLogger.info("Error when procesing rule: " + e);
170 nextComponent = components[i];
172 if (nextComponent.startsWith(string)) {
174 createField(caption, type);
175 caption = nextComponent.replace(string, "");
176 } else if (nextComponent.startsWith("int")) {
178 createField(caption, type);
179 caption = nextComponent.replace("int", "");
184 private StringBuilder getParamsBuilderFromRule(final String rule) {
185 StringBuilder params = new StringBuilder();
186 boolean flag = false;
187 boolean comment = false;
188 String[] lines = rule.split("\n");
189 for (String line : lines) {
190 if (line.isEmpty() || line.startsWith("//")) {
193 if (line.startsWith("/*")) {
197 if (line.contains("//")) {
198 line = splitSingleLineComment(line);
200 if (line.contains("/*")) {
202 if (line.contains("*/")) {
204 line = processMultiLineFullComment(line);
206 line = splitMultiLineStartComment(line);
209 if (line.contains("*/")) {
211 line = processEndComment(line);
219 if (line.contains("declare Params")) {
223 if (line.contains("end") && flag) {
230 private String splitMultiLineStartComment(String line) {
231 return line.split("\\/\\*")[0];
234 private String splitMultiLineEndComment(String line) {
235 return line.split("\\*\\/")[1].replace("*/", "");
238 private String splitSingleLineComment(String line) {
239 return line.split("\\/\\/")[0];
242 private void createField(String caption, String type) {
243 dynamicLayoutMap.put(caption, type);
247 * When the User Click Edit or View Policy the following method will get invoked for setting the data to PolicyRestAdapter.
248 * Which is used to bind the data in GUI
250 public void prePopulateBRMSParamPolicyData(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
251 dynamicLayoutMap = new HashMap<>();
252 if (policyAdapter.getPolicyData() instanceof PolicyType) {
253 PolicyType policy = (PolicyType) policyAdapter.getPolicyData();
254 policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
255 // policy name value is the policy name without any prefix and
257 String policyNameValue = policyAdapter.getPolicyName()
258 .substring(policyAdapter.getPolicyName().indexOf("BRMS_Param_") + 11);
259 if (policyLogger.isDebugEnabled()) {
261 .debug("Prepopulating form data for BRMS RAW Policy selected:" + policyAdapter.getPolicyName());
263 policyAdapter.setPolicyName(policyNameValue);
266 description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
267 } catch (Exception e) {
268 policyLogger.info("Error getting description: " + e);
269 description = policy.getDescription();
271 policyAdapter.setPolicyDescription(description);
272 setDataAdapterFromAdviceExpressions(policy, policyAdapter);
276 paramUIGenerate(policyAdapter, entity);
277 } catch (Exception e) {
278 policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e);
281 // Get the target data under policy.
282 policyAdapter.setDynamicLayoutMap(dynamicLayoutMap);
283 if (policyAdapter.getDynamicLayoutMap().size() > 0) {
284 LinkedHashMap<String, String> drlRule = policyAdapter.getDynamicLayoutMap()
287 .toMap(String::toString, keyValue -> policyAdapter.getDynamicLayoutMap().get(keyValue),
288 (a, b) -> b, LinkedHashMap::new));
289 policyAdapter.setRuleData(drlRule);
291 TargetType target = policy.getTarget();
292 if (target != null) {
293 setDataToAdapterFromTarget(target, policyAdapter);
298 private void setDataAdapterFromAdviceExpressions(PolicyType policy, PolicyRestAdapter policyAdapter) {
299 ArrayList<Object> attributeList = new ArrayList<>();
301 AdviceExpressionsType expressionTypes = ((RuleType) policy
302 .getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().get(0)).getAdviceExpressions();
303 for (AdviceExpressionType adviceExpression : expressionTypes.getAdviceExpression()) {
304 for (AttributeAssignmentExpressionType attributeAssignment : adviceExpression
305 .getAttributeAssignmentExpression()) {
306 if (attributeAssignment.getAttributeId().startsWith("key:")) {
307 Map<String, String> attribute = new HashMap<>();
308 String key = attributeAssignment.getAttributeId().replace("key:", "");
309 attribute.put("key", key);
310 @SuppressWarnings("unchecked")
311 JAXBElement<AttributeValueType> attributeValue = (JAXBElement<AttributeValueType>) attributeAssignment
313 String value = (String) attributeValue.getValue().getContent().get(0);
314 attribute.put("value", value);
315 attributeList.add(attribute);
316 } else if (attributeAssignment.getAttributeId().startsWith("dependencies:")) {
317 ArrayList<String> dependencies = new ArrayList<>(
318 Arrays.asList(attributeAssignment.getAttributeId().replace("dependencies:", "").split(",")));
319 dependencies.remove("");
320 policyAdapter.setBrmsDependency(dependencies);
321 } else if (attributeAssignment.getAttributeId().startsWith("controller:")) {
322 policyAdapter.setBrmsController(attributeAssignment.getAttributeId().replace("controller:", ""));
325 policyAdapter.setAttributes(attributeList);
329 private void setDataToAdapterFromTarget(TargetType target, PolicyRestAdapter policyAdapter) {
330 // Under target we have AnyOFType
331 List<AnyOfType> anyOfList = target.getAnyOf();
332 if (anyOfList == null) {
335 anyOfList.stream().map(AnyOfType::getAllOf)
336 .filter(Objects::nonNull)
337 .flatMap(Collection::stream)
338 .forEach(allOf -> setDataToAdapterFromMatchList(allOf.getMatch(), policyAdapter));
341 private void setDataToAdapterFromMatchList(List<MatchType> matchList, PolicyRestAdapter policyAdapter) {
342 if (matchList == null) {
345 for (final MatchType match : matchList) {
347 // Under the match we have attribute value and
348 // attributeDesignator. So,finally down to the actual attribute.
350 AttributeValueType attributeValue = match.getAttributeValue();
351 String value = (String) attributeValue.getContent().get(0);
352 AttributeDesignatorType designator = match.getAttributeDesignator();
353 String attributeId = designator.getAttributeId();
354 if ("RiskType".equals(attributeId)) {
355 policyAdapter.setRiskType(value);
357 if ("RiskLevel".equals(attributeId)) {
358 policyAdapter.setRiskLevel(value);
360 if ("guard".equals(attributeId)) {
361 policyAdapter.setGuard(value);
363 if ("TTLDate".equals(attributeId) && !value.contains("NA")) {
364 PolicyController controller = new PolicyController();
365 String newDate = controller.convertDate(value);
366 policyAdapter.setTtlDate(newDate);
371 // This method generates the UI from rule configuration
372 private void paramUIGenerate(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
373 String data = entity.getConfigurationData().getConfigBody();
377 StringBuilder params = new StringBuilder();
378 boolean flag = false;
379 boolean comment = false;
380 for (String line : data.split("\n")) {
381 if (line.isEmpty() || line.startsWith("//")) {
384 if (line.contains(brmsTemplateVlaue)) {
385 String value = line.substring(line.indexOf("<$%"), line.indexOf("%$>"));
386 value = value.replace(brmsTemplateVlaue, "");
387 policyAdapter.setRuleName(value);
389 if (line.contains("<%$Values=")) {
390 String value = line.substring(line.indexOf("<%$"), line.indexOf("$%>"));
391 value = value.replaceAll("<%\\$Values=", "");
392 Arrays.stream(value.split(":\\|:")).map(keyValue -> keyValue.split(":-:"))
393 .filter(pair -> pair.length > 0)
394 .forEach(pair -> dynamicLayoutMap.put(pair[0], (pair.length > 1) ? pair[1] : ""));
397 if (line.startsWith("/*")) {
401 if ((line.contains("//")) && (!(line.contains("http://") || line.contains("https://")))) {
402 line = splitSingleLineComment(line);
404 if (line.contains("/*")) {
406 if (line.contains("*/")) {
408 line = processMultiLineFullComment(line);
410 line = splitMultiLineStartComment(line);
413 if (line.contains("*/")) {
415 line = processEndComment(line);
423 if (line.contains("rule") && line.contains(".Params\"")) {
427 if (line.contains("end") && flag) {
431 params = new StringBuilder(params.substring(params.indexOf(".Params\"") + 11));
432 params = new StringBuilder(params.toString().replaceAll("\\s+", "")
433 .replace("salience1000whenthenParamsparams=newParams();", "")
434 .replace("insert(params);end", "")
435 .replace("params.set", ""));
436 updateCaptionToDynamicLayoutMap(params);
439 private void updateCaptionToDynamicLayoutMap(final StringBuilder params) {
440 String[] components = params.toString().split("\\);");
441 if(components.length > 0){
442 for (int i = 0; i < components.length; i++) {
444 components[i] = components[i] + ")";
445 String caption = components[i].substring(0,
446 components[i].indexOf('('));
447 caption = caption.substring(0, 1).toLowerCase() + caption.substring(1);
448 if (components[i].contains("(\"")) {
449 value = components[i]
450 .substring(components[i].indexOf("(\""),
451 components[i].indexOf("\")"))
452 .replace("(\"", "").replace("\")", "");
454 value = components[i]
455 .substring(components[i].indexOf('('),
456 components[i].indexOf(')'))
457 .replace("(", "").replace(")", "");
459 dynamicLayoutMap.put(caption, value);
464 private String processEndComment(String line) {
466 line = splitMultiLineEndComment(line);
467 } catch (Exception e) {
468 policyLogger.info("Just for Logging" + e);
474 private String processMultiLineFullComment(String line) {
476 line = splitMultiLineStartComment(line)
477 + splitMultiLineEndComment(line);
478 } catch (Exception e) {
479 policyLogger.info("Just for Logging" + e);
480 line = splitMultiLineStartComment(line);
486 @SuppressWarnings("unchecked")
487 @RequestMapping(value = {"/policyController/ViewBRMSParamPolicyRule.htm"}, method = { RequestMethod.POST})
488 public void setViewRule(HttpServletRequest request, HttpServletResponse response) {
490 ObjectMapper mapper = new ObjectMapper();
491 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
492 JsonNode root = mapper.readTree(request.getReader());
493 PolicyRestAdapter policyData = mapper
494 .readValue(root.get(PolicyController.getPolicydata()).get("policy").toString(),
495 PolicyRestAdapter.class);
496 policyData.setDomainDir(
497 root.get(PolicyController.getPolicydata()).get("model").get("name").toString().replace("\"", ""));
498 if (root.get(PolicyController.getPolicydata()).get("model").get("type").toString().replace("\"", "")
499 .equals(PolicyController.getFile())) {
500 policyData.setEditPolicy(true);
503 String body = findRule(policyData.getRuleName()) + "\n";
504 StringBuilder generatedMetadata = new StringBuilder().append(
505 "/* Autogenerated Code Please Don't change/remove this comment section. This is for the UI purpose. \n\t ")
506 .append(brmsTemplateVlaue).append(policyData.getRuleName()).append("%$> \n */ \n");
508 if (policyData.getDynamicLayoutMap().size() > 0) {
509 generatedMetadata.append("/* <%$Values=");
510 for (Entry<?, ?> entry : policyData.getRuleData().entrySet()) {
511 String uiKey = (String) entry.getKey();
512 if (!"templateName".equals(uiKey)) {
513 generatedMetadata.append(uiKey).append(":-:").append(entry.getValue()).append(":|:");
516 generatedMetadata.append("$%> \n*/ \n");
518 policyLogger.info("Metadata generated with :" + generatedMetadata.toString());
519 body = generatedMetadata.toString() + body;
521 Map<String, String> copyMap = new HashMap<>(
522 (Map<? extends String, ? extends String>) policyData.getRuleData());
523 copyMap.put("policyName",
524 policyData.getDomainDir().replace("\\", ".") + ".Config_BRMS_Param_" + policyData.getPolicyName());
525 copyMap.put("policyScope", policyData.getDomainDir().replace("\\", "."));
526 copyMap.put("policyVersion", "1");
527 //Finding all the keys in the Map data-structure.
528 Set<String> keySet = copyMap.keySet();
529 Iterator<String> iterator = keySet.iterator();
532 while (iterator.hasNext()) {
533 //Converting the first character of the key into a lower case.
534 String input = iterator.next();
535 String output = Character.toLowerCase(input.charAt(0)) +
536 (input.length() > 1 ? input.substring(1) : "");
537 //Searching for a pattern in the String using the key.
538 p = Pattern.compile("\\$\\{" + output + "\\}");
540 //Replacing the value with the inputs provided by the user in the editor.
541 body = m.replaceAll(copyMap.get(input));
543 response.setCharacterEncoding("UTF-8");
544 response.setContentType("application / json");
545 request.setCharacterEncoding("UTF-8");
547 PrintWriter out = response.getWriter();
548 String responseString = mapper.writeValueAsString(body);
549 JSONObject j = new JSONObject("{policyData: " + responseString + "}");
550 out.write(j.toString());
551 } catch (Exception e) {
552 policyLogger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);