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