6bab919ad4e2ebf8eb99cf523ed1a889c29e4b65
[policy/engine.git] / ONAP-REST / src / main / java / org / onap / policy / rest / util / PolicyValidation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP Policy Engine
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Modifications Copyright (C) 2019 Nordix Foundation.
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.rest.util;
23
24 import com.fasterxml.jackson.core.JsonProcessingException;
25 import com.fasterxml.jackson.databind.JsonNode;
26 import com.fasterxml.jackson.databind.ObjectMapper;
27 import com.google.common.base.Splitter;
28 import com.google.common.base.Strings;
29
30 import java.io.ByteArrayInputStream;
31 import java.io.IOException;
32 import java.io.StringReader;
33 import java.nio.charset.StandardCharsets;
34 import java.util.ArrayList;
35 import java.util.HashMap;
36 import java.util.HashSet;
37 import java.util.Iterator;
38 import java.util.LinkedHashMap;
39 import java.util.List;
40 import java.util.Map;
41 import java.util.Map.Entry;
42 import java.util.Set;
43
44 import javax.json.Json;
45 import javax.json.JsonException;
46 import javax.json.JsonObject;
47 import javax.json.JsonReader;
48 import javax.json.JsonValue;
49
50 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicySetType;
51 import oasis.names.tc.xacml._3_0.core.schema.wd_17.PolicyType;
52
53 import org.apache.commons.lang3.StringEscapeUtils;
54 import org.apache.commons.lang3.StringUtils;
55 import org.json.JSONArray;
56 import org.json.JSONObject;
57 import org.onap.policy.common.logging.flexlogger.FlexLogger;
58 import org.onap.policy.common.logging.flexlogger.Logger;
59 import org.onap.policy.rest.adapter.ClosedLoopFaultBody;
60 import org.onap.policy.rest.adapter.ClosedLoopPMBody;
61 import org.onap.policy.rest.adapter.PolicyRestAdapter;
62 import org.onap.policy.rest.dao.CommonClassDao;
63 import org.onap.policy.rest.jpa.MicroServiceModels;
64 import org.onap.policy.rest.jpa.OptimizationModels;
65 import org.onap.policy.rest.jpa.SafePolicyWarning;
66 import org.onap.policy.utils.PolicyUtils;
67 import org.onap.policy.xacml.api.XACMLErrorConstants;
68 import org.onap.policy.xacml.util.XACMLPolicyScanner;
69 import org.springframework.beans.factory.annotation.Autowired;
70 import org.springframework.stereotype.Service;
71
72 @Service
73 public class PolicyValidation {
74     private static final Logger LOGGER = FlexLogger.getLogger(PolicyValidation.class);
75
76     private static final String ACTION_POLICY = "Action";
77     private static final String BOOLEAN = "boolean";
78     private static final String BRMSPARAM = "BRMS_Param";
79     private static final String BRMSRAW = "BRMS_Raw";
80     private static final String CLOSEDLOOP_PM = "ClosedLoop_PM";
81     private static final String CLOSEDLOOP_POLICY = "ClosedLoop_Fault";
82     private static final String CONFIG_POLICY = "Config";
83     private static final String DECISION_MS_MODEL = "MicroService_Model";
84     private static final String DECISION_POLICY = "Decision";
85     private static final String DECISION_POLICY_MS = "Decision_MS";
86     private static final String ENFORCER_CONFIG_POLICY = "Enforcer Config";
87     private static final String FIREWALL = "Firewall Config";
88     private static final String HTML_ITALICS_LNBREAK = "</i><br>";
89     private static final String INTEGER = "integer";
90     private static final String ISREQUIRED = " is required";
91     private static final String JAVA = "java";
92     private static final String LIST = "list";
93     private static final String MAP = "map";
94     private static final String MICROSERVICES = "Micro Service";
95     private static final String MISSING_COMPONENT_ATTRIBUTE_VALUE = "<b>Component Attributes</b>:"
96                     + "<i> has one missing Component Attribute value</i><br>";
97     private static final String MISSING_ATTRIBUTE_VALUE = "<b>Rule Attributes</b>:"
98                     + "<i> has one missing Attribute value</i><br>";
99     private static final String MISSING_COMPONENT_ATTRIBUTE_KEY = "<b>Component Attributes</b>:"
100                     + "<i> has one missing Component Attribute key</i><br>";
101     private static final String OPTIMIZATION = "Optimization";
102     private static final String RAW = "Raw";
103     private static final String REQUIRED_ATTRIBUTE = "required-true";
104     private static final String RULE_ALGORITHMS = "<b>Rule Algorithms</b>:<i>";
105     private static final String SELECT_AT_LEAST_ONE_D2_VIRTUALIZED_SERVICES = "<b>D2/Virtualized Services</b>: "
106                     + "<i>Select at least one D2/Virtualized Services";
107     private static final String SPACESINVALIDCHARS = " : value has spaces or invalid characters</i><br>";
108     private static final String STRING = "string";
109     private static final String SUCCESS = "success";
110     private static final String VALUE = "value";
111
112     private static Map<String, String> mapAttribute = new HashMap<>();
113     private static Map<String, String> jsonRequestMap = new HashMap<>();
114     private static List<String> modelRequiredFieldsList = new ArrayList<>();
115
116     private static CommonClassDao commonClassDao;
117
118     private Set<String> allReqTrueKeys = new HashSet<>();
119     private Set<String> allOptReqTrueKeys = new HashSet<>();
120
121     @Autowired
122     public PolicyValidation(CommonClassDao commonClassDao) {
123         PolicyValidation.commonClassDao = commonClassDao;
124     }
125
126     /*
127      * This is an empty constructor
128      */
129     public PolicyValidation() {
130         // Empty constructor
131     }
132
133     /**
134      * Validate policy.
135      *
136      * @param policyData the policy data
137      * @return the string builder
138      * @throws IOException Signals that an I/O exception has occurred.
139      */
140     public StringBuilder validatePolicy(PolicyRestAdapter policyData) throws IOException {
141         try {
142             boolean valid = true;
143             StringBuilder responseString = new StringBuilder();
144             ObjectMapper mapper = new ObjectMapper();
145
146             if (policyData.getPolicyName() != null) {
147                 String policyNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getPolicyName());
148                 if (!policyNameValidate.contains(SUCCESS)) {
149                     responseString.append("<b>PolicyName</b>:<i>" + policyNameValidate + HTML_ITALICS_LNBREAK);
150                     valid = false;
151                 }
152             } else {
153                 responseString.append("<b>PolicyName</b>: PolicyName Should not be empty" + HTML_ITALICS_LNBREAK);
154                 valid = false;
155             }
156             if (policyData.getPolicyDescription() != null) {
157                 String descriptionValidate = PolicyUtils.descriptionValidator(policyData.getPolicyDescription());
158                 if (!descriptionValidate.contains(SUCCESS)) {
159                     responseString.append("<b>Description</b>:<i>" + descriptionValidate + HTML_ITALICS_LNBREAK);
160                     valid = false;
161                 }
162             }
163
164             if (!"API".equals(policyData.getApiflag()) && policyData.getAttributes() != null
165                             && !policyData.getAttributes().isEmpty()) {
166                 for (Object attribute : policyData.getAttributes()) {
167                     if (attribute instanceof LinkedHashMap<?, ?>) {
168                         String attValue = null;
169                         String key = null;
170                         if (((LinkedHashMap<?, ?>) attribute).get("key") != null) {
171                             key = ((LinkedHashMap<?, ?>) attribute).get("key").toString();
172                             if (!PolicyUtils.policySpecialCharWithDashValidator(key).contains(SUCCESS)) {
173                                 responseString.append("<b>Attributes or Component Attributes</b>:<i>" + attValue
174                                                 + SPACESINVALIDCHARS);
175                                 valid = false;
176                             }
177                         } else {
178                             if (CONFIG_POLICY.equals(policyData.getPolicyType())) {
179                                 if ("Base".equals(policyData.getConfigPolicyType())) {
180                                     responseString.append(
181                                                     "<b>Attributes</b>:<i> has one missing Attribute key</i><br>");
182                                 }
183                                 if (BRMSPARAM.equals(policyData.getConfigPolicyType())
184                                                 || BRMSRAW.equals(policyData.getConfigPolicyType())) {
185                                     responseString.append(
186                                                     "<b>Rule Attributes</b>:<i> has one missing Attribute key</i><br>");
187                                 }
188                             } else {
189                                 responseString.append(MISSING_COMPONENT_ATTRIBUTE_KEY);
190                             }
191                             valid = false;
192                         }
193                         if (((LinkedHashMap<?, ?>) attribute).get(VALUE) != null) {
194                             attValue = ((LinkedHashMap<?, ?>) attribute).get(VALUE).toString();
195                             if (!PolicyUtils.policySpecialCharWithDashValidator(attValue).contains(SUCCESS)) {
196                                 if (CONFIG_POLICY.equals(policyData.getPolicyType())) {
197                                     if ("Base".equals(policyData.getConfigPolicyType())) {
198                                         responseString.append("<b>Attributes</b>:<i>" + attValue + SPACESINVALIDCHARS);
199                                     }
200                                     if (BRMSPARAM.equals(policyData.getConfigPolicyType())
201                                                     || BRMSRAW.equals(policyData.getConfigPolicyType())) {
202                                         responseString.append(
203                                                         "<b>Rule Attributes</b>:<i>" + attValue + SPACESINVALIDCHARS);
204                                     }
205                                 } else {
206                                     responseString.append(
207                                                     "<b>Component Attributes</b>:<i>" + attValue + SPACESINVALIDCHARS);
208                                 }
209                                 valid = false;
210                             }
211                         } else {
212                             if (CONFIG_POLICY.equals(policyData.getPolicyType())) {
213                                 if ("Base".equals(policyData.getConfigPolicyType())) {
214                                     responseString.append(
215                                                     "<b>Attributes</b>:<i> has one missing Attribute value</i><br>");
216                                 }
217                                 if (BRMSPARAM.equals(policyData.getConfigPolicyType())
218                                                 || BRMSRAW.equals(policyData.getConfigPolicyType())) {
219                                     responseString.append(MISSING_ATTRIBUTE_VALUE);
220                                 }
221                             } else {
222                                 responseString.append(MISSING_COMPONENT_ATTRIBUTE_VALUE);
223                             }
224                             valid = false;
225                         }
226                     }
227                 }
228             }
229
230             // Decision Policy Attributes Validation
231             if (!"API".equals(policyData.getApiflag()) && policyData.getSettings() != null
232                             && !policyData.getSettings().isEmpty()) {
233                 for (Object attribute : policyData.getAttributes()) {
234                     if (attribute instanceof LinkedHashMap<?, ?>) {
235                         String value = null;
236                         if (((LinkedHashMap<?, ?>) attribute).get("key") == null) {
237                             responseString.append(
238                                             "<b>Settings Attributes</b>:<i> has one missing Attribute key</i><br>");
239                             valid = false;
240                         }
241                         if (((LinkedHashMap<?, ?>) attribute).get(VALUE) != null) {
242                             value = ((LinkedHashMap<?, ?>) attribute).get(VALUE).toString();
243                             if (!PolicyUtils.policySpecialCharValidator(value).contains(SUCCESS)) {
244                                 responseString.append("<b>Settings Attributes</b>:<i>" + value + SPACESINVALIDCHARS);
245                                 valid = false;
246                             }
247                         } else {
248                             responseString.append(
249                                             "<b>Settings Attributes</b>:<i> has one missing Attribute Value</i><br>");
250                             valid = false;
251                         }
252                     }
253                 }
254             }
255
256             if (!"API".equals(policyData.getApiflag()) && policyData.getRuleAlgorithmschoices() != null
257                             && !policyData.getRuleAlgorithmschoices().isEmpty()) {
258                 for (Object attribute : policyData.getRuleAlgorithmschoices()) {
259                     if (attribute instanceof LinkedHashMap<?, ?>) {
260                         String label = ((LinkedHashMap<?, ?>) attribute).get("id").toString();
261                         if (((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField1") == null) {
262                             responseString.append(RULE_ALGORITHMS + label + " : Field 1 value is not selected</i><br>");
263                             valid = false;
264                         }
265                         if (((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmCombo") == null) {
266                             responseString.append(RULE_ALGORITHMS + label + " : Field 2 value is not selected</i><br>");
267                             valid = false;
268                         }
269                         if (((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField2") != null) {
270                             String value = ((LinkedHashMap<?, ?>) attribute).get("dynamicRuleAlgorithmField2")
271                                             .toString();
272                             if (!PolicyUtils.policySpecialCharValidator(value).contains(SUCCESS)) {
273                                 responseString.append(RULE_ALGORITHMS + label
274                                                 + " : Field 3 value has special characters</i><br>");
275                                 valid = false;
276                             }
277                         } else {
278                             responseString.append(RULE_ALGORITHMS + label + " : Field 3 value is empty</i><br>");
279                             valid = false;
280                         }
281                     }
282                 }
283             }
284
285             if (CONFIG_POLICY.equalsIgnoreCase(policyData.getPolicyType())) {
286                 if ("Base".equals(policyData.getConfigPolicyType())
287                                 || CLOSEDLOOP_POLICY.equals(policyData.getConfigPolicyType())
288                                 || CLOSEDLOOP_PM.equals(policyData.getConfigPolicyType())
289                                 || ENFORCER_CONFIG_POLICY.equals(policyData.getConfigPolicyType())
290                                 || MICROSERVICES.equals(policyData.getConfigPolicyType())
291                                 || OPTIMIZATION.equals(policyData.getConfigPolicyType())) {
292
293                     if (!Strings.isNullOrEmpty(policyData.getOnapName())) {
294                         String onapNameValidate = PolicyUtils
295                                         .policySpecialCharWithDashValidator(policyData.getOnapName());
296                         if (!onapNameValidate.contains(SUCCESS)) {
297                             responseString.append("<b>OnapName</b>:<i>" + onapNameValidate + HTML_ITALICS_LNBREAK);
298                             valid = false;
299                         }
300                     } else {
301                         responseString.append("<b>Onap Name</b>: Onap Name Should not be empty" + HTML_ITALICS_LNBREAK);
302                         valid = false;
303                     }
304                 }
305
306                 if (!Strings.isNullOrEmpty(policyData.getRiskType())) {
307                     String riskTypeValidate = PolicyUtils.policySpecialCharValidator(policyData.getRiskType());
308                     if (!riskTypeValidate.contains(SUCCESS)) {
309                         responseString.append("<b>RiskType</b>:<i>" + riskTypeValidate + HTML_ITALICS_LNBREAK);
310                         valid = false;
311                     }
312                 } else {
313                     responseString.append("<b>RiskType</b>: Risk Type Should not be Empty" + HTML_ITALICS_LNBREAK);
314                     valid = false;
315                 }
316
317                 if (!Strings.isNullOrEmpty(policyData.getRiskLevel())) {
318                     String validateRiskLevel = PolicyUtils.policySpecialCharValidator(policyData.getRiskLevel());
319                     if (!validateRiskLevel.contains(SUCCESS)) {
320                         responseString.append("<b>RiskLevel</b>:<i>" + validateRiskLevel + HTML_ITALICS_LNBREAK);
321                         valid = false;
322                     }
323                 } else {
324                     responseString.append("<b>RiskLevel</b>: Risk Level Should not be Empty" + HTML_ITALICS_LNBREAK);
325                     valid = false;
326                 }
327
328                 if (!Strings.isNullOrEmpty(policyData.getGuard())) {
329                     String validateGuard = PolicyUtils.policySpecialCharValidator(policyData.getGuard());
330                     if (!validateGuard.contains(SUCCESS)) {
331                         responseString.append("<b>Guard</b>:<i>" + validateGuard + HTML_ITALICS_LNBREAK);
332                         valid = false;
333                     }
334                 } else {
335                     responseString.append("<b>Guard</b>: Guard Value Should not be Empty" + HTML_ITALICS_LNBREAK);
336                     valid = false;
337                 }
338
339                 // Validate Config Base Policy Data
340                 if ("Base".equalsIgnoreCase(policyData.getConfigPolicyType())) {
341                     if (!Strings.isNullOrEmpty(policyData.getConfigName())) {
342                         String configNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getConfigName());
343                         if (!configNameValidate.contains(SUCCESS)) {
344                             responseString.append("ConfigName:" + configNameValidate + HTML_ITALICS_LNBREAK);
345                             valid = false;
346                         }
347                     } else {
348                         responseString.append("Config Name: Config Name Should not be Empty" + HTML_ITALICS_LNBREAK);
349                         valid = false;
350                     }
351                     if (!Strings.isNullOrEmpty(policyData.getConfigType())) {
352                         String configTypeValidate = PolicyUtils.policySpecialCharValidator(policyData.getConfigType());
353                         if (!configTypeValidate.contains(SUCCESS)) {
354                             responseString.append("ConfigType:" + configTypeValidate + HTML_ITALICS_LNBREAK);
355                             valid = false;
356                         }
357                     } else {
358                         responseString.append("Config Type: Config Type Should not be Empty" + HTML_ITALICS_LNBREAK);
359                         valid = false;
360                     }
361                     if (!Strings.isNullOrEmpty(policyData.getConfigBodyData())) {
362                         String configBodyData = policyData.getConfigBodyData();
363                         String configType = policyData.getConfigType();
364                         if (configType != null) {
365                             if ("JSON".equals(configType)) {
366                                 if (!PolicyUtils.isJSONValid(configBodyData)) {
367                                     responseString.append(
368                                                     "Config Body: JSON Content is not valid" + HTML_ITALICS_LNBREAK);
369                                     valid = false;
370                                 }
371                             } else if ("XML".equals(configType)) {
372                                 if (!PolicyUtils.isXMLValid(configBodyData)) {
373                                     responseString.append("Config Body: XML Content data is not valid"
374                                                     + HTML_ITALICS_LNBREAK);
375                                     valid = false;
376                                 }
377                             } else if ("PROPERTIES".equals(configType)) {
378                                 if (!PolicyUtils.isPropValid(configBodyData) || "".equals(configBodyData)) {
379                                     responseString.append(
380                                                     "Config Body: Property data is not valid" + HTML_ITALICS_LNBREAK);
381                                     valid = false;
382                                 }
383                             } else if ("OTHER".equals(configType) && ("".equals(configBodyData))) {
384                                 responseString.append(
385                                                 "Config Body: Config Body Should not be Empty" + HTML_ITALICS_LNBREAK);
386                                 valid = false;
387                             }
388                         }
389                     } else {
390                         responseString.append("Config Body: Config Body Should not be Empty" + HTML_ITALICS_LNBREAK);
391                         valid = false;
392                     }
393                 }
394                 // Validate Config Firewall Policy Data
395                 if (FIREWALL.equalsIgnoreCase(policyData.getConfigPolicyType())) {
396                     if (policyData.getConfigName() != null && !policyData.getConfigName().isEmpty()) {
397                         String configNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getConfigName());
398                         if (!configNameValidate.contains(SUCCESS)) {
399                             responseString.append("<b>ConfigName</b>:<i>" + configNameValidate + HTML_ITALICS_LNBREAK);
400                             valid = false;
401                         }
402                     } else {
403                         responseString.append("<b>Config Name</b>:<i> Config Name is required" + HTML_ITALICS_LNBREAK);
404                         valid = false;
405                     }
406                     if (policyData.getSecurityZone() == null || policyData.getSecurityZone().isEmpty()) {
407                         responseString.append(
408                                         "<b>Security Zone</b>:<i> Security Zone is required" + HTML_ITALICS_LNBREAK);
409                         valid = false;
410                     }
411                 }
412                 // Validate BRMS_Param Policy Data
413                 if (BRMSPARAM.equalsIgnoreCase(policyData.getConfigPolicyType())
414                                 && Strings.isNullOrEmpty(policyData.getRuleName())) {
415                     responseString.append("<b>BRMS Template</b>:<i>BRMS Template is required" + HTML_ITALICS_LNBREAK);
416                     valid = false;
417                 }
418                 // Validate BRMS_Raw Policy Data
419                 if (BRMSRAW.equalsIgnoreCase(policyData.getConfigPolicyType())) {
420                     if (policyData.getConfigBodyData() != null && !policyData.getConfigBodyData().isEmpty()) {
421                         String message = PolicyUtils.brmsRawValidate(policyData.getConfigBodyData());
422
423                         // If there are any error other than Annotations then this is not Valid
424                         if (message.contains("[ERR")) {
425                             responseString.append("<b>Raw Rule Validate</b>:<i>Raw Rule has error" + message
426                                             + HTML_ITALICS_LNBREAK);
427                             valid = false;
428                         }
429                     } else {
430                         responseString.append("<b>Raw Rule</b>:<i>Raw Rule is required" + HTML_ITALICS_LNBREAK);
431                         valid = false;
432                     }
433                 }
434                 // Validate ClosedLoop_PM Policy Data
435                 if (CLOSEDLOOP_PM.equalsIgnoreCase(policyData.getConfigPolicyType())) {
436                     try {
437                         if (Strings.isNullOrEmpty(policyData.getServiceTypePolicyName().get("serviceTypePolicyName")
438                                         .toString())) {
439                             responseString.append("<b>ServiceType PolicyName</b>:<i>ServiceType PolicyName is required"
440                                             + HTML_ITALICS_LNBREAK);
441                             valid = false;
442                         }
443
444                     } catch (Exception e) {
445                         LOGGER.error("ERROR in ClosedLoop_PM PolicyName", e);
446                         responseString.append("<b>ServiceType PolicyName</b>:<i>ServiceType PolicyName is required"
447                                         + HTML_ITALICS_LNBREAK);
448                         valid = false;
449                     }
450
451                     if (policyData.getJsonBody() != null) {
452
453                         ClosedLoopPMBody pmBody = mapper.readValue(policyData.getJsonBody(), ClosedLoopPMBody.class);
454                         if (pmBody.getEmailAddress() != null) {
455                             String result = emailValidation(pmBody.getEmailAddress(), responseString.toString());
456                             if (result != SUCCESS) {
457                                 responseString.append(result + HTML_ITALICS_LNBREAK);
458                                 valid = false;
459                             }
460                         }
461                         if (!pmBody.isGamma() && !pmBody.isMcr() && !pmBody.isTrinity() && !pmBody.isvDNS()
462                                         && !pmBody.isvUSP()) {
463                             responseString.append(SELECT_AT_LEAST_ONE_D2_VIRTUALIZED_SERVICES + HTML_ITALICS_LNBREAK);
464                             valid = false;
465                         }
466                         if (pmBody.getGeoLink() != null && !pmBody.getGeoLink().isEmpty()) {
467                             String result = PolicyUtils.policySpecialCharValidator(pmBody.getGeoLink());
468                             if (!result.contains(SUCCESS)) {
469                                 responseString.append("<b>GeoLink</b>:<i>" + result + HTML_ITALICS_LNBREAK);
470                                 valid = false;
471                             }
472                         }
473                         if (pmBody.getAttributes() != null && !pmBody.getAttributes().isEmpty()) {
474                             for (Entry<String, String> entry : pmBody.getAttributes().entrySet()) {
475                                 String key = entry.getKey();
476                                 String value = entry.getValue();
477                                 if (!key.contains("Message")) {
478                                     String attributeValidate = PolicyUtils.policySpecialCharValidator(value);
479                                     if (!attributeValidate.contains(SUCCESS)) {
480                                         responseString.append("<b>Attributes</b>:<i>" + key
481                                                         + " : value has spaces or invalid characters"
482                                                         + HTML_ITALICS_LNBREAK);
483                                         valid = false;
484                                     }
485                                 }
486                             }
487                         }
488                     } else {
489                         responseString.append(
490                                         "<b>D2/Virtualized Services</b>:<i>Select atleast one D2/Virtualized Services"
491                                                         + HTML_ITALICS_LNBREAK);
492                         valid = false;
493                     }
494                 }
495                 if (CLOSEDLOOP_POLICY.equalsIgnoreCase(policyData.getConfigPolicyType())) {
496                     if (policyData.getJsonBody() != null) {
497
498                         // For API we need to get the conditions key from the Json request and check it before
499                         // deserializing to POJO due to the enum
500                         if ("API".equals(policyData.getApiflag())) {
501                             JSONObject json = new JSONObject(policyData.getJsonBody());
502                             if (!json.isNull("conditions")) {
503                                 String apiCondition = (String) json.get("conditions");
504                                 if (Strings.isNullOrEmpty(apiCondition)) {
505                                     responseString.append("<b>Conditions</b>: <i>Select At least one Condition"
506                                                     + HTML_ITALICS_LNBREAK);
507                                     return responseString;
508                                 }
509                             } else {
510                                 responseString.append("<b>Conditions</b>:"
511                                                 + " <i>There were no conditions provided in configBody json"
512                                                 + HTML_ITALICS_LNBREAK);
513                                 return responseString;
514                             }
515                         } else {
516                             if (policyData.getTrapDatas().getTrap1() != null) {
517                                 if (policyData.getClearTimeOut() == null) {
518                                     responseString.append("<b>Trigger Clear TimeOut</b>: "
519                                                     + "<i>Trigger Clear TimeOut is required when at "
520                                                     + "least One Trigger Signature is enabled</i><br>");
521                                     valid = false;
522                                 }
523                                 if (policyData.getTrapMaxAge() == null) {
524                                     responseString.append("<b>Trap Max Age</b>: <i>Trap Max Age is required when at "
525                                                     + "least One Trigger Signature is enabled</i><br>");
526                                     valid = false;
527                                 }
528                             }
529                             if (policyData.getFaultDatas().getTrap1() != null
530                                             && policyData.getVerificationclearTimeOut() == null) {
531                                 responseString.append(
532                                                 "<b>Fault Clear TimeOut</b>: <i>Fault Clear TimeOut is required when at"
533                                                                 + "least One Fault Signature is enabled</i><br>");
534                                 valid = false;
535                             }
536                         }
537
538                         ClosedLoopFaultBody faultBody = mapper.readValue(policyData.getJsonBody(),
539                                         ClosedLoopFaultBody.class);
540                         if (faultBody.getEmailAddress() != null && !faultBody.getEmailAddress().isEmpty()) {
541                             String result = emailValidation(faultBody.getEmailAddress(), responseString.toString());
542                             if (!SUCCESS.equals(result)) {
543                                 responseString.append(result + HTML_ITALICS_LNBREAK);
544                                 valid = false;
545                             }
546                         }
547                         if (!(faultBody.isGamma() || faultBody.isMcr() || faultBody.isTrinity() || faultBody.isvDNS()
548                                         || faultBody.isvUSP())) {
549                             responseString.append(SELECT_AT_LEAST_ONE_D2_VIRTUALIZED_SERVICES + HTML_ITALICS_LNBREAK);
550                             valid = false;
551                         }
552                         if (faultBody.getActions() == null || faultBody.getActions().isEmpty()) {
553                             responseString.append(
554                                             "<b>vPRO Actions</b>: <i>vPRO Actions is required" + HTML_ITALICS_LNBREAK);
555                             valid = false;
556                         }
557                         if (faultBody.getClosedLoopPolicyStatus() == null
558                                         || faultBody.getClosedLoopPolicyStatus().isEmpty()) {
559                             responseString.append("<b>Policy Status</b>: <i>Policy Status is required"
560                                             + HTML_ITALICS_LNBREAK);
561                             valid = false;
562                         }
563                         if (faultBody.getConditions() == null) {
564                             responseString.append("<b>Conditions</b>: <i>Select At least one Condition"
565                                             + HTML_ITALICS_LNBREAK);
566                             valid = false;
567                         }
568                         if (faultBody.getGeoLink() != null && !faultBody.getGeoLink().isEmpty()) {
569                             String result = PolicyUtils.policySpecialCharWithSpaceValidator(faultBody.getGeoLink());
570                             if (!result.contains(SUCCESS)) {
571                                 responseString.append("<b>GeoLink</b>:<i>" + result + HTML_ITALICS_LNBREAK);
572                                 valid = false;
573                             }
574                         }
575                         if (faultBody.getAgingWindow() == 0) {
576                             responseString.append(
577                                             "<b>Aging Window</b>: <i>Aging Window is required" + HTML_ITALICS_LNBREAK);
578                             valid = false;
579                         }
580                         if (faultBody.getTimeInterval() == 0) {
581                             responseString.append("<b>Time Interval</b>: <i>Time Interval is required"
582                                             + HTML_ITALICS_LNBREAK);
583                             valid = false;
584                         }
585                         if (faultBody.getRetrys() == 0) {
586                             responseString.append("<b>Number of Retries</b>: <i>Number of Retries is required"
587                                             + HTML_ITALICS_LNBREAK);
588                             valid = false;
589                         }
590                         if (faultBody.getTimeOutvPRO() == 0) {
591                             responseString.append("<b>APP-C Timeout</b>: <i>APP-C Timeout is required"
592                                             + HTML_ITALICS_LNBREAK);
593                             valid = false;
594                         }
595                         if (faultBody.getTimeOutRuby() == 0) {
596                             responseString.append(
597                                             "<b>TimeOutRuby</b>: <i>TimeOutRuby is required" + HTML_ITALICS_LNBREAK);
598                             valid = false;
599                         }
600                         if (faultBody.getVnfType() == null || faultBody.getVnfType().isEmpty()) {
601                             responseString.append("<b>Vnf Type</b>: <i>Vnf Type is required" + HTML_ITALICS_LNBREAK);
602                             valid = false;
603                         }
604                     } else {
605                         responseString.append(
606                                         "<b>D2/Virtualized Services</b>: <i>Select atleast one D2/Virtualized Services"
607                                                         + HTML_ITALICS_LNBREAK);
608                         responseString.append(
609                                         "<b>vPRO Actions</b>: <i>vPRO Actions is required" + HTML_ITALICS_LNBREAK);
610                         responseString.append(
611                                         "<b>Aging Window</b>: <i>Aging Window is required" + HTML_ITALICS_LNBREAK);
612                         responseString.append(
613                                         "<b>Policy Status</b>: <i>Policy Status is required" + HTML_ITALICS_LNBREAK);
614                         responseString.append(
615                                         "<b>Conditions</b>: <i>Select Atleast one Condition" + HTML_ITALICS_LNBREAK);
616                         responseString.append("<b>PEP Name</b>: <i>PEP Name is required" + HTML_ITALICS_LNBREAK);
617                         responseString.append("<b>PEP Action</b>: <i>PEP Action is required" + HTML_ITALICS_LNBREAK);
618                         responseString.append(
619                                         "<b>Time Interval</b>: <i>Time Interval is required" + HTML_ITALICS_LNBREAK);
620                         responseString.append("<b>Number of Retries</b>: <i>Number of Retries is required"
621                                         + HTML_ITALICS_LNBREAK);
622                         responseString.append(
623                                         "<b>APP-C Timeout</b>: <i>APP-C Timeout is required" + HTML_ITALICS_LNBREAK);
624                         responseString.append("<b>TimeOutRuby</b>: <i>TimeOutRuby is required" + HTML_ITALICS_LNBREAK);
625                         responseString.append("<b>Vnf Type</b>: <i>Vnf Type is required" + HTML_ITALICS_LNBREAK);
626                         valid = false;
627                     }
628                 }
629
630                 // Validate MicroService Policy Data
631                 if (MICROSERVICES.equals(policyData.getConfigPolicyType())) {
632                     boolean tmpValid = validateMsModel(policyData, responseString);
633                     if (!tmpValid) {
634                         valid = false;
635                     }
636                 }
637
638                 // Validate Optimization Policy Data
639                 if (OPTIMIZATION.equals(policyData.getConfigPolicyType())) {
640                     boolean tmpValid = validateOptimization(policyData, responseString);
641                     if (!tmpValid) {
642                         valid = false;
643                     }
644                 }
645             }
646
647             if ((DECISION_POLICY.equalsIgnoreCase(policyData.getPolicyType()))
648                             || (DECISION_POLICY_MS.equalsIgnoreCase(policyData.getPolicyType()))) {
649                 if (!RAW.equalsIgnoreCase(policyData.getRuleProvider())) {
650                     if (!Strings.isNullOrEmpty(policyData.getOnapName())) {
651                         String onapNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getOnapName());
652                         if (!onapNameValidate.contains(SUCCESS)) {
653                             responseString.append("OnapName:" + onapNameValidate + HTML_ITALICS_LNBREAK);
654                             valid = false;
655                         }
656                     } else {
657                         responseString.append("Onap Name: Onap Name Should not be empty" + HTML_ITALICS_LNBREAK);
658                         valid = false;
659                     }
660                 }
661                 if (RAW.equalsIgnoreCase(policyData.getRuleProvider())) {
662                     Object policy = XACMLPolicyScanner.readPolicy(new ByteArrayInputStream(StringEscapeUtils
663                                     .unescapeXml(policyData.getRawXacmlPolicy()).getBytes(StandardCharsets.UTF_8)));
664                     if (!(policy instanceof PolicySetType || policy instanceof PolicyType)) {
665                         responseString.append("Raw XACML: The XACML Content is not valid" + HTML_ITALICS_LNBREAK);
666                         valid = false;
667                     }
668                 }
669
670                 if (DECISION_MS_MODEL.equals(policyData.getRuleProvider())) {
671                     LOGGER.info("Validating Decision MS Policy - ");
672                     boolean tmpValid = validateMsModel(policyData, responseString);
673                     if (!tmpValid) {
674                         valid = false;
675                     }
676                 }
677
678                 if ("Rainy_Day".equals(policyData.getRuleProvider())) {
679                     if (policyData.getRainyday() == null) {
680                         responseString.append("<b> Rainy Day Parameters are Required </b><br>");
681                         valid = false;
682                     } else {
683                         if (Strings.isNullOrEmpty(policyData.getRainyday().getServiceType())) {
684                             responseString.append("Rainy Day <b>Service Type</b> is Required<br>");
685                             valid = false;
686                         }
687                         if (Strings.isNullOrEmpty(policyData.getRainyday().getVnfType())) {
688                             responseString.append("Rainy Day <b>VNF Type</b> is Required<br>");
689                             valid = false;
690                         }
691                         if (Strings.isNullOrEmpty(policyData.getRainyday().getBbid())) {
692                             responseString.append("Rainy Day <b>Building Block ID</b> is Required<br>");
693                             valid = false;
694                         }
695                         if (Strings.isNullOrEmpty(policyData.getRainyday().getWorkstep())) {
696                             responseString.append("Rainy Day <b>Work Step</b> is Required<br>");
697                             valid = false;
698                         }
699                         if (!policyData.getRainyday().getTreatmentTableChoices().isEmpty()
700                                         && policyData.getRainyday().getTreatmentTableChoices() != null) {
701
702                             for (Object treatmentMap : policyData.getRainyday().getTreatmentTableChoices()) {
703                                 String errorCode = null;
704                                 String treatment = null;
705                                 if (treatmentMap instanceof LinkedHashMap<?, ?>) {
706
707                                     if (((LinkedHashMap<?, ?>) treatmentMap).containsKey("errorcode")) {
708                                         errorCode = ((LinkedHashMap<?, ?>) treatmentMap).get("errorcode").toString();
709                                     }
710                                     if (((LinkedHashMap<?, ?>) treatmentMap).containsKey("treatment")) {
711                                         treatment = ((LinkedHashMap<?, ?>) treatmentMap).get("treatment").toString();
712                                     }
713
714                                 }
715                                 if (Strings.isNullOrEmpty(errorCode) && Strings.isNullOrEmpty(treatment)) {
716                                     responseString.append("Rainy Day <b>Error Code</b> and "
717                                                     + "<b>Desired Treatment</b> cannot be empty<br>");
718                                     valid = false;
719                                     break;
720                                 }
721                                 if (Strings.isNullOrEmpty(errorCode)) {
722                                     responseString.append("Rainy Day <b>Error Code</b> is Required "
723                                                     + "for each Desired Treatment<br>");
724                                     valid = false;
725                                     break;
726                                 }
727                                 if (Strings.isNullOrEmpty(treatment)) {
728                                     responseString.append("Rainy Day <b>Desired Treatment"
729                                                     + "</b> is Required for each Error Code<br>");
730                                     valid = false;
731                                     break;
732                                 }
733                             }
734
735                         } else {
736                             responseString.append("Rainy Day <b>Desired Automated Treatments</b> are Required<br>");
737                             valid = false;
738                         }
739                     }
740                 }
741
742                 if ("GUARD_YAML".equals(policyData.getRuleProvider())
743                                 || "GUARD_BL_YAML".equals(policyData.getRuleProvider())
744                                 || "GUARD_MIN_MAX".equals(policyData.getRuleProvider())) {
745                     if (policyData.getYamlparams() == null) {
746                         responseString.append("<b> Guard Params are Required </b>" + HTML_ITALICS_LNBREAK);
747                         valid = false;
748                     } else {
749                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getActor())) {
750                             responseString.append("Guard Params <b>Actor</b> is Required " + HTML_ITALICS_LNBREAK);
751                             valid = false;
752                         }
753                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getRecipe())) {
754                             responseString.append("Guard Params <b>Recipe</b> is Required " + HTML_ITALICS_LNBREAK);
755                             valid = false;
756                         }
757                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getGuardActiveStart())) {
758                             responseString.append("Guard Params <b>Guard Active Start</b> is Required "
759                                             + HTML_ITALICS_LNBREAK);
760                             valid = false;
761                         }
762                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getGuardActiveEnd())) {
763                             responseString.append(
764                                             "Guard Params <b>Guard Active End</b> is Required " + HTML_ITALICS_LNBREAK);
765                             valid = false;
766                         }
767                         if ("GUARD_YAML".equals(policyData.getRuleProvider())) {
768                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getLimit())) {
769                                 responseString.append(" Guard Params <b>Limit</b> is Required " + HTML_ITALICS_LNBREAK);
770                                 valid = false;
771                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getLimit())) {
772                                 responseString.append(
773                                                 " Guard Params <b>Limit</b> Should be Integer " + HTML_ITALICS_LNBREAK);
774                                 valid = false;
775                             }
776                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getTimeWindow())) {
777                                 responseString.append(
778                                                 "Guard Params <b>Time Window</b> is Required" + HTML_ITALICS_LNBREAK);
779                                 valid = false;
780                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getTimeWindow())) {
781                                 responseString.append(" Guard Params <b>Time Window</b> Should be Integer "
782                                                 + HTML_ITALICS_LNBREAK);
783                                 valid = false;
784                             }
785                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getTimeUnits())) {
786                                 responseString.append(
787                                                 "Guard Params <b>Time Units</b> is Required" + HTML_ITALICS_LNBREAK);
788                                 valid = false;
789                             }
790                         } else if ("GUARD_MIN_MAX".equals(policyData.getRuleProvider())) {
791                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getMin())) {
792                                 responseString.append(" Guard Params <b>Min</b> is Required " + HTML_ITALICS_LNBREAK);
793                                 valid = false;
794                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getMin())) {
795                                 responseString.append(
796                                                 " Guard Params <b>Min</b> Should be Integer " + HTML_ITALICS_LNBREAK);
797                                 valid = false;
798                             }
799                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getMax())) {
800                                 responseString.append(" Guard Params <b>Max</b> is Required " + HTML_ITALICS_LNBREAK);
801                                 valid = false;
802                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getMax())) {
803                                 responseString.append(
804                                                 " Guard Params <b>Max</b> Should be Integer " + HTML_ITALICS_LNBREAK);
805                                 valid = false;
806                             }
807                         } else if ("GUARD_BL_YAML".equals(policyData.getRuleProvider())
808                                         && "Use Manual Entry".equals(policyData.getBlackListEntryType())) {
809
810                             if (policyData.getYamlparams().getBlackList() == null
811                                             || policyData.getYamlparams().getBlackList().isEmpty()) {
812                                 responseString.append(
813                                                 " Guard Params <b>BlackList</b> is Required " + HTML_ITALICS_LNBREAK);
814                                 valid = false;
815                             } else {
816                                 for (String blackList : policyData.getYamlparams().getBlackList()) {
817                                     if (blackList == null || !(SUCCESS
818                                                     .equals(PolicyUtils.policySpecialCharValidator(blackList)))) {
819                                         responseString.append(" Guard Params <b>BlackList</b> Should be valid String"
820                                                         + HTML_ITALICS_LNBREAK);
821                                         valid = false;
822                                         break;
823                                     }
824                                 }
825                             }
826                         }
827                     }
828                 }
829             }
830
831             if (ACTION_POLICY.equalsIgnoreCase(policyData.getPolicyType())) {
832                 if (!Strings.isNullOrEmpty(policyData.getActionPerformer())) {
833                     String actionPerformer = PolicyUtils.policySpecialCharValidator(policyData.getActionPerformer());
834                     if (!actionPerformer.contains(SUCCESS)) {
835                         responseString.append("<b>ActionPerformer</b>:<i>" + actionPerformer + HTML_ITALICS_LNBREAK);
836                         valid = false;
837                     }
838                 } else {
839                     responseString.append("<b>ActionPerformer</b>:<i> ActionPerformer Should not be empty"
840                                     + HTML_ITALICS_LNBREAK);
841                     valid = false;
842                 }
843
844                 if (!Strings.isNullOrEmpty(policyData.getActionAttributeValue())) {
845                     String actionAttribute = PolicyUtils
846                                     .policySpecialCharValidator(policyData.getActionAttributeValue());
847                     if (!actionAttribute.contains(SUCCESS)) {
848                         responseString.append("<b>ActionAttribute</b>:<i>" + actionAttribute + HTML_ITALICS_LNBREAK);
849                         valid = false;
850                     }
851                 } else {
852                     responseString.append("<b>ActionAttribute</b>:<i> ActionAttribute Should not be empty"
853                                     + HTML_ITALICS_LNBREAK);
854                     valid = false;
855                 }
856             }
857
858             if (CONFIG_POLICY.equals(policyData.getPolicyType())) {
859                 String value = "";
860                 if (valid) {
861                     if (commonClassDao != null) {
862                         List<Object> spData = commonClassDao.getDataById(SafePolicyWarning.class, "riskType",
863                                         policyData.getRiskType());
864                         if (!spData.isEmpty()) {
865                             SafePolicyWarning safePolicyWarningData = (SafePolicyWarning) spData.get(0);
866                             value = "<b>Message</b>:<i>" + safePolicyWarningData.getMessage() + "</i>";
867                         }
868                     }
869                     responseString.append(SUCCESS + "@#" + value);
870                 }
871             } else {
872                 if (valid) {
873                     responseString.append(SUCCESS);
874                 }
875             }
876
877             return responseString;
878         } catch (Exception e) {
879             LOGGER.error("Exception Occured during Policy Validation" + e);
880             return null;
881         }
882     }
883
884     protected String emailValidation(String email, String response) {
885         String res = response;
886         if (email != null) {
887             String validateEmail = PolicyUtils.validateEmailAddress(email.replace("\"", ""));
888             if (!validateEmail.contains(SUCCESS)) {
889                 res += "<b>Email</b>:<i>" + validateEmail + HTML_ITALICS_LNBREAK;
890             } else {
891                 return SUCCESS;
892             }
893         }
894         return res;
895     }
896
897     private MicroServiceModels getAttributeObject(String name, String version) {
898         MicroServiceModels workingModel = null;
899         try {
900             List<Object> microServiceModelsData = commonClassDao.getDataById(MicroServiceModels.class,
901                             "modelName:version", name + ":" + version);
902             if (microServiceModelsData != null) {
903                 workingModel = (MicroServiceModels) microServiceModelsData.get(0);
904             }
905         } catch (Exception e) {
906             String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Template.  The template name, " + name
907                             + " was not found in the dictionary: ";
908             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message + e);
909             return null;
910         }
911
912         return workingModel;
913     }
914
915     private OptimizationModels getOptimizationModelData(String name, String version) {
916         OptimizationModels workingModel = null;
917         try {
918             List<Object> optimizationModelsData = commonClassDao.getDataById(OptimizationModels.class,
919                             "modelName:version", name + ":" + version);
920             if (optimizationModelsData != null) {
921                 workingModel = (OptimizationModels) optimizationModelsData.get(0);
922             }
923         } catch (Exception e) {
924             String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Template.  The template name, " + name
925                             + " was not found in the dictionary: ";
926             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message + e);
927             return null;
928         }
929
930         return workingModel;
931     }
932
933     private void pullJsonKeyPairs(JsonNode rootNode) {
934         Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
935
936         while (fieldsIterator.hasNext()) {
937             Map.Entry<String, JsonNode> field = fieldsIterator.next();
938             final String key = field.getKey();
939             final JsonNode value = field.getValue();
940             if (value.isContainerNode() && !value.isArray()) {
941                 pullJsonKeyPairs(value); // RECURSIVE CALL
942             } else {
943                 if (value.isArray()) {
944                     String newValue = StringUtils.replaceEach(value.toString(), new String[]
945                         { "[", "]", "\"" }, new String[]
946                         { "", "", "" });
947                     mapAttribute.put(key, newValue);
948                 } else {
949                     mapAttribute.put(key, value.toString().trim());
950                 }
951             }
952         }
953     }
954
955     private void pullModelJsonKeyPairs(JsonNode rootNode) {
956         Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
957
958         while (fieldsIterator.hasNext()) {
959             Map.Entry<String, JsonNode> field = fieldsIterator.next();
960             final String key = field.getKey();
961             final JsonNode value = field.getValue();
962
963             if (value.isContainerNode() && !value.isArray()) {
964                 jsonRequestMap.put(key.trim(), value.toString().trim());
965                 pullModelJsonKeyPairs(value); // RECURSIVE CALL
966             } else if (value.isArray()) {
967                 try {
968                     String valueStr = value.toString();
969                     String stringValue = valueStr.substring(valueStr.indexOf('[') + 1, valueStr.lastIndexOf(']'));
970
971                     if (stringValue.isEmpty()) {
972                         stringValue = "{\"test\":\"test\"}";
973                     }
974
975                     ObjectMapper mapper = new ObjectMapper();
976                     JsonNode newValue = mapper.readTree(stringValue);
977                     jsonRequestMap.put(key.trim(), value.toString().trim());
978                     pullModelJsonKeyPairs(newValue);
979                 } catch (IOException e) {
980                     LOGGER.info("PolicyValidation: Exception occurred while mapping string to JsonNode " + e);
981                 }
982             } else {
983                 jsonRequestMap.put(key.trim(), value.toString().trim());
984             }
985         }
986
987     }
988
989     private JsonObject stringToJsonObject(String value) {
990         try (JsonReader jsonReader = Json.createReader(new StringReader(value))) {
991             return jsonReader.readObject();
992         } catch (JsonException | IllegalStateException e) {
993             LOGGER.info(XACMLErrorConstants.ERROR_DATA_ISSUE
994                             + "Improper JSON format... may or may not cause issues in validating the policy: " + value,
995                             e);
996             return null;
997         }
998     }
999
1000     private void findRequiredFields(JsonObject json) {
1001         if (json == null) {
1002             return;
1003         }
1004         for (Entry<String, JsonValue> keyMap : json.entrySet()) {
1005             Object obj = keyMap.getValue();
1006             String key = keyMap.getKey();
1007             if (obj instanceof JsonObject) {
1008                 if (allReqTrueKeys.contains(key)) {
1009                     JsonObject jsonObj = (JsonObject) obj;
1010                     // only check fields in obj if obj itself is required.
1011                     for (Entry<String, JsonValue> jsonMap : jsonObj.entrySet()) {
1012                         if (jsonMap.getValue().toString().contains(REQUIRED_ATTRIBUTE)) {
1013                             modelRequiredFieldsList.add(jsonMap.getKey().trim());
1014                         }
1015                     }
1016                 }
1017             } else if (keyMap.getValue().toString().contains(REQUIRED_ATTRIBUTE)) {
1018                 modelRequiredFieldsList.add(key.trim());
1019
1020             }
1021         }
1022
1023     }
1024
1025     // call this method to start the recursive
1026     private Set<String> getAllKeys(JSONObject json) {
1027         return getAllKeys(json, new HashSet<>());
1028     }
1029
1030     private Set<String> getAllKeys(JSONArray arr) {
1031         return getAllKeys(arr, new HashSet<>());
1032     }
1033
1034     private Set<String> getAllKeys(JSONArray arr, Set<String> keys) {
1035         for (int i = 0; i < arr.length(); i++) {
1036             Object obj = arr.get(i);
1037             if (obj instanceof JSONObject) {
1038                 keys.addAll(getAllKeys(arr.getJSONObject(i)));
1039             }
1040             if (obj instanceof JSONArray) {
1041                 keys.addAll(getAllKeys(arr.getJSONArray(i)));
1042             }
1043         }
1044
1045         return keys;
1046     }
1047
1048     // this method returns a set of keys with "required-true" defined in their value.
1049     private Set<String> getAllKeys(JSONObject json, Set<String> keys) {
1050         for (String key : json.keySet()) {
1051             Object obj = json.get(key);
1052             if (obj instanceof String && ((String) obj).contains(REQUIRED_ATTRIBUTE)) {
1053                 LOGGER.debug("key : " + key);
1054                 LOGGER.debug("obj : " + obj);
1055                 allReqTrueKeys.add(key); // For MicroService policies
1056                 allOptReqTrueKeys.add(key); // For Optimization policies
1057
1058                 // get the type from value and add that one also
1059                 String type = StringUtils.substringBefore((String) obj, ":");
1060                 if (!StringUtils.isBlank(type) && !StringUtils.containsAny(type.toLowerCase(), STRING, INTEGER, LIST,
1061                                 MAP, JAVA, BOOLEAN)) {
1062                     allReqTrueKeys.add(type);
1063                 }
1064             }
1065             if (obj instanceof JSONObject) {
1066                 keys.addAll(getAllKeys(json.getJSONObject(key)));
1067             }
1068             if (obj instanceof JSONArray) {
1069                 keys.addAll(getAllKeys(json.getJSONArray(key)));
1070             }
1071         }
1072
1073         return keys;
1074     }
1075
1076     private boolean validateMsModel(PolicyRestAdapter policyData, StringBuilder responseString)
1077                     throws JsonProcessingException {
1078         boolean valid = true;
1079         if (!Strings.isNullOrEmpty(policyData.getServiceType())) {
1080
1081             modelRequiredFieldsList.clear();
1082             pullJsonKeyPairs((JsonNode) policyData.getPolicyJSON());
1083
1084             String service;
1085             String version;
1086             if (policyData.getServiceType().contains("-v")) {
1087                 service = policyData.getServiceType().split("-v")[0];
1088                 version = policyData.getServiceType().split("-v")[1];
1089             } else {
1090                 service = policyData.getServiceType();
1091                 version = policyData.getVersion();
1092             }
1093
1094             if (!Strings.isNullOrEmpty(version)) {
1095                 MicroServiceModels returnModel = getAttributeObject(service, version);
1096
1097                 if (returnModel != null) {
1098
1099                     String annotation = returnModel.getAnnotation();
1100                     String refAttributes = returnModel.getRefAttributes();
1101                     String subAttributes = returnModel.getSubAttributes();
1102                     String modelAttributes = returnModel.getAttributes();
1103
1104                     if (!Strings.isNullOrEmpty(annotation)) {
1105                         Map<String, String> rangeMap = Splitter.on(",").withKeyValueSeparator("=").split(annotation);
1106                         for (Entry<String, String> raMap : rangeMap.entrySet()) {
1107                             if (raMap.getValue().contains("range::")) {
1108                                 String value = mapAttribute.get(raMap.getKey().trim());
1109                                 String[] tempString = raMap.getValue().split("::")[1].split("-");
1110                                 int startNum = Integer.parseInt(tempString[0]);
1111                                 int endNum = Integer.parseInt(tempString[1]);
1112                                 String returnString = "InvalidreturnModel Range:" + raMap.getKey() + " must be between "
1113                                                 + startNum + " - " + endNum + ",";
1114
1115                                 if (value != null) {
1116                                     if (PolicyUtils.isInteger(value.replace("\"", ""))) {
1117                                         int result = Integer.parseInt(value.replace("\"", ""));
1118                                         if (result < startNum || result > endNum) {
1119                                             responseString.append(returnString);
1120                                             valid = false;
1121                                         }
1122                                     } else {
1123                                         responseString.append(returnString);
1124                                         valid = false;
1125                                     }
1126                                 } else {
1127                                     responseString.append("<b>" + raMap.getKey() + "</b>:<i>" + raMap.getKey()
1128                                                     + " is required for the MicroService model " + service
1129                                                     + HTML_ITALICS_LNBREAK);
1130                                     valid = false;
1131                                 }
1132
1133                             }
1134                         }
1135                     } else if (!DECISION_MS_MODEL.equals(policyData.getRuleProvider())) {
1136                         // Validate for configName, location, uuid, and policyScope if no annotations exist for this
1137                         // model
1138                         if (Strings.isNullOrEmpty(policyData.getLocation())) {
1139                             responseString.append("<b>Micro Service Model</b>:<i> location is required for this model"
1140                                             + HTML_ITALICS_LNBREAK);
1141                             valid = false;
1142                         }
1143
1144                         if (Strings.isNullOrEmpty(policyData.getConfigName())) {
1145                             responseString.append("<b>Micro Service Model</b>:<i> configName is required for this model"
1146                                             + HTML_ITALICS_LNBREAK);
1147                             valid = false;
1148                         }
1149
1150                         if (Strings.isNullOrEmpty(policyData.getUuid())) {
1151                             responseString.append("<b>Micro Service Model</b>:<i> uuid is required for this model"
1152                                             + HTML_ITALICS_LNBREAK);
1153                             valid = false;
1154                         }
1155
1156                         if (Strings.isNullOrEmpty(policyData.getPolicyScope())) {
1157                             responseString.append(
1158                                             "<b>Micro Service Model</b>:<i> policyScope is required for this model"
1159                                                             + HTML_ITALICS_LNBREAK);
1160                             valid = false;
1161                         }
1162                     }
1163
1164                     // If request comes from the API we need to validate required fields in the Micro Service Model
1165                     // GUI request are already validated from the SDK-APP
1166                     if ("API".equals(policyData.getApiflag())) {
1167                         // first , get the complete set of required fields
1168                         populateReqFieldSet(new String[]
1169                             { refAttributes, modelAttributes }, subAttributes);
1170
1171                         // ignore req fields in which parent is not reqd
1172                         populateRequiredFields(new String[]
1173                             { refAttributes, modelAttributes }, subAttributes, modelAttributes);
1174
1175                         if (modelRequiredFieldsList != null && !modelRequiredFieldsList.isEmpty()) {
1176                             // create jsonRequestMap with all json keys and values from request
1177                             JsonNode rootNode = (JsonNode) policyData.getPolicyJSON();
1178                             jsonRequestMap.clear();
1179                             pullModelJsonKeyPairs(rootNode);
1180
1181                             // validate if the requiredFields are in the request
1182                             for (String requiredField : modelRequiredFieldsList) {
1183                                 if (jsonRequestMap.containsKey(requiredField)) {
1184                                     String value = jsonRequestMap.get(requiredField);
1185                                     if (StringUtils.isBlank(value) || "\"\"".equals(value)) {
1186                                         responseString.append("<b>Micro Service Model</b>:<i> " + requiredField
1187                                                         + ISREQUIRED + HTML_ITALICS_LNBREAK);
1188                                         valid = false;
1189                                     }
1190                                 } else {
1191                                     responseString.append("<b>Micro Service Model</b>:<i> " + requiredField + ISREQUIRED
1192                                                     + HTML_ITALICS_LNBREAK);
1193                                     valid = false;
1194                                 }
1195                             }
1196                         }
1197                     }
1198                 } else {
1199                     responseString.append("<b>Micro Service Model</b>:<i> Invalid Model. The model name, " + service
1200                                     + " of version, " + version + " was not found in the dictionary"
1201                                     + HTML_ITALICS_LNBREAK);
1202                     valid = false;
1203                 }
1204             } else {
1205                 responseString.append("<b>Micro Service Version</b>:<i> Micro Service Version is required"
1206                                 + HTML_ITALICS_LNBREAK);
1207                 valid = false;
1208             }
1209         } else {
1210             responseString.append("<b>Micro Service</b>:<i> Micro Service Model is required" + HTML_ITALICS_LNBREAK);
1211             valid = false;
1212         }
1213
1214         if (Strings.isNullOrEmpty(policyData.getPriority())
1215                         && !DECISION_MS_MODEL.equals(policyData.getRuleProvider())) {
1216             responseString.append("<b>Priority</b>:<i> Priority is required" + HTML_ITALICS_LNBREAK);
1217         }
1218
1219         return valid;
1220     }
1221
1222     private boolean validateOptimization(PolicyRestAdapter policyData, StringBuilder responseString) {
1223         boolean valid = true;
1224
1225         // Checks for required policy data in request
1226         if (Strings.isNullOrEmpty(policyData.getServiceType())) {
1227             responseString.append("<b>Optimization Service</b>:<i> Optimization policy data is missing or invalid Json."
1228                             + HTML_ITALICS_LNBREAK);
1229             return false;
1230         }
1231
1232         modelRequiredFieldsList.clear();
1233         pullJsonKeyPairs((JsonNode) policyData.getPolicyJSON());
1234
1235         // parse the service and version from the policy data
1236         String service;
1237         String version;
1238         if (policyData.getServiceType().contains("-v")) {
1239             service = policyData.getServiceType().split("-v")[0];
1240             version = policyData.getServiceType().split("-v")[1];
1241         } else {
1242             service = policyData.getServiceType();
1243             version = policyData.getVersion();
1244         }
1245
1246         // Checks for required version in policy data
1247         if (Strings.isNullOrEmpty(version)) {
1248             responseString.append("<b>Optimization Service Version</b>:<i> Optimization Service Version is required"
1249                             + HTML_ITALICS_LNBREAK);
1250             return false;
1251         }
1252
1253         OptimizationModels returnModel = getOptimizationModelData(service, version);
1254
1255         // Checks if valid model exists in the database
1256         if (returnModel == null) {
1257             responseString.append("<b>Optimization Service Model</b>:<i> Invalid Model. The model name, " + service
1258                             + " of version, " + version + " was not found in the dictionary" + HTML_ITALICS_LNBREAK);
1259             return false;
1260         }
1261
1262         String annotation = returnModel.getAnnotation();
1263         String refAttributes = returnModel.getRefattributes();
1264         String subAttributes = returnModel.getSubattributes();
1265         String modelAttributes = returnModel.getAttributes();
1266
1267         if (!Strings.isNullOrEmpty(annotation)) {
1268             Map<String, String> rangeMap = Splitter.on(",").withKeyValueSeparator("=").split(annotation);
1269             for (Entry<String, String> rangeMapEntry : rangeMap.entrySet()) {
1270                 if (rangeMapEntry.getValue().contains("range::")) {
1271                     String value = mapAttribute.get(rangeMapEntry.getKey().trim());
1272                     String[] tempString = rangeMapEntry.getValue().split("::")[1].split("-");
1273                     int startNum = Integer.parseInt(tempString[0]);
1274                     int endNum = Integer.parseInt(tempString[1]);
1275                     String returnString = "InvalidreturnModel Range:" + rangeMapEntry.getKey() + " must be between "
1276                                     + startNum + " - " + endNum + ",";
1277
1278                     if (value != null) {
1279                         if (PolicyUtils.isInteger(value.replace("\"", ""))) {
1280                             int result = Integer.parseInt(value.replace("\"", ""));
1281                             if (result < startNum || result > endNum) {
1282                                 responseString.append(returnString);
1283                                 valid = false;
1284                             }
1285                         } else {
1286                             responseString.append(returnString);
1287                             valid = false;
1288                         }
1289                     } else {
1290                         responseString.append("<b>" + rangeMapEntry.getKey() + "</b>:<i>" + rangeMapEntry.getKey()
1291                                         + " is required for the Optimization model " + service + HTML_ITALICS_LNBREAK);
1292                         valid = false;
1293                     }
1294
1295                 }
1296             }
1297         }
1298
1299         // If request comes from the API we need to validate required fields in the Micro Service Modelvalid
1300         // GUI request are already validated from the SDK-APP
1301         if ("API".equals(policyData.getApiflag())) {
1302             // first , get the complete set of required fields
1303             populateReqFieldSet(new String[]
1304                 { refAttributes, modelAttributes }, subAttributes);
1305
1306             modelRequiredFieldsList.addAll(allOptReqTrueKeys);
1307
1308             if (modelRequiredFieldsList != null && !modelRequiredFieldsList.isEmpty()) {
1309
1310                 // create jsonRequestMap with all json keys and values from request
1311                 JsonNode rootNode = (JsonNode) policyData.getPolicyJSON();
1312                 jsonRequestMap.clear();
1313                 pullModelJsonKeyPairs(rootNode);
1314
1315                 // validate if the requiredFields are in the request
1316                 for (String requiredField : modelRequiredFieldsList) {
1317                     if (jsonRequestMap.containsKey(requiredField)) {
1318                         String value = jsonRequestMap.get(requiredField);
1319                         if (StringUtils.isBlank(value) || "\"\"".equals(value)) {
1320                             responseString.append("<b>Optimization Service Model</b>:<i> " + requiredField + ISREQUIRED
1321                                             + HTML_ITALICS_LNBREAK);
1322                             valid = false;
1323                         }
1324                     } else {
1325                         responseString.append("<b>Optimization Service Model</b>:<i> " + requiredField + ISREQUIRED
1326                                         + HTML_ITALICS_LNBREAK);
1327                         valid = false;
1328                     }
1329                 }
1330             }
1331         }
1332
1333         if (Strings.isNullOrEmpty(policyData.getPriority())) {
1334             responseString.append("<b>Priority</b>:<i> Priority is required" + HTML_ITALICS_LNBREAK);
1335             valid = false;
1336         }
1337
1338         return valid;
1339     }
1340
1341     private void populateRequiredFields(String[] attrArr, String subAttributes, String modelAttributes)
1342                     throws JsonProcessingException {
1343         // get list of required fields from the ref_Attributes of the Model
1344         for (String attributes : attrArr) {
1345             if (!StringUtils.isBlank(attributes)) {
1346                 Map<String, String> attributesMap = null;
1347                 if (",".equals(attributes.substring(attributes.length() - 1))) {
1348                     String attributesString = attributes.substring(0, attributes.length() - 1);
1349                     attributesMap = Splitter.on(",").withKeyValueSeparator("=").split(attributesString);
1350                 } else if (!StringUtils.isBlank(modelAttributes)) {
1351                     attributesMap = Splitter.on(",").withKeyValueSeparator("=").split(modelAttributes);
1352                 } else {
1353                     continue;
1354                 }
1355                 String json = new ObjectMapper().writeValueAsString(attributesMap);
1356                 findRequiredFields(stringToJsonObject(json));
1357             }
1358
1359         }
1360
1361         // get list of required fields from the sub_Attributes of the Model
1362         if (!StringUtils.isBlank(subAttributes)) {
1363             JsonObject subAttributesJson = stringToJsonObject(subAttributes);
1364             findRequiredFields(subAttributesJson);
1365         }
1366
1367     }
1368
1369     private void populateReqFieldSet(String[] attrArr, String subAttributes) {
1370         allReqTrueKeys.clear();
1371         JSONObject jsonSub = new JSONObject(subAttributes);
1372         // Get all keys with "required-true" defined in their value from subAttribute
1373         getAllKeys(jsonSub);
1374
1375         // parse refAttrbutes
1376         for (String attr : attrArr) {
1377             if (attr != null) {
1378                 String[] referAarray = attr.split(",");
1379                 String[] element = null;
1380                 for (int i = 0; i < referAarray.length; i++) {
1381                     element = referAarray[i].split("=");
1382                     if (element.length > 1 && element[1].contains(REQUIRED_ATTRIBUTE)) {
1383                         allReqTrueKeys.add(element[0]);
1384                     }
1385                 }
1386             }
1387         }
1388     }
1389
1390 }