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