Fix missing result field from data router
[aai/data-router.git] / src / main / java / org / onap / aai / datarouter / policy / ServiceIntegrityValidationPolicy.java
1 /**\r
2  * ============LICENSE_START=======================================================\r
3  * org.onap.aai\r
4  * ================================================================================\r
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.\r
6  * Copyright © 2017-2018 Amdocs\r
7  * ================================================================================\r
8  * Licensed under the Apache License, Version 2.0 (the "License");\r
9  * you may not use this file except in compliance with the License.\r
10  * You may obtain a copy of the License at\r
11  *\r
12  *       http://www.apache.org/licenses/LICENSE-2.0\r
13  *\r
14  * Unless required by applicable law or agreed to in writing, software\r
15  * distributed under the License is distributed on an "AS IS" BASIS,\r
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
17  * See the License for the specific language governing permissions and\r
18  * limitations under the License.\r
19  * ============LICENSE_END=========================================================\r
20  */\r
21 package org.onap.aai.datarouter.policy;\r
22 \r
23 import com.google.gson.JsonArray;\r
24 import com.google.gson.JsonElement;\r
25 import com.google.gson.JsonObject;\r
26 import com.google.gson.JsonParser;\r
27 import java.util.Arrays;\r
28 import java.util.HashMap;\r
29 import java.util.Iterator;\r
30 import java.util.List;\r
31 import java.util.Map;\r
32 import org.apache.camel.Exchange;\r
33 import org.onap.aai.cl.api.Logger;\r
34 import org.onap.aai.cl.eelf.LoggerFactory;\r
35 import org.onap.aai.cl.mdc.MdcContext;\r
36 import org.onap.aai.restclient.client.Headers;\r
37 import org.onap.aai.datarouter.logging.ServiceIntegrityValidationsMsgs;\r
38 import org.onap.aai.datarouter.util.SearchServiceAgent;\r
39 import org.slf4j.MDC;\r
40 \r
41 /**\r
42  *  This class handles the logic which transformers the POA-AUDIT-RESULT event message to the ElasticSearch validation/violation message\r
43  *  in order to prepare two Json structures, one for validation index and one for violation index and then submit POST request to\r
44  *  Search-Data-Service to insert the document into ES.\r
45  *\r
46  */\r
47 public class ServiceIntegrityValidationPolicy {\r
48 \r
49     private static final String SERVICE_VALIDATION_SCHEMA_FILE = "auditservice_validation_schema.json";\r
50     private static final String SERVICE_VIOLATION_SCHEMA_FILE = "auditservice_violation_schema.json";\r
51 \r
52     private static Logger logger = LoggerFactory.getInstance()\r
53             .getLogger(ServiceIntegrityValidationPolicy.class.getSimpleName());\r
54 \r
55     private static JsonParser jsonParser = new JsonParser();\r
56 \r
57     private String validationIndexName = null;\r
58     private String violationIndexName = null;\r
59 \r
60     private SearchServiceAgent searchAgent = null;\r
61 \r
62     public ServiceIntegrityValidationPolicy(String searchCertPath,\r
63             String searchCertTruststore,\r
64             String searchCertPassword,\r
65             String searchBaseURL,\r
66             String endpoint,\r
67             String validationIndexName,\r
68             String violationIndexName) {\r
69         searchAgent = new SearchServiceAgent(searchCertPath,\r
70                 searchCertTruststore,\r
71                 searchCertPassword,\r
72                 concatSubURI(searchBaseURL, endpoint),\r
73                 "documents",\r
74                 logger);\r
75 \r
76         this.validationIndexName = validationIndexName;\r
77         this.violationIndexName = violationIndexName;\r
78     }\r
79 \r
80     public void startup(){\r
81 \r
82         searchAgent.createSearchIndex(validationIndexName, SERVICE_VALIDATION_SCHEMA_FILE);\r
83         searchAgent.createSearchIndex(violationIndexName, SERVICE_VIOLATION_SCHEMA_FILE);\r
84 \r
85         logger.info(ServiceIntegrityValidationsMsgs.SI_POLICY_REGISTRATION);\r
86     }\r
87 \r
88     public void process(Exchange exchange) throws Exception {\r
89 \r
90         logger.debug("Invoking ServiceIntegrityViolationPolicy with payload" + exchange.getIn().getBody());\r
91 \r
92         String payload = (String)exchange.getIn().getBody();\r
93 \r
94         JsonObject serviceValidation = jsonParser.parse(payload).getAsJsonObject();\r
95         JsonElement serviceViolationsElement = serviceValidation.get("violations");\r
96         // Calculate the document id to use for this entity.\r
97         JsonElement id = serviceValidation.get("validationId");\r
98 \r
99         if(serviceViolationsElement == null || serviceViolationsElement.getAsJsonArray().size() == 0) {\r
100             serviceValidation.addProperty("result", "Pass");\r
101             logger.debug("Service integrity validation event processing for event with ID " + id + " as a Pass due to no violations.");\r
102         }else {\r
103             serviceValidation.addProperty("result", "Fail");\r
104             logger.debug("Service integrity validation event processing for event with ID " + id + " as a Fail due to one or more violations.");\r
105         }\r
106 \r
107         if(serviceViolationsElement != null) {\r
108             JsonArray violationsArray = serviceViolationsElement.getAsJsonArray();\r
109             Iterator<JsonElement> vit = violationsArray.iterator();\r
110             while(vit.hasNext()) {\r
111                 JsonObject currentViolation = vit.next().getAsJsonObject();\r
112                 JsonObject oldViolationDetails =  currentViolation.getAsJsonObject("violationDetails");\r
113                 JsonObject newViolationDetails = new JsonObject();\r
114                 for (Map.Entry<String, JsonElement> e : oldViolationDetails.entrySet()) {\r
115                     String oldKey  = e.getKey();\r
116                     String newKey = oldKey.replace(".","-");\r
117                     newViolationDetails.add(newKey,e.getValue());\r
118                 }\r
119                 currentViolation.remove("violationDetails");\r
120                 currentViolation.remove("modelName");\r
121                 currentViolation.add("violationDetails",newViolationDetails);\r
122                 logger.debug("new violation:" + currentViolation.toString());\r
123                 JsonObject formattedViolation = buildViolation(serviceValidation, currentViolation);\r
124 \r
125                 handleSearchDataServiceOperation(violationIndexName, null, formattedViolation.toString(), "POST");\r
126 \r
127             }\r
128         }\r
129         logger.debug("validation: " + serviceValidation.toString());\r
130 \r
131         JsonObject formattedValidation = buildValidation(serviceValidation);\r
132         // Persist the entity that we received from the event to the Search Service.\r
133         handleSearchDataServiceOperation(validationIndexName, id.getAsString(), formattedValidation.toString(), "PUT");\r
134 \r
135     }\r
136 \r
137 \r
138     private JsonObject buildViolation(JsonObject validation, JsonObject violation) {\r
139         JsonObject formattedViolation = new JsonObject();\r
140 \r
141         formattedViolation.addProperty("validationId", validation.get("validationId").getAsString());\r
142         formattedViolation.addProperty("validationTimestamp", validation.get("validationTimestamp").getAsString());\r
143         formattedViolation.addProperty("modelVersionId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelVersionId").getAsString());\r
144         formattedViolation.addProperty("modelInvariantId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelInvariantId").getAsString());\r
145         formattedViolation.addProperty("serviceInstanceId",validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("serviceInstanceId").getAsString());\r
146 \r
147         formattedViolation.addProperty("violationId", violation.get("violationId").getAsString());\r
148         formattedViolation.addProperty("violationTimestamp", validation.get("validationTimestamp").getAsString());\r
149         formattedViolation.addProperty("category", violation.get("category").getAsString());\r
150         formattedViolation.addProperty("severity", violation.get("severity").getAsString());\r
151         formattedViolation.addProperty("violationType", violation.get("violationType").getAsString());\r
152         formattedViolation.addProperty("validationRule", violation.get("validationRule").getAsString());\r
153         formattedViolation.addProperty("message", violation.get("errorMessage").getAsString());\r
154 \r
155         //formattedViolation.add("violationDetails",violation.get("violationDetails"));\r
156         return formattedViolation;\r
157     }\r
158 \r
159     private JsonObject buildValidation(JsonObject validation) {\r
160         JsonObject formattedValidation = new JsonObject();\r
161 \r
162         formattedValidation.add("violations", validation.get("violations"));\r
163         formattedValidation.addProperty("validationId", validation.get("validationId").getAsString());\r
164         formattedValidation.addProperty("validationTimestamp", validation.get("validationTimestamp").getAsString());\r
165         formattedValidation.addProperty("modelVersionId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelVersionId").getAsString());\r
166         formattedValidation.addProperty("modelInvariantId", validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("modelInvariantId").getAsString());\r
167         formattedValidation.addProperty("serviceInstanceId",validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("serviceInstanceId").getAsString());\r
168         formattedValidation.addProperty("requestId",validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("xTransactionId").getAsString());\r
169         formattedValidation.addProperty("client",validation.get("entity").getAsJsonObject().get("poa-event").getAsJsonObject().get("xFromAppId").getAsString());\r
170         formattedValidation.addProperty("result", validation.get("result").getAsString());\r
171 \r
172         try {\r
173             formattedValidation.addProperty("modelName", validation.get("entity").getAsJsonObject().get("context-list").getAsJsonObject().get("sdc").getAsJsonObject().get("service").getAsJsonObject().get("name").getAsString());\r
174             logger.debug("model name: " +  validation.get("entity").getAsJsonObject().get("context-list").getAsJsonObject().get("sdc").getAsJsonObject().get("service").getAsJsonObject().get("name").getAsString());\r
175         }catch (NullPointerException ex){\r
176             logger.debug(ex.getMessage());\r
177             formattedValidation.addProperty("modelName","");\r
178         }\r
179 \r
180         return formattedValidation;\r
181     }\r
182 \r
183 \r
184     private static String concatSubURI(String... suburis) {\r
185         String finalURI = "";\r
186 \r
187         for (String suburi : suburis) {\r
188 \r
189             if (suburi != null) {\r
190                 // Remove any leading / since we only want to append /\r
191                 suburi = suburi.replaceFirst("^/*", "");\r
192 \r
193                 // Add a trailing / if one isn't already there\r
194                 finalURI += suburi.endsWith("/") ? suburi : suburi + "/";\r
195             }\r
196         }\r
197 \r
198         return finalURI;\r
199     }\r
200 \r
201 \r
202     public void handleSearchDataServiceOperation(String index, String id, String payload, String action) {\r
203 \r
204         Map<String, List<String>> headers = new HashMap<>();\r
205         headers.put(Headers.FROM_APP_ID, Arrays.asList("DataRouter"));\r
206         headers.put(Headers.TRANSACTION_ID, Arrays.asList(MDC.get(MdcContext.MDC_REQUEST_ID)));\r
207 \r
208         if (action.equalsIgnoreCase("PUT")) {\r
209             searchAgent.putDocument(index, id, payload, headers);\r
210 \r
211         }else if (action.equalsIgnoreCase("POST")) {\r
212             searchAgent.postDocument(index,  payload, headers);\r
213         }\r
214 \r
215     }\r
216 }\r