Standalone TCA with EELF Logger
[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 com.fasterxml.jackson.databind.JsonNode;
25
26 import java.io.IOException;
27 import java.net.URI;
28 import java.util.Collections;
29 import java.util.Iterator;
30 import java.util.Map;
31 import java.util.Set;
32
33 import org.onap.dcae.analytics.model.AnalyticsHttpConstants;
34 import org.onap.dcae.analytics.model.TcaModelConstants;
35 import org.onap.dcae.analytics.tca.core.service.TcaAaiEnrichmentService;
36 import org.onap.dcae.analytics.tca.core.service.TcaExecutionContext;
37 import org.onap.dcae.analytics.tca.model.facade.Aai;
38 import org.onap.dcae.analytics.tca.model.facade.TcaAlert;
39 import org.onap.dcae.analytics.tca.web.TcaAppProperties;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerFactory;
42 import org.springframework.http.HttpEntity;
43 import org.springframework.http.HttpHeaders;
44 import org.springframework.http.HttpMethod;
45 import org.springframework.http.ResponseEntity;
46 import org.springframework.util.StringUtils;
47 import org.springframework.web.client.RestTemplate;
48 import org.springframework.web.util.UriComponentsBuilder;
49
50 /**
51  * @author Rajiv Singla
52  */
53 public class TcaAaiEnrichmentServiceImpl implements TcaAaiEnrichmentService {
54
55     private static final Logger logger = LoggerFactory.getLogger(TcaAaiEnrichmentServiceImpl.class);
56
57     private final TcaAppProperties tcaAppProperties;
58     private final RestTemplate aaiRestTemplate;
59
60     public TcaAaiEnrichmentServiceImpl(final TcaAppProperties tcaAppProperties,
61                                        final RestTemplate aaiRestTemplate) {
62         this.tcaAppProperties = tcaAppProperties;
63         this.aaiRestTemplate = aaiRestTemplate;
64     }
65
66
67     @Override
68     public TcaAlert doAaiEnrichment(final TcaExecutionContext tcaExecutionContext) {
69
70         final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
71
72         // do aai enrichment
73         if (isVNFAlert(tcaAlert)) {
74             // do vnf enrichment
75             doAaiVnfEnrichment(tcaExecutionContext, aaiRestTemplate, tcaAppProperties);
76         } else {
77             // do vm enrichment
78             doAaiVmEnrichment(tcaExecutionContext, aaiRestTemplate, tcaAppProperties);
79         }
80
81         return tcaAlert;
82     }
83
84     private static void doAaiVmEnrichment(final TcaExecutionContext tcaExecutionContext,
85                                           final RestTemplate aaiRestTemplate,
86                                           final TcaAppProperties tcaAppProperties) {
87
88         final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
89         final String requestId = tcaExecutionContext.getRequestId();
90         final String transactionId = tcaExecutionContext.getTransactionId();
91         final String vServerName = tcaAlert.getAai().getGenericServerName();
92
93         // create new node query uri
94         final TcaAppProperties.Aai aai = tcaAppProperties.getTca().getAai();
95         final URI nodeQueryUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
96                 .path(aai.getNodeQueryPath())
97                 .queryParam("search-node-type", "vserver")
98                 .queryParam("filter", "vserver-name:EQUALS:" + vServerName)
99                 .build(Collections.emptyMap());
100
101         // get resource link
102         final String resourceLink =
103                 getVMResourceLink(getAAIRestAPIResponse(aaiRestTemplate, nodeQueryUri, requestId, transactionId));
104         if (resourceLink == null) {
105             return;
106         }
107
108         // create virtual server enrichment uri
109         final URI vServerEnrichmentUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
110                 .path(resourceLink)
111                 .build(Collections.emptyMap());
112
113         // fetch virtual server enrichment details
114         final String vServerEnrichmentDetails =
115                 getAAIRestAPIResponse(aaiRestTemplate, vServerEnrichmentUri, requestId, transactionId);
116
117         // do aai enrichment
118         enrichAAI(vServerEnrichmentDetails, tcaAlert, TcaModelConstants.AAI_VSERVER_KEY_PREFIX);
119     }
120
121     private static void doAaiVnfEnrichment(final TcaExecutionContext tcaExecutionContext,
122                                            final RestTemplate aaiRestTemplate,
123                                            final TcaAppProperties tcaAppProperties) {
124
125         final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
126         final String requestId = tcaExecutionContext.getRequestId();
127         final String transactionId = tcaExecutionContext.getTransactionId();
128         final String genericVnfName = tcaAlert.getAai().getGenericVNFName();
129
130         // create new generic vnf uri
131         final TcaAppProperties.Aai aai = tcaAppProperties.getTca().getAai();
132         final URI genericVnfUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
133                 .path(aai.getGenericVnfPath())
134                 .queryParam("vnf-name", genericVnfName)
135                 .build(Collections.emptyMap());
136
137         // fetch response
138         final String aaiResponse = getAAIRestAPIResponse(aaiRestTemplate, genericVnfUri, requestId, transactionId);
139
140         // do AAI enrichment
141         enrichAAI(aaiResponse, tcaAlert, TcaModelConstants.AAI_VNF_KEY_PREFIX);
142     }
143
144
145     /**
146      * Fetch response from A&AI Rest API as json string for given aai uri. Returns null if unable to fetch response
147      * from A&AI API
148      *
149      * @param aaiRestTemplate aai rest template
150      * @param aaiUri aai uri
151      *
152      * @return A&AI API response as json string
153      */
154     private static String getAAIRestAPIResponse(final RestTemplate aaiRestTemplate, final URI aaiUri,
155                                                 final String requestId, final String transactionId) {
156         // fetch response
157         ResponseEntity<String> aaiResponseEntity = null;
158         try {
159             final HttpHeaders headers = new HttpHeaders();
160             headers.add(AnalyticsHttpConstants.REQUEST_ID_HEADER_KEY, requestId);
161             headers.add(AnalyticsHttpConstants.REQUEST_TRANSACTION_ID_HEADER_KEY, transactionId);
162             final HttpEntity<String> httpEntity = new HttpEntity<>(headers);
163             aaiResponseEntity = aaiRestTemplate.exchange(aaiUri, HttpMethod.GET, httpEntity, String.class);
164         } catch (Exception e) {
165             logger.debug("Request id: " + requestId + ". Unable to get A&AI enrichment details", e);
166         }
167
168         if (aaiResponseEntity != null && aaiResponseEntity.getStatusCode().is2xxSuccessful()) {
169             return aaiResponseEntity.getBody();
170         }
171
172         return null;
173     }
174
175
176     /**
177      * Populates A&AI details retrieved from A&AI Enrichment API into Alerts A&AI Object
178      *
179      * @param aaiEnrichmentDetails A&AI Enrichment API fetched JSON String
180      * @param tcaAlert tca alert
181      * @param keyPrefix Key prefix that needs to be added to each fetched A&AI Enrichment record
182      *
183      * @return true if A&AI enrichment completed successfully
184      */
185     private static boolean enrichAAI(final String aaiEnrichmentDetails, final TcaAlert tcaAlert,
186                                      final String keyPrefix) {
187
188         final Aai preEnrichmentAAI = tcaAlert.getAai();
189         if (aaiEnrichmentDetails == null) {
190             logger.warn("Request id: {}. No A&AI Enrichment possible. A&AI Enrichment details are absent.",
191                     tcaAlert.getRequestId());
192             return false;
193         }
194
195         final Aai enrichedAAI = getNewEnrichedAAI(aaiEnrichmentDetails);
196
197         if (enrichedAAI != null) {
198             final Set<Map.Entry<String, Object>> enrichedAAIEntrySet =
199                     enrichedAAI.getDynamicProperties().entrySet();
200             final Map<String, Object> preEnrichmentAAIDynamicProperties = preEnrichmentAAI.getDynamicProperties();
201
202             // populate Alert A&AI Enrichment details and add prefix to key
203             for (Map.Entry<String, Object> enrichedAAIEntry : enrichedAAIEntrySet) {
204                 preEnrichmentAAIDynamicProperties.put(
205                         keyPrefix + enrichedAAIEntry.getKey(), enrichedAAIEntry.getValue());
206             }
207
208             logger.debug("Request id: {}. A&AI Enrichment was completed successfully.", tcaAlert.getRequestId());
209             return true;
210         } else {
211             logger.warn("Request id: {}. No A&AI Enrichment possible. Skipped - Invalid A&AI Response.",
212                     tcaAlert.getRequestId());
213             return false;
214         }
215
216     }
217
218     /**
219      * Creates a new A&AI object with only top level A&AI Enrichment details
220      *
221      * @param aaiEnrichmentDetails A&AI Enrichment details
222      *
223      * @return new A&AI with only top level A&AI Enrichment details
224      */
225     private static Aai getNewEnrichedAAI(final String aaiEnrichmentDetails) {
226         try {
227             final JsonNode rootNode = TCA_OBJECT_MAPPER.readTree(aaiEnrichmentDetails);
228             final Iterator<Map.Entry<String, JsonNode>> fieldsIterator = rootNode.fields();
229             while (fieldsIterator.hasNext()) {
230                 final Map.Entry<String, JsonNode> fieldEntry = fieldsIterator.next();
231                 final JsonNode jsonNode = fieldEntry.getValue();
232                 // remove all arrays, objects from A&AI Enrichment Json
233                 if (jsonNode.isPojo() || jsonNode.isObject() || jsonNode.isArray()) {
234                     fieldsIterator.remove();
235                 }
236             }
237             return TCA_OBJECT_MAPPER.treeToValue(rootNode, Aai.class);
238         } catch (IOException e) {
239             logger.error(
240                     "Failed to Parse AAI Enrichment Details from JSON: {}, Exception: {}.", aaiEnrichmentDetails, e);
241         }
242         return null;
243     }
244
245     /**
246      * Fetches VM Object Resource Link from A&AI Resource Link Json
247      *
248      * @param vmAAIResourceLinkDetails VM Object Resource Link from A&AI Resource Link Json
249      *
250      * @return object resource link String
251      */
252     private static String getVMResourceLink(final String vmAAIResourceLinkDetails) {
253         if (StringUtils.hasText(vmAAIResourceLinkDetails)) {
254             try {
255                 final JsonNode jsonNode = TCA_OBJECT_MAPPER.readTree(vmAAIResourceLinkDetails);
256                 final JsonNode resourceLinkJsonNode = jsonNode.findPath("resource-link");
257                 if (!resourceLinkJsonNode.isMissingNode()) {
258                     return resourceLinkJsonNode.asText();
259                 }
260             } catch (IOException e) {
261                 logger.error("Unable to determine VM Object link inside AAI Resource Link Response JSON: {}",
262                         vmAAIResourceLinkDetails, e);
263             }
264         }
265         return null;
266     }
267
268
269     private static boolean isVNFAlert(final TcaAlert tcaAlert) {
270         return tcaAlert.getTargetType().equals(TcaModelConstants.TCA_ALERT_VNF_TARGET_TYPE);
271     }
272
273 }