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
9 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.onap.dcae.analytics.tca.web.aai;
22 import static org.onap.dcae.analytics.tca.model.util.json.TcaModelJsonConversion.TCA_OBJECT_MAPPER;
24 import com.fasterxml.jackson.databind.JsonNode;
26 import java.io.IOException;
28 import java.util.Collections;
29 import java.util.Iterator;
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;
51 * @author Rajiv Singla
53 public class TcaAaiEnrichmentServiceImpl implements TcaAaiEnrichmentService {
55 private static final Logger logger = LoggerFactory.getLogger(TcaAaiEnrichmentServiceImpl.class);
57 private final TcaAppProperties tcaAppProperties;
58 private final RestTemplate aaiRestTemplate;
60 public TcaAaiEnrichmentServiceImpl(final TcaAppProperties tcaAppProperties,
61 final RestTemplate aaiRestTemplate) {
62 this.tcaAppProperties = tcaAppProperties;
63 this.aaiRestTemplate = aaiRestTemplate;
68 public TcaAlert doAaiEnrichment(final TcaExecutionContext tcaExecutionContext) {
70 final TcaAlert tcaAlert = tcaExecutionContext.getTcaResultContext().getTcaAlert();
73 if (isVNFAlert(tcaAlert)) {
75 doAaiVnfEnrichment(tcaExecutionContext, aaiRestTemplate, tcaAppProperties);
78 doAaiVmEnrichment(tcaExecutionContext, aaiRestTemplate, tcaAppProperties);
84 private static void doAaiVmEnrichment(final TcaExecutionContext tcaExecutionContext,
85 final RestTemplate aaiRestTemplate,
86 final TcaAppProperties tcaAppProperties) {
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();
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());
102 final String resourceLink =
103 getVMResourceLink(getAAIRestAPIResponse(aaiRestTemplate, nodeQueryUri, requestId, transactionId));
104 if (resourceLink == null) {
108 // create virtual server enrichment uri
109 final URI vServerEnrichmentUri = UriComponentsBuilder.fromHttpUrl(aai.getUrl())
111 .build(Collections.emptyMap());
113 // fetch virtual server enrichment details
114 final String vServerEnrichmentDetails =
115 getAAIRestAPIResponse(aaiRestTemplate, vServerEnrichmentUri, requestId, transactionId);
118 enrichAAI(vServerEnrichmentDetails, tcaAlert, TcaModelConstants.AAI_VSERVER_KEY_PREFIX);
121 private static void doAaiVnfEnrichment(final TcaExecutionContext tcaExecutionContext,
122 final RestTemplate aaiRestTemplate,
123 final TcaAppProperties tcaAppProperties) {
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();
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());
138 final String aaiResponse = getAAIRestAPIResponse(aaiRestTemplate, genericVnfUri, requestId, transactionId);
141 enrichAAI(aaiResponse, tcaAlert, TcaModelConstants.AAI_VNF_KEY_PREFIX);
146 * Fetch response from A&AI Rest API as json string for given aai uri. Returns null if unable to fetch response
149 * @param aaiRestTemplate aai rest template
150 * @param aaiUri aai uri
152 * @return A&AI API response as json string
154 private static String getAAIRestAPIResponse(final RestTemplate aaiRestTemplate, final URI aaiUri,
155 final String requestId, final String transactionId) {
157 ResponseEntity<String> aaiResponseEntity = null;
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);
168 if (aaiResponseEntity != null && aaiResponseEntity.getStatusCode().is2xxSuccessful()) {
169 return aaiResponseEntity.getBody();
177 * Populates A&AI details retrieved from A&AI Enrichment API into Alerts A&AI Object
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
183 * @return true if A&AI enrichment completed successfully
185 private static boolean enrichAAI(final String aaiEnrichmentDetails, final TcaAlert tcaAlert,
186 final String keyPrefix) {
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());
195 final Aai enrichedAAI = getNewEnrichedAAI(aaiEnrichmentDetails);
197 if (enrichedAAI != null) {
198 final Set<Map.Entry<String, Object>> enrichedAAIEntrySet =
199 enrichedAAI.getDynamicProperties().entrySet();
200 final Map<String, Object> preEnrichmentAAIDynamicProperties = preEnrichmentAAI.getDynamicProperties();
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());
208 logger.debug("Request id: {}. A&AI Enrichment was completed successfully.", tcaAlert.getRequestId());
211 logger.warn("Request id: {}. No A&AI Enrichment possible. Skipped - Invalid A&AI Response.",
212 tcaAlert.getRequestId());
219 * Creates a new A&AI object with only top level A&AI Enrichment details
221 * @param aaiEnrichmentDetails A&AI Enrichment details
223 * @return new A&AI with only top level A&AI Enrichment details
225 private static Aai getNewEnrichedAAI(final String aaiEnrichmentDetails) {
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();
237 return TCA_OBJECT_MAPPER.treeToValue(rootNode, Aai.class);
238 } catch (IOException e) {
240 "Failed to Parse AAI Enrichment Details from JSON: {}, Exception: {}.", aaiEnrichmentDetails, e);
246 * Fetches VM Object Resource Link from A&AI Resource Link Json
248 * @param vmAAIResourceLinkDetails VM Object Resource Link from A&AI Resource Link Json
250 * @return object resource link String
252 private static String getVMResourceLink(final String vmAAIResourceLinkDetails) {
253 if (StringUtils.hasText(vmAAIResourceLinkDetails)) {
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();
260 } catch (IOException e) {
261 logger.error("Unable to determine VM Object link inside AAI Resource Link Response JSON: {}",
262 vmAAIResourceLinkDetails, e);
269 private static boolean isVNFAlert(final TcaAlert tcaAlert) {
270 return tcaAlert.getTargetType().equals(TcaModelConstants.TCA_ALERT_VNF_TARGET_TYPE);