2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2021 Nordix Foundation
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
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 * SPDX-License-Identifier: Apache-2.0
17 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.model.operations.impl;
22 import static org.assertj.core.api.Assertions.assertThat;
23 import static org.junit.jupiter.api.Assertions.assertEquals;
24 import static org.junit.jupiter.api.Assertions.assertFalse;
25 import static org.junit.jupiter.api.Assertions.assertNotNull;
26 import static org.junit.jupiter.api.Assertions.assertThrows;
27 import static org.junit.jupiter.api.Assertions.assertTrue;
28 import static org.mockito.ArgumentMatchers.any;
29 import static org.mockito.ArgumentMatchers.anyList;
30 import static org.mockito.ArgumentMatchers.anyMap;
31 import static org.mockito.ArgumentMatchers.anyString;
32 import static org.mockito.ArgumentMatchers.eq;
33 import static org.mockito.Mockito.mock;
34 import static org.mockito.Mockito.never;
35 import static org.mockito.Mockito.times;
36 import static org.mockito.Mockito.verify;
37 import static org.mockito.Mockito.when;
38 import static org.openecomp.sdc.be.model.operations.impl.ModelOperation.ADDITIONAL_TYPE_DEFINITIONS_PATH;
40 import fj.data.Either;
41 import java.io.IOException;
42 import java.nio.charset.StandardCharsets;
43 import java.nio.file.Files;
44 import java.nio.file.Path;
45 import java.util.ArrayList;
46 import java.util.Collections;
47 import java.util.HashMap;
48 import java.util.List;
50 import java.util.Optional;
51 import java.util.TreeMap;
52 import java.util.stream.Stream;
53 import org.apache.commons.lang3.tuple.ImmutablePair;
54 import org.junit.jupiter.api.BeforeAll;
55 import org.junit.jupiter.api.BeforeEach;
56 import org.junit.jupiter.api.Test;
57 import org.mockito.ArgumentCaptor;
58 import org.mockito.InjectMocks;
59 import org.mockito.Mock;
60 import org.mockito.MockitoAnnotations;
61 import org.openecomp.sdc.be.dao.api.ActionStatus;
62 import org.openecomp.sdc.be.dao.cassandra.ToscaModelImportCassandraDao;
63 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
64 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
65 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
66 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
67 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
68 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
69 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
70 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
71 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
72 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
73 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
74 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
75 import org.openecomp.sdc.be.model.Model;
76 import org.openecomp.sdc.be.model.ModelTestBase;
77 import org.openecomp.sdc.be.model.dto.PropertyDefinitionDto;
78 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ModelOperationExceptionSupplier;
79 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
80 import org.openecomp.sdc.be.model.normatives.ElementTypeEnum;
81 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
82 import org.openecomp.sdc.be.resources.data.ModelData;
83 import org.springframework.test.context.ContextConfiguration;
85 @ContextConfiguration("classpath:application-context-test.xml")
86 class ModelOperationTest extends ModelTestBase {
88 private static final String modelName = "ETSI-SDC-MODEL-TEST";
90 private ModelOperation modelOperation;
92 private JanusGraphGenericDao janusGraphGenericDao;
94 private JanusGraphDao janusGraphDao;
96 private ToscaModelImportCassandraDao toscaModelImportCassandraDao;
98 private DerivedFromOperation derivedFromOperation;
101 static void beforeAllInit() {
106 void beforeEachInit() {
107 MockitoAnnotations.openMocks(this);
111 void createModelSuccessTest() {
112 final ModelData modelData = new ModelData(modelName, UniqueIdBuilder.buildModelUid(modelName), ModelTypeEnum.NORMATIVE);
113 when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.left(modelData));
114 final Model createdModel = modelOperation.createModel(new Model(modelName, ModelTypeEnum.NORMATIVE), false);
115 assertThat(createdModel).isNotNull();
116 assertThat(createdModel.getName()).isEqualTo(modelName);
120 void createDerivedModelSuccessTest() {
121 final String derivedModelName = "derivedModel";
122 final ModelData modelData = new ModelData(derivedModelName, UniqueIdBuilder.buildModelUid(derivedModelName), ModelTypeEnum.NORMATIVE);
123 when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.left(modelData));
125 final GraphVertex modelVertex = new GraphVertex();
126 modelVertex.addMetadataProperty(GraphPropertyEnum.NAME, "baseModel");
127 modelVertex.addMetadataProperty(GraphPropertyEnum.MODEL_TYPE, ModelTypeEnum.NORMATIVE.getValue());
128 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), anyMap())).thenReturn(Either.left(Collections.singletonList(modelVertex)));
129 when(janusGraphGenericDao.getChild(eq("uid"), anyString(), eq(GraphEdgeLabels.DERIVED_FROM), eq(NodeTypeEnum.Model),
130 eq(ModelData.class))).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
131 when(derivedFromOperation.addDerivedFromRelation("model.derivedModel", "model.baseModel", NodeTypeEnum.Model)).thenReturn(
132 Either.left(new GraphRelation()));
134 final Model createdModel = modelOperation.createModel(new Model(derivedModelName, modelName, ModelTypeEnum.NORMATIVE), false);
135 assertThat(createdModel).isNotNull();
136 assertThat(createdModel.getName()).isEqualTo(derivedModelName);
140 void createModelFailWithModelAlreadyExistTest() {
141 when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.right(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION));
142 final var model = new Model(modelName, ModelTypeEnum.NORMATIVE);
143 assertThrows(OperationException.class, () -> modelOperation.createModel(model, false));
147 void createModelFailTest() {
148 when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.right(JanusGraphOperationStatus.GRAPH_IS_NOT_AVAILABLE));
149 final var model = new Model(modelName, ModelTypeEnum.NORMATIVE);
150 assertThrows(OperationException.class, () -> modelOperation.createModel(model, false));
154 void createModelImportsSuccessTest() {
155 var modelId = "modelId";
156 var contentEntry1 = "contentEntry1";
157 var pathEntry1 = "entry1";
158 var contentEntry2 = "contentEntry2";
159 var pathEntry2 = "entry2/path";
160 final Map<String, byte[]> zipContent = new TreeMap<>();
161 zipContent.put(pathEntry1, contentEntry1.getBytes(StandardCharsets.UTF_8));
162 zipContent.put(pathEntry2, contentEntry2.getBytes(StandardCharsets.UTF_8));
164 modelOperation.createModelImports(modelId, zipContent);
166 final var toscaImport1 = new ToscaImportByModel();
167 toscaImport1.setModelId(modelId);
168 toscaImport1.setContent(contentEntry1);
169 toscaImport1.setFullPath(pathEntry1);
170 final var toscaImport2 = new ToscaImportByModel();
171 toscaImport2.setModelId(modelId);
172 toscaImport2.setContent(contentEntry2);
173 toscaImport2.setFullPath(pathEntry2);
174 final List<ToscaImportByModel> toscaImportByModelList = List.of(toscaImport1, toscaImport2);
176 verify(toscaModelImportCassandraDao).replaceImports(modelId, toscaImportByModelList);
180 void createModelImportsTest_emptyZipContent() {
181 var modelId = "modelId";
182 modelOperation.createModelImports(modelId, Collections.emptyMap());
183 verify(toscaModelImportCassandraDao, never()).replaceImports(eq(modelId), anyList());
184 modelOperation.createModelImports(modelId, null);
185 verify(toscaModelImportCassandraDao, never()).replaceImports(eq(null), anyList());
189 void findModelVertexSuccessTest() {
190 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
191 final GraphVertex expectedVertex = new GraphVertex();
192 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture())).thenReturn(Either.left(List.of(expectedVertex)));
193 var modelName = "modelName";
194 final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
195 assertTrue(modelVertexByNameOpt.isPresent());
196 assertEquals(expectedVertex, modelVertexByNameOpt.get());
197 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
198 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
199 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
203 void findModelVertexTest_modelNotFound() {
204 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
205 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
206 .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
207 var modelName = "modelName";
209 final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
211 assertTrue(modelVertexByNameOpt.isEmpty());
212 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
213 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
214 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
218 void findModelVertexTest_janusGraphError() {
219 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
220 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
221 .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
222 var modelName = "modelName";
224 final var actualException = assertThrows(OperationException.class, () -> modelOperation.findModelVertexByName(modelName));
226 assertEquals(ActionStatus.GENERAL_ERROR, actualException.getActionStatus());
227 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
228 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
229 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
233 void findModelVertexTest_emptyOrNullModelName() {
234 assertTrue(modelOperation.findModelVertexByName("").isEmpty());
235 assertTrue(modelOperation.findModelVertexByName(null).isEmpty());
239 void findModelByNameSuccessTest() {
240 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
241 var modelName = "modelName";
242 final GraphVertex expectedVertex = mock(GraphVertex.class);
243 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
244 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE.getValue());
245 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture())).thenReturn(Either.left(List.of(expectedVertex)));
246 when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
247 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
248 final Optional<Model> modelByNameOpt = modelOperation.findModelByName(modelName);
250 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
251 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
252 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
254 final Model expectedModel = new Model(modelName, ModelTypeEnum.NORMATIVE);
255 assertTrue(modelByNameOpt.isPresent());
256 assertEquals(expectedModel, modelByNameOpt.get());
260 void findModelByNameTest_modelNameNotFound() {
261 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
262 var modelName = "modelName";
263 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
264 .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
265 final Optional<Model> modelByNameOpt = modelOperation.findModelByName(modelName);
266 assertTrue(modelByNameOpt.isEmpty());
270 void findModelByNameTest_emptyOrNullModelName() {
271 assertTrue(modelOperation.findModelByName("").isEmpty());
272 assertTrue(modelOperation.findModelByName(null).isEmpty());
276 void findAllModelsSuccessTest() {
277 final GraphVertex expectedVertex = mock(GraphVertex.class);
278 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
279 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE.getValue());
280 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap())).thenReturn(Either.left(List.of(expectedVertex)));
281 when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
282 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
284 final List<Model> actualModelList = modelOperation.findAllModels();
285 assertFalse(actualModelList.isEmpty());
286 assertEquals(1, actualModelList.size());
287 assertEquals(modelName, actualModelList.get(0).getName());
291 void findAllModelsTest_noModelsFound() {
292 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap())).thenReturn(Either.left(Collections.emptyList()));
293 final List<Model> actualModelList = modelOperation.findAllModels();
294 assertTrue(actualModelList.isEmpty());
298 void findAllModelsTest_janusGraphNotFound() {
299 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap()))
300 .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
301 final List<Model> actualModelList = modelOperation.findAllModels();
302 assertTrue(actualModelList.isEmpty());
306 void findAllModelsTest_janusGraphError() {
307 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap()))
308 .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
309 final var actualException = assertThrows(OperationException.class, () -> modelOperation.findAllModels());
310 final var expectedException = ModelOperationExceptionSupplier.failedToRetrieveModels(JanusGraphOperationStatus.GENERAL_ERROR).get();
311 assertEquals(expectedException.getMessage(), actualException.getMessage());
315 void findAllModelImportsTest() {
317 final var modelName = "modelName";
318 final var parentModelName = "parentModelName";
319 final GraphVertex expectedVertex = mock(GraphVertex.class);
320 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
321 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE_EXTENSION.getValue());
322 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), anyMap())).thenReturn(Either.left(List.of(expectedVertex)));
324 final var modelData = new ModelData(parentModelName, parentModelName, ModelTypeEnum.NORMATIVE);
325 final ImmutablePair<ModelData, GraphEdge> modelDataGraphEdgePair = new ImmutablePair<>(modelData, null);
327 when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
328 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.left(modelDataGraphEdgePair));
330 final ArrayList<ToscaImportByModel> childModelImportList = new ArrayList<>();
331 childModelImportList.add(createModelImport(modelName, "anyPath1"));
332 childModelImportList.add(createModelImport(modelName, "anyPath2"));
333 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(new ArrayList<>(childModelImportList));
334 final ArrayList<ToscaImportByModel> parentModelImportList = new ArrayList<>();
335 parentModelImportList.add(createModelImport(parentModelName, "anyPath1"));
336 parentModelImportList.add(createModelImport(parentModelName, "anyPath2"));
337 when(toscaModelImportCassandraDao.findAllByModel(parentModelName)).thenReturn(parentModelImportList);
340 final List<ToscaImportByModel> actualModelImportList = modelOperation.findAllModelImports(modelName, true);
343 assertFalse(actualModelImportList.isEmpty());
344 assertEquals(childModelImportList.size() + parentModelImportList.size(), actualModelImportList.size());
345 Stream.concat(childModelImportList.stream(), parentModelImportList.stream())
346 .forEach(toscaImportByModel -> assertTrue(actualModelImportList.contains(toscaImportByModel)));
350 void addTypesToDefaultImportsTest_nonExistingAdditionalTypesImport() throws IOException {
351 var modelName = "model";
352 final Path testResourcePath = Path.of("src/test/resources/modelOperation");
354 final var dataTypesPath = testResourcePath.resolve(Path.of("input-data_types.yaml"));
355 final var dataTypes = Files.readString(dataTypesPath);
357 final Path import1RelativePath = Path.of("original-import-1.yaml");
358 final Path import1Path = testResourcePath.resolve(import1RelativePath);
359 final Path import2RelativePath = Path.of("original-import-2.yaml");
360 final Path import2Path = testResourcePath.resolve(import2RelativePath);
362 var toscaImportByModel1 = new ToscaImportByModel();
363 toscaImportByModel1.setModelId(modelName);
364 toscaImportByModel1.setFullPath(import1RelativePath.toString());
365 toscaImportByModel1.setContent(Files.readString(import1Path));
367 var toscaImportByModel2 = new ToscaImportByModel();
368 toscaImportByModel2.setModelId(modelName);
369 toscaImportByModel2.setFullPath(import2RelativePath.toString());
370 toscaImportByModel2.setContent(Files.readString(import2Path));
372 final List<ToscaImportByModel> modelImports = new ArrayList<>();
373 modelImports.add(toscaImportByModel1);
374 modelImports.add(toscaImportByModel2);
375 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
377 modelOperation.addTypesToDefaultImports(ElementTypeEnum.DATA_TYPE, dataTypes, modelName);
378 ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
379 verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
381 final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
382 assertEquals(3, actualImportList.size());
383 assertTrue(actualImportList.contains(toscaImportByModel1));
384 assertTrue(actualImportList.contains(toscaImportByModel2));
386 var expectedAdditionalTypesImport = new ToscaImportByModel();
387 expectedAdditionalTypesImport.setModelId(modelName);
388 expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
389 expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-1.yaml"))));
390 final ToscaImportByModel actualAdditionalTypesImport =
391 actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
392 assertNotNull(actualAdditionalTypesImport);
393 assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
395 var expectedImport1 = new ToscaImportByModel();
396 expectedImport1.setModelId(modelName);
397 expectedImport1.setFullPath(import1RelativePath.toString());
398 expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-1.yaml"))));
399 final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
400 assertNotNull(actualImport1);
401 assertEquals(expectedImport1.getContent(), actualImport1.getContent());
403 var expectedImport2 = new ToscaImportByModel();
404 expectedImport2.setModelId(modelName);
405 expectedImport2.setFullPath(import2RelativePath.toString());
406 expectedImport2.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-2.yaml"))));
407 final ToscaImportByModel actualImport2 = actualImportList.stream().filter(expectedImport2::equals).findFirst().orElse(null);
408 assertNotNull(actualImport2);
409 assertEquals(expectedImport2.getContent(), actualImport2.getContent());
413 void addArtifactsToDefaultImportsTest_nonExistingAdditionalTypesImport() throws IOException {
414 var modelName = "model";
415 final Path testResourcePath = Path.of("src/test/resources/modelOperation");
417 final var dataTypesPath = testResourcePath.resolve(Path.of("input-artifact_types.yaml"));
418 final var dataTypes = Files.readString(dataTypesPath);
420 final Path import1RelativePath = Path.of("original-import-3.yaml");
421 final Path import1Path = testResourcePath.resolve(import1RelativePath);
423 var toscaImportByModel1 = new ToscaImportByModel();
424 toscaImportByModel1.setModelId(modelName);
425 toscaImportByModel1.setFullPath(import1RelativePath.toString());
426 toscaImportByModel1.setContent(Files.readString(import1Path));
428 final List<ToscaImportByModel> modelImports = new ArrayList<>();
429 modelImports.add(toscaImportByModel1);
430 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
432 modelOperation.addTypesToDefaultImports(ElementTypeEnum.ARTIFACT_TYPE, dataTypes, modelName);
433 ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
434 verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
436 final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
437 assertEquals(2, actualImportList.size());
438 assertTrue(actualImportList.contains(toscaImportByModel1));
440 var expectedAdditionalTypesImport = new ToscaImportByModel();
441 expectedAdditionalTypesImport.setModelId(modelName);
442 expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
443 expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-3.yaml"))));
444 final ToscaImportByModel actualAdditionalTypesImport =
445 actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
446 assertNotNull(actualAdditionalTypesImport);
447 assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
449 var expectedImport1 = new ToscaImportByModel();
450 expectedImport1.setModelId(modelName);
451 expectedImport1.setFullPath(import1RelativePath.toString());
452 expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-3.yaml"))));
453 final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
454 assertNotNull(actualImport1);
455 assertEquals(expectedImport1.getContent(), actualImport1.getContent());
460 void addTypesToDefaultImportsTest_existingAdditionalTypesImport() throws IOException {
461 var modelName = "model";
462 final Path testResourcePath = Path.of("src/test/resources/modelOperation");
464 final var dataTypesPath = testResourcePath.resolve(Path.of("input-data_types.yaml"));
465 final var dataTypes = Files.readString(dataTypesPath);
467 final Path import1RelativePath = Path.of("original-import-1.yaml");
468 final Path import1Path = testResourcePath.resolve(import1RelativePath);
470 var toscaImportByModel1 = new ToscaImportByModel();
471 toscaImportByModel1.setModelId(modelName);
472 toscaImportByModel1.setFullPath(import1RelativePath.toString());
473 toscaImportByModel1.setContent(Files.readString(import1Path));
475 var originalAdditionalTypesImport = new ToscaImportByModel();
476 originalAdditionalTypesImport.setModelId(modelName);
477 originalAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
478 final Path originalAdditionalTypesImportPath = testResourcePath.resolve(Path.of("original-additional_types-1.yaml"));
479 originalAdditionalTypesImport.setContent(Files.readString(originalAdditionalTypesImportPath));
481 final List<ToscaImportByModel> modelImports = new ArrayList<>();
482 modelImports.add(toscaImportByModel1);
483 modelImports.add(originalAdditionalTypesImport);
484 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
486 modelOperation.addTypesToDefaultImports(ElementTypeEnum.DATA_TYPE, dataTypes, modelName);
487 ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
488 verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
490 final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
491 assertEquals(2, actualImportList.size());
492 assertTrue(actualImportList.contains(toscaImportByModel1));
494 var expectedAdditionalTypesImport = new ToscaImportByModel();
495 expectedAdditionalTypesImport.setModelId(modelName);
496 expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
497 expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-2.yaml"))));
498 final ToscaImportByModel actualAdditionalTypesImport =
499 actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
500 assertNotNull(actualAdditionalTypesImport);
501 assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
503 var expectedImport1 = new ToscaImportByModel();
504 expectedImport1.setModelId(modelName);
505 expectedImport1.setFullPath(import1RelativePath.toString());
506 expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-1.yaml"))));
507 final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
508 assertNotNull(actualImport1);
509 assertEquals(expectedImport1.getContent(), actualImport1.getContent());
511 // Update the added additional type
512 final var updatedDataTypesPath = testResourcePath.resolve(Path.of("input-data_types-updated.yaml"));
513 final var updatedDataTypes = Files.readString(updatedDataTypesPath);
514 modelOperation.updateTypesInAdditionalTypesImport(ElementTypeEnum.DATA_TYPE, updatedDataTypes, modelName);
516 ArgumentCaptor<List<ToscaImportByModel>> updatedImportListArgumentCaptor = ArgumentCaptor.forClass(List.class);
517 verify(toscaModelImportCassandraDao, times(2)).saveAll(eq(modelName), updatedImportListArgumentCaptor.capture());
519 final List<ToscaImportByModel> updatedActualImportList = updatedImportListArgumentCaptor.getValue();
520 assertEquals(2, updatedActualImportList.size());
522 var expectedUpdatedAdditionalTypesImport = new ToscaImportByModel();
523 expectedUpdatedAdditionalTypesImport.setModelId(modelName);
524 expectedUpdatedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
525 expectedUpdatedAdditionalTypesImport.setContent(
526 Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-2-updated.yaml"))));
527 final ToscaImportByModel actualUpdatedAdditionalTypesImport =
528 actualImportList.stream().filter(expectedUpdatedAdditionalTypesImport::equals).findFirst().orElse(null);
529 assertNotNull(actualUpdatedAdditionalTypesImport);
531 assertTrue(actualUpdatedAdditionalTypesImport.getContent().contains("added_property_1"));
532 assertTrue(actualUpdatedAdditionalTypesImport.getContent().contains("added_property_2"));
536 void addArtifactsToDefaultImportsTest_existingAdditionalTypesImport() throws IOException {
537 var modelName = "model";
538 final Path testResourcePath = Path.of("src/test/resources/modelOperation");
540 final var dataTypesPath = testResourcePath.resolve(Path.of("input-artifact_types.yaml"));
541 final var dataTypes = Files.readString(dataTypesPath);
543 final Path import1RelativePath = Path.of("original-import-3.yaml");
544 final Path import1Path = testResourcePath.resolve(import1RelativePath);
546 var toscaImportByModel1 = new ToscaImportByModel();
547 toscaImportByModel1.setModelId(modelName);
548 toscaImportByModel1.setFullPath(import1RelativePath.toString());
549 toscaImportByModel1.setContent(Files.readString(import1Path));
551 var originalAdditionalTypesImport = new ToscaImportByModel();
552 originalAdditionalTypesImport.setModelId(modelName);
553 originalAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
554 final Path originalAdditionalTypesImportPath = testResourcePath.resolve(Path.of("original-additional_types-2.yaml"));
555 originalAdditionalTypesImport.setContent(Files.readString(originalAdditionalTypesImportPath));
557 final List<ToscaImportByModel> modelImports = new ArrayList<>();
558 modelImports.add(toscaImportByModel1);
559 modelImports.add(originalAdditionalTypesImport);
560 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
562 modelOperation.addTypesToDefaultImports(ElementTypeEnum.ARTIFACT_TYPE, dataTypes, modelName);
563 ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
564 verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
566 final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
567 assertEquals(2, actualImportList.size());
568 assertTrue(actualImportList.contains(toscaImportByModel1));
570 var expectedAdditionalTypesImport = new ToscaImportByModel();
571 expectedAdditionalTypesImport.setModelId(modelName);
572 expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
573 expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-3.yaml"))));
574 final ToscaImportByModel actualAdditionalTypesImport =
575 actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
576 assertNotNull(actualAdditionalTypesImport);
577 assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
579 var expectedImport1 = new ToscaImportByModel();
580 expectedImport1.setModelId(modelName);
581 expectedImport1.setFullPath(import1RelativePath.toString());
582 expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-3.yaml"))));
583 final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
584 assertNotNull(actualImport1);
585 assertEquals(expectedImport1.getContent(), actualImport1.getContent());
590 void addPropertyToExistingAdditionalType() throws IOException {
591 var modelName = "model";
592 final Path testResourcePath = Path.of("src/test/resources/modelOperation");
594 var originalAdditionalTypesImport = new ToscaImportByModel();
595 originalAdditionalTypesImport.setModelId(modelName);
596 originalAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
597 final Path originalAdditionalTypesImportPath = testResourcePath.resolve(Path.of("original-additional_types-1.yaml"));
598 originalAdditionalTypesImport.setContent(Files.readString(originalAdditionalTypesImportPath));
600 final List<ToscaImportByModel> modelImports = new ArrayList<>();
601 modelImports.add(originalAdditionalTypesImport);
602 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
604 PropertyDefinitionDto property = new PropertyDefinitionDto();
605 property.setName("addedMapProperty");
606 property.setType("map");
607 property.setSchemaType("string");
608 property.setDescription("This is a description");
609 Map<Object, Object> defaultValue = new HashMap<>();
610 defaultValue.put("k1", "v1");
611 defaultValue.put("k2", "v2");
612 property.setDefaultValue(defaultValue);
613 property.setRequired(true);
615 String dataTypeName = "tosca.datatypes.nfv.PreviouslyExistingType1";
616 modelOperation.updatePropertyInAdditionalType(ElementTypeEnum.DATA_TYPE, property, modelName, dataTypeName, true);
617 ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
618 verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
620 final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
621 assertEquals(1, actualImportList.size());
623 var expectedAdditionalTypesImport = new ToscaImportByModel();
624 expectedAdditionalTypesImport.setModelId(modelName);
625 expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
626 expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-4.yaml"))));
627 final ToscaImportByModel actualAdditionalTypesImport =
628 actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
629 assertNotNull(actualAdditionalTypesImport);
630 assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
633 private ToscaImportByModel createModelImport(final String parentModelName, final String importPath) {
634 var toscaImportByModel = new ToscaImportByModel();
635 toscaImportByModel.setModelId(parentModelName);
636 toscaImportByModel.setFullPath(importPath);
637 return toscaImportByModel;