Include custom data types from VSP in csar imports
[sdc.git] / catalog-model / src / test / java / org / openecomp / sdc / be / model / operations / impl / ModelOperationTest.java
1 /*
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
8  *
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.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19 package org.openecomp.sdc.be.model.operations.impl;
20
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;
35
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;
41 import java.util.Map;
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;
74
75 @ContextConfiguration("classpath:application-context-test.xml")
76 class ModelOperationTest extends ModelTestBase {
77
78     @InjectMocks
79     private ModelOperation modelOperation;
80     @Mock
81     private JanusGraphGenericDao janusGraphGenericDao;
82     @Mock
83     private JanusGraphDao janusGraphDao;
84     @Mock
85     private ToscaModelImportCassandraDao toscaModelImportCassandraDao;
86     @Mock
87     private DerivedFromOperation derivedFromOperation;
88
89     private final String modelName = "ETSI-SDC-MODEL-TEST";
90
91     @BeforeAll
92     static void beforeAllInit() {
93         init();
94     }
95
96     @BeforeEach
97     void beforeEachInit() {
98         MockitoAnnotations.openMocks(this);
99     }
100
101     @Test
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);
108     }
109     
110     @Test
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));
115         
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()));
122         
123         final Model createdModel = modelOperation.createModel(new Model(derivedModelName, modelName, ModelTypeEnum.NORMATIVE), false);
124         assertThat(createdModel).isNotNull();
125         assertThat(createdModel.getName()).isEqualTo(derivedModelName);
126     }
127
128     @Test
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));
133     }
134
135     @Test
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));
140     }
141
142     @Test
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));
152
153         modelOperation.createModelImports(modelId, zipContent);
154
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);
164
165         verify(toscaModelImportCassandraDao).importAll(modelId, toscaImportByModelList);
166     }
167
168     @Test
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());
175     }
176
177     @Test
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));
189     }
190
191     @Test
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";
197
198         final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
199
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));
204     }
205
206     @Test
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";
212
213         final var actualException = assertThrows(OperationException.class, () -> modelOperation.findModelVertexByName(modelName));
214
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));
219     }
220
221     @Test
222     void findModelVertexTest_emptyOrNullModelName() {
223         assertTrue(modelOperation.findModelVertexByName("").isEmpty());
224         assertTrue(modelOperation.findModelVertexByName(null).isEmpty());
225     }
226
227     @Test
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);
238
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));
242
243         final Model expectedModel = new Model(modelName, ModelTypeEnum.NORMATIVE);
244         assertTrue(modelByNameOpt.isPresent());
245         assertEquals(expectedModel, modelByNameOpt.get());
246     }
247
248     @Test
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());
256     }
257
258     @Test
259     void findModelByNameTest_emptyOrNullModelName() {
260         assertTrue(modelOperation.findModelByName("").isEmpty());
261         assertTrue(modelOperation.findModelByName(null).isEmpty());
262     }
263
264     @Test
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));
272
273         final List<Model> actualModelList = modelOperation.findAllModels();
274         assertFalse(actualModelList.isEmpty());
275         assertEquals(1, actualModelList.size());
276         assertEquals(modelName, actualModelList.get(0).getName());
277     }
278
279     @Test
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());
284     }
285
286     @Test
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());
292     }
293
294     @Test
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());
301     }
302
303     @Test
304     void findAllModelImportsTest() {
305         //given
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)));
312
313         final var modelData = new ModelData(parentModelName, parentModelName, ModelTypeEnum.NORMATIVE);
314         final ImmutablePair<ModelData, GraphEdge> modelDataGraphEdgePair = new ImmutablePair<>(modelData, null);
315
316         when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
317             GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.left(modelDataGraphEdgePair));
318
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);
327
328         //when
329         final List<ToscaImportByModel> actualModelImportList = modelOperation.findAllModelImports(modelName, true);
330
331         //then
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)));
336     }
337
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;
343     }
344 }