2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2019 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.vid.services;
23 import com.fasterxml.jackson.databind.JsonNode;
24 import com.google.common.collect.ImmutableList;
25 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
26 import org.onap.vid.aai.AaiClientInterface;
27 import org.onap.vid.aai.util.AAITreeConverter;
28 import org.onap.vid.asdc.AsdcCatalogException;
29 import org.onap.vid.asdc.parser.ServiceModelInflator;
30 import org.onap.vid.exceptions.GenericUncheckedException;
31 import org.onap.vid.model.ServiceModel;
32 import org.onap.vid.model.aaiTree.AAITreeNode;
33 import org.onap.vid.model.aaiTree.NodeType;
34 import org.onap.vid.model.aaiTree.ServiceInstance;
35 import org.onap.vid.utils.Tree;
36 import org.springframework.http.HttpMethod;
37 import org.springframework.stereotype.Component;
39 import javax.inject.Inject;
40 import javax.ws.rs.core.Response;
42 import java.util.concurrent.ConcurrentSkipListSet;
43 import java.util.concurrent.ExecutorService;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
47 import static java.util.Comparator.comparing;
48 import static java.util.stream.Collectors.toSet;
49 import static org.apache.commons.lang3.ObjectUtils.defaultIfNull;
50 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
53 public class AAIServiceTree {
55 private final AAITreeNodeBuilder aaiTreeNodeBuilder;
57 private final AAITreeConverter aaiTreeConverter;
59 private final AaiClientInterface aaiClient;
61 private final VidService sdcService;
63 private final ServiceModelInflator serviceModelInflator;
65 private final ExecutorService executorService;
67 private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AAIServiceTree.class);
69 public static final Tree<AaiRelationship> AAI_TREE_PATHS =
70 new Tree<>(new AaiRelationship(NodeType.SERVICE_INSTANCE));
73 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.GENERIC_VNF, NodeType.VOLUME_GROUP));
74 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.GENERIC_VNF, NodeType.VF_MODULE));
75 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.GENERIC_VNF, NodeType.NETWORK, NodeType.VPN_BINDING));
76 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.NETWORK, NodeType.VPN_BINDING));
77 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.INSTANCE_GROUP, NodeType.GENERIC_VNF));
78 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.COLLECTION_RESOURCE, NodeType.INSTANCE_GROUP));
79 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.CONFIGURATION, NodeType.NETWORK, NodeType.VPN_BINDING));
80 AAI_TREE_PATHS.addPath(toAaiRelationshipList(NodeType.CONFIGURATION, NodeType.VPN_BINDING));
83 public static List<AAIServiceTree.AaiRelationship> toAaiRelationshipList(NodeType... types) {
84 return Stream.of(types).map(AAIServiceTree.AaiRelationship::new).collect(Collectors.toList());
88 public AAIServiceTree(AaiClientInterface aaiClient, AAITreeNodeBuilder aaiTreeNodeBuilder,
89 AAITreeConverter aaiTreeConverter, VidService sdcService,
90 ServiceModelInflator serviceModelInflator, ExecutorService executorService) {
91 this.aaiClient = aaiClient;
92 this.aaiTreeNodeBuilder = aaiTreeNodeBuilder;
93 this.aaiTreeConverter = aaiTreeConverter;
94 this.sdcService = sdcService;
95 this.serviceModelInflator = serviceModelInflator;
96 this.executorService = executorService;
99 List<AAITreeNode> buildAAITreeForUniqueResource(String getUrl, NodeType nodeType) {
100 return buildAAITreeForUniqueResourceFromCustomQuery(getUrl, null, HttpMethod.GET, nodeType);
103 List<AAITreeNode> buildAAITreeForUniqueResourceFromCustomQuery(String url, String payload, HttpMethod method, NodeType nodeType) {
104 Tree<AAIServiceTree.AaiRelationship> pathsToSearch = new Tree<>(new AAIServiceTree.AaiRelationship(nodeType));
105 return buildAAITree(url, payload, method, pathsToSearch, false);
108 public List<AAITreeNode> buildAAITree(String url, String payload, HttpMethod method, Tree<AaiRelationship> pathsToSearch, boolean enrichWithModelVersion) {
110 ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = createNodesAccumulator();
112 List<AAITreeNode> aaiTreeNodes = fetchAAITree(url, payload, method, pathsToSearch, nodesAccumulator);
114 if (enrichWithModelVersion) {
115 enrichNodesWithModelVersionAndModelName(nodesAccumulator);
121 public ServiceInstance getServiceInstanceTopology(String globalCustomerId, String serviceType, String serviceInstanceId) {
123 String getURL = "business/customers/customer/" +
124 globalCustomerId + "/service-subscriptions/service-subscription/" +
125 serviceType + "/service-instances/service-instance/" + serviceInstanceId;
127 //Used later to get the nodes UUID
128 ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = createNodesAccumulator();
130 AAITreeNode aaiTree = fetchAAITree(getURL, null, HttpMethod.GET, AAI_TREE_PATHS, nodesAccumulator).get(0);
132 //Populate nodes with model-name & model-version (from aai)
133 enrichNodesWithModelVersionAndModelName(nodesAccumulator);
135 final ServiceModel serviceModel = getServiceModel(aaiTree.getModelVersionId());
137 //Populate nodes with model-customization-name (from sdc model)
138 enrichNodesWithModelCustomizationName(nodesAccumulator, serviceModel);
140 return aaiTreeConverter.convertTreeToUIModel(aaiTree, globalCustomerId, serviceType, getInstantiationType(serviceModel), getInstanceRole(serviceModel), getInstanceType(serviceModel));
143 private String getInstanceType(ServiceModel serviceModel){
144 if (serviceModel != null && serviceModel.getService() != null) {
145 return serviceModel.getService().getServiceType();
150 private String getInstanceRole(ServiceModel serviceModel) {
151 if (serviceModel != null && serviceModel.getService() != null) {
152 return serviceModel.getService().getServiceRole();
157 private List<AAITreeNode> fetchAAITree(String url, String payload, HttpMethod method, Tree<AaiRelationship> pathsToSearch,
158 ConcurrentSkipListSet<AAITreeNode> nodesAccumulator) {
159 return aaiTreeNodeBuilder.buildNode(NodeType.fromString(pathsToSearch.getRootValue().type),
160 url, payload, method, defaultIfNull(nodesAccumulator, createNodesAccumulator()),
161 executorService, pathsToSearch);
164 private ConcurrentSkipListSet<AAITreeNode> createNodesAccumulator() {
165 return new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
168 private String getInstantiationType(ServiceModel serviceModel) {
169 if (serviceModel.getService() != null && serviceModel.getService().getInstantiationType() != null) {
170 return serviceModel.getService().getInstantiationType();
176 private ServiceModel getServiceModel(String modelVersionId) {
178 final ServiceModel serviceModel = sdcService.getService(modelVersionId);
179 if (serviceModel == null) {
180 throw new GenericUncheckedException("Model version '" + modelVersionId + "' not found");
183 } catch (AsdcCatalogException e) {
184 throw new GenericUncheckedException("Exception while loading model version '" + modelVersionId + "'", e);
189 void enrichNodesWithModelCustomizationName(Collection<AAITreeNode> nodes, ServiceModel serviceModel) {
190 final Map<String, ServiceModelInflator.Names> customizationNameByVersionId = serviceModelInflator.toNamesByVersionId(serviceModel);
192 nodes.forEach(node -> {
193 final ServiceModelInflator.Names names = customizationNameByVersionId.get(node.getModelVersionId());
195 node.setKeyInModel(names.getModelKey());
196 node.setModelCustomizationName(names.getModelCustomizationName());
202 private void enrichNodesWithModelVersionAndModelName(Collection<AAITreeNode> nodes) {
204 Collection<String> invariantIDs = getModelInvariantIds(nodes);
206 Map<String, String> modelVersionByModelVersionId = new HashMap<>();
207 Map<String, String> modelNameByModelVersionId = new HashMap<>();
209 JsonNode models = getModels(aaiClient, invariantIDs);
210 for (JsonNode model: models) {
211 JsonNode modelVersions = model.get("model-vers").get("model-ver");
212 for (JsonNode modelVersion: modelVersions) {
213 final String modelVersionId = modelVersion.get("model-version-id").asText();
214 modelVersionByModelVersionId.put(modelVersionId, modelVersion.get("model-version").asText());
215 modelNameByModelVersionId.put(modelVersionId, modelVersion.get("model-name").asText());
219 nodes.forEach(node -> {
220 node.setModelVersion(modelVersionByModelVersionId.get(node.getModelVersionId()));
221 node.setModelName(modelNameByModelVersionId.get(node.getModelVersionId()));
226 private JsonNode getModels(AaiClientInterface aaiClient, Collection<String> invariantIDs) {
227 Response response = aaiClient.getVersionByInvariantId(ImmutableList.copyOf(invariantIDs));
229 JsonNode responseJson = JACKSON_OBJECT_MAPPER.readTree(response.readEntity(String.class));
230 return responseJson.get("model");
231 } catch (Exception e) {
232 LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to getVersionByInvariantId from A&AI", e);
234 return JACKSON_OBJECT_MAPPER.createObjectNode();
237 private Set<String> getModelInvariantIds(Collection<AAITreeNode> nodes) {
238 return nodes.stream()
239 .map(AAITreeNode::getModelInvariantId)
240 .filter(Objects::nonNull)
244 public static class AaiRelationship {
246 public final String type;
248 public AaiRelationship(String type) {
252 public AaiRelationship(NodeType nodeType) {
253 this.type = nodeType.getType();
257 public boolean equals(Object o) {
258 if (this == o) return true;
259 if (!(o instanceof AaiRelationship)) return false;
260 AaiRelationship that = (AaiRelationship) o;
261 return Objects.equals(type, that.type);
265 public int hashCode() {
266 return Objects.hash(type);