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.emptyList;
24 import static java.util.Collections.emptyMap;
25 import static java.util.Collections.singletonMap;
26 import static java.util.stream.Collectors.toList;
27 import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
28 import static org.hamcrest.MatcherAssert.assertThat;
29 import static org.hamcrest.Matchers.allOf;
30 import static org.hamcrest.collection.IsIterableContainingInAnyOrder.containsInAnyOrder;
31 import static org.hamcrest.collection.IsMapContaining.hasKey;
32 import static org.hamcrest.core.IsNot.not;
33 import static org.mockito.Matchers.any;
34 import static org.mockito.Mockito.mock;
35 import static org.mockito.Mockito.times;
36 import static org.mockito.Mockito.verify;
37 import static org.mockito.Mockito.when;
39 import com.google.common.collect.ImmutableList;
40 import com.google.common.collect.ImmutableMap;
41 import com.google.common.collect.Streams;
42 import java.util.Collection;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.ListIterator;
47 import net.javacrumbs.jsonunit.core.Option;
48 import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
49 import org.apache.commons.lang3.builder.ToStringStyle;
50 import org.jetbrains.annotations.NotNull;
51 import org.mockito.InjectMocks;
52 import org.mockito.Mock;
53 import org.onap.vid.aai.AaiClientInterface;
54 import org.onap.vid.aai.model.ModelVer;
55 import org.onap.vid.asdc.parser.ServiceModelInflator;
56 import org.onap.vid.asdc.parser.ServiceModelInflator.Names;
57 import org.onap.vid.exceptions.GenericUncheckedException;
58 import org.onap.vid.model.ServiceModel;
59 import org.onap.vid.model.aaiTree.AAITreeNode;
60 import org.onap.vid.model.aaiTree.NodeType;
61 import org.onap.vid.properties.Features;
62 import org.onap.vid.testUtils.TestUtils;
63 import org.testng.annotations.BeforeMethod;
64 import org.testng.annotations.DataProvider;
65 import org.testng.annotations.Test;
66 import org.togglz.core.manager.FeatureManager;
68 public class AAITreeNodesEnricherTest {
71 private AaiClientInterface aaiClient;
73 private VidService sdcService;
75 private ServiceModelInflator serviceModelInflator;
77 private FeatureManager featureManager;
79 private AAITreeNodesEnricher aaiTreeNodesEnricher;
82 public void initMocks() {
83 TestUtils.initMockitoMocks(this);
86 private final static String nullString = "null placeholder";
89 public void enrichNodesWithModelCustomizationName_simple3NodesCase_nodesEnriched() {
91 when(serviceModelInflator.toNamesByVersionId(any())).thenReturn(ImmutableMap.of(
92 "version id a", new Names("name a", "key a"),
93 "version id b", new Names("name b", "key b"),
94 "version id c", new Names("name c", "key c")
97 final ImmutableList<String> versionIds = ImmutableList.of("version id a", "version id b", "version id c");
98 final ImmutableList<Names> expectedNames = ImmutableList.of(
99 new Names("name a", "key a"),
100 new Names("name b", "key b"),
101 new Names("name c", "key c"));
104 final List<AAITreeNode> nodesUnderTest = nodesWithVersionIds(versionIds);
105 aaiTreeNodesEnricher.enrichNodesWithModelCustomizationName(nodesUnderTest, null);
107 assertThat(toStrings(nodesUnderTest), containsInAnyOrder(toStringsArray(nodesWithVersionIdsAndCustomizationNames(versionIds, expectedNames))));
111 public void enrichNodesWithModelCustomizationName_noNodes_noError() {
113 when(serviceModelInflator.toNamesByVersionId(any())).thenReturn(ImmutableMap.of(
114 "11c6dc3e-cd6a-41b3-a50e-b5a10f7157d0", new Names("my model cust name", "my key")
117 aaiTreeNodesEnricher.enrichNodesWithModelCustomizationName(emptyList(), null);
121 public void enrichNodesWithModelCustomizationName_nothingInModel_nodesUnchanged() {
123 when(serviceModelInflator.toNamesByVersionId(any())).thenReturn(emptyMap());
125 final ImmutableList<String> versionIds = ImmutableList.of("version id a", "version id b", "version id c");
126 final Names nullNames = new Names(nullString, nullString);
127 final ImmutableList<Names> expectedNames = ImmutableList.of(nullNames, nullNames, nullNames);
130 final List<AAITreeNode> nodesUnderTest = nodesWithVersionIds(versionIds);
132 aaiTreeNodesEnricher.enrichNodesWithModelCustomizationName(nodesUnderTest, null);
134 assertThat(toStrings(nodesUnderTest), containsInAnyOrder(toStringsArray(nodesWithVersionIdsAndCustomizationNames(versionIds, expectedNames))));
138 public void enrichNodesWithModelCustomizationName_staggered4NodesAndNull_3nodesEnriched2isNull() {
140 when(serviceModelInflator.toNamesByVersionId(any())).thenReturn(ImmutableMap.of(
141 "version id Z", new Names("name Z", "key Z"),
142 "version id d", new Names(null, "key d"),
143 "version id c", new Names("name c", null),
144 "version id a", new Names("name a", "key a")
147 final ImmutableList<String> versionIds = ImmutableList.of("version id a", "version id b", "version id c", "version id d", nullString);
148 final ImmutableList<Names> expectedNames = ImmutableList.of(
149 new Names("name a", "key a"),
150 new Names(nullString, nullString),
151 new Names("name c", nullString),
152 new Names(nullString, "key d"),
153 new Names(nullString, nullString)
157 final List<AAITreeNode> nodesUnderTest = nodesWithVersionIds(versionIds);
159 aaiTreeNodesEnricher.enrichNodesWithModelCustomizationName(nodesUnderTest, null);
161 assertThat(toStrings(nodesUnderTest), containsInAnyOrder(toStringsArray(nodesWithVersionIdsAndCustomizationNames(versionIds, expectedNames))));
165 public static Object[][] enrichVfModulesFilteredOutCases() {
166 AAITreeNode volumeGroup = new AAITreeNode();
167 volumeGroup.setType(NodeType.VOLUME_GROUP);
169 AAITreeNode vfModuleWithoutData = new AAITreeNode();
170 vfModuleWithoutData.setType(NodeType.VF_MODULE);
172 AAITreeNode vfModuleWithModelCustomizationName = new AAITreeNode();
173 vfModuleWithModelCustomizationName.setType(NodeType.VF_MODULE);
174 vfModuleWithModelCustomizationName.setModelCustomizationName("foo");
176 AAITreeNode vfModuleWithKeyInModel = new AAITreeNode();
177 vfModuleWithKeyInModel.setType(NodeType.VF_MODULE);
178 vfModuleWithKeyInModel.setKeyInModel("foo");
180 return new Object[][]{
181 {"no nodes", null, true},
182 {"no vfmodules", volumeGroup, true},
183 {"flag is off", vfModuleWithoutData, false},
184 {"all vfmodules with either getKeyInModel or getModelCustomizationId", vfModuleWithModelCustomizationName, true},
185 {"all vfmodules with either getKeyInModel or getModelCustomizationId", vfModuleWithKeyInModel, true},
189 @Test(dataProvider = "enrichVfModulesFilteredOutCases")
190 public void enrichVfModulesWithModelCustomizationNameFromOtherVersions_givenFilteredOutCases_doNothing(String reasonToSkip, AAITreeNode node, boolean flagState) {
191 when(featureManager.isActive(Features.FLAG_EXP_TOPOLOGY_TREE_VFMODULE_NAMES_FROM_OTHER_TOSCA_VERSIONS))
192 .thenReturn(flagState);
194 when(aaiClient.getSortedVersionsByInvariantId(any()))
195 .thenThrow(new AssertionError("did not expect reaching getSortedVersionsByInvariantId"));
197 List<AAITreeNode> nodes = (node == null) ? emptyList() : ImmutableList.of(node);
198 aaiTreeNodesEnricher.enrichVfModulesWithModelCustomizationNameFromOtherVersions(nodes, "modelInvariantId");
202 public void enrichVfModulesWithModelCustomizationNameFromOtherVersions_givenMissingKeysFoundInFirstSdcModels_sdcRequestsNotExhausted() {
203 when(featureManager.isActive(Features.FLAG_EXP_TOPOLOGY_TREE_VFMODULE_NAMES_FROM_OTHER_TOSCA_VERSIONS))
206 final ListIterator<ModelVer> manyVersionsIterator = manyModelVerIteratorMock();
208 String customizationIdToFind = "please-find-me";
209 Names anyNames = mock(Names.class);
211 when(serviceModelInflator.toNamesByCustomizationId(any()))
212 .thenReturn(singletonMap("uuidBefore", anyNames))
213 .thenReturn(singletonMap(customizationIdToFind, anyNames))
214 .thenReturn(singletonMap("uuidAfter", anyNames))
218 final Map<String, Names> inOutMutableNamesByCustomizationId = new HashMap<>();
219 aaiTreeNodesEnricher.fetchCustomizationIdsFromToscaModelsWhileNeeded(
220 inOutMutableNamesByCustomizationId, manyVersionsIterator, customizationIdToFind);
222 assertThat(inOutMutableNamesByCustomizationId, allOf(
223 hasKey(customizationIdToFind),
224 hasKey("uuidBefore"),
225 not(hasKey("uuidAfter")))
228 verify(manyVersionsIterator, times(2)).next();
229 verify(sdcService, times(2)).getServiceModelOrThrow(any());
232 private ListIterator<ModelVer> manyModelVerIteratorMock() {
233 final ModelVer modelVerMock = mock(ModelVer.class);
234 final ListIterator<ModelVer> result = mock(ListIterator.class);
236 when(result.next()).thenReturn(modelVerMock);
237 when(result.hasNext())
238 .thenReturn(true, true, true, true, true, true, false);
244 public interface Creator<T, R> {
249 public void enrichVfModulesWithModelCustomizationNameFromOtherVersions() {
251 Verifies the following
253 [*] aaiClient.getSortedVersionsByInvariantId response is exhausted
254 and all models fetched from sdc
255 -> we can see that model #1 info is populated in nodes
256 [*] relevant nodes enriched
257 [*] where data not found: nodes not enriched
258 [*] where data there already: node left pristine
259 [*] where node is not vfmodule: node left pristine
263 String modelInvariantId = "modelInvariantId";
265 ///////////// HELPERS
267 Creator<Integer, AAITreeNode> nodeMissingData = n -> {
268 AAITreeNode node = new AAITreeNode();
269 node.setType(NodeType.VF_MODULE);
270 node.setModelCustomizationId("model-customization-id-" + n);
274 Creator<Integer, AAITreeNode> nodeWithData = n -> {
275 AAITreeNode node = nodeMissingData.by(n);
276 node.setModelCustomizationName("modelCustomizationName-" + n);
277 node.setKeyInModel("modelKey-" + n);
281 Creator<Integer, ImmutableMap<String, Names>> namesMap = n -> ImmutableMap.of(
282 "model-customization-id-" + n,
283 new Names("modelCustomizationName-" + n, "modelKey-" + n)
286 Creator<Integer, ModelVer> modelVer = n -> {
287 ModelVer m = new ModelVer();
288 m.setModelVersion("model-version-" + n);
289 m.setModelVersionId("model-version-id-" + n);
295 when(featureManager.isActive(Features.FLAG_EXP_TOPOLOGY_TREE_VFMODULE_NAMES_FROM_OTHER_TOSCA_VERSIONS))
299 +-------------+----------+----------+----------+-----------+-----------+
300 | | model v1 | model v2 | model v3 | model v77 | model v99 |
301 +-------------+----------+----------+----------+-----------+-----------+
302 | in AAI list | v | v | v | v | |
303 | in SDC | v | v | v | | |
304 | in nodes | v | | v | v | v |
305 +-------------+----------+----------+----------+-----------+-----------+
307 when(aaiClient.getSortedVersionsByInvariantId(modelInvariantId))
308 .thenReturn(ImmutableList.of(modelVer.by(3), modelVer.by(77), modelVer.by(2), modelVer.by(1)));
310 ServiceModel serviceModel_1 = mock(ServiceModel.class);
311 when(sdcService.getServiceModelOrThrow("model-version-id-1")).thenReturn(serviceModel_1);
312 when(serviceModelInflator.toNamesByCustomizationId(serviceModel_1)).thenReturn(namesMap.by(1));
314 ServiceModel serviceModel_2 = mock(ServiceModel.class);
315 when(sdcService.getServiceModelOrThrow("model-version-id-2")).thenReturn(serviceModel_2);
316 when(serviceModelInflator.toNamesByCustomizationId(serviceModel_2)).thenReturn(namesMap.by(2));
318 ServiceModel serviceModel_3 = mock(ServiceModel.class);
319 when(sdcService.getServiceModelOrThrow("model-version-id-3")).thenReturn(serviceModel_3);
320 when(serviceModelInflator.toNamesByCustomizationId(serviceModel_3)).thenReturn(namesMap.by(3));
322 when(sdcService.getServiceModelOrThrow("model-version-id-77")).thenThrow(GenericUncheckedException.class);
324 AAITreeNode nodeWithDataAlready = nodeMissingData.by(1);
325 nodeWithDataAlready.setModelCustomizationName("significant-customization-name");
326 nodeWithDataAlready.setKeyInModel("significant-key-in-model");
328 AAITreeNode nodeNotVfModule = nodeMissingData.by(1);
329 nodeNotVfModule.setType(NodeType.GENERIC_VNF);
331 Collection<AAITreeNode> nodes = ImmutableList.of(
332 nodeMissingData.by(1), nodeMissingData.by(77),
333 nodeMissingData.by(3), nodeMissingData.by(99),
334 nodeWithDataAlready, nodeNotVfModule
339 aaiTreeNodesEnricher.enrichVfModulesWithModelCustomizationNameFromOtherVersions(nodes, modelInvariantId);
341 assertThat(nodes, jsonEquals(ImmutableList.of(
344 nodeMissingData.by(77), // not in sdcService
345 nodeMissingData.by(99), // not in aaiClient
346 nodeWithDataAlready, // pristine
347 nodeNotVfModule // pristine
348 )).when(Option.IGNORING_ARRAY_ORDER));
353 private String[] toStringsArray(List<AAITreeNode> nodes) {
354 return toStrings(nodes).toArray(new String[] {});
358 private List<String> toStrings(List<AAITreeNode> nodes) {
359 return nodes.stream().map(n -> {
360 final ReflectionToStringBuilder reflectionToStringBuilder = new ReflectionToStringBuilder(n, ToStringStyle.SHORT_PREFIX_STYLE);
361 reflectionToStringBuilder.setExcludeNullValues(true);
362 return reflectionToStringBuilder.toString();
363 }).collect(toList());
367 private List<AAITreeNode> nodesWithVersionIdsAndCustomizationNames(List<String> versionIds, List<Names> customizationNames) {
369 .zip(versionIds.stream(), customizationNames.stream(), this::nodeWithVersionIdAndCustomizationName)
374 private List<AAITreeNode> nodesWithVersionIds(List<String> versionIds) {
375 return versionIds.stream()
376 .map(versionId -> nodeWithVersionIdAndCustomizationName(versionId, new Names(nullString, nullString)))
380 private AAITreeNode nodeWithVersionIdAndCustomizationName(String versionId, Names names) {
381 AAITreeNode newNode = new AAITreeNode();
382 newNode.setModelVersionId(versionId.equals(nullString) ? null : versionId);
383 newNode.setModelCustomizationName(names.getModelCustomizationName().equals(nullString) ? null : names.getModelCustomizationName());
384 newNode.setKeyInModel(names.getModelKey().equals(nullString) ? null : names.getModelKey());