2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 - 2020 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 static java.util.Collections.emptyMap;
24 import static java.util.stream.Collectors.toSet;
25 import static org.apache.commons.lang3.StringUtils.isAllEmpty;
26 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
28 import com.fasterxml.jackson.databind.JsonNode;
29 import com.google.common.collect.ImmutableList;
30 import java.util.Collection;
31 import java.util.HashMap;
32 import java.util.List;
33 import java.util.ListIterator;
35 import java.util.Objects;
37 import java.util.function.Predicate;
38 import javax.inject.Inject;
39 import javax.ws.rs.core.Response;
40 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
41 import org.onap.vid.aai.AaiClientInterface;
42 import org.onap.vid.aai.model.ModelVer;
43 import org.onap.vid.asdc.parser.ServiceModelInflator;
44 import org.onap.vid.asdc.parser.ServiceModelInflator.Names;
45 import org.onap.vid.model.ServiceModel;
46 import org.onap.vid.model.aaiTree.AAITreeNode;
47 import org.onap.vid.model.aaiTree.NodeType;
48 import org.onap.vid.properties.Features;
49 import org.springframework.stereotype.Component;
50 import org.togglz.core.manager.FeatureManager;
53 public class AAITreeNodesEnricher {
55 private final AaiClientInterface aaiClient;
57 private final VidService sdcService;
59 private final ServiceModelInflator serviceModelInflator;
61 private final FeatureManager featureManager;
63 private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AAITreeNodesEnricher.class);
66 public AAITreeNodesEnricher(
67 AaiClientInterface aaiClient,
68 VidService sdcService,
69 FeatureManager featureManager,
70 ServiceModelInflator serviceModelInflator
72 this.aaiClient = aaiClient;
73 this.sdcService = sdcService;
74 this.featureManager = featureManager;
75 this.serviceModelInflator = serviceModelInflator;
78 void enrichNodesWithModelCustomizationName(Collection<AAITreeNode> nodes, ServiceModel serviceModel) {
79 final Map<String, Names> customizationNameByVersionId = serviceModelInflator.toNamesByVersionId(serviceModel);
81 nodes.forEach(node -> {
82 final Names names = customizationNameByVersionId.get(node.getModelVersionId());
84 node.setKeyInModel(names.getModelKey());
85 node.setModelCustomizationName(names.getModelCustomizationName());
90 void enrichVfModulesWithModelCustomizationNameFromOtherVersions(Collection<AAITreeNode> nodes, String modelInvariantId) {
91 if (!featureManager.isActive(Features.FLAG_EXP_TOPOLOGY_TREE_VFMODULE_NAMES_FROM_OTHER_TOSCA_VERSIONS)) {
95 if (nodes.stream().noneMatch(vfModuleWithMissingData())) {
99 final List<ModelVer> allModelVersions = aaiClient.getSortedVersionsByInvariantId(modelInvariantId);
101 final ListIterator<ModelVer> modelVersionsIterator = allModelVersions.listIterator();
102 final Map<String, Names> namesByCustomizationId = new HashMap<>();
104 nodes.stream().filter(vfModuleWithMissingData()).forEach(node -> {
105 String modelCustomizationId = node.getModelCustomizationId();
107 fetchCustomizationIdsFromToscaModelsWhileNeeded(namesByCustomizationId, modelVersionsIterator, modelCustomizationId);
109 final Names names = namesByCustomizationId.get(modelCustomizationId);
111 node.setKeyInModel(names.getModelKey());
112 node.setModelCustomizationName(names.getModelCustomizationName());
117 private Predicate<AAITreeNode> vfModuleWithMissingData() {
118 final Predicate<AAITreeNode> isVfModule = node -> node.getType() == NodeType.VF_MODULE;
120 final Predicate<AAITreeNode> nodeWithMissingData =
121 node -> isAllEmpty(node.getKeyInModel(), node.getModelCustomizationName());
123 return isVfModule.and(nodeWithMissingData);
127 * Loads inOutMutableNamesByCustomizationId with all customization IDs from the list of modelVersions. Will seize loading
128 * if yieldCustomizationId presents in inOutMutableNamesByCustomizationId.
129 * @param inOutMutableNamesByCustomizationId Mutable Map to fill-up
130 * @param modelVersions Iterable of model-version-ids to load
131 * @param yieldCustomizationId The key to stop loading on
133 private void fetchCustomizationIdsFromToscaModelsWhileNeeded(
134 Map<String, Names> inOutMutableNamesByCustomizationId, ListIterator<ModelVer> modelVersions, String yieldCustomizationId
136 while (modelVersions.hasNext() && !inOutMutableNamesByCustomizationId.containsKey(yieldCustomizationId)) {
137 inOutMutableNamesByCustomizationId.putAll(
138 fetchAllCustomizationIds(modelVersions.next().getModelVersionId())
143 private Map<String, Names> fetchAllCustomizationIds(String modelVersionId) {
145 ServiceModel serviceModel = sdcService.getServiceModelOrThrow(modelVersionId);
146 return serviceModelInflator.toNamesByCustomizationId(serviceModel);
147 } catch (Exception e) {
148 // Ignore the failure: SDC may lack the historic model, but this is NOT a reason to fail the whole enrichment
149 LOGGER.debug(EELFLoggerDelegate.debugLogger,
150 "Could not get model customization ids from SCD where modelVersionId={}", modelVersionId, e);
155 public void enrichNodesWithModelVersionAndModelName(Collection<AAITreeNode> nodes) {
157 Collection<String> invariantIDs = getModelInvariantIds(nodes);
159 Map<String, String> modelVersionByModelVersionId = new HashMap<>();
160 Map<String, String> modelNameByModelVersionId = new HashMap<>();
162 JsonNode models = getModels(aaiClient, invariantIDs);
164 for (JsonNode model : models) {
165 JsonNode modelVersions = model.get("model-vers").get("model-ver");
166 for (JsonNode modelVersion : modelVersions) {
167 final String modelVersionId = modelVersion.get("model-version-id").asText();
168 modelVersionByModelVersionId.put(modelVersionId, modelVersion.get("model-version").asText());
169 modelNameByModelVersionId.put(modelVersionId, modelVersion.get("model-name").asText());
174 nodes.forEach(node -> {
175 node.setModelVersion(modelVersionByModelVersionId.get(node.getModelVersionId()));
176 node.setModelName(modelNameByModelVersionId.get(node.getModelVersionId()));
181 private JsonNode getModels(AaiClientInterface aaiClient, Collection<String> invariantIDs) {
182 Response response = aaiClient.getVersionByInvariantId(ImmutableList.copyOf(invariantIDs));
184 JsonNode responseJson = JACKSON_OBJECT_MAPPER.readTree(response.readEntity(String.class));
185 return responseJson.get("model");
186 } catch (Exception e) {
187 LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to getVersionByInvariantId from A&AI", e);
189 return JACKSON_OBJECT_MAPPER.createObjectNode();
192 private Set<String> getModelInvariantIds(Collection<AAITreeNode> nodes) {
193 return nodes.stream()
194 .map(AAITreeNode::getModelInvariantId)
195 .filter(Objects::nonNull)