Implant vid-app-common org.onap.vid.job (main and test)
[vid.git] / vid-app-common / src / test / java / org / onap / vid / services / AAITreeNodeBuilderTest.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * VID
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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=========================================================
19  */
20
21 package org.onap.vid.services;
22
23 import com.fasterxml.jackson.core.JsonProcessingException;
24 import com.fasterxml.jackson.databind.JsonNode;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import com.fasterxml.jackson.databind.node.ArrayNode;
27 import com.fasterxml.jackson.databind.node.ObjectNode;
28 import com.google.common.collect.ImmutableList;
29 import com.google.common.collect.ImmutableMap;
30 import com.google.common.util.concurrent.MoreExecutors;
31
32 import org.apache.commons.lang3.tuple.Pair;
33 import org.jetbrains.annotations.NotNull;
34 import org.mockito.Mock;
35 import org.mockito.MockitoAnnotations;
36 import org.mockito.stubbing.Answer;
37 import org.onap.vid.aai.AaiClientInterface;
38 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship;
39 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.RelationshipList;
40 import org.onap.vid.exceptions.GenericUncheckedException;
41 import org.onap.vid.model.aaiTree.AAITreeNode;
42 import org.onap.vid.model.aaiTree.NodeType;
43 import org.onap.vid.mso.model.CloudConfiguration;
44 import org.onap.vid.utils.Tree;
45 import org.onap.vid.utils.Unchecked;
46 import org.onap.vid.testUtils.TestUtils;
47 import org.springframework.http.HttpMethod;
48 import org.testng.annotations.BeforeClass;
49 import org.testng.annotations.DataProvider;
50 import org.testng.annotations.Test;
51
52 import java.io.IOException;
53 import java.util.HashMap;
54 import java.util.List;
55 import java.util.Map;
56 import java.util.Optional;
57 import java.util.concurrent.ConcurrentSkipListSet;
58 import java.util.concurrent.ExecutorService;
59 import java.util.concurrent.Executors;
60
61 import static java.util.Comparator.comparing;
62 import static net.javacrumbs.jsonunit.JsonMatchers.jsonEquals;
63 import static net.javacrumbs.jsonunit.core.Option.IGNORING_ARRAY_ORDER;
64 import static net.javacrumbs.jsonunit.core.Option.IGNORING_EXTRA_FIELDS;
65 import static org.hamcrest.MatcherAssert.assertThat;
66 import static org.hamcrest.Matchers.empty;
67 import static org.hamcrest.core.Is.is;
68 import static org.junit.Assert.assertEquals;
69 import static org.mockito.Mockito.when;
70 import static org.onap.vid.services.AAIServiceTree.AAI_TREE_PATHS;
71 import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
72 import static org.testng.Assert.assertNull;
73 import static org.testng.Assert.assertTrue;
74
75 public class AAITreeNodeBuilderTest {
76
77     private AAITreeNodeBuilder aaiTreeNodeBuilder;
78
79     @Mock
80     private AaiClientInterface aaiClientMock;
81
82     private ExecutorService executorService;
83
84     private static final ObjectMapper mapper = new ObjectMapper();
85
86     @BeforeClass
87     public void initMocks() {
88         MockitoAnnotations.initMocks(this);
89         aaiTreeNodeBuilder = new AAITreeNodeBuilder(aaiClientMock);
90         executorService = MoreExecutors.newDirectExecutorService();
91     }
92
93     private void buildNodeAndAssert(JsonNode inputNode, AAITreeNode expectedNode, NodeType nodeType){
94         ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
95         when(aaiClientMock.typedAaiRest(Unchecked.toURI("anyUrl"), JsonNode.class, null, HttpMethod.GET, false)).thenReturn(inputNode);
96         AAITreeNode actualNode = aaiTreeNodeBuilder.buildNode(
97                 nodeType,
98                 "anyUrl",
99                 null,
100                 HttpMethod.GET,
101                 nodesAccumulator,
102                 executorService,
103                 AAI_TREE_PATHS.getSubTree(new AAIServiceTree.AaiRelationship(nodeType))
104         ).get(0);
105         assertThat(actualNode, jsonEquals(expectedNode).when(IGNORING_ARRAY_ORDER, IGNORING_EXTRA_FIELDS).whenIgnoringPaths("relationshipList","children[0].relationshipList"));
106     }
107
108     @Test
109     public void buildNode_buildGroupNode_NodeIsAsExpected() {
110         buildNodeAndAssert(createGroupJson(), createExpectedGroupNode(), NodeType.INSTANCE_GROUP);
111     }
112
113     private AAITreeNode createExpectedGroupNode() {
114         AAITreeNode expectedNode = new AAITreeNode();
115         expectedNode.setId("c4fcf022-31a0-470a-b5b8-c18335b7af32");
116         expectedNode.setType(NodeType.INSTANCE_GROUP);
117         expectedNode.setName("Test vE-Flex");
118         expectedNode.setModelVersionId("Test vE-Flex");
119         expectedNode.setModelInvariantId("dd182d7d-6949-4b90-b3cc-5befe400742e");
120         expectedNode.setInMaint(false);
121         HashMap<String,Object> additionalProperties = new HashMap<>();
122         additionalProperties.put("inMaint","false");
123         additionalProperties.put("description","Test vE-Flex instance-group");
124         additionalProperties.put("instance-group-type","ha");
125         additionalProperties.put("instance-group-role","test-IG-role");
126         additionalProperties.put("resource-version","1533315433086");
127         additionalProperties.put("instance-group-function","vTSBC Customer Landing Network Collection");
128         expectedNode.setAdditionalProperties(additionalProperties);
129         return expectedNode;
130     }
131
132     private JsonNode createGroupJson() {
133         ObjectMapper objectMapper = new ObjectMapper();
134         JsonNode groupNode = null;
135         try {
136             groupNode = objectMapper.readTree("" +
137                     "{" +
138                     "      \"id\": \"c4fcf022-31a0-470a-b5b8-c18335b7af32\"," +
139                     "      \"instance-group-role\": \"test-IG-role\"," +
140                     "      \"description\": \"Test vE-Flex instance-group\"," +
141                     "      \"instance-group-type\": \"ha\"," +
142                     "      \"resource-version\": \"1533315433086\"," +
143                     "      \"instance-group-name\": \"Test vE-Flex\"," +
144                     "      \"model-invariant-id\": \"dd182d7d-6949-4b90-b3cc-5befe400742e\"," +
145                     "      \"model-version-id\": \"Test vE-Flex\"," +
146                     "      \"inMaint\": \"false\"," +
147                     "      \"instance-group-function\": \"vTSBC Customer Landing Network Collection\"," +
148                     "      \"relationship-list\": {" +
149                     "      \"relationship\": []" +
150                     "    }" +
151                     "    }");
152         } catch (IOException e) {
153             e.printStackTrace();
154         }
155         return groupNode;
156     }
157
158     @Test
159     public void whenReadNetworkNode_thenNodeIsAsExpected() throws IOException {
160         JsonNode mockedAaiResponse = TestUtils.readJsonResourceFileAsObject("/getTopology/network.json", JsonNode.class);
161
162         AAITreeNode expectedNetworkNode = new AAITreeNode();
163         expectedNetworkNode.setId("94c86b39-bbbf-4027-8120-ff37c6d2493a");
164         expectedNetworkNode.setName("AUK51a_oam_calea_net_1");
165         expectedNetworkNode.setOrchestrationStatus("Assigned");
166         expectedNetworkNode.setModelInvariantId("b9a9b549-0ee4-49fc-b4f2-5edc6701da68");
167         expectedNetworkNode.setModelVersionId("77010093-df36-4dcb-8428-c3d02bf3f88d");
168         expectedNetworkNode.setModelCustomizationId("e5f33853-f84c-4cdd-99f2-93846957aa18");
169         expectedNetworkNode.setType(NodeType.NETWORK);
170         expectedNetworkNode.setCloudConfiguration(new CloudConfiguration("auk51a", "b530fc990b6d4334bd45518bebca6a51", "att-nc"));
171
172         buildNodeAndAssert(mockedAaiResponse, expectedNetworkNode, NodeType.NETWORK);
173     }
174
175     @Test
176     public void whenCloudRegionMissing_otherPlacementFieldsReadAsExpected() throws IOException {
177
178         AAITreeNode node = new AAITreeNode();
179         Optional<Relationship> tenantRelationShip = Optional.of(
180                 JACKSON_OBJECT_MAPPER.readValue("{" +
181                         "      \"related-to\": \"tenant\"," +
182                         "      \"relationship-label\": \"org.onap.relationships.inventory.Uses\"," +
183                         "      \"related-link\": \"/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/att-nc/auk51a/tenants/tenant/b530fc990b6d4334bd45518bebca6a51\"," +
184                         "      \"relationship-data\": [{" +
185                         "        \"relationship-key\": \"cloud-region.cloud-owner\"," +
186                         "        \"relationship-value\": \"att-nc\"" +
187                         "      }, {" +
188                         "        \"relationship-key\": \"tenant.tenant-id\"," +
189                         "        \"relationship-value\": \"b530fc990b6d4334bd45518bebca6a51\"" +
190                         "      }" +
191                         "      ]," +
192                         "      \"related-to-property\": [{" +
193                         "        \"property-key\": \"tenant.tenant-name\"," +
194                         "        \"property-value\": \"ecomp_ispt\"" +
195                         "      }" +
196                         "      ]" +
197                         "    }", Relationship.class)
198         );
199         aaiTreeNodeBuilder.enrichPlacementDataUsingTenantInfo(node, tenantRelationShip);
200         assertEquals(new CloudConfiguration(null, "b530fc990b6d4334bd45518bebca6a51", "att-nc"), node.getCloudConfiguration());
201     }
202
203     @Test
204     public void whenTenantMissing_otherPlacementFieldsReadAsExpected() throws IOException {
205
206         AAITreeNode node = new AAITreeNode();
207         Optional<Relationship> tenantRelationShip = Optional.of(
208                 JACKSON_OBJECT_MAPPER.readValue("{" +
209                         "      \"related-to\": \"tenant\"," +
210                         "      \"relationship-label\": \"org.onap.relationships.inventory.Uses\"," +
211                         "      \"related-link\": \"/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/att-nc/auk51a/tenants/tenant/b530fc990b6d4334bd45518bebca6a51\"," +
212                         "      \"relationship-data\": [{" +
213                         "        \"relationship-key\": \"cloud-region.cloud-owner\"," +
214                         "        \"relationship-value\": \"att-nc\"" +
215                         "      }, {" +
216                         "        \"relationship-key\": \"cloud-region.cloud-region-id\"," +
217                         "        \"relationship-value\": \"auk51a\"" +
218                         "      }" +
219                         "      ]," +
220                         "      \"related-to-property\": [{" +
221                         "        \"property-key\": \"tenant.tenant-name\"," +
222                         "        \"property-value\": \"ecomp_ispt\"" +
223                         "      }" +
224                         "      ]" +
225                         "    }", Relationship.class)
226         );
227         aaiTreeNodeBuilder.enrichPlacementDataUsingTenantInfo(node, tenantRelationShip);
228         assertEquals(new CloudConfiguration("auk51a", null, "att-nc"), node.getCloudConfiguration());
229     }
230
231     @Test
232     public void whenCloudOwnerMissing_otherPlacementFieldsReadAsExpected() throws IOException {
233
234         AAITreeNode node = new AAITreeNode();
235         Optional<Relationship> tenantRelationShip = Optional.of(
236                 JACKSON_OBJECT_MAPPER.readValue("{" +
237                         "      \"related-to\": \"tenant\"," +
238                         "      \"relationship-label\": \"org.onap.relationships.inventory.Uses\"," +
239                         "      \"related-link\": \"/aai/v14/cloud-infrastructure/cloud-regions/cloud-region/att-nc/auk51a/tenants/tenant/b530fc990b6d4334bd45518bebca6a51\"," +
240                         "      \"relationship-data\": [{" +
241                         "        \"relationship-key\": \"tenant.tenant-id\"," +
242                         "        \"relationship-value\": \"b530fc990b6d4334bd45518bebca6a51\"" +
243                         "      }, {" +
244                         "        \"relationship-key\": \"cloud-region.cloud-region-id\"," +
245                         "        \"relationship-value\": \"auk51a\"" +
246                         "      }" +
247                         "      ]," +
248                         "      \"related-to-property\": [{" +
249                         "        \"property-key\": \"tenant.tenant-name\"," +
250                         "        \"property-value\": \"ecomp_ispt\"" +
251                         "      }" +
252                         "      ]" +
253                         "    }", Relationship.class)
254         );
255         aaiTreeNodeBuilder.enrichPlacementDataUsingTenantInfo(node, tenantRelationShip);
256         assertEquals(new CloudConfiguration("auk51a", "b530fc990b6d4334bd45518bebca6a51",  null), node.getCloudConfiguration());
257     }
258
259     @Test
260     public void whenThereIsNoTenantRelationship_thenPlacementIsNull() throws IOException {
261         AAITreeNode node = new AAITreeNode();
262         aaiTreeNodeBuilder.enrichPlacementData(node);
263         assertNull(node.getCloudConfiguration());
264     }
265
266
267     @Test
268     public void whenReadVnfNodeWithVfModule_thenNodeIsAsExpected() throws IOException {
269         JsonNode mockedAaiGetVnfResponse = TestUtils.readJsonResourceFileAsObject("/getTopology/vnf.json", JsonNode.class);
270
271         //add mock for vfModule of the VNF
272         JsonNode mockedAaiGetVfModuleResponse = TestUtils.readJsonResourceFileAsObject("/getTopology/vfModule.json", JsonNode.class);
273         when(aaiClientMock.typedAaiGet(Unchecked.toURI("anyUrl/vf-modules"), JsonNode.class)).thenReturn(mockedAaiGetVfModuleResponse);
274
275         CloudConfiguration expectedCloudConfiguration = new CloudConfiguration("dyh3b", "c8035f5ee95d4c62bbc8074c044122b9", "irma-aic");
276
277         AAITreeNode expectedVnfNode = createExpectedVnfTreeNode(expectedCloudConfiguration);
278
279         AAITreeNode expectedVfModule = new AAITreeNode();
280         expectedVfModule.setId("2cb6d41e-2bef-4cb2-80ce-c7815bcdcf4e");
281         expectedVfModule.setName("dyh3brarf8000v_base");
282         expectedVfModule.setOrchestrationStatus("Active");
283         expectedVfModule.setModelInvariantId("3ecca473-b0c0-46ae-b0b7-bd2969d8b79f");
284         expectedVfModule.setModelVersionId("5c35b764-e266-4498-af87-a88c4ba92dc4");
285         expectedVfModule.setModelCustomizationId("06b4ece0-f6f8-4003-b445-653418292101");
286         expectedVfModule.setType(NodeType.VF_MODULE);
287         expectedVfModule.setInMaint(false);
288         expectedVfModule.setCloudConfiguration(expectedCloudConfiguration);
289
290         expectedVnfNode.addChildren(ImmutableList.of(expectedVfModule));
291
292         buildNodeAndAssert(mockedAaiGetVnfResponse, expectedVnfNode, NodeType.GENERIC_VNF);
293     }
294
295     @NotNull
296     public static AAITreeNode createExpectedVnfTreeNode(CloudConfiguration expectedCloudConfiguration) {
297         AAITreeNode expectedVnfNode = new AAITreeNode();
298         expectedVnfNode.setId("9a7a4dc1-8e5f-43fe-a360-7734c5f51382");
299         expectedVnfNode.setName("dyh3brarf8000v");
300         expectedVnfNode.setOrchestrationStatus("Active");
301         expectedVnfNode.setModelInvariantId("b711997f-36b3-4a9b-8b37-71a0fc2ebd6d");
302         expectedVnfNode.setModelVersionId("7f23e4f7-e44c-44df-b066-4cedc6950bfe");
303         expectedVnfNode.setModelCustomizationId("401350be-0f56-481c-86d8-f32d573fec26");
304         expectedVnfNode.setType(NodeType.GENERIC_VNF);
305         expectedVnfNode.setInMaint(true);
306         expectedVnfNode.setProvStatus("PREPROV");
307         expectedVnfNode.setCloudConfiguration(expectedCloudConfiguration);
308         return expectedVnfNode;
309     }
310
311     @DataProvider
312     public static Object[][] isArrayDataProvider() {
313         return new Object[][] {
314                 {"Json Array", buildArrayJson(NodeType.GENERIC_VNF), true},
315                 {"Json Object", buildOneLevelJson(NodeType.GENERIC_VNF), false},
316                 {"Json Array with another node type", buildArrayJson(NodeType.SERVICE_INSTANCE), false},
317                 {"null json", null, false}
318         };
319     }
320
321     @Test(dataProvider = "isArrayDataProvider")
322     public void IsArrayType(String description, JsonNode jsonNode, boolean expectedResult) {
323         boolean isArray = aaiTreeNodeBuilder.isArray(jsonNode, NodeType.GENERIC_VNF);
324         assertEquals(expectedResult, isArray);
325     }
326
327     @Test
328     public void jsonToAaiNodeTest() {
329         NodeType nodeType = NodeType.SERVICE_INSTANCE;
330         JsonNode node = buildOneLevelJson(nodeType);
331         ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
332
333         AAITreeNode aaiTreeNode = aaiTreeNodeBuilder.createAaiNode(nodeType, node, nodesAccumulator);
334
335         assertEquals("any-instance-id", aaiTreeNode.getId());
336         assertEquals("any-instance-name", aaiTreeNode.getName());
337         assertTrue(nodesAccumulator.contains(aaiTreeNode));
338     }
339
340     @Test
341     public void getNextLevelInPathsTreeTest() {
342         Tree<AAIServiceTree.AaiRelationship> firstLevelTree = getPathsTree();
343
344         Tree<AAIServiceTree.AaiRelationship> secondLevelTree = aaiTreeNodeBuilder.getNextLevelInPathsTree(firstLevelTree, NodeType.GENERIC_VNF.getType());
345         assertEquals(NodeType.GENERIC_VNF.getType(), secondLevelTree.getRootValue().type);
346
347         Tree<AAIServiceTree.AaiRelationship> thirdLevelTree = aaiTreeNodeBuilder.getNextLevelInPathsTree(secondLevelTree, NodeType.INSTANCE_GROUP.getType());
348         assertEquals(NodeType.INSTANCE_GROUP.getType(), thirdLevelTree.getRootValue().type);
349     }
350
351     @Test
352     public void getNextLevelInPathsTreeTest_givenIrrelevantNode_expectedNull() {
353         Tree<AAIServiceTree.AaiRelationship> pathsTree = getPathsTree();
354
355         Tree<AAIServiceTree.AaiRelationship> subTree = aaiTreeNodeBuilder.getNextLevelInPathsTree(pathsTree, NodeType.INSTANCE_GROUP.getType());
356
357         assertNull(subTree);
358     }
359
360     @Test
361     public void getRelationships_given2Relationships_expect1filtered() {
362         NodeType firstRelationship = NodeType.GENERIC_VNF;
363         NodeType secondRelationship = NodeType.INSTANCE_GROUP;
364         JsonNode jsonNode = buildOneLevelJson(NodeType.SERVICE_INSTANCE, firstRelationship, secondRelationship);
365
366         List<Relationship> relationships = aaiTreeNodeBuilder.getFilteredRelationships(jsonNode, getPathsTree());
367
368         assertEquals(1, relationships.size());
369         assertEquals(firstRelationship.getType(), relationships.get(0).getRelatedTo());
370     }
371
372     @Test
373     public void getRelationships_givenNoRelationships_expectedEmptyListTest() {
374         JsonNode jsonNode = buildOneLevelJson(NodeType.SERVICE_INSTANCE);
375
376         List<Relationship> relationships = aaiTreeNodeBuilder.getFilteredRelationships(jsonNode, getPathsTree());
377
378         assertThat(relationships, is(empty()));
379     }
380
381     @Test
382     public void getRelationships_given2RelationshipsNotExistInTreePaths_expectAllFiltered() {
383         NodeType firstRelationship = NodeType.CONFIGURATION;
384         NodeType secondRelationship = NodeType.INSTANCE_GROUP;
385         JsonNode jsonNode = buildOneLevelJson(NodeType.SERVICE_INSTANCE, firstRelationship, secondRelationship);
386
387         List<Relationship> relationships = aaiTreeNodeBuilder.getFilteredRelationships(jsonNode, getPathsTree());
388
389         assertThat(relationships, is(empty()));
390     }
391
392     @Test
393     public void aggregateAllOtherPropertiesTest() {
394         NodeType nodeType = NodeType.SERVICE_INSTANCE;
395         JsonNode jsonNode = buildOneLevelJson(nodeType, NodeType.GENERIC_VNF, NodeType.GENERIC_VNF);
396         ((ObjectNode) jsonNode).put("nf-role", "any-value");
397
398         Map<String, Object> additionalProps = aaiTreeNodeBuilder.aggregateAllOtherProperties(jsonNode, nodeType);
399         assertThat(additionalProps, is(ImmutableMap.of(
400                 "nf-role", "any-value")));
401     }
402
403     @Test
404     public void parseNodeAndFilterRelationshipsTest() {
405         NodeType nodeType = NodeType.SERVICE_INSTANCE;
406         JsonNode jsonNode = buildOneLevelJson(NodeType.SERVICE_INSTANCE, NodeType.GENERIC_VNF, NodeType.NETWORK, NodeType.VF_MODULE);
407         ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
408
409         Pair<AAITreeNode, List<Relationship>> resultNode = aaiTreeNodeBuilder.parseNodeAndFilterRelationships(jsonNode, nodeType,
410                 nodesAccumulator, getPathsTree());
411
412         assertEquals(nodeType, resultNode.getKey().getType());
413         assertEquals(2, resultNode.getValue().size());
414         assertEquals(NodeType.GENERIC_VNF.getType(), resultNode.getValue().get(0).getRelatedTo());
415         assertEquals(NodeType.NETWORK.getType(), resultNode.getValue().get(1).getRelatedTo());
416     }
417
418     @Test(expectedExceptions = GenericUncheckedException.class ,expectedExceptionsMessageRegExp = "AAI node fetching failed.")
419     public void fetchChildrenAsyncTest_given2children_expected1Ok1Timeout() {
420         ConcurrentSkipListSet<AAITreeNode> nodesAccumulator = new ConcurrentSkipListSet<>(comparing(AAITreeNode::getUniqueNodeKey));
421         ExecutorService threadPool = Executors.newFixedThreadPool(5);
422
423         AAITreeNode rootNode = createExpectedGroupNode();
424         JsonNode relationshipJson = getRelationships(NodeType.GENERIC_VNF, NodeType.NETWORK);
425         List<Relationship> relationships = mapper.convertValue(relationshipJson, RelationshipList.class).getRelationship();
426
427         when(aaiClientMock.typedAaiRest(Unchecked.toURI(relationships.get(0).getRelatedLink()), JsonNode.class, null, HttpMethod.GET, false))
428                 .thenReturn(buildOneLevelJson(NodeType.GENERIC_VNF));
429
430         when(aaiClientMock.typedAaiRest(Unchecked.toURI(relationships.get(1).getRelatedLink()), JsonNode.class, null, HttpMethod.GET, false))
431                 .thenAnswer((Answer<JsonNode>) invocation -> {
432                     Thread.sleep(2000);
433                     return buildOneLevelJson(NodeType.NETWORK);
434                 });
435
436         aaiTreeNodeBuilder.fetchChildrenAsync(threadPool, nodesAccumulator, rootNode, relationships, getPathsTree(), 1);
437
438         assertEquals(2, rootNode.getChildren().size());
439         assertEquals(NodeType.GENERIC_VNF, rootNode.getChildren().get(0).getType());
440         assertEquals(NodeType.NETWORK, rootNode.getChildren().get(1).getType());
441     }
442
443     @DataProvider
444     public Object[][] testIsListOfKeyResultsDataProvider() {
445         return new Object[][]{
446                 {"Node has results with several values",
447                         "{\"results\":[{\"l3-network\":{}},{\"l3-network\":{}},{\"l3-network\":{}}]}",
448                         true},
449                 {"Node has results with no values",
450                         "{\"results\":[]}",
451                         true},
452                 {"Node has results, but it isn't an array",
453                         "{\"results\":{\"some-field\":{}}}",
454                         false},
455                 {"Node doesn't have results",
456                         "{\"l3-network\":[{},{}]}",
457                         false},
458                 {"Node is null",
459                         "null",
460                         false},
461         };
462     }
463
464     @Test(dataProvider = "testIsListOfKeyResultsDataProvider")
465     public void testIsListOfKeyResults(String testCase, String input, boolean expectedResult) throws IOException {
466         assertEquals(testCase + ": " + input,
467                 expectedResult, aaiTreeNodeBuilder.isListOfKeyResults(new ObjectMapper().readTree(input)));
468     }
469
470     private Tree<AAIServiceTree.AaiRelationship> getPathsTree() {
471         Tree<AAIServiceTree.AaiRelationship> pathsTree = new Tree<>(new AAIServiceTree.AaiRelationship(NodeType.SERVICE_INSTANCE));
472         pathsTree.addPath(AAIServiceTree.toAaiRelationshipList(NodeType.GENERIC_VNF, NodeType.INSTANCE_GROUP));
473         pathsTree.addPath(AAIServiceTree.toAaiRelationshipList(NodeType.NETWORK));
474
475         return pathsTree;
476     }
477
478     private static JsonNode buildOneLevelJson(NodeType nodeType, NodeType...relationships) {
479         ObjectNode objectNode = mapper.createObjectNode();
480         objectNode.put(nodeType.getId(), "any-instance-id");
481         objectNode.put(nodeType.getName(), "any-instance-name");
482         if (relationships.length > 0 ) {
483             objectNode.putPOJO("relationship-list", getRelationships(relationships));
484         }
485         return objectNode;
486     }
487
488     private static JsonNode buildArrayJson(NodeType nodeType) {
489         ObjectNode objectNode = mapper.createObjectNode();
490         ArrayNode arrayNode = objectNode.putArray(nodeType.getType());
491         arrayNode.add(buildOneLevelJson(nodeType));
492         arrayNode.add(buildOneLevelJson(nodeType));
493
494         return objectNode;
495     }
496
497     private static JsonNode getRelationship(String nodeType) {
498         ObjectNode relationship = mapper.createObjectNode();
499         relationship.put("related-to", nodeType);
500         relationship.put("relationship-label", "org.onap.relationships.inventory.ComposedOf");
501         relationship.put("related-link", "/aai/v12/network/" + nodeType + "s/" + nodeType + "/cf6f60cd-808d-44e6-978b-c663e00dba8d");
502         return relationship;
503     }
504
505     private static JsonNode getRelationships(NodeType...nodeTypes) {
506         ObjectNode relationshipList = mapper.createObjectNode();
507         ArrayNode relationships = relationshipList.putArray("relationship");
508
509         for (NodeType nodeType: nodeTypes) {
510             relationships.add(getRelationship(nodeType.getType()));
511         }
512
513         return relationshipList;
514     }
515
516 }