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=========================================================
19 package org.openecomp.sdc.be.model.operations.impl;
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertThrows;
25 import static org.junit.jupiter.api.Assertions.assertTrue;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.anyList;
28 import static org.mockito.ArgumentMatchers.anyMap;
29 import static org.mockito.ArgumentMatchers.anyString;
30 import static org.mockito.ArgumentMatchers.eq;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.never;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
36 import fj.data.Either;
37 import java.nio.charset.StandardCharsets;
38 import java.util.ArrayList;
39 import java.util.Collections;
40 import java.util.List;
42 import java.util.Optional;
43 import java.util.TreeMap;
44 import java.util.stream.Stream;
45 import org.apache.commons.lang3.tuple.ImmutablePair;
46 import org.junit.jupiter.api.BeforeAll;
47 import org.junit.jupiter.api.BeforeEach;
48 import org.junit.jupiter.api.Test;
49 import org.mockito.ArgumentCaptor;
50 import org.mockito.InjectMocks;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 import org.openecomp.sdc.be.dao.api.ActionStatus;
54 import org.openecomp.sdc.be.dao.cassandra.ToscaModelImportCassandraDao;
55 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
56 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
57 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
58 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
59 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
60 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
61 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
62 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
63 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
64 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
65 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
66 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
67 import org.openecomp.sdc.be.model.Model;
68 import org.openecomp.sdc.be.model.ModelTestBase;
69 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ModelOperationExceptionSupplier;
70 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
71 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
72 import org.openecomp.sdc.be.resources.data.ModelData;
73 import org.springframework.test.context.ContextConfiguration;
75 @ContextConfiguration("classpath:application-context-test.xml")
76 class ModelOperationTest extends ModelTestBase {
79 private ModelOperation modelOperation;
81 private JanusGraphGenericDao janusGraphGenericDao;
83 private JanusGraphDao janusGraphDao;
85 private ToscaModelImportCassandraDao toscaModelImportCassandraDao;
87 private DerivedFromOperation derivedFromOperation;
89 private final String modelName = "ETSI-SDC-MODEL-TEST";
92 static void beforeAllInit() {
97 void beforeEachInit() {
98 MockitoAnnotations.openMocks(this);
102 void createModelSuccessTest() {
103 final ModelData modelData = new ModelData(modelName, UniqueIdBuilder.buildModelUid(modelName), ModelTypeEnum.NORMATIVE);
104 when(janusGraphGenericDao.createNode(any(),any())).thenReturn(Either.left(modelData));
105 final Model createdModel = modelOperation.createModel(new Model(modelName, ModelTypeEnum.NORMATIVE), false);
106 assertThat(createdModel).isNotNull();
107 assertThat(createdModel.getName()).isEqualTo(modelName);
111 void createDerivedModelSuccessTest() {
112 final String derivedModelName = "derivedModel";
113 final ModelData modelData = new ModelData(derivedModelName, UniqueIdBuilder.buildModelUid(derivedModelName), ModelTypeEnum.NORMATIVE);
114 when(janusGraphGenericDao.createNode(any(),any())).thenReturn(Either.left(modelData));
116 final GraphVertex modelVertex = new GraphVertex();
117 modelVertex.addMetadataProperty(GraphPropertyEnum.NAME, "baseModel");
118 modelVertex.addMetadataProperty(GraphPropertyEnum.MODEL_TYPE, ModelTypeEnum.NORMATIVE.getValue());
119 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), anyMap())).thenReturn(Either.left(Collections.singletonList(modelVertex)));
120 when(janusGraphGenericDao.getChild(eq("uid"), anyString(), eq(GraphEdgeLabels.DERIVED_FROM), eq(NodeTypeEnum.Model), eq(ModelData.class))).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
121 when(derivedFromOperation.addDerivedFromRelation("model.derivedModel", "model.baseModel", NodeTypeEnum.Model)).thenReturn(Either.left(new GraphRelation()));
123 final Model createdModel = modelOperation.createModel(new Model(derivedModelName, modelName, ModelTypeEnum.NORMATIVE), false);
124 assertThat(createdModel).isNotNull();
125 assertThat(createdModel.getName()).isEqualTo(derivedModelName);
129 void createModelFailWithModelAlreadyExistTest() {
130 when(janusGraphGenericDao.createNode(any(),any())).thenReturn(Either.right(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION));
131 final var model = new Model(modelName, ModelTypeEnum.NORMATIVE);
132 assertThrows(OperationException.class, () -> modelOperation.createModel(model, false));
136 void createModelFailTest() {
137 when(janusGraphGenericDao.createNode(any(),any())).thenReturn(Either.right(JanusGraphOperationStatus.GRAPH_IS_NOT_AVAILABLE));
138 final var model = new Model(modelName, ModelTypeEnum.NORMATIVE);
139 assertThrows(OperationException.class, () -> modelOperation.createModel(model, false));
143 void createModelImportsSuccessTest() {
144 var modelId = "modelId";
145 var contentEntry1 = "contentEntry1";
146 var pathEntry1 = "entry1";
147 var contentEntry2 = "contentEntry2";
148 var pathEntry2 = "entry2/path";
149 final Map<String, byte[]> zipContent = new TreeMap<>();
150 zipContent.put(pathEntry1, contentEntry1.getBytes(StandardCharsets.UTF_8));
151 zipContent.put(pathEntry2, contentEntry2.getBytes(StandardCharsets.UTF_8));
153 modelOperation.createModelImports(modelId, zipContent);
155 final var toscaImport1 = new ToscaImportByModel();
156 toscaImport1.setModelId(modelId);
157 toscaImport1.setContent(contentEntry1);
158 toscaImport1.setFullPath(pathEntry1);
159 final var toscaImport2 = new ToscaImportByModel();
160 toscaImport2.setModelId(modelId);
161 toscaImport2.setContent(contentEntry2);
162 toscaImport2.setFullPath(pathEntry2);
163 final List<ToscaImportByModel> toscaImportByModelList = List.of(toscaImport1, toscaImport2);
165 verify(toscaModelImportCassandraDao).importAll(modelId, toscaImportByModelList);
169 void createModelImportsTest_emptyZipContent() {
170 var modelId = "modelId";
171 modelOperation.createModelImports(modelId, Collections.emptyMap());
172 verify(toscaModelImportCassandraDao, never()).importAll(eq(modelId), anyList());
173 modelOperation.createModelImports(modelId, null);
174 verify(toscaModelImportCassandraDao, never()).importAll(eq(null), anyList());
178 void findModelVertexSuccessTest() {
179 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
180 final GraphVertex expectedVertex = new GraphVertex();
181 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture())).thenReturn(Either.left(List.of(expectedVertex)));
182 var modelName = "modelName";
183 final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
184 assertTrue(modelVertexByNameOpt.isPresent());
185 assertEquals(expectedVertex, modelVertexByNameOpt.get());
186 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
187 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
188 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
192 void findModelVertexTest_modelNotFound() {
193 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
194 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
195 .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
196 var modelName = "modelName";
198 final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
200 assertTrue(modelVertexByNameOpt.isEmpty());
201 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
202 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
203 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
207 void findModelVertexTest_janusGraphError() {
208 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
209 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
210 .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
211 var modelName = "modelName";
213 final var actualException = assertThrows(OperationException.class, () -> modelOperation.findModelVertexByName(modelName));
215 assertEquals(ActionStatus.GENERAL_ERROR, actualException.getActionStatus());
216 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
217 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
218 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
222 void findModelVertexTest_emptyOrNullModelName() {
223 assertTrue(modelOperation.findModelVertexByName("").isEmpty());
224 assertTrue(modelOperation.findModelVertexByName(null).isEmpty());
228 void findModelByNameSuccessTest() {
229 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
230 var modelName = "modelName";
231 final GraphVertex expectedVertex = mock(GraphVertex.class);
232 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
233 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE.getValue());
234 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture())).thenReturn(Either.left(List.of(expectedVertex)));
235 when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
236 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
237 final Optional<Model> modelByNameOpt = modelOperation.findModelByName(modelName);
239 final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
240 assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
241 assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
243 final Model expectedModel = new Model(modelName, ModelTypeEnum.NORMATIVE);
244 assertTrue(modelByNameOpt.isPresent());
245 assertEquals(expectedModel, modelByNameOpt.get());
249 void findModelByNameTest_modelNameNotFound() {
250 final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
251 var modelName = "modelName";
252 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
253 .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
254 final Optional<Model> modelByNameOpt = modelOperation.findModelByName(modelName);
255 assertTrue(modelByNameOpt.isEmpty());
259 void findModelByNameTest_emptyOrNullModelName() {
260 assertTrue(modelOperation.findModelByName("").isEmpty());
261 assertTrue(modelOperation.findModelByName(null).isEmpty());
265 void findAllModelsSuccessTest() {
266 final GraphVertex expectedVertex = mock(GraphVertex.class);
267 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
268 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE.getValue());
269 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap())).thenReturn(Either.left(List.of(expectedVertex)));
270 when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
271 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
273 final List<Model> actualModelList = modelOperation.findAllModels();
274 assertFalse(actualModelList.isEmpty());
275 assertEquals(1, actualModelList.size());
276 assertEquals(modelName, actualModelList.get(0).getName());
280 void findAllModelsTest_noModelsFound() {
281 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap())).thenReturn(Either.left(Collections.emptyList()));
282 final List<Model> actualModelList = modelOperation.findAllModels();
283 assertTrue(actualModelList.isEmpty());
287 void findAllModelsTest_janusGraphNotFound() {
288 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap()))
289 .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
290 final List<Model> actualModelList = modelOperation.findAllModels();
291 assertTrue(actualModelList.isEmpty());
295 void findAllModelsTest_janusGraphError() {
296 when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap()))
297 .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
298 final var actualException = assertThrows(OperationException.class, () -> modelOperation.findAllModels());
299 final var expectedException = ModelOperationExceptionSupplier.failedToRetrieveModels(JanusGraphOperationStatus.GENERAL_ERROR).get();
300 assertEquals(expectedException.getMessage(), actualException.getMessage());
304 void findAllModelImportsTest() {
306 final var modelName = "modelName";
307 final var parentModelName = "parentModelName";
308 final GraphVertex expectedVertex = mock(GraphVertex.class);
309 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
310 when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE_EXTENSION.getValue());
311 when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), anyMap())).thenReturn(Either.left(List.of(expectedVertex)));
313 final var modelData = new ModelData(parentModelName, parentModelName, ModelTypeEnum.NORMATIVE);
314 final ImmutablePair<ModelData, GraphEdge> modelDataGraphEdgePair = new ImmutablePair<>(modelData, null);
316 when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
317 GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.left(modelDataGraphEdgePair));
319 final ArrayList<ToscaImportByModel> childModelImportList = new ArrayList<>();
320 childModelImportList.add(createModelImport(modelName, "anyPath1"));
321 childModelImportList.add(createModelImport(modelName, "anyPath2"));
322 when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(new ArrayList<>(childModelImportList));
323 final ArrayList<ToscaImportByModel> parentModelImportList = new ArrayList<>();
324 parentModelImportList.add(createModelImport(parentModelName, "anyPath1"));
325 parentModelImportList.add(createModelImport(parentModelName, "anyPath2"));
326 when(toscaModelImportCassandraDao.findAllByModel(parentModelName)).thenReturn(parentModelImportList);
329 final List<ToscaImportByModel> actualModelImportList = modelOperation.findAllModelImports(modelName, true);
332 assertFalse(actualModelImportList.isEmpty());
333 assertEquals(childModelImportList.size() + parentModelImportList.size(), actualModelImportList.size());
334 Stream.concat(childModelImportList.stream(), parentModelImportList.stream())
335 .forEach(toscaImportByModel -> assertTrue(actualModelImportList.contains(toscaImportByModel)));
338 private ToscaImportByModel createModelImport(final String parentModelName, final String importPath) {
339 var toscaImportByModel = new ToscaImportByModel();
340 toscaImportByModel.setModelId(parentModelName);
341 toscaImportByModel.setFullPath(importPath);
342 return toscaImportByModel;