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