Merge "Remove auto generated rule to the drl"
[policy/engine.git] / POLICY-SDK-APP / src / main / java / org / onap / policy / controller / CreateBRMSParamController.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Engine
4  * ================================================================================
5  * Copyright (C) 2017-2018 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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.onap.policy.controller;
22
23 import java.io.PrintWriter;
24 import java.util.ArrayList;
25 import java.util.Arrays;
26 import java.util.HashMap;
27 import java.util.Iterator;
28 import java.util.LinkedHashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Map.Entry;
32 import java.util.Set;
33 import java.util.regex.Matcher;
34 import java.util.regex.Pattern;
35
36 import javax.servlet.http.HttpServletRequest;
37 import javax.servlet.http.HttpServletResponse;
38 import javax.xml.bind.JAXBElement;
39
40 import org.json.JSONObject;
41 import org.onap.policy.common.logging.flexlogger.FlexLogger;
42 import org.onap.policy.common.logging.flexlogger.Logger;
43 import org.onap.policy.rest.adapter.PolicyRestAdapter;
44 import org.onap.policy.rest.dao.CommonClassDao;
45 import org.onap.policy.rest.jpa.BRMSParamTemplate;
46 import org.onap.policy.rest.jpa.PolicyEntity;
47 import org.onap.policy.xacml.api.XACMLErrorConstants;
48 import org.onap.portalsdk.core.controller.RestrictedBaseController;
49 import org.springframework.beans.factory.annotation.Autowired;
50 import org.springframework.stereotype.Controller;
51 import org.springframework.web.bind.annotation.RequestMapping;
52
53 import com.fasterxml.jackson.databind.DeserializationFeature;
54 import com.fasterxml.jackson.databind.JsonNode;
55 import com.fasterxml.jackson.databind.ObjectMapper;
56
57 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionType;
58 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AdviceExpressionsType;
59 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AllOfType;
60 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AnyOfType;
61 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeAssignmentExpressionType;
62 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeDesignatorType;
63 import oasis.names.tc.xacml._3_0.core.schema.wd_17.AttributeValueType;
64 import oasis.names.tc.xacml._3_0.core.schema.wd_17.MatchType;
65 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
66 import oasis.names.tc.xacml._3_0.core.schema.wd_17.RuleType;
67 import oasis.names.tc.xacml._3_0.core.schema.wd_17.TargetType;
68
69 @Controller
70 @RequestMapping("/")
71 public class CreateBRMSParamController extends RestrictedBaseController {
72         private static final Logger policyLogger = FlexLogger.getLogger(CreateBRMSParamController.class);
73
74         private static CommonClassDao commonClassDao;
75
76         public static CommonClassDao getCommonClassDao() {
77                 return commonClassDao;
78         }
79
80         public static void setCommonClassDao(CommonClassDao commonClassDao) {
81                 CreateBRMSParamController.commonClassDao = commonClassDao;
82         }
83         
84         @Autowired
85         private CreateBRMSParamController(CommonClassDao commonClassDao){
86                 CreateBRMSParamController.commonClassDao = commonClassDao;
87         }
88
89         public CreateBRMSParamController(){
90                 // Empty constructor
91         }
92         protected PolicyRestAdapter policyAdapter = null; 
93
94         private HashMap<String, String> dynamicLayoutMap;
95         
96         private static String brmsTemplateVlaue = "<$%BRMSParamTemplate=";
97         private static String string = "String";
98
99
100         @RequestMapping(value={"/policyController/getBRMSTemplateData.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
101         public void getBRMSParamPolicyRuleData(HttpServletRequest request, HttpServletResponse response){
102                 try{
103                         dynamicLayoutMap = new HashMap<>();
104                         ObjectMapper mapper = new ObjectMapper();
105                         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
106                         JsonNode root = mapper.readTree(request.getReader());
107                         String rule = findRule(root.get(PolicyController.getPolicydata()).toString().replaceAll("^\"|\"$", ""));
108                         generateUI(rule);
109                         response.setCharacterEncoding(PolicyController.getCharacterencoding());
110                         response.setContentType(PolicyController.getContenttype());
111                         request.setCharacterEncoding(PolicyController.getCharacterencoding());
112
113                         PrintWriter out = response.getWriter();
114                         String responseString = mapper.writeValueAsString(dynamicLayoutMap);
115                         JSONObject j = new JSONObject("{policyData: " + responseString + "}");
116                         out.write(j.toString());
117                 }catch(Exception e){
118                         policyLogger.error("Exception Occured while getting BRMS Rule data" , e);
119                 }
120         }
121
122         protected String findRule(String ruleTemplate) {
123                 List<Object> datas = commonClassDao.getDataById(BRMSParamTemplate.class, "ruleName", ruleTemplate);
124                 if(datas != null && !datas.isEmpty()){
125                         BRMSParamTemplate  bRMSParamTemplate = (BRMSParamTemplate) datas.get(0);
126                         return bRMSParamTemplate.getRule();
127                 }
128                 return null;
129         }
130
131         protected void generateUI(String rule) {
132                 if(rule!=null){
133                         try {
134                                 StringBuilder params = new StringBuilder("");
135                                 Boolean flag = false;
136                                 Boolean comment = false;
137                                 String[] lines = rule.split("\n");
138                                 for(String line : lines){
139                                         if (line.isEmpty() || line.startsWith("//")) {
140                                                 continue;
141                                         }
142                                         if (line.startsWith("/*")) {
143                                                 comment = true;
144                                                 continue;
145                                         }
146                                         if (line.contains("//")) {
147                                                 line = line.split("\\/\\/")[0];
148                                         }
149                                         if (line.contains("/*")) {
150                                                 comment = true;
151                                                 if (line.contains("*/")) {
152                                                         try {
153                                                                 comment = false;
154                                                                 line = line.split("\\/\\*")[0]
155                                                                                 + line.split("\\*\\/")[1].replace("*/", "");
156                                                         } catch (Exception e) {
157                                                                 policyLogger.info("Just for Logging"+e);
158                                                                 line = line.split("\\/\\*")[0];
159                                                         }
160                                                 } else {
161                                                         line = line.split("\\/\\*")[0];
162                                                 }
163                                         }
164                                         if (line.contains("*/")) {
165                                                 comment = false;
166                                                 try {
167                                                         line = line.split("\\*\\/")[1].replace("*/", "");
168                                                 } catch (Exception e) {
169                                                         policyLogger.info("Just for Logging"+e);
170                                                         line = "";
171                                                 }
172                                         }
173                                         if (comment) {
174                                                 continue;
175                                         }
176                                         if (flag) {
177                                                 params.append(line);
178                                         }
179                                         if (line.contains("declare Params")) {
180                                                 params.append(line);
181                                                 flag = true;
182                                         }
183                                         if (line.contains("end") && flag) {
184                                                 break;
185                                         }
186                                 }
187                                 params = new StringBuilder(params.toString().replace("declare Params", "").replace("end", "").replaceAll("\\s+", ""));
188                                 String[] components = params.toString().split(":");
189                                 String caption = "";
190                                 for (int i = 0; i < components.length; i++) {
191                                         String type;
192                                         if (i == 0) {
193                                                 caption = components[i];
194                                         }
195                                         if("".equals(caption)){
196                                                 break;
197                                         }
198                                         String nextComponent = "";
199                                         try {
200                                                 nextComponent = components[i + 1];
201                                         } catch (Exception e) {
202                                                 policyLogger.info("Just for Logging"+e);
203                                                 nextComponent = components[i];
204                                         }
205                                         if (nextComponent.startsWith(string)) {
206                                                 type = "String";
207                                                 createField(caption, type);
208                                                 caption = nextComponent.replace(string, "");
209                                         } else if (nextComponent.startsWith("int")) {
210                                                 type = "int";
211                                                 createField(caption, type);
212                                                 caption = nextComponent.replace("int", "");
213                                         }
214                                 }
215                         } catch (Exception e) {
216                                 policyLogger.error(XACMLErrorConstants.ERROR_SYSTEM_ERROR + e);
217                         }
218                 }
219         }
220         
221         private void createField(String caption, String type) {
222                 dynamicLayoutMap.put(caption, type);
223         }
224
225         /*
226          * When the User Click Edit or View Policy the following method will get invoked for setting the data to PolicyRestAdapter.
227          * Which is used to bind the data in GUI
228          */
229         public void prePopulateBRMSParamPolicyData(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
230                 dynamicLayoutMap = new HashMap<>();
231                 if (policyAdapter.getPolicyData() instanceof PolicyType) {
232                         PolicyType policy = (PolicyType) policyAdapter.getPolicyData();
233                         policyAdapter.setOldPolicyFileName(policyAdapter.getPolicyName());
234                         // policy name value is the policy name without any prefix and
235                         // Extensions.
236                         String policyNameValue = policyAdapter.getPolicyName().substring(policyAdapter.getPolicyName().indexOf("BRMS_Param_") + 11);
237                         if (policyLogger.isDebugEnabled()) {
238                                 policyLogger.debug("Prepopulating form data for BRMS RAW Policy selected:" + policyAdapter.getPolicyName());
239                         }
240                         policyAdapter.setPolicyName(policyNameValue);
241                         String description = "";
242                         try{
243                                 description = policy.getDescription().substring(0, policy.getDescription().indexOf("@CreatedBy:"));
244                         }catch(Exception e){
245                                 policyLogger.info("Just for Logging"+e);
246                                 description = policy.getDescription();
247                         }
248                         policyAdapter.setPolicyDescription(description);
249                         setDataAdapterFromAdviceExpressions(policy, policyAdapter);
250                         paramUIGenerate(policyAdapter, entity);
251                         // Get the target data under policy.
252                         policyAdapter.setDynamicLayoutMap(dynamicLayoutMap);
253                         if(policyAdapter.getDynamicLayoutMap().size() > 0){
254                                 LinkedHashMap<String,String> drlRule = new LinkedHashMap<>();
255                                 for(Object keyValue: policyAdapter.getDynamicLayoutMap().keySet()){
256                                         drlRule.put(keyValue.toString(), policyAdapter.getDynamicLayoutMap().get(keyValue));
257                                 }
258                                 policyAdapter.setRuleData(drlRule);
259                         }       
260                         TargetType target = policy.getTarget();
261                         if (target != null) {
262                                 setDataToAdapterFromTarget(target, policyAdapter);
263                         }
264                 }               
265         }
266         
267         private void setDataAdapterFromAdviceExpressions(PolicyType policy, PolicyRestAdapter policyAdapter){
268                 ArrayList<Object> attributeList = new ArrayList<>();
269                 // Set Attributes. 
270                 AdviceExpressionsType expressionTypes = ((RuleType)policy.getCombinerParametersOrRuleCombinerParametersOrVariableDefinition().get(0)).getAdviceExpressions();
271                 for( AdviceExpressionType adviceExpression: expressionTypes.getAdviceExpression()){
272                         for(AttributeAssignmentExpressionType attributeAssignment: adviceExpression.getAttributeAssignmentExpression()){
273                                 if(attributeAssignment.getAttributeId().startsWith("key:")){
274                                         Map<String, String> attribute = new HashMap<>();
275                                         String key = attributeAssignment.getAttributeId().replace("key:", "");
276                                         attribute.put("key", key);
277                                         @SuppressWarnings("unchecked")
278                                         JAXBElement<AttributeValueType> attributevalue = (JAXBElement<AttributeValueType>) attributeAssignment.getExpression();
279                                         String value = (String) attributevalue.getValue().getContent().get(0);
280                                         attribute.put("value", value);
281                                         attributeList.add(attribute);
282                                 }else if(attributeAssignment.getAttributeId().startsWith("dependencies:")){
283                                         ArrayList<String> dependencies = new ArrayList<>(Arrays.asList(attributeAssignment.getAttributeId().replace("dependencies:", "").split(",")));
284                                         if(dependencies.contains("")){
285                                                 dependencies.remove("");
286                                         }
287                                         policyAdapter.setBrmsDependency(dependencies);
288                                 }else if(attributeAssignment.getAttributeId().startsWith("controller:")){
289                                         policyAdapter.setBrmsController(attributeAssignment.getAttributeId().replace("controller:", ""));
290                                 }
291                         }
292                         policyAdapter.setAttributes(attributeList);
293                 }
294         }
295         
296         private void setDataToAdapterFromTarget(TargetType target, PolicyRestAdapter policyAdapter){
297                 // Under target we have AnyOFType
298                 List<AnyOfType> anyOfList = target.getAnyOf();
299                 if (anyOfList != null) {
300                         Iterator<AnyOfType> iterAnyOf = anyOfList.iterator();
301                         while (iterAnyOf.hasNext()) {
302                                 AnyOfType anyOf = iterAnyOf.next();
303                                 // Under AnyOFType we have AllOFType
304                                 List<AllOfType> allOfList = anyOf.getAllOf();
305                                 if (allOfList != null) {
306                                         Iterator<AllOfType> iterAllOf = allOfList.iterator();
307                                         while (iterAllOf.hasNext()) {
308                                                 AllOfType allOf = iterAllOf.next();
309                                                 // Under AllOFType we have Match
310                                                 List<MatchType> matchList = allOf.getMatch();
311                                                 if (matchList != null) {
312                                                         setDataToAdapterFromMatchList(matchList, policyAdapter);
313                                                 }
314                                         }
315                                 }
316                         }
317                 }
318         }
319         
320         private void setDataToAdapterFromMatchList(List<MatchType> matchList, PolicyRestAdapter policyAdapter){
321                 Iterator<MatchType> iterMatch = matchList.iterator();
322                 while (iterMatch.hasNext()) {
323                         MatchType match = iterMatch.next();
324                         //
325                         // Under the match we have attribute value and
326                         // attributeDesignator. So,finally down to the actual attribute.
327                         //
328                         AttributeValueType attributeValue = match.getAttributeValue();
329                         String value = (String) attributeValue.getContent().get(0);
330                         AttributeDesignatorType designator = match.getAttributeDesignator();
331                         String attributeId = designator.getAttributeId();
332
333                         if ("RiskType".equals(attributeId)){
334                                 policyAdapter.setRiskType(value);
335                         }
336                         if ("RiskLevel".equals(attributeId)){
337                                 policyAdapter.setRiskLevel(value);
338                         }
339                         if ("guard".equals(attributeId)){
340                                 policyAdapter.setGuard(value);
341                         }
342                         if ("TTLDate".equals(attributeId) && !value.contains("NA")){
343                                 PolicyController controller = new PolicyController();
344                                 String newDate = controller.convertDate(value);
345                                 policyAdapter.setTtlDate(newDate);
346                         }
347                 }
348         }
349
350         // This method generates the UI from rule configuration
351         public void paramUIGenerate(PolicyRestAdapter policyAdapter, PolicyEntity entity) {
352                 String data = entity.getConfigurationData().getConfigBody();
353                 if(data != null){
354                         try {   
355                                 StringBuilder params = new StringBuilder("");
356                                 Boolean flag = false;
357                                 Boolean comment = false;
358                                 for (String line : data.split("\n")) {
359                                         if (line.isEmpty() || line.startsWith("//")) {
360                                                 continue;
361                                         }
362                                         if(line.contains(brmsTemplateVlaue)){
363                                                 String value = line.substring(line.indexOf("<$%"),line.indexOf("%$>"));
364                                                 value = value.replace(brmsTemplateVlaue, "");
365                                                 policyAdapter.setRuleName(value);
366                                         }
367                                         if(line.contains("<%$Values=")) {
368                                             String value = line.substring(line.indexOf("<%$"), line.indexOf("$%>"));
369                                             value = value.replaceAll("<%\\$Values=", "");
370                                             for( String keyValue : value.split(":\\|:")) {
371                                                 String[] pair = keyValue.split(":-:");
372                                                 if (pair != null && pair.length > 0) {
373                                                         dynamicLayoutMap.put(pair[0], (pair.length > 1) ? pair[1] : "");
374                                                 }
375                                             }
376                                             return;
377                                         }
378                                         if (line.startsWith("/*")) {
379                                                 comment = true;
380                                                 continue;
381                                         }
382                                         if ((line.contains("//"))&&(!(line.contains("http://") || line.contains("https://")))){
383                                                 line = line.split("\\/\\/")[0];
384                                         }
385                                         if (line.contains("/*")) {
386                                                 comment = true;
387                                                 if (line.contains("*/")) {
388                                                         try {
389                                                                 comment = false;
390                                                                 line = line.split("\\/\\*")[0]
391                                                                                 + line.split("\\*\\/")[1].replace(
392                                                                                                 "*/", "");
393                                                         } catch (Exception e) {
394                                                                 policyLogger.info("Just for Logging"+e);
395                                                                 line = line.split("\\/\\*")[0];
396                                                         }
397                                                 } else {
398                                                         line = line.split("\\/\\*")[0];
399                                                 }
400                                         }
401                                         if (line.contains("*/")) {
402                                                 comment = false;
403                                                 try {
404                                                         line = line.split("\\*\\/")[1]
405                                                                         .replace("*/", "");
406                                                 } catch (Exception e) {
407                                                         policyLogger.info("Just for Logging"+e);
408                                                         line = "";
409                                                 }
410                                         }
411                                         if (comment) {
412                                                 continue;
413                                         }
414                                         if (flag) {
415                                                 params.append(line);
416                                         }
417                                         if (line.contains("rule") && line.contains(".Params\"")) {
418                                                 params.append(line);
419                                                 flag = true;
420                                         }
421                                         if (line.contains("end") && flag) {
422                                                 break;
423                                         }
424                                 }
425                                 params = new StringBuilder(params.substring(params.indexOf(".Params\"")+ 11));
426                                 params = new StringBuilder(params.toString().replaceAll("\\s+", "").replace("salience1000whenthenParamsparams=newParams();","")
427                         .replace("insert(params);end", "")
428                         .replace("params.set", ""));
429                                 String[] components = params.toString().split("\\);");
430                                 if(components!= null && components.length > 0){
431                                         for (int i = 0; i < components.length; i++) {
432                                                 String value;
433                                                 components[i] = components[i]+")";
434                                                 String caption = components[i].substring(0,
435                                                                 components[i].indexOf('('));
436                                                 caption = caption.substring(0, 1).toLowerCase() + caption.substring(1);
437                                                 if (components[i].contains("(\"")) {
438                                                         value = components[i]
439                                                                         .substring(components[i].indexOf("(\""),
440                                                                                         components[i].indexOf("\")"))
441                                                                         .replace("(\"", "").replace("\")", "");
442                                                 } else {
443                                                         value = components[i]
444                                                                         .substring(components[i].indexOf('('),
445                                                                                         components[i].indexOf(')'))
446                                                                         .replace("(", "").replace(")", "");
447                                                 }
448                                                 dynamicLayoutMap.put(caption, value);
449
450                                         }
451                                 }
452                         } catch (Exception e) {
453                                 policyLogger.error(XACMLErrorConstants.ERROR_DATA_ISSUE + e.getMessage() + e);
454                         } 
455                 }
456                 
457         }
458
459         // set View Rule
460         @SuppressWarnings("unchecked")
461         @RequestMapping(value={"/policyController/ViewBRMSParamPolicyRule.htm"}, method={org.springframework.web.bind.annotation.RequestMethod.POST})
462         public void setViewRule(HttpServletRequest request, HttpServletResponse response){
463                 try {
464                         ObjectMapper mapper = new ObjectMapper();
465                         mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
466                         JsonNode root = mapper.readTree(request.getReader());
467                         PolicyRestAdapter policyData = mapper.readValue(root.get(PolicyController.getPolicydata()).get("policy").toString(), PolicyRestAdapter.class);
468                         policyData.setDomainDir(root.get(PolicyController.getPolicydata()).get("model").get("name").toString().replace("\"", ""));
469                         if(root.get(PolicyController.getPolicydata()).get("model").get("type").toString().replace("\"", "").equals(PolicyController.getFile())){
470                                 policyData.setEditPolicy(true);
471                         }
472
473                         String body;
474                         body = findRule((String) policyData.getRuleName()) + "\n";
475                         StringBuilder generatedMetadata = new StringBuilder();
476                         generatedMetadata.append("/* Autogenerated Code Please Don't change/remove this comment section. This is for the UI purpose. \n\t " +
477                                         brmsTemplateVlaue + policyData.getRuleName() + "%$> \n */ \n");
478
479                         if(policyData.getDynamicLayoutMap().size() > 0){
480                                 generatedMetadata.append("/* <%$Values=");
481                             for (Entry<?, ?> entry : policyData.getRuleData().entrySet()) {
482                                 String uiKey = (String) entry.getKey();
483                                 if(!"templateName".equals(uiKey)) {
484                                         generatedMetadata.append(uiKey+":-:"+entry.getValue()+":|:");
485                                 }
486                             }
487                             generatedMetadata.append("$%> \n*/ \n");                        
488                         }
489                         policyLogger.info("Metadata generated with :" + generatedMetadata.toString());
490                         body = generatedMetadata.toString() + body;
491                         // Expand the body. 
492                         Map<String,String> copyMap=new HashMap<>();
493                         copyMap.putAll((Map<? extends String, ? extends String>) policyData.getRuleData());
494                         copyMap.put("policyName", policyData.getDomainDir().replace("\\", ".") +".Config_BRMS_Param_" + policyData.getPolicyName());
495                         copyMap.put("policyScope", policyData.getDomainDir().replace("\\", "."));
496                         copyMap.put("policyVersion", "1");
497                         //Finding all the keys in the Map data-structure.
498                         Set<String> keySet= copyMap.keySet();
499                         Iterator<String> iterator = keySet.iterator(); 
500                         Pattern p;
501                         Matcher m;
502                         while(iterator.hasNext()) {
503                                 //Converting the first character of the key into a lower case. 
504                                 String input= iterator.next();
505                                 String output  = Character.toLowerCase(input.charAt(0)) +
506                                                 (input.length() > 1 ? input.substring(1) : "");
507                                 //Searching for a pattern in the String using the key. 
508                                 p=Pattern.compile("\\$\\{"+output+"\\}");   
509                                 m=p.matcher(body);
510                                 //Replacing the value with the inputs provided by the user in the editor. 
511                                 body=m.replaceAll(copyMap.get(input));
512                         }
513                         response.setCharacterEncoding("UTF-8");
514                         response.setContentType("application / json");
515                         request.setCharacterEncoding("UTF-8");
516
517                         PrintWriter out = response.getWriter();
518                         String responseString = mapper.writeValueAsString(body);
519                         JSONObject j = new JSONObject("{policyData: " + responseString + "}");
520                         out.write(j.toString());
521                 } catch (Exception e) {
522                         policyLogger.error(XACMLErrorConstants.ERROR_PROCESS_FLOW + e);
523                 }       
524         }
525 }