2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2021, Nordix Foundation. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
20 package org.openecomp.sdc.be.components.impl;
22 import static org.assertj.core.api.Assertions.assertThat;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertNull;
25 import static org.junit.Assert.fail;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.eq;
28 import static org.mockito.Mockito.times;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
32 import fj.data.Either;
33 import java.util.ArrayList;
34 import java.util.Collections;
35 import java.util.HashMap;
36 import java.util.List;
38 import java.util.stream.Collectors;
39 import org.apache.commons.collections.CollectionUtils;
40 import org.junit.jupiter.api.BeforeEach;
41 import org.junit.jupiter.api.Test;
42 import org.mockito.InjectMocks;
43 import org.mockito.Mock;
44 import org.mockito.MockitoAnnotations;
45 import org.openecomp.sdc.be.components.attribute.AttributeDeclarationOrchestrator;
46 import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException;
47 import org.openecomp.sdc.be.components.impl.exceptions.ComponentException;
48 import org.openecomp.sdc.be.components.validation.UserValidations;
49 import org.openecomp.sdc.be.config.ConfigurationManager;
50 import org.openecomp.sdc.be.dao.api.ActionStatus;
51 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
52 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
53 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
54 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
55 import org.openecomp.sdc.be.impl.ComponentsUtils;
56 import org.openecomp.sdc.be.model.ComponentInstOutputsMap;
57 import org.openecomp.sdc.be.model.ComponentInstance;
58 import org.openecomp.sdc.be.model.ComponentInstanceOutput;
59 import org.openecomp.sdc.be.model.ComponentInstanceAttribOutput;
60 import org.openecomp.sdc.be.model.ComponentParametersView;
61 import org.openecomp.sdc.be.model.OutputDefinition;
62 import org.openecomp.sdc.be.model.LifecycleStateEnum;
63 import org.openecomp.sdc.be.model.Service;
64 import org.openecomp.sdc.be.model.User;
65 import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache;
66 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade;
67 import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation;
68 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
69 import org.openecomp.sdc.be.model.operations.impl.AttributeOperation;
70 import org.openecomp.sdc.be.user.UserBusinessLogic;
71 import org.openecomp.sdc.common.impl.ExternalConfiguration;
72 import org.openecomp.sdc.common.impl.FSConfigurationSource;
73 import org.openecomp.sdc.exception.ResponseFormat;
75 class OutputsBusinessLogicTest {
77 private static final String COMPONENT_INSTANCE_ID = "instanceId";
78 private static final String COMPONENT_ID = "componentId";
79 private static final String USER_ID = "userId";
80 private static final String OUTPUT_ID = "outputId";
81 private static final String OUTPUT_TYPE = "string";
82 private static final String LISTOUTPUT_NAME = "listOutput";
83 private static final String LISTOUTPUT_SCHEMA_TYPE = "org.onap.datatypes.listoutput";
84 private static final String LISTOUTPUT_PROP1_NAME = "prop1";
85 private static final String LISTOUTPUT_PROP1_TYPE = "string";
86 private static final String LISTOUTPUT_PROP2_NAME = "prop2";
87 private static final String LISTOUTPUT_PROP2_TYPE = "integer";
88 private static final String OLD_VALUE = "old value";
89 private static final String NEW_VALUE = "new value";
90 private final ConfigurationManager configurationManager =
91 new ConfigurationManager(new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be"));
94 private ComponentsUtils componentsUtilsMock;
97 private UserBusinessLogic userAdminMock;
100 private ToscaOperationFacade toscaOperationFacadeMock;
103 private UserValidations userValidations;
106 private IGraphLockOperation graphLockOperation;
109 private AttributeDeclarationOrchestrator attributeDeclarationOrchestrator;
112 private ApplicationDataTypeCache applicationDataTypeCache;
115 private AttributeOperation attributeOperation;
118 private JanusGraphDao janusGraphDao;
121 private OutputsBusinessLogic testInstance;
123 private Service service;
125 private Map<String, List<ComponentInstanceOutput>> instanceOutputMap;
126 private List<ComponentInstanceOutput> outputsList;
129 public void setUp() {
130 MockitoAnnotations.openMocks(this);
131 service = new Service();
132 service.setUniqueId(COMPONENT_ID);
133 service.setLastUpdaterUserId(USER_ID);
134 service.setIsDeleted(false);
135 service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
137 testInstance.setUserValidations(userValidations);
138 testInstance.setToscaOperationFacade(toscaOperationFacadeMock);
139 testInstance.setGraphLockOperation(graphLockOperation);
140 testInstance.setComponentsUtils(componentsUtilsMock);
141 testInstance.setJanusGraphDao(janusGraphDao);
142 testInstance.setApplicationDataTypeCache(applicationDataTypeCache);
143 testInstance.setAttributeOperation(attributeOperation);
145 // add a ComponentInstance
146 final ComponentInstance componentInstance = new ComponentInstance();
147 componentInstance.setUniqueId(COMPONENT_INSTANCE_ID);
148 service.setComponentInstances(Collections.singletonList(componentInstance));
150 instanceOutputMap = new HashMap<>();
151 final ComponentInstanceOutput componentInstanceOutput = new ComponentInstanceOutput();
152 componentInstanceOutput.setOutputId(OUTPUT_ID);
153 componentInstanceOutput.setName(OUTPUT_ID);
154 outputsList = Collections.singletonList(componentInstanceOutput);
155 instanceOutputMap.put(COMPONENT_INSTANCE_ID, outputsList);
156 instanceOutputMap.put("someOutputId", Collections.singletonList(new ComponentInstanceOutput()));
157 service.setComponentInstancesOutputs(instanceOutputMap);
158 when(userValidations.validateUserExists(USER_ID)).thenReturn(new User());
159 when(userAdminMock.getUser(USER_ID, false)).thenReturn(new User());
163 void getComponentInstanceOutputs_ComponentInstanceNotExist() {
164 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(Either.left(service));
165 final Either<List<ComponentInstanceOutput>, ResponseFormat> componentInstanceOutputs = testInstance
166 .getComponentInstanceOutputs(USER_ID, COMPONENT_ID, "nonExisting");
167 assertThat(componentInstanceOutputs.isRight()).isTrue();
168 verify(componentsUtilsMock).getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND);
172 void getComponentInstanceOutputs_emptyOutputsMap() {
173 service.setComponentInstancesOutputs(Collections.emptyMap());
174 getComponents_emptyOutputs(service);
178 void getComponentInstanceOutputs_nullOutputsMap() {
179 service.setComponentInstancesOutputs(null);
180 getComponents_emptyOutputs(service);
184 void getComponentInstanceOutputs_instanceHasNoOutputs() {
185 service.setComponentInstancesOutputs(Collections.singletonMap("someOutputId", new ArrayList<>()));
186 getComponents_emptyOutputs(service);
190 void getComponentInstanceOutputs() {
191 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(Either.left(service));
192 final Either<List<ComponentInstanceOutput>, ResponseFormat> componentInstanceOutputs = testInstance
193 .getComponentInstanceOutputs(USER_ID, COMPONENT_ID, COMPONENT_INSTANCE_ID);
194 assertEquals("outputId", componentInstanceOutputs.left().value().get(0).getOutputId());
198 void testDeclareAttributes() {
199 service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
200 service.setLastUpdaterUserId(USER_ID);
201 final ComponentInstOutputsMap componentInstOutputsMap = new ComponentInstOutputsMap();
202 final Map<String, List<ComponentInstanceAttribOutput>> propertiesForDeclaration = new HashMap<>();
203 propertiesForDeclaration.put(COMPONENT_ID, getPropertiesListForDeclaration());
205 final List<OutputDefinition> declaredPropertiesToOutputs = getDeclaredProperties();
206 initMockitoStubbings(declaredPropertiesToOutputs);
208 final Either<List<OutputDefinition>, ResponseFormat> declaredPropertiesEither =
209 testInstance.declareAttributes(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, componentInstOutputsMap);
211 assertThat(declaredPropertiesEither.isLeft()).isTrue();
213 final List<OutputDefinition> declaredProperties = declaredPropertiesEither.left().value();
214 assertThat(CollectionUtils.isNotEmpty(declaredProperties)).isTrue();
215 assertEquals(1, declaredProperties.size());
216 assertEquals(declaredProperties, declaredPropertiesToOutputs);
220 void testDeclareAttributes_fail() {
221 service.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
222 service.setLastUpdaterUserId(USER_ID);
223 final ComponentInstOutputsMap componentInstOutputsMap = new ComponentInstOutputsMap();
224 final Map<String, List<ComponentInstanceAttribOutput>> propertiesForDeclaration = new HashMap<>();
225 propertiesForDeclaration.put(COMPONENT_ID, getPropertiesListForDeclaration());
227 final List<OutputDefinition> declaredPropertiesToOutputs = getDeclaredProperties();
228 initMockitoStubbings(declaredPropertiesToOutputs);
229 when(attributeDeclarationOrchestrator.declareAttributesToOutputs(any(), any())).thenThrow(ByResponseFormatComponentException.class);
230 final Either<List<OutputDefinition>, ResponseFormat> declaredPropertiesEither =
231 testInstance.declareAttributes(USER_ID, COMPONENT_ID, ComponentTypeEnum.SERVICE, componentInstOutputsMap);
233 assertThat(declaredPropertiesEither.isRight()).isTrue();
237 private void initMockitoStubbings(List<OutputDefinition> declaredPropertiesToOutputs) {
238 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(
239 Either.left(service));
240 when(attributeDeclarationOrchestrator.declareAttributesToOutputs(any(), any())).thenReturn(Either.left(
241 declaredPropertiesToOutputs));
242 when(toscaOperationFacadeMock.addOutputsToComponent(any(), any())).thenReturn(Either.left(declaredPropertiesToOutputs));
243 when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK);
244 when(graphLockOperation.lockComponent(any(), any())).thenReturn(StorageOperationStatus.OK);
245 when(graphLockOperation.unlockComponent(any(), any())).thenReturn(StorageOperationStatus.OK);
248 private void getComponents_emptyOutputs(Service service) {
249 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))).thenReturn(Either.left(service));
250 final Either<List<ComponentInstanceOutput>, ResponseFormat> componentInstanceOutputs = testInstance
251 .getComponentInstanceOutputs(USER_ID, COMPONENT_ID, COMPONENT_INSTANCE_ID);
252 assertEquals(Collections.emptyList(), componentInstanceOutputs.left().value());
255 private List<ComponentInstanceAttribOutput> getPropertiesListForDeclaration() {
256 return outputsList.stream().map(this::getPropertyForDeclaration).collect(Collectors.toList());
259 private ComponentInstanceAttribOutput getPropertyForDeclaration(ComponentInstanceOutput componentInstanceOutput) {
260 final ComponentInstanceAttribOutput propOutput = new ComponentInstanceAttribOutput();
261 propOutput.setOutput(componentInstanceOutput);
262 propOutput.setAttributesName(componentInstanceOutput.getName());
267 private List<OutputDefinition> getDeclaredProperties() {
268 return outputsList.stream().map(OutputDefinition::new).collect(Collectors.toList());
271 private OutputDefinition setUpListOutput() {
272 final OutputDefinition listOutput = new OutputDefinition();
273 listOutput.setName(LISTOUTPUT_NAME);
274 listOutput.setType("list");
279 void test_deleteOutput_listOutput_fail_getComponent() throws Exception {
280 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
281 .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
282 when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND)).thenReturn(ActionStatus.RESOURCE_NOT_FOUND);
285 testInstance.deleteOutput(COMPONENT_ID, USER_ID, LISTOUTPUT_NAME);
286 } catch (ComponentException e) {
287 assertEquals(ActionStatus.RESOURCE_NOT_FOUND, e.getActionStatus());
288 verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
295 void test_deleteOutput_listOutput_fail_validateOutput() throws Exception {
296 final OutputDefinition listOutput = setUpListOutput();
297 final String outputId = COMPONENT_ID + "." + listOutput.getName();
298 listOutput.setUniqueId(outputId);
299 service.setOutputs(Collections.singletonList(listOutput));
300 final String NONEXIST_OUTPUT_NAME = "myOutput";
302 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
303 .thenReturn(Either.left(service));
306 testInstance.deleteOutput(COMPONENT_ID, USER_ID, NONEXIST_OUTPUT_NAME);
307 } catch (ComponentException e) {
308 assertEquals(ActionStatus.OUTPUT_IS_NOT_CHILD_OF_COMPONENT, e.getActionStatus());
309 verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
316 void test_deleteOutput_listOutput_fail_lockComponent() throws Exception {
317 final OutputDefinition listOutput = setUpListOutput();
318 final String outputId = COMPONENT_ID + "." + listOutput.getName();
319 listOutput.setUniqueId(outputId);
320 service.setOutputs(Collections.singletonList(listOutput));
322 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
323 .thenReturn(Either.left(service));
324 when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.NOT_FOUND);
325 when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, ComponentTypeEnum.SERVICE))
326 .thenReturn(ActionStatus.SERVICE_NOT_FOUND);
329 testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
330 } catch (ComponentException e) {
331 assertEquals(ActionStatus.SERVICE_NOT_FOUND, e.getActionStatus());
332 verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
333 verify(graphLockOperation, times(1)).lockComponent(COMPONENT_ID, NodeTypeEnum.Service);
340 void test_deleteOutput_listOutput_fail_deleteOutput() throws Exception {
341 final OutputDefinition listOutput = setUpListOutput();
342 final String outputId = COMPONENT_ID + "." + listOutput.getName();
343 listOutput.setUniqueId(outputId);
344 service.setOutputs(Collections.singletonList(listOutput));
346 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
347 .thenReturn(Either.left(service));
348 when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK);
349 when(toscaOperationFacadeMock.deleteOutputOfResource(service, listOutput.getName())).thenReturn(StorageOperationStatus.BAD_REQUEST);
350 when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST)).thenReturn(ActionStatus.INVALID_CONTENT);
353 testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
354 } catch (ComponentException e) {
355 assertEquals(ActionStatus.INVALID_CONTENT, e.getActionStatus());
356 verify(toscaOperationFacadeMock, times(1)).getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class));
357 verify(graphLockOperation, times(1)).lockComponent(COMPONENT_ID, NodeTypeEnum.Service);
358 verify(toscaOperationFacadeMock, times(1)).deleteOutputOfResource(service, listOutput.getName());
365 void test_deleteOutput_output_fail_unDeclare() throws Exception {
366 final OutputDefinition listOutput = setUpListOutput();
367 final String outputId = COMPONENT_ID + "." + listOutput.getName();
368 listOutput.setUniqueId(outputId);
369 service.setOutputs(Collections.singletonList(listOutput));
371 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
372 .thenReturn(Either.left(service));
373 when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK);
374 when(toscaOperationFacadeMock.deleteOutputOfResource(service, listOutput.getName())).thenReturn(StorageOperationStatus.OK);
375 when(attributeDeclarationOrchestrator.unDeclareAttributesAsOutputs(service, listOutput)).thenReturn(StorageOperationStatus.BAD_REQUEST);
376 when(componentsUtilsMock.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST)).thenReturn(ActionStatus.INVALID_CONTENT);
379 testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
380 } catch (ComponentException e) {
381 assertEquals(ActionStatus.INVALID_CONTENT, e.getActionStatus());
382 verify(attributeDeclarationOrchestrator, times(1)).unDeclareAttributesAsOutputs(service, listOutput);
389 void test_deleteOutput_output_success() throws Exception {
390 final OutputDefinition listOutput = setUpListOutput();
391 final String outputId = COMPONENT_ID + "." + listOutput.getName();
392 listOutput.setUniqueId(outputId);
393 service.setOutputs(Collections.singletonList(listOutput));
395 when(toscaOperationFacadeMock.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class)))
396 .thenReturn(Either.left(service));
397 when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)).thenReturn(StorageOperationStatus.OK);
398 when(toscaOperationFacadeMock.deleteOutputOfResource(service, listOutput.getName())).thenReturn(StorageOperationStatus.OK);
399 when(attributeDeclarationOrchestrator.unDeclareAttributesAsOutputs(service, listOutput)).thenReturn(StorageOperationStatus.OK);
401 testInstance.deleteOutput(COMPONENT_ID, USER_ID, outputId);
402 verify(attributeDeclarationOrchestrator, times(1)).unDeclareAttributesAsOutputs(service, listOutput);