fix debug log
[dcaegen2/analytics/tca-gen2.git] / dcae-analytics / dcae-analytics-tca-web / src / main / java / org / onap / dcae / analytics / tca / web / aai / TcaAaiEnrichmentServiceImpl.java
1 /*
2  * ================================================================================
3  * Copyright (c) 2018 AT&T Intellectual Property. All rights reserved.
4  * ================================================================================
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  * ============LICENSE_END=========================================================
17  *
18  */
19
20 package org.onap.dcae.analytics.tca.web.aai;
21
22 import static org.onap.dcae.analytics.tca.model.util.json.TcaModelJsonConversion.TCA_OBJECT_MAPPER;
23
24 import java.io.IOException;
25 import java.net.URI;
26 import java.util.Collections;
27 import java.util.Iterator;
28 import java.util.Map;
29 import java.util.Set;
30
31 import org.onap.dcae.analytics.model.AnalyticsHttpConstants;
32 import org.onap.dcae.analytics.model.TcaModelConstants;
33 import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentService;
34 import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
35 import org.onap.dcae.analytics.tca.core.util.LogSpec;
36 import org.onap.dcae.analytics.tca.model.facade.Aai;
37 import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
38 import org.onap.dcae.analytics.tca.web.TcaAppProperties;
39 import org.onap.dcae.utils.eelf.logger.api.log.EELFLogFactory;
40 import org.onap.dcae.utils.eelf.logger.api.log.EELFLogger;
41 import org.onap.dcae.utils.eelf.logger.api.spec.DebugLogSpec;
42 import org.onap.dcae.utils.eelf.logger.api.spec.ErrorLogSpec;
43 import org.springframework.http.HttpEntity;
44 import org.springframework.http.HttpHeaders;
45 import org.springframework.http.HttpMethod;
46 import org.springframework.http.ResponseEntity;
47 import org.springframework.util.StringUtils;
48 import org.springframework.web.client.RestTemplate;
49 import org.springframework.web.util.UriComponentsBuilder;
50
51 import com.fasterxml.jackson.databind.JsonNode;
52
53 /**
54  * @author Rajiv Singla
55  */
56 public class TcaAaiEnrichmentServiceImpl implements TcaAaiEnrichmentService {
57
58     private static final EELFLogger logger = EELFLogFactory.getLogger(TcaAaiEnrichmentServiceImpl.class);
59
60     private final TcaAppProperties tcaAppProperties;
61     private final RestTemplate aaiRestTemplate;
62
63     public TcaAaiEnrichmentServiceImpl(final TcaAppProperties tcaAppProperties,
64                                        final RestTemplate aaiRestTemplate) {
65         this.tcaAppProperties = tcaAppProperties;
66         this.aaiRestTemplate = aaiRestTemplate;
67     }
68
69
70     @Override
71     public TcaAlert doAaiEnrichment(final TcaExecutionContext tcaExecutionContext) {
72
73         final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
74
75         // do aai enrichment
76         if (isVNFAlert(tcaAlert)) {
77             // do vnf enrichment
78             doAaiVnfEnrichment(tcaExecutionContext, aaiRestTemplate, tcaAppProperties);
79         } else {
80             // do vm enrichment
81             doAaiVmEnrichment(tcaExecutionContext, aaiRestTemplate, tcaAppProperties);
82         }
83
84         return tcaAlert;
85     }
86
87     private static void doAaiVmEnrichment(final TcaExecutionContext tcaExecutionContext,
88                                           final RestTemplate aaiRestTemplate,
89                                           final TcaAppProperties tcaAppProperties) {
90
91         final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
92         final String requestId = tcaExecutionContext.getRequestId();
93         final String transactionId = tcaExecutionContext.getTransactionId();
94         final String vServerName = tcaAlert.getAai().getGenericServerName();
95
96         // create new node query uri
97         final TcaAppProperties.Aai aai = tcaAppProperties.getTca().getAai();
98         final URI nodeQueryUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
99                 .path(aai.getNodeQueryPath())
100                 .queryParam("search-node-type", "vserver")
101                 .queryParam("filter", "vserver-name:EQUALS:" + vServerName)
102                 .build(Collections.emptyMap());
103
104         // get resource link
105         final String resourceLink =
106                 getVMResourceLink(requestId, getAAIRestAPIResponse(aaiRestTemplate, nodeQueryUri, requestId, transactionId));
107         if (resourceLink == null) {
108             return;
109         }
110
111         // create virtual server enrichment uri
112         final URI vServerEnrichmentUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
113                 .path(resourceLink)
114                 .build(Collections.emptyMap());
115
116         // fetch virtual server enrichment details
117         final String vServerEnrichmentDetails =
118                 getAAIRestAPIResponse(aaiRestTemplate, vServerEnrichmentUri, requestId, transactionId);
119
120         // do aai enrichment
121         enrichAAI(requestId, vServerEnrichmentDetails, tcaAlert, TcaModelConstants.AAI_VSERVER_KEY_PREFIX);
122     }
123
124     private static void doAaiVnfEnrichment(final TcaExecutionContext tcaExecutionContext,
125                                            final RestTemplate aaiRestTemplate,
126                                            final TcaAppProperties tcaAppProperties) {
127
128         final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
129         final String requestId = tcaExecutionContext.getRequestId();
130         final String transactionId = tcaExecutionContext.getTransactionId();
131         final String genericVnfName = tcaAlert.getAai().getGenericVNFName();
132
133         // create new generic vnf uri
134         final TcaAppProperties.Aai aai = tcaAppProperties.getTca().getAai();
135         final URI genericVnfUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
136                 .path(aai.getGenericVnfPath())
137                 .queryParam("vnf-name", genericVnfName)
138                 .build(Collections.emptyMap());
139
140         // fetch response
141         final String aaiResponse = getAAIRestAPIResponse(aaiRestTemplate, genericVnfUri, requestId, transactionId);
142
143         // do AAI enrichment
144         enrichAAI(requestId, aaiResponse, tcaAlert, TcaModelConstants.AAI_VNF_KEY_PREFIX);
145     }
146
147
148     /**
149      * Fetch response from A&AI Rest API as json string for given aai uri. Returns null if unable to fetch response
150      * from A&AI API
151      *
152      * @param aaiRestTemplate aai rest template
153      * @param aaiUri aai uri
154      *
155      * @return A&AI API response as json string
156      */
157     private static String getAAIRestAPIResponse(final RestTemplate aaiRestTemplate, final URI aaiUri,
158                                                 final String requestId, final String transactionId) {
159         // fetch response
160         ResponseEntity<String> aaiResponseEntity = null;
161         try {
162             final HttpHeaders headers = new HttpHeaders();
163             headers.add(AnalyticsHttpConstants.REQUEST_ID_HEADER_KEY, requestId);
164             headers.add(AnalyticsHttpConstants.REQUEST_TRANSACTION_ID_HEADER_KEY, transactionId);
165             final HttpEntity<String> httpEntity = new HttpEntity<>(headers);
166             aaiResponseEntity = aaiRestTemplate.exchange(aaiUri, HttpMethod.GET, httpEntity, String.class);
167         } catch (Exception e) {
168             final ErrorLogSpec errorLogSpec = LogSpec.createErrorLogSpec(requestId);
169             logger.errorLog().error("Request id: " + requestId + ". Unable to get A&AI enrichment details",
170                     errorLogSpec, e.toString());
171         }
172
173         if (aaiResponseEntity != null && aaiResponseEntity.getStatusCode().is2xxSuccessful()) {
174             return aaiResponseEntity.getBody();
175         }
176
177         return null;
178     }
179
180
181     /**
182      * Populates A&AI details retrieved from A&AI Enrichment API into Alerts A&AI Object
183      *
184      * @param aaiEnrichmentDetails A&AI Enrichment API fetched JSON String
185      * @param tcaAlert tca alert
186      * @param keyPrefix Key prefix that needs to be added to each fetched A&AI Enrichment record
187      *
188      * @return true if A&AI enrichment completed successfully
189      */
190     private static boolean enrichAAI(final String requestId, final String aaiEnrichmentDetails, final TcaAlert tcaAlert,
191                                      final String keyPrefix) {
192
193         final Aai preEnrichmentAAI = tcaAlert.getAai();
194         final ErrorLogSpec errorLogSpec = LogSpec.createErrorLogSpec(requestId);
195         final DebugLogSpec debugLogSpec = LogSpec.createDebugLogSpec(requestId);
196
197         if (aaiEnrichmentDetails == null) {
198             logger.errorLog().error("Request id: {}. No A&AI Enrichment possible. A&AI Enrichment details are absent.",
199                     errorLogSpec, tcaAlert.getRequestId());
200             return false;
201         }
202
203         final Aai enrichedAAI = getNewEnrichedAAI(requestId, aaiEnrichmentDetails);
204
205         if (enrichedAAI != null) {
206             final Set<Map.Entry<String, Object>> enrichedAAIEntrySet =
207                     enrichedAAI.getDynamicProperties().entrySet();
208             final Map<String, Object> preEnrichmentAAIDynamicProperties = preEnrichmentAAI.getDynamicProperties();
209
210             // populate Alert A&AI Enrichment details and add prefix to key
211             for (Map.Entry<String, Object> enrichedAAIEntry : enrichedAAIEntrySet) {
212                 preEnrichmentAAIDynamicProperties.put(
213                         keyPrefix + enrichedAAIEntry.getKey(), enrichedAAIEntry.getValue());
214             }
215
216             logger.debugLog().debug("Request id: {}. A&AI Enrichment was completed successfully.",
217                     debugLogSpec, tcaAlert.getRequestId());
218             return true;
219         } else {
220             logger.errorLog().error("Request id: {}. No A&AI Enrichment possible. Skipped - Invalid A&AI Response.",
221                     errorLogSpec, tcaAlert.getRequestId());
222             return false;
223         }
224
225     }
226
227     /**
228      * Creates a new A&AI object with only top level A&AI Enrichment details
229      *
230      * @param aaiEnrichmentDetails A&AI Enrichment details
231      *
232      * @return new A&AI with only top level A&AI Enrichment details
233      */
234     private static Aai getNewEnrichedAAI(final String requestId, final String aaiEnrichmentDetails) {
235         try {
236             final JsonNode rootNode = TCA_OBJECT_MAPPER.readTree(aaiEnrichmentDetails);
237             final Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
238             while (fieldsIterator.hasNext()) {
239                 final Map.Entry<String, JsonNode> fieldEntry = fieldsIterator.next();
240                 final JsonNode jsonNode = fieldEntry.getValue();
241                 // remove all arrays, objects from A&AI Enrichment Json
242                 if (jsonNode.isPojo() || jsonNode.isObject() || jsonNode.isArray()) {
243                     fieldsIterator.remove();
244                 }
245             }
246             return TCA_OBJECT_MAPPER.treeToValue(rootNode, Aai.class);
247         } catch (IOException e) {
248             final ErrorLogSpec errorLogSpec = LogSpec.createErrorLogSpec(requestId);
249             logger.errorLog().error(
250                     "Failed to Parse AAI Enrichment Details from JSON: {}, Exception: {}.",
251                     errorLogSpec, aaiEnrichmentDetails, e.toString());
252         }
253         return null;
254     }
255
256     /**
257      * Fetches VM Object Resource Link from A&AI Resource Link Json
258      *
259      * @param vmAAIResourceLinkDetails VM Object Resource Link from A&AI Resource Link Json
260      *
261      * @return object resource link String
262      */
263     private static String getVMResourceLink(final String requestId, final String vmAAIResourceLinkDetails) {
264         if (StringUtils.hasText(vmAAIResourceLinkDetails)) {
265             try {
266                 final JsonNode jsonNode = TCA_OBJECT_MAPPER.readTree(vmAAIResourceLinkDetails);
267                 final JsonNode resourceLinkJsonNode = jsonNode.findPath("resource-link");
268                 if (!resourceLinkJsonNode.isMissingNode()) {
269                     return resourceLinkJsonNode.asText();
270                 }
271             } catch (IOException e) {
272                 final ErrorLogSpec errorLogSpec = LogSpec.createErrorLogSpec(requestId);
273                 logger.errorLog().error("Unable to determine VM Object link inside AAI Resource Link Response JSON: {}",
274                         errorLogSpec, vmAAIResourceLinkDetails, e.toString());
275             }
276         }
277         return null;
278     }
279
280
281     private static boolean isVNFAlert(final TcaAlert tcaAlert) {
282         return tcaAlert.getTargetType().equals(TcaModelConstants.TCA_ALERT_VNF_TARGET_TYPE);
283     }
284
285 }