adb8995c525c6bc1ead32b3c72ef629f34599a4c
[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) || "".equals(configBodyData)) {
382                                     responseString.append(
383                                                     "Config Body: Property data is not valid" + HTML_ITALICS_LNBREAK);
384                                     valid = false;
385                                 }
386                             } else if ("OTHER".equals(configType) && ("".equals(configBodyData))) {
387                                 responseString.append(
388                                                 "Config Body: Config Body Should not be Empty" + HTML_ITALICS_LNBREAK);
389                                 valid = false;
390                             }
391                         }
392                     } else {
393                         responseString.append("Config Body: Config Body Should not be Empty" + HTML_ITALICS_LNBREAK);
394                         valid = false;
395                     }
396                 }
397                 // Validate Config Firewall Policy Data
398                 if (FIREWALL.equalsIgnoreCase(policyData.getConfigPolicyType())) {
399                     if (policyData.getConfigName() != null && !policyData.getConfigName().isEmpty()) {
400                         String configNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getConfigName());
401                         if (!configNameValidate.contains(SUCCESS)) {
402                             responseString.append("<b>ConfigName</b>:<i>" + configNameValidate + HTML_ITALICS_LNBREAK);
403                             valid = false;
404                         }
405                     } else {
406                         responseString.append("<b>Config Name</b>:<i> Config Name is required" + HTML_ITALICS_LNBREAK);
407                         valid = false;
408                     }
409                     if (policyData.getSecurityZone() == null || policyData.getSecurityZone().isEmpty()) {
410                         responseString.append(
411                                         "<b>Security Zone</b>:<i> Security Zone is required" + HTML_ITALICS_LNBREAK);
412                         valid = false;
413                     }
414                 }
415                 // Validate BRMS_Param Policy Data
416                 if (BRMSPARAM.equalsIgnoreCase(policyData.getConfigPolicyType())
417                                 && Strings.isNullOrEmpty(policyData.getRuleName())) {
418                     responseString.append("<b>BRMS Template</b>:<i>BRMS Template is required" + HTML_ITALICS_LNBREAK);
419                     valid = false;
420                 }
421                 // Validate BRMS_Raw Policy Data
422                 if (BRMSRAW.equalsIgnoreCase(policyData.getConfigPolicyType())) {
423                     if (policyData.getConfigBodyData() != null && !policyData.getConfigBodyData().isEmpty()) {
424                         String message = PolicyUtils.brmsRawValidate(policyData.getConfigBodyData());
425
426                         // If there are any error other than Annotations then this is not Valid
427                         if (message.contains("[ERR")) {
428                             responseString.append("<b>Raw Rule Validate</b>:<i>Raw Rule has error" + message
429                                             + HTML_ITALICS_LNBREAK);
430                             valid = false;
431                         }
432                     } else {
433                         responseString.append("<b>Raw Rule</b>:<i>Raw Rule is required" + HTML_ITALICS_LNBREAK);
434                         valid = false;
435                     }
436                 }
437                 // Validate ClosedLoop_PM Policy Data
438                 if (CLOSEDLOOP_PM.equalsIgnoreCase(policyData.getConfigPolicyType())) {
439                     try {
440                         if (Strings.isNullOrEmpty(policyData.getServiceTypePolicyName().get("serviceTypePolicyName")
441                                         .toString())) {
442                             responseString.append("<b>ServiceType PolicyName</b>:<i>ServiceType PolicyName is required"
443                                             + HTML_ITALICS_LNBREAK);
444                             valid = false;
445                         }
446
447                     } catch (Exception e) {
448                         LOGGER.error("ERROR in ClosedLoop_PM PolicyName", e);
449                         responseString.append("<b>ServiceType PolicyName</b>:<i>ServiceType PolicyName is required"
450                                         + HTML_ITALICS_LNBREAK);
451                         valid = false;
452                     }
453
454                     if (policyData.getJsonBody() != null) {
455
456                         ClosedLoopPMBody pmBody = mapper.readValue(policyData.getJsonBody(), ClosedLoopPMBody.class);
457                         if (pmBody.getEmailAddress() != null) {
458                             String result = emailValidation(pmBody.getEmailAddress(), responseString.toString());
459                             if (result != SUCCESS) {
460                                 responseString.append(result + HTML_ITALICS_LNBREAK);
461                                 valid = false;
462                             }
463                         }
464                         if (!pmBody.isGamma() && !pmBody.isMcr() && !pmBody.isTrinity() && !pmBody.isvDNS()
465                                         && !pmBody.isvUSP()) {
466                             responseString.append(SELECT_AT_LEAST_ONE_D2_VIRTUALIZED_SERVICES + HTML_ITALICS_LNBREAK);
467                             valid = false;
468                         }
469                         if (pmBody.getGeoLink() != null && !pmBody.getGeoLink().isEmpty()) {
470                             String result = PolicyUtils.policySpecialCharValidator(pmBody.getGeoLink());
471                             if (!result.contains(SUCCESS)) {
472                                 responseString.append("<b>GeoLink</b>:<i>" + result + HTML_ITALICS_LNBREAK);
473                                 valid = false;
474                             }
475                         }
476                         if (pmBody.getAttributes() != null && !pmBody.getAttributes().isEmpty()) {
477                             for (Entry<String, String> entry : pmBody.getAttributes().entrySet()) {
478                                 String key = entry.getKey();
479                                 String value = entry.getValue();
480                                 if (!key.contains("Message")) {
481                                     String attributeValidate = PolicyUtils.policySpecialCharValidator(value);
482                                     if (!attributeValidate.contains(SUCCESS)) {
483                                         responseString.append("<b>Attributes</b>:<i>" + key
484                                                         + " : value has spaces or invalid characters"
485                                                         + HTML_ITALICS_LNBREAK);
486                                         valid = false;
487                                     }
488                                 }
489                             }
490                         }
491                     } else {
492                         responseString.append(
493                                         "<b>D2/Virtualized Services</b>:<i>Select atleast one D2/Virtualized Services"
494                                                         + HTML_ITALICS_LNBREAK);
495                         valid = false;
496                     }
497                 }
498                 if (CLOSEDLOOP_POLICY.equalsIgnoreCase(policyData.getConfigPolicyType())) {
499                     if (policyData.getJsonBody() != null) {
500
501                         // For API we need to get the conditions key from the Json request and check it before
502                         // deserializing to POJO due to the enum
503                         if ("API".equals(policyData.getApiflag())) {
504                             JSONObject json = new JSONObject(policyData.getJsonBody());
505                             if (!json.isNull("conditions")) {
506                                 String apiCondition = (String) json.get("conditions");
507                                 if (Strings.isNullOrEmpty(apiCondition)) {
508                                     responseString.append("<b>Conditions</b>: <i>Select At least one Condition"
509                                                     + HTML_ITALICS_LNBREAK);
510                                     return responseString;
511                                 }
512                             } else {
513                                 responseString.append("<b>Conditions</b>:"
514                                                 + " <i>There were no conditions provided in configBody json"
515                                                 + HTML_ITALICS_LNBREAK);
516                                 return responseString;
517                             }
518                         } else {
519                             if (policyData.getTrapDatas().getTrap1() != null) {
520                                 if (policyData.getClearTimeOut() == null) {
521                                     responseString.append("<b>Trigger Clear TimeOut</b>: "
522                                                     + "<i>Trigger Clear TimeOut is required when at "
523                                                     + "least One Trigger Signature is enabled</i><br>");
524                                     valid = false;
525                                 }
526                                 if (policyData.getTrapMaxAge() == null) {
527                                     responseString.append("<b>Trap Max Age</b>: <i>Trap Max Age is required when at "
528                                                     + "least One Trigger Signature is enabled</i><br>");
529                                     valid = false;
530                                 }
531                             }
532                             if (policyData.getFaultDatas().getTrap1() != null
533                                             && policyData.getVerificationclearTimeOut() == null) {
534                                 responseString.append(
535                                                 "<b>Fault Clear TimeOut</b>: <i>Fault Clear TimeOut is required when at"
536                                                                 + "least One Fault Signature is enabled</i><br>");
537                                 valid = false;
538                             }
539                         }
540
541                         ClosedLoopFaultBody faultBody = mapper.readValue(policyData.getJsonBody(),
542                                         ClosedLoopFaultBody.class);
543                         if (faultBody.getEmailAddress() != null && !faultBody.getEmailAddress().isEmpty()) {
544                             String result = emailValidation(faultBody.getEmailAddress(), responseString.toString());
545                             if (!SUCCESS.equals(result)) {
546                                 responseString.append(result + HTML_ITALICS_LNBREAK);
547                                 valid = false;
548                             }
549                         }
550                         if (!(faultBody.isGamma() || faultBody.isMcr() || faultBody.isTrinity() || faultBody.isvDNS()
551                                         || faultBody.isvUSP())) {
552                             responseString.append(SELECT_AT_LEAST_ONE_D2_VIRTUALIZED_SERVICES + HTML_ITALICS_LNBREAK);
553                             valid = false;
554                         }
555                         if (faultBody.getActions() == null || faultBody.getActions().isEmpty()) {
556                             responseString.append(
557                                             "<b>vPRO Actions</b>: <i>vPRO Actions is required" + HTML_ITALICS_LNBREAK);
558                             valid = false;
559                         }
560                         if (faultBody.getClosedLoopPolicyStatus() == null
561                                         || faultBody.getClosedLoopPolicyStatus().isEmpty()) {
562                             responseString.append("<b>Policy Status</b>: <i>Policy Status is required"
563                                             + HTML_ITALICS_LNBREAK);
564                             valid = false;
565                         }
566                         if (faultBody.getConditions() == null) {
567                             responseString.append("<b>Conditions</b>: <i>Select At least one Condition"
568                                             + HTML_ITALICS_LNBREAK);
569                             valid = false;
570                         }
571                         if (faultBody.getGeoLink() != null && !faultBody.getGeoLink().isEmpty()) {
572                             String result = PolicyUtils.policySpecialCharWithSpaceValidator(faultBody.getGeoLink());
573                             if (!result.contains(SUCCESS)) {
574                                 responseString.append("<b>GeoLink</b>:<i>" + result + HTML_ITALICS_LNBREAK);
575                                 valid = false;
576                             }
577                         }
578                         if (faultBody.getAgingWindow() == 0) {
579                             responseString.append(
580                                             "<b>Aging Window</b>: <i>Aging Window is required" + HTML_ITALICS_LNBREAK);
581                             valid = false;
582                         }
583                         if (faultBody.getTimeInterval() == 0) {
584                             responseString.append("<b>Time Interval</b>: <i>Time Interval is required"
585                                             + HTML_ITALICS_LNBREAK);
586                             valid = false;
587                         }
588                         if (faultBody.getRetrys() == 0) {
589                             responseString.append("<b>Number of Retries</b>: <i>Number of Retries is required"
590                                             + HTML_ITALICS_LNBREAK);
591                             valid = false;
592                         }
593                         if (faultBody.getTimeOutvPRO() == 0) {
594                             responseString.append("<b>APP-C Timeout</b>: <i>APP-C Timeout is required"
595                                             + HTML_ITALICS_LNBREAK);
596                             valid = false;
597                         }
598                         if (faultBody.getTimeOutRuby() == 0) {
599                             responseString.append(
600                                             "<b>TimeOutRuby</b>: <i>TimeOutRuby is required" + HTML_ITALICS_LNBREAK);
601                             valid = false;
602                         }
603                         if (faultBody.getVnfType() == null || faultBody.getVnfType().isEmpty()) {
604                             responseString.append("<b>Vnf Type</b>: <i>Vnf Type is required" + HTML_ITALICS_LNBREAK);
605                             valid = false;
606                         }
607                     } else {
608                         responseString.append(
609                                         "<b>D2/Virtualized Services</b>: <i>Select atleast one D2/Virtualized Services"
610                                                         + HTML_ITALICS_LNBREAK);
611                         responseString.append(
612                                         "<b>vPRO Actions</b>: <i>vPRO Actions is required" + HTML_ITALICS_LNBREAK);
613                         responseString.append(
614                                         "<b>Aging Window</b>: <i>Aging Window is required" + HTML_ITALICS_LNBREAK);
615                         responseString.append(
616                                         "<b>Policy Status</b>: <i>Policy Status is required" + HTML_ITALICS_LNBREAK);
617                         responseString.append(
618                                         "<b>Conditions</b>: <i>Select Atleast one Condition" + HTML_ITALICS_LNBREAK);
619                         responseString.append("<b>PEP Name</b>: <i>PEP Name is required" + HTML_ITALICS_LNBREAK);
620                         responseString.append("<b>PEP Action</b>: <i>PEP Action is required" + HTML_ITALICS_LNBREAK);
621                         responseString.append(
622                                         "<b>Time Interval</b>: <i>Time Interval is required" + HTML_ITALICS_LNBREAK);
623                         responseString.append("<b>Number of Retries</b>: <i>Number of Retries is required"
624                                         + HTML_ITALICS_LNBREAK);
625                         responseString.append(
626                                         "<b>APP-C Timeout</b>: <i>APP-C Timeout is required" + HTML_ITALICS_LNBREAK);
627                         responseString.append("<b>TimeOutRuby</b>: <i>TimeOutRuby is required" + HTML_ITALICS_LNBREAK);
628                         responseString.append("<b>Vnf Type</b>: <i>Vnf Type is required" + HTML_ITALICS_LNBREAK);
629                         valid = false;
630                     }
631                 }
632
633                 // Validate MicroService Policy Data
634                 if (MICROSERVICES.equals(policyData.getConfigPolicyType())) {
635                     boolean tmpValid = validateMsModel(policyData, responseString);
636                     if (!tmpValid) {
637                         valid = false;
638                     }
639                 }
640
641                 // Validate Optimization Policy Data
642                 if (OPTIMIZATION.equals(policyData.getConfigPolicyType())) {
643                     boolean tmpValid = validateOptimization(policyData, responseString);
644                     if (!tmpValid) {
645                         valid = false;
646                     }
647                 }
648             }
649
650             if ((DECISION_POLICY.equalsIgnoreCase(policyData.getPolicyType()))
651                             || (DECISION_POLICY_MS.equalsIgnoreCase(policyData.getPolicyType()))) {
652                 if (!RAW.equalsIgnoreCase(policyData.getRuleProvider())) {
653                     if (!Strings.isNullOrEmpty(policyData.getOnapName())) {
654                         String onapNameValidate = PolicyUtils.policySpecialCharValidator(policyData.getOnapName());
655                         if (!onapNameValidate.contains(SUCCESS)) {
656                             responseString.append("OnapName:" + onapNameValidate + HTML_ITALICS_LNBREAK);
657                             valid = false;
658                         }
659                     } else {
660                         responseString.append("Onap Name: Onap Name Should not be empty" + HTML_ITALICS_LNBREAK);
661                         valid = false;
662                     }
663                 }
664                 if (RAW.equalsIgnoreCase(policyData.getRuleProvider())) {
665                     Object policy = XACMLPolicyScanner.readPolicy(new ByteArrayInputStream(StringEscapeUtils
666                                     .unescapeXml(policyData.getRawXacmlPolicy()).getBytes(StandardCharsets.UTF_8)));
667                     if (!(policy instanceof PolicySetType || policy instanceof PolicyType)) {
668                         responseString.append("Raw XACML: The XACML Content is not valid" + HTML_ITALICS_LNBREAK);
669                         valid = false;
670                     }
671                 }
672
673                 if (DECISION_MS_MODEL.equals(policyData.getRuleProvider())) {
674                     LOGGER.info("Validating Decision MS Policy - ");
675                     boolean tmpValid = validateMsModel(policyData, responseString);
676                     if (!tmpValid) {
677                         valid = false;
678                     }
679                 }
680
681                 if ("Rainy_Day".equals(policyData.getRuleProvider())) {
682                     if (policyData.getRainyday() == null) {
683                         responseString.append("<b> Rainy Day Parameters are Required </b><br>");
684                         valid = false;
685                     } else {
686                         if (Strings.isNullOrEmpty(policyData.getRainyday().getServiceType())) {
687                             responseString.append("Rainy Day <b>Service Type</b> is Required<br>");
688                             valid = false;
689                         }
690                         if (Strings.isNullOrEmpty(policyData.getRainyday().getVnfType())) {
691                             responseString.append("Rainy Day <b>VNF Type</b> is Required<br>");
692                             valid = false;
693                         }
694                         if (Strings.isNullOrEmpty(policyData.getRainyday().getBbid())) {
695                             responseString.append("Rainy Day <b>Building Block ID</b> is Required<br>");
696                             valid = false;
697                         }
698                         if (Strings.isNullOrEmpty(policyData.getRainyday().getWorkstep())) {
699                             responseString.append("Rainy Day <b>Work Step</b> is Required<br>");
700                             valid = false;
701                         }
702                         if (!policyData.getRainyday().getTreatmentTableChoices().isEmpty()
703                                         && policyData.getRainyday().getTreatmentTableChoices() != null) {
704
705                             for (Object treatmentMap : policyData.getRainyday().getTreatmentTableChoices()) {
706                                 String errorCode = null;
707                                 String treatment = null;
708                                 if (treatmentMap instanceof LinkedHashMap<?, ?>) {
709
710                                     if (((LinkedHashMap<?, ?>) treatmentMap).containsKey("errorcode")) {
711                                         errorCode = ((LinkedHashMap<?, ?>) treatmentMap).get("errorcode").toString();
712                                     }
713                                     if (((LinkedHashMap<?, ?>) treatmentMap).containsKey("treatment")) {
714                                         treatment = ((LinkedHashMap<?, ?>) treatmentMap).get("treatment").toString();
715                                     }
716
717                                 }
718                                 if (Strings.isNullOrEmpty(errorCode) && Strings.isNullOrEmpty(treatment)) {
719                                     responseString.append("Rainy Day <b>Error Code</b> and "
720                                                     + "<b>Desired Treatment</b> cannot be empty<br>");
721                                     valid = false;
722                                     break;
723                                 }
724                                 if (Strings.isNullOrEmpty(errorCode)) {
725                                     responseString.append("Rainy Day <b>Error Code</b> is Required "
726                                                     + "for each Desired Treatment<br>");
727                                     valid = false;
728                                     break;
729                                 }
730                                 if (Strings.isNullOrEmpty(treatment)) {
731                                     responseString.append("Rainy Day <b>Desired Treatment"
732                                                     + "</b> is Required for each Error Code<br>");
733                                     valid = false;
734                                     break;
735                                 }
736                             }
737
738                         } else {
739                             responseString.append("Rainy Day <b>Desired Automated Treatments</b> are Required<br>");
740                             valid = false;
741                         }
742                     }
743                 }
744
745                 if ("GUARD_YAML".equals(policyData.getRuleProvider())
746                                 || "GUARD_BL_YAML".equals(policyData.getRuleProvider())
747                                 || "GUARD_MIN_MAX".equals(policyData.getRuleProvider())) {
748                     if (policyData.getYamlparams() == null) {
749                         responseString.append("<b> Guard Params are Required </b>" + HTML_ITALICS_LNBREAK);
750                         valid = false;
751                     } else {
752                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getActor())) {
753                             responseString.append("Guard Params <b>Actor</b> is Required " + HTML_ITALICS_LNBREAK);
754                             valid = false;
755                         }
756                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getRecipe())) {
757                             responseString.append("Guard Params <b>Recipe</b> is Required " + HTML_ITALICS_LNBREAK);
758                             valid = false;
759                         }
760                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getGuardActiveStart())) {
761                             responseString.append("Guard Params <b>Guard Active Start</b> is Required "
762                                             + HTML_ITALICS_LNBREAK);
763                             valid = false;
764                         }
765                         if (Strings.isNullOrEmpty(policyData.getYamlparams().getGuardActiveEnd())) {
766                             responseString.append(
767                                             "Guard Params <b>Guard Active End</b> is Required " + HTML_ITALICS_LNBREAK);
768                             valid = false;
769                         }
770                         if ("GUARD_YAML".equals(policyData.getRuleProvider())) {
771                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getLimit())) {
772                                 responseString.append(" Guard Params <b>Limit</b> is Required " + HTML_ITALICS_LNBREAK);
773                                 valid = false;
774                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getLimit())) {
775                                 responseString.append(
776                                                 " Guard Params <b>Limit</b> Should be Integer " + HTML_ITALICS_LNBREAK);
777                                 valid = false;
778                             }
779                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getTimeWindow())) {
780                                 responseString.append(
781                                                 "Guard Params <b>Time Window</b> is Required" + HTML_ITALICS_LNBREAK);
782                                 valid = false;
783                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getTimeWindow())) {
784                                 responseString.append(" Guard Params <b>Time Window</b> Should be Integer "
785                                                 + HTML_ITALICS_LNBREAK);
786                                 valid = false;
787                             }
788                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getTimeUnits())) {
789                                 responseString.append(
790                                                 "Guard Params <b>Time Units</b> is Required" + HTML_ITALICS_LNBREAK);
791                                 valid = false;
792                             }
793                         } else if ("GUARD_MIN_MAX".equals(policyData.getRuleProvider())) {
794                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getMin())) {
795                                 responseString.append(" Guard Params <b>Min</b> is Required " + HTML_ITALICS_LNBREAK);
796                                 valid = false;
797                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getMin())) {
798                                 responseString.append(
799                                                 " Guard Params <b>Min</b> Should be Integer " + HTML_ITALICS_LNBREAK);
800                                 valid = false;
801                             }
802                             if (Strings.isNullOrEmpty(policyData.getYamlparams().getMax())) {
803                                 responseString.append(" Guard Params <b>Max</b> is Required " + HTML_ITALICS_LNBREAK);
804                                 valid = false;
805                             } else if (!PolicyUtils.isInteger(policyData.getYamlparams().getMax())) {
806                                 responseString.append(
807                                                 " Guard Params <b>Max</b> Should be Integer " + HTML_ITALICS_LNBREAK);
808                                 valid = false;
809                             }
810                         } else if ("GUARD_BL_YAML".equals(policyData.getRuleProvider())
811                                         && "Use Manual Entry".equals(policyData.getBlackListEntryType())) {
812
813                             if (policyData.getYamlparams().getBlackList() == null
814                                             || policyData.getYamlparams().getBlackList().isEmpty()) {
815                                 responseString.append(
816                                                 " Guard Params <b>BlackList</b> is Required " + HTML_ITALICS_LNBREAK);
817                                 valid = false;
818                             } else {
819                                 for (String blackList : policyData.getYamlparams().getBlackList()) {
820                                     if (blackList == null || !(SUCCESS
821                                                     .equals(PolicyUtils.policySpecialCharValidator(blackList)))) {
822                                         responseString.append(" Guard Params <b>BlackList</b> Should be valid String"
823                                                         + HTML_ITALICS_LNBREAK);
824                                         valid = false;
825                                         break;
826                                     }
827                                 }
828                             }
829                         }
830                     }
831                 }
832             }
833
834             if (ACTION_POLICY.equalsIgnoreCase(policyData.getPolicyType())) {
835                 if (!Strings.isNullOrEmpty(policyData.getActionPerformer())) {
836                     String actionPerformer = PolicyUtils.policySpecialCharValidator(policyData.getActionPerformer());
837                     if (!actionPerformer.contains(SUCCESS)) {
838                         responseString.append("<b>ActionPerformer</b>:<i>" + actionPerformer + HTML_ITALICS_LNBREAK);
839                         valid = false;
840                     }
841                 } else {
842                     responseString.append("<b>ActionPerformer</b>:<i> ActionPerformer Should not be empty"
843                                     + HTML_ITALICS_LNBREAK);
844                     valid = false;
845                 }
846
847                 if (!Strings.isNullOrEmpty(policyData.getActionAttributeValue())) {
848                     String actionAttribute = PolicyUtils
849                                     .policySpecialCharValidator(policyData.getActionAttributeValue());
850                     if (!actionAttribute.contains(SUCCESS)) {
851                         responseString.append("<b>ActionAttribute</b>:<i>" + actionAttribute + HTML_ITALICS_LNBREAK);
852                         valid = false;
853                     }
854                 } else {
855                     responseString.append("<b>ActionAttribute</b>:<i> ActionAttribute Should not be empty"
856                                     + HTML_ITALICS_LNBREAK);
857                     valid = false;
858                 }
859             }
860
861             if (CONFIG_POLICY.equals(policyData.getPolicyType())) {
862                 String value = "";
863                 if (valid) {
864                     if (commonClassDao != null) {
865                         List<Object> spData = commonClassDao.getDataById(SafePolicyWarning.class, "riskType",
866                                         policyData.getRiskType());
867                         if (!spData.isEmpty()) {
868                             SafePolicyWarning safePolicyWarningData = (SafePolicyWarning) spData.get(0);
869                             value = "<b>Message</b>:<i>" + safePolicyWarningData.getMessage() + "</i>";
870                         }
871                     }
872                     responseString.append(SUCCESS + "@#" + value);
873                 }
874             } else {
875                 if (valid) {
876                     responseString.append(SUCCESS);
877                 }
878             }
879
880             return responseString;
881         } catch (Exception e) {
882             LOGGER.error("Exception Occured during Policy Validation" + e);
883             return null;
884         }
885     }
886
887     protected String emailValidation(String email, String response) {
888         String res = response;
889         if (email != null) {
890             String validateEmail = PolicyUtils.validateEmailAddress(email.replace("\"", ""));
891             if (!validateEmail.contains(SUCCESS)) {
892                 res += "<b>Email</b>:<i>" + validateEmail + HTML_ITALICS_LNBREAK;
893             } else {
894                 return SUCCESS;
895             }
896         }
897         return res;
898     }
899
900     private MicroServiceModels getAttributeObject(String name, String version) {
901         MicroServiceModels workingModel = null;
902         try {
903             List<Object> microServiceModelsData = commonClassDao.getDataById(MicroServiceModels.class,
904                             "modelName:version", name + ":" + version);
905             if (microServiceModelsData != null) {
906                 workingModel = (MicroServiceModels) microServiceModelsData.get(0);
907             }
908         } catch (Exception e) {
909             String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Template.  The template name, " + name
910                             + " was not found in the dictionary: ";
911             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message + e);
912             return null;
913         }
914
915         return workingModel;
916     }
917
918     private OptimizationModels getOptimizationModelData(String name, String version) {
919         OptimizationModels workingModel = null;
920         try {
921             List<Object> optimizationModelsData = commonClassDao.getDataById(OptimizationModels.class,
922                             "modelName:version", name + ":" + version);
923             if (optimizationModelsData != null) {
924                 workingModel = (OptimizationModels) optimizationModelsData.get(0);
925             }
926         } catch (Exception e) {
927             String message = XACMLErrorConstants.ERROR_DATA_ISSUE + "Invalid Template.  The template name, " + name
928                             + " was not found in the dictionary: ";
929             LOGGER.error(XACMLErrorConstants.ERROR_DATA_ISSUE + message + e);
930             return null;
931         }
932
933         return workingModel;
934     }
935
936     private void pullJsonKeyPairs(JsonNode rootNode) {
937         Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
938
939         while (fieldsIterator.hasNext()) {
940             Map.Entry<String, JsonNode> field = fieldsIterator.next();
941             final String key = field.getKey();
942             final JsonNode value = field.getValue();
943             if (value.isContainerNode() && !value.isArray()) {
944                 pullJsonKeyPairs(value); // RECURSIVE CALL
945             } else {
946                 if (value.isArray()) {
947                     String newValue = StringUtils.replaceEach(value.toString(), new String[]
948                         { "[", "]", "\"" }, new String[]
949                         { "", "", "" });
950                     mapAttribute.put(key, newValue);
951                 } else {
952                     mapAttribute.put(key, value.toString().trim());
953                 }
954             }
955         }
956     }
957
958     private void pullModelJsonKeyPairs(JsonNode rootNode) {
959         Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
960
961         while (fieldsIterator.hasNext()) {
962             Map.Entry<String, JsonNode> field = fieldsIterator.next();
963             final String key = field.getKey();
964             final JsonNode value = field.getValue();
965
966             if (value.isContainerNode() && !value.isArray()) {
967                 jsonRequestMap.put(key.trim(), value.toString().trim());
968                 pullModelJsonKeyPairs(value); // RECURSIVE CALL
969             } else if (value.isArray()) {
970                 try {
971                     String valueStr = value.toString();
972                     String stringValue = valueStr.substring(valueStr.indexOf('[') + 1, valueStr.lastIndexOf(']'));
973
974                     if (stringValue.isEmpty()) {
975                         stringValue = "{\"test\":\"test\"}";
976                     }
977
978                     ObjectMapper mapper = new ObjectMapper();
979                     JsonNode newValue = mapper.readTree(stringValue);
980                     jsonRequestMap.put(key.trim(), value.toString().trim());
981                     pullModelJsonKeyPairs(newValue);
982                 } catch (IOException e) {
983                     LOGGER.info("PolicyValidation: Exception occurred while mapping string to JsonNode " + e);
984                 }
985             } else {
986                 jsonRequestMap.put(key.trim(), value.toString().trim());
987             }
988         }
989
990     }
991
992     private JsonObject stringToJsonObject(String value) {
993         try (JsonReader jsonReader = Json.createReader(new StringReader(value))) {
994             return jsonReader.readObject();
995         } catch (JsonException | IllegalStateException e) {
996             LOGGER.info(XACMLErrorConstants.ERROR_DATA_ISSUE
997                             + "Improper JSON format... may or may not cause issues in validating the policy: " + value,
998                             e);
999             return null;
1000         }
1001     }
1002
1003     private void findRequiredFields(JsonObject json) {
1004         if (json == null) {
1005             return;
1006         }
1007         for (Entry<String, JsonValue> keyMap : json.entrySet()) {
1008             Object obj = keyMap.getValue();
1009             String key = keyMap.getKey();
1010             if (obj instanceof JsonObject) {
1011                 if (allReqTrueKeys.contains(key)) {
1012                     JsonObject jsonObj = (JsonObject) obj;
1013                     // only check fields in obj if obj itself is required.
1014                     for (Entry<String, JsonValue> jsonMap : jsonObj.entrySet()) {
1015                         if (jsonMap.getValue().toString().contains(REQUIRED_ATTRIBUTE)) {
1016                             modelRequiredFieldsList.add(jsonMap.getKey().trim());
1017                         }
1018                     }
1019                 }
1020             } else if (keyMap.getValue().toString().contains(REQUIRED_ATTRIBUTE)) {
1021                 modelRequiredFieldsList.add(key.trim());
1022
1023             }
1024         }
1025
1026     }
1027
1028     // call this method to start the recursive
1029     private Set<String> getAllKeys(JSONObject json) {
1030         return getAllKeys(json, new HashSet<>());
1031     }
1032
1033     private Set<String> getAllKeys(JSONArray arr) {
1034         return getAllKeys(arr, new HashSet<>());
1035     }
1036
1037     private Set<String> getAllKeys(JSONArray arr, Set<String> keys) {
1038         for (int i = 0; i < arr.length(); i++) {
1039             Object obj = arr.get(i);
1040             if (obj instanceof JSONObject) {
1041                 keys.addAll(getAllKeys(arr.getJSONObject(i)));
1042             }
1043             if (obj instanceof JSONArray) {
1044                 keys.addAll(getAllKeys(arr.getJSONArray(i)));
1045             }
1046         }
1047
1048         return keys;
1049     }
1050
1051     // this method returns a set of keys with "required-true" defined in their value.
1052     private Set<String> getAllKeys(JSONObject json, Set<String> keys) {
1053         for (String key : json.keySet()) {
1054             Object obj = json.get(key);
1055             if (obj instanceof String && ((String) obj).contains(REQUIRED_ATTRIBUTE)) {
1056                 LOGGER.debug("key : " + key);
1057                 LOGGER.debug("obj : " + obj);
1058                 allReqTrueKeys.add(key); // For MicroService policies
1059                 allOptReqTrueKeys.add(key); // For Optimization policies
1060
1061                 // get the type from value and add that one also
1062                 String type = StringUtils.substringBefore((String) obj, ":");
1063                 if (!StringUtils.isBlank(type) && !StringUtils.containsAny(type.toLowerCase(), STRING, INTEGER, LIST,
1064                                 MAP, JAVA, BOOLEAN)) {
1065                     allReqTrueKeys.add(type);
1066                 }
1067             }
1068             if (obj instanceof JSONObject) {
1069                 keys.addAll(getAllKeys(json.getJSONObject(key)));
1070             }
1071             if (obj instanceof JSONArray) {
1072                 keys.addAll(getAllKeys(json.getJSONArray(key)));
1073             }
1074         }
1075
1076         return keys;
1077     }
1078
1079     private boolean validateMsModel(PolicyRestAdapter policyData, StringBuilder responseString)
1080                     throws JsonProcessingException {
1081         boolean valid = true;
1082         if (!Strings.isNullOrEmpty(policyData.getServiceType())) {
1083
1084             modelRequiredFieldsList.clear();
1085             pullJsonKeyPairs((JsonNode) policyData.getPolicyJSON());
1086
1087             String service;
1088             String version;
1089             if (policyData.getServiceType().contains("-v")) {
1090                 service = policyData.getServiceType().split("-v")[0];
1091                 version = policyData.getServiceType().split("-v")[1];
1092             } else {
1093                 service = policyData.getServiceType();
1094                 version = policyData.getVersion();
1095             }
1096
1097             if (!Strings.isNullOrEmpty(version)) {
1098                 MicroServiceModels returnModel = getAttributeObject(service, version);
1099
1100                 if (returnModel != null) {
1101
1102                     String annotation = returnModel.getAnnotation();
1103                     String refAttributes = returnModel.getRefAttributes();
1104                     String subAttributes = returnModel.getSubAttributes();
1105                     String modelAttributes = returnModel.getAttributes();
1106
1107                     if (!Strings.isNullOrEmpty(annotation)) {
1108                         Map<String, String> rangeMap = Splitter.on(",").withKeyValueSeparator("=").split(annotation);
1109                         for (Entry<String, String> raMap : rangeMap.entrySet()) {
1110                             if (raMap.getValue().contains("range::")) {
1111                                 String value = mapAttribute.get(raMap.getKey().trim());
1112                                 String[] tempString = raMap.getValue().split("::")[1].split("-");
1113                                 int startNum = Integer.parseInt(tempString[0]);
1114                                 int endNum = Integer.parseInt(tempString[1]);
1115                                 String returnString = "InvalidreturnModel Range:" + raMap.getKey() + " must be between "
1116                                                 + startNum + " - " + endNum + ",";
1117
1118                                 if (value != null) {
1119                                     if (PolicyUtils.isInteger(value.replace("\"", ""))) {
1120                                         int result = Integer.parseInt(value.replace("\"", ""));
1121                                         if (result < startNum || result > endNum) {
1122                                             responseString.append(returnString);
1123                                             valid = false;
1124                                         }
1125                                     } else {
1126                                         responseString.append(returnString);
1127                                         valid = false;
1128                                     }
1129                                 } else {
1130                                     responseString.append("<b>" + raMap.getKey() + "</b>:<i>" + raMap.getKey()
1131                                                     + " is required for the MicroService model " + service
1132                                                     + HTML_ITALICS_LNBREAK);
1133                                     valid = false;
1134                                 }
1135
1136                             }
1137                         }
1138                     } else if (!DECISION_MS_MODEL.equals(policyData.getRuleProvider())) {
1139                         // Validate for configName, location, uuid, and policyScope if no annotations exist for this
1140                         // model
1141                         if (Strings.isNullOrEmpty(policyData.getLocation())) {
1142                             responseString.append("<b>Micro Service Model</b>:<i> location is required for this model"
1143                                             + HTML_ITALICS_LNBREAK);
1144                             valid = false;
1145                         }
1146
1147                         if (Strings.isNullOrEmpty(policyData.getConfigName())) {
1148                             responseString.append("<b>Micro Service Model</b>:<i> configName is required for this model"
1149                                             + HTML_ITALICS_LNBREAK);
1150                             valid = false;
1151                         }
1152
1153                         if (Strings.isNullOrEmpty(policyData.getUuid())) {
1154                             responseString.append("<b>Micro Service Model</b>:<i> uuid is required for this model"
1155                                             + HTML_ITALICS_LNBREAK);
1156                             valid = false;
1157                         }
1158
1159                         if (Strings.isNullOrEmpty(policyData.getPolicyScope())) {
1160                             responseString.append(
1161                                             "<b>Micro Service Model</b>:<i> policyScope is required for this model"
1162                                                             + HTML_ITALICS_LNBREAK);
1163                             valid = false;
1164                         }
1165                     }
1166
1167                     // If request comes from the API we need to validate required fields in the Micro Service Model
1168                     // GUI request are already validated from the SDK-APP
1169                     if ("API".equals(policyData.getApiflag())) {
1170                         // first , get the complete set of required fields
1171                         populateReqFieldSet(new String[]
1172                             { refAttributes, modelAttributes }, subAttributes);
1173
1174                         // ignore req fields in which parent is not reqd
1175                         populateRequiredFields(new String[]
1176                             { refAttributes, modelAttributes }, subAttributes, modelAttributes);
1177
1178                         if (modelRequiredFieldsList != null && !modelRequiredFieldsList.isEmpty()) {
1179                             // create jsonRequestMap with all json keys and values from request
1180                             JsonNode rootNode = (JsonNode) policyData.getPolicyJSON();
1181                             jsonRequestMap.clear();
1182                             pullModelJsonKeyPairs(rootNode);
1183
1184                             // validate if the requiredFields are in the request
1185                             for (String requiredField : modelRequiredFieldsList) {
1186                                 if (jsonRequestMap.containsKey(requiredField)) {
1187                                     String value = jsonRequestMap.get(requiredField);
1188                                     if (StringUtils.isBlank(value) || "\"\"".equals(value)) {
1189                                         responseString.append("<b>Micro Service Model</b>:<i> " + requiredField
1190                                                         + ISREQUIRED + HTML_ITALICS_LNBREAK);
1191                                         valid = false;
1192                                     }
1193                                 } else {
1194                                     responseString.append("<b>Micro Service Model</b>:<i> " + requiredField + ISREQUIRED
1195                                                     + HTML_ITALICS_LNBREAK);
1196                                     valid = false;
1197                                 }
1198                             }
1199                         }
1200                     }
1201                 } else {
1202                     responseString.append("<b>Micro Service Model</b>:<i> Invalid Model. The model name, " + service
1203                                     + " of version, " + version + " was not found in the dictionary"
1204                                     + HTML_ITALICS_LNBREAK);
1205                     valid = false;
1206                 }
1207             } else {
1208                 responseString.append("<b>Micro Service Version</b>:<i> Micro Service Version is required"
1209                                 + HTML_ITALICS_LNBREAK);
1210                 valid = false;
1211             }
1212         } else {
1213             responseString.append("<b>Micro Service</b>:<i> Micro Service Model is required" + HTML_ITALICS_LNBREAK);
1214             valid = false;
1215         }
1216
1217         if (Strings.isNullOrEmpty(policyData.getPriority())
1218                         && !DECISION_MS_MODEL.equals(policyData.getRuleProvider())) {
1219             responseString.append("<b>Priority</b>:<i> Priority is required" + HTML_ITALICS_LNBREAK);
1220         }
1221
1222         return valid;
1223     }
1224
1225     private boolean validateOptimization(PolicyRestAdapter policyData, StringBuilder responseString) {
1226         boolean valid = true;
1227
1228         // Checks for required policy data in request
1229         if (Strings.isNullOrEmpty(policyData.getServiceType())) {
1230             responseString.append("<b>Optimization Service</b>:<i> Optimization policy data is missing or invalid Json."
1231                             + HTML_ITALICS_LNBREAK);
1232             return false;
1233         }
1234
1235         modelRequiredFieldsList.clear();
1236         pullJsonKeyPairs((JsonNode) policyData.getPolicyJSON());
1237
1238         // parse the service and version from the policy data
1239         String service;
1240         String version;
1241         if (policyData.getServiceType().contains("-v")) {
1242             service = policyData.getServiceType().split("-v")[0];
1243             version = policyData.getServiceType().split("-v")[1];
1244         } else {
1245             service = policyData.getServiceType();
1246             version = policyData.getVersion();
1247         }
1248
1249         // Checks for required version in policy data
1250         if (Strings.isNullOrEmpty(version)) {
1251             responseString.append("<b>Optimization Service Version</b>:<i> Optimization Service Version is required"
1252                             + HTML_ITALICS_LNBREAK);
1253             return false;
1254         }
1255
1256         OptimizationModels returnModel = getOptimizationModelData(service, version);
1257
1258         // Checks if valid model exists in the database
1259         if (returnModel == null) {
1260             responseString.append("<b>Optimization Service Model</b>:<i> Invalid Model. The model name, " + service
1261                             + " of version, " + version + " was not found in the dictionary" + HTML_ITALICS_LNBREAK);
1262             return false;
1263         }
1264
1265         String annotation = returnModel.getAnnotation();
1266         String refAttributes = returnModel.getRefattributes();
1267         String subAttributes = returnModel.getSubattributes();
1268         String modelAttributes = returnModel.getAttributes();
1269
1270         if (!Strings.isNullOrEmpty(annotation)) {
1271             Map<String, String> rangeMap = Splitter.on(",").withKeyValueSeparator("=").split(annotation);
1272             for (Entry<String, String> rangeMapEntry : rangeMap.entrySet()) {
1273                 if (rangeMapEntry.getValue().contains("range::")) {
1274                     String value = mapAttribute.get(rangeMapEntry.getKey().trim());
1275                     String[] tempString = rangeMapEntry.getValue().split("::")[1].split("-");
1276                     int startNum = Integer.parseInt(tempString[0]);
1277                     int endNum = Integer.parseInt(tempString[1]);
1278                     String returnString = "InvalidreturnModel Range:" + rangeMapEntry.getKey() + " must be between "
1279                                     + startNum + " - " + endNum + ",";
1280
1281                     if (value != null) {
1282                         if (PolicyUtils.isInteger(value.replace("\"", ""))) {
1283                             int result = Integer.parseInt(value.replace("\"", ""));
1284                             if (result < startNum || result > endNum) {
1285                                 responseString.append(returnString);
1286                                 valid = false;
1287                             }
1288                         } else {
1289                             responseString.append(returnString);
1290                             valid = false;
1291                         }
1292                     } else {
1293                         responseString.append("<b>" + rangeMapEntry.getKey() + "</b>:<i>" + rangeMapEntry.getKey()
1294                                         + " is required for the Optimization model " + service + HTML_ITALICS_LNBREAK);
1295                         valid = false;
1296                     }
1297
1298                 }
1299             }
1300         }
1301
1302         // If request comes from the API we need to validate required fields in the Micro Service Modelvalid
1303         // GUI request are already validated from the SDK-APP
1304         if ("API".equals(policyData.getApiflag())) {
1305             // first , get the complete set of required fields
1306             populateReqFieldSet(new String[]
1307                 { refAttributes, modelAttributes }, subAttributes);
1308
1309             modelRequiredFieldsList.addAll(allOptReqTrueKeys);
1310
1311             if (modelRequiredFieldsList != null && !modelRequiredFieldsList.isEmpty()) {
1312
1313                 // create jsonRequestMap with all json keys and values from request
1314                 JsonNode rootNode = (JsonNode) policyData.getPolicyJSON();
1315                 jsonRequestMap.clear();
1316                 pullModelJsonKeyPairs(rootNode);
1317
1318                 // validate if the requiredFields are in the request
1319                 for (String requiredField : modelRequiredFieldsList) {
1320                     if (jsonRequestMap.containsKey(requiredField)) {
1321                         String value = jsonRequestMap.get(requiredField);
1322                         if (StringUtils.isBlank(value) || "\"\"".equals(value)) {
1323                             responseString.append("<b>Optimization Service Model</b>:<i> " + requiredField + ISREQUIRED
1324                                             + HTML_ITALICS_LNBREAK);
1325                             valid = false;
1326                         }
1327                     } else {
1328                         responseString.append("<b>Optimization Service Model</b>:<i> " + requiredField + ISREQUIRED
1329                                         + HTML_ITALICS_LNBREAK);
1330                         valid = false;
1331                     }
1332                 }
1333             }
1334         }
1335
1336         if (Strings.isNullOrEmpty(policyData.getPriority())) {
1337             responseString.append("<b>Priority</b>:<i> Priority is required" + HTML_ITALICS_LNBREAK);
1338             valid = false;
1339         }
1340
1341         return valid;
1342     }
1343
1344     private void populateRequiredFields(String[] attrArr, String subAttributes, String modelAttributes)
1345                     throws JsonProcessingException {
1346         // get list of required fields from the ref_Attributes of the Model
1347         for (String attributes : attrArr) {
1348             if (!StringUtils.isBlank(attributes)) {
1349                 Map<String, String> attributesMap = null;
1350                 if (",".equals(attributes.substring(attributes.length() - 1))) {
1351                     String attributesString = attributes.substring(0, attributes.length() - 1);
1352                     attributesMap = Splitter.on(",").withKeyValueSeparator("=").split(attributesString);
1353                 } else if (!StringUtils.isBlank(modelAttributes)) {
1354                     attributesMap = Splitter.on(",").withKeyValueSeparator("=").split(modelAttributes);
1355                 } else {
1356                     continue;
1357                 }
1358                 String json = new ObjectMapper().writeValueAsString(attributesMap);
1359                 findRequiredFields(stringToJsonObject(json));
1360             }
1361
1362         }
1363
1364         // get list of required fields from the sub_Attributes of the Model
1365         if (!StringUtils.isBlank(subAttributes)) {
1366             JsonObject subAttributesJson = stringToJsonObject(subAttributes);
1367             findRequiredFields(subAttributesJson);
1368         }
1369
1370     }
1371
1372     private void populateReqFieldSet(String[] attrArr, String subAttributes) {
1373         allReqTrueKeys.clear();
1374         JSONObject jsonSub = new JSONObject(subAttributes);
1375         // Get all keys with "required-true" defined in their value from subAttribute
1376         getAllKeys(jsonSub);
1377
1378         // parse refAttrbutes
1379         for (String attr : attrArr) {
1380             if (attr != null) {
1381                 String[] referAarray = attr.split(",");
1382                 String[] element = null;
1383                 for (int i = 0; i < referAarray.length; i++) {
1384                     element = referAarray[i].split("=");
1385                     if (element.length > 1 && element[1].contains(REQUIRED_ATTRIBUTE)) {
1386                         allReqTrueKeys.add(element[0]);
1387                     }
1388                 }
1389             }
1390         }
1391     }
1392
1393 }