X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Ftest%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fimpl%2FComponentInstanceBusinessLogicTest.java;h=3a5f40cb8cb3f818779bdb7baae50b38b49f695e;hb=7be04e3e3bdc899c52ffea1f6e11731771903f93;hp=f21383540659b9107a70d15b10b01e2cc14338a8;hpb=1ec3dde2067e0181faa8e5098219c93126638aef;p=sdc.git diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java index f213835406..3a5f40cb8c 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogicTest.java @@ -23,6 +23,7 @@ package org.openecomp.sdc.be.components.impl; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; @@ -32,9 +33,13 @@ import static org.junit.jupiter.api.DynamicTest.dynamicTest; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anySet; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum.RESOURCE_PARAM_NAME; import fj.data.Either; import java.util.ArrayList; @@ -50,26 +55,22 @@ import mockit.Deencapsulation; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.assertj.core.util.Lists; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import org.mockito.junit.jupiter.MockitoExtension; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.components.validation.UserValidations; import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; -import org.openecomp.sdc.be.dao.jsongraph.JanusGraphDao; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ForwardingPathDataDefinition; @@ -79,26 +80,31 @@ import org.openecomp.sdc.be.datatypes.elements.GetPolicyValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.elements.ToscaGetFunctionDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.PropertySource; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.datatypes.tosca.ToscaGetFunctionType; +import org.openecomp.sdc.be.exception.BusinessException; import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.ArtifactDefinition; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.CapabilityRequirementRelationship; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstancePropInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; -import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentParametersView; import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.PolicyDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RelationshipImpl; import org.openecomp.sdc.be.model.RelationshipInfo; import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; @@ -110,9 +116,11 @@ import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ForwardingPathOperation; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.validation.ToscaFunctionValidator; import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; import org.openecomp.sdc.common.api.ArtifactTypeEnum; import org.openecomp.sdc.common.api.ConfigurationSource; @@ -124,9 +132,6 @@ import org.openecomp.sdc.exception.ResponseFormat; /** * The test suite designed for test functionality of ComponentInstanceBusinessLogic class */ - -@ExtendWith(MockitoExtension.class) -@MockitoSettings(strictness = Strictness.LENIENT) class ComponentInstanceBusinessLogicTest { private final static String USER_ID = "jh0003"; @@ -156,13 +161,7 @@ class ComponentInstanceBusinessLogicTest { private final static String INPUT_ID = "inputId"; private final static String ICON_NAME = "icon"; - private static ConfigurationSource configurationSource = new FSConfigurationSource( - ExternalConfiguration.getChangeListener(), - "src/test/resources/config/catalog-be"); - private static ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); - - @InjectMocks - private static ComponentInstanceBusinessLogic componentInstanceBusinessLogic; + private ComponentInstanceBusinessLogic componentInstanceBusinessLogic; @Mock private ComponentInstancePropInput componentInstancePropInput; @Mock @@ -182,13 +181,15 @@ class ComponentInstanceBusinessLogicTest { @Mock private JanusGraphDao janusGraphDao; @Mock - private ApplicationDataTypeCache dataTypeCache; + private ApplicationDataTypeCache applicationDataTypeCache; @Mock private PropertyOperation propertyOperation; @Mock private ContainerInstanceTypesData containerInstanceTypeData; @Mock private CompositionBusinessLogic compositionBusinessLogic; + @Mock + private ToscaFunctionValidator toscaFunctionValidator; private Component service; private Component resource; @@ -198,9 +199,34 @@ class ComponentInstanceBusinessLogicTest { private List ciPropertyList; private List ciInputList; + @BeforeAll + static void beforeAll() { + initConfig(); + } + + private static void initConfig() { + final ConfigurationSource configurationSource = new FSConfigurationSource( + ExternalConfiguration.getChangeListener(), + "src/test/resources/config/catalog-be" + ); + new ConfigurationManager(configurationSource); + } + @BeforeEach void init() { - MockitoAnnotations.initMocks(this); + MockitoAnnotations.openMocks(this); + componentInstanceBusinessLogic = new ComponentInstanceBusinessLogic(null, null, null, null, null, null, null, artifactsBusinessLogic, null, + null, forwardingPathOperation, null, null, toscaFunctionValidator); + componentInstanceBusinessLogic.setComponentsUtils(componentsUtils); + componentInstanceBusinessLogic.setToscaOperationFacade(toscaOperationFacade); + componentInstanceBusinessLogic.setUserValidations(userValidations); + componentInstanceBusinessLogic.setGraphLockOperation(graphLockOperation); + componentInstanceBusinessLogic.setJanusGraphDao(janusGraphDao); + componentInstanceBusinessLogic.setApplicationDataTypeCache(applicationDataTypeCache); + componentInstanceBusinessLogic.setPropertyOperation(propertyOperation); + componentInstanceBusinessLogic.setContainerInstanceTypesData(containerInstanceTypeData); + componentInstanceBusinessLogic.setCompositionBusinessLogic(compositionBusinessLogic); + stubMethods(); createComponents(); } @@ -268,7 +294,7 @@ class ComponentInstanceBusinessLogicTest { when(toscaOperationFacade.getToscaElement(eq(containerComponentID), any(ComponentParametersView.class))) .thenReturn(Either.left(component)); when(toscaOperationFacade.validateComponentExists(any(String.class))).thenReturn(Either.left(Boolean.TRUE)); - when(toscaOperationFacade.getToscaFullElement(eq(new_Comp_UID))).thenReturn(Either.left(component2)); + when(toscaOperationFacade.getToscaFullElement(new_Comp_UID)).thenReturn(Either.left(component2)); Either, ResponseFormat> resultOp = componentInstanceBusinessLogic .forwardingPathOnVersionChange(containerComponentParam, @@ -317,7 +343,7 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(containerComponentID, NodeTypeEnum.ResourceInstance)) .thenReturn(StorageOperationStatus.OK); - when(dataTypeCache.getAll()).thenReturn(Either.left(types)); + when(componentsUtils.getAllDataTypes(applicationDataTypeCache, component.getModel())).thenReturn(types); when(propertyOperation.validateAndUpdatePropertyValue(property.getType(), "newVal", true, null, types)) .thenReturn(Either.left("newVal")); when(propertyOperation.validateAndUpdateRules("string", property.getRules(), @@ -337,6 +363,8 @@ class ComponentInstanceBusinessLogicTest { assertThat(responseFormatEither.left().value()).isEqualTo(properties); } + + @Test void testCreateOrUpdatePropertiesValuesPropertyNotExists() { String containerComponentID = "containerId"; @@ -416,16 +444,18 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(Either.left(component)); when(graphLockOperation.lockComponent(containerComponentID, NodeTypeEnum.ResourceInstance)) .thenReturn(StorageOperationStatus.OK); - when(dataTypeCache.getAll()).thenReturn(Either.left(types)); + when(componentsUtils.getAllDataTypes(applicationDataTypeCache, component.getModel())).thenReturn(types); when(propertyOperation.validateAndUpdatePropertyValue(property.getType(), "newVal", true, null, types)) .thenReturn(Either.right(false)); when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST)) .thenReturn(ActionStatus.INVALID_CONTENT); - ComponentException e = assertThrows(ComponentException.class, - () -> componentInstanceBusinessLogic.createOrUpdatePropertiesValues( - ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentID, resourceInstanceId, properties, "userId")); - assertThat(e.getActionStatus()).isEqualTo(ActionStatus.INVALID_CONTENT); + final Either, ResponseFormat> response = componentInstanceBusinessLogic.createOrUpdatePropertiesValues( + ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentID, resourceInstanceId, properties, "userId"); + assertThat(response.isRight()).as("Response should be an error").isTrue(); + final ResponseFormat responseFormat = response.right().value(); + assertThat(responseFormat.getStatus()).as("Response status should be as expected").isEqualTo(400); + assertThat(responseFormat.getMessageId()).as("Error message id should be as expected").isEqualTo("SVC4000"); } @Test @@ -485,7 +515,7 @@ class ComponentInstanceBusinessLogicTest { component.addForwardingPath(createPath("Path2", "NodeA2", "NodeB2", "2")); when(toscaOperationFacade.getToscaElement(eq(containerComponentID), any(ComponentParametersView.class))) .thenReturn(Either.left(component)); - when(toscaOperationFacade.getToscaElement(eq(containerComponentID))).thenReturn(Either.left(component)); + when(toscaOperationFacade.getToscaElement(containerComponentID)).thenReturn(Either.left(component)); when(forwardingPathOperation.deleteForwardingPath(any(Service.class), anySet())) .thenReturn(Either.left(new HashSet<>())); final ComponentInstance ci = new ComponentInstance(); @@ -525,7 +555,6 @@ class ComponentInstanceBusinessLogicTest { finalDeploymentArtifacts.put(deploymentArtifact3.getArtifactLabel(), deploymentArtifact3); finalDeploymentArtifacts.put(heatEnvPlaceHolder.getArtifactLabel(), heatEnvPlaceHolder); finalDeploymentArtifacts.put(heatEnvPlaceHolder2.getArtifactLabel(), heatEnvPlaceHolder2); - when(artifactsBusinessLogic.getArtifacts(componentInstance.getComponentUid(), NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)).thenReturn(getResourceDeploymentArtifacts); when(artifactsBusinessLogic.createHeatEnvPlaceHolder(new ArrayList<>(), @@ -624,8 +653,7 @@ class ComponentInstanceBusinessLogicTest { } private void getServiceRelationByIdUserValidationFailure(Component component) { - when(userValidations.validateUserExists(eq(USER_ID))) - .thenThrow(new ByActionStatusComponentException(ActionStatus.USER_NOT_FOUND)); + doThrow(new ByActionStatusComponentException(ActionStatus.USER_NOT_FOUND)).when(userValidations).validateUserExists(USER_ID); try { componentInstanceBusinessLogic .getRelationById(COMPONENT_ID, RELATION_ID, USER_ID, component.getComponentType()); @@ -1144,6 +1172,36 @@ class ComponentInstanceBusinessLogicTest { assertNotNull(result); } + @Test + void testUpdateInstanceRequirement() { + ComponentInstanceBusinessLogic testSubject; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.RESOURCE; + createComponents(); + String userId = "userId"; + resource.setLastUpdaterUserId(userId); + String containerComponentId = resource.getUniqueId(); + String componentInstanceUniqueId = TO_INSTANCE_ID; + String capabilityType = ""; + String capabilityName = ""; + RequirementDefinition requirementDef = new RequirementDefinition(); + + Either result; + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)).thenReturn(Either.left(resource)); + testSubject = createTestSubject(); + when(toscaOperationFacade.updateComponentInstanceRequirement(containerComponentId, TO_INSTANCE_ID, requirementDef)).thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(resource)).thenReturn(Either.left(resource)); + when(graphLockOperation.unlockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource))) + .thenReturn(StorageOperationStatus.OK); + when(graphLockOperation.lockComponent(Mockito.anyString(), eq(NodeTypeEnum.Resource))) + .thenReturn(StorageOperationStatus.OK); + + result = testSubject.updateInstanceRequirement(componentTypeEnum, containerComponentId, + componentInstanceUniqueId, requirementDef, userId); + assertEquals(requirementDef, result.left().value()); + + } + @Test void testCopyComponentInstanceWrongUserId() { @@ -1235,8 +1293,6 @@ class ComponentInstanceBusinessLogicTest { ComponentInstanceAttribute attribute = new ComponentInstanceAttribute(); attribute.setType("string"); attribute.setUniqueId("testCreateOrUpdateAttributeValueForCopyPaste"); - SchemaDefinition def = Mockito.mock(SchemaDefinition.class); - attribute.setSchema(def); LifecycleStateEnum oldLifeCycleState = service.getLifecycleState(); String oldLastUpdatedUserId = service.getLastUpdaterUserId(); service.setLastUpdaterUserId(USER_ID); @@ -1333,7 +1389,7 @@ class ComponentInstanceBusinessLogicTest { deleteErrorIds.add(componentInstanceId); deleteErrorMap.put("deleteFailedIds", deleteErrorIds); Either cont = Either.left(service); - when(componentsUtils.convertFromStorageResponse(eq(StorageOperationStatus.NOT_FOUND), eq(null))) + when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, null)) .thenReturn(ActionStatus.GENERAL_ERROR); when(toscaOperationFacade.getToscaElement(any(String.class), any(ComponentParametersView.class))) .thenReturn(cont); @@ -1446,7 +1502,7 @@ class ComponentInstanceBusinessLogicTest { .thenReturn(StorageOperationStatus.OK); Either resultEither; resultEither = Either.right(StorageOperationStatus.OK); - when(componentsUtils.convertFromStorageResponseForResourceInstance(eq(StorageOperationStatus.OK), eq(true))) + when(componentsUtils.convertFromStorageResponseForResourceInstance(StorageOperationStatus.OK, true)) .thenReturn(ActionStatus.GENERAL_ERROR); when(toscaOperationFacade.dissociateResourceInstances(componentId, ref)).thenReturn(resultEither); @@ -1558,6 +1614,7 @@ class ComponentInstanceBusinessLogicTest { } // Prepare ComponentInstance & Resource objects used in createComponentInstance() tests + private Pair prepareResourcesForCreateComponentInstanceTest() { ComponentInstance instanceToBeCreated = new ComponentInstance(); instanceToBeCreated.setName(COMPONENT_INSTANCE_NAME); @@ -1573,8 +1630,8 @@ class ComponentInstanceBusinessLogicTest { return Pair.of(instanceToBeCreated, originComponent); } - // Common part for testing component instance name validation + private void testCreateComponentInstanceNameValidationFailure(String ciName) { ComponentInstance ci = new ComponentInstance(); ci.setName(ciName); @@ -1589,7 +1646,6 @@ class ComponentInstanceBusinessLogicTest { }); assertEquals(ActionStatus.INVALID_COMPONENT_NAME, e.getActionStatus()); } - @TestFactory Iterable testCreateComponentInstanceNameValidationFailureFactory() { String longName = String.join("", Collections.nCopies(ValidationUtils.COMPONENT_NAME_MAX_LENGTH + 1, "x")); @@ -1611,7 +1667,7 @@ class ComponentInstanceBusinessLogicTest { // Stub for getting component when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND)); when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.NOT_FOUND, ComponentTypeEnum.RESOURCE)) .thenReturn(ActionStatus.RESOURCE_NOT_FOUND); @@ -1632,7 +1688,7 @@ class ComponentInstanceBusinessLogicTest { // Stub for getting component when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); ByActionStatusComponentException e = assertThrows(ByActionStatusComponentException.class, () -> { @@ -1651,7 +1707,7 @@ class ComponentInstanceBusinessLogicTest { // Stub for getting component when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); ByActionStatusComponentException e = assertThrows(ByActionStatusComponentException.class, () -> { @@ -1670,7 +1726,7 @@ class ComponentInstanceBusinessLogicTest { // Stub for getting component when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); final ByActionStatusComponentException e = assertThrows(ByActionStatusComponentException.class, () -> { @@ -1688,17 +1744,17 @@ class ComponentInstanceBusinessLogicTest { // Stub for getting component when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); // Assume services cannot contain VF resource - when(containerInstanceTypeData.isAllowedForServiceComponent(eq(ResourceTypeEnum.VF))) + when(containerInstanceTypeData.isAllowedForServiceComponent(ResourceTypeEnum.VF, null)) .thenReturn(false); ByActionStatusComponentException actualException = assertThrows(ByActionStatusComponentException.class, () -> { componentInstanceBusinessLogic.createComponentInstance(ComponentTypeEnum.SERVICE_PARAM_NAME, COMPONENT_ID, USER_ID, ci); }); assertThat(actualException.getActionStatus()).isEqualTo(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE); - verify(containerInstanceTypeData, times(1)).isAllowedForServiceComponent(eq(ResourceTypeEnum.VF)); + verify(containerInstanceTypeData, times(1)).isAllowedForServiceComponent(ResourceTypeEnum.VF, null); //given final Resource resource = createResource(); @@ -1707,12 +1763,12 @@ class ComponentInstanceBusinessLogicTest { //when when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(resource)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); - when(containerInstanceTypeData.isAllowedForResourceComponent(eq(ResourceTypeEnum.VF), eq(ResourceTypeEnum.VF))) + when(containerInstanceTypeData.isAllowedForResourceComponent(ResourceTypeEnum.VF, ResourceTypeEnum.VF)) .thenReturn(false); actualException = assertThrows(ByActionStatusComponentException.class, () -> { - componentInstanceBusinessLogic.createComponentInstance(ComponentTypeEnum.RESOURCE_PARAM_NAME, COMPONENT_ID, USER_ID, ci); + componentInstanceBusinessLogic.createComponentInstance(RESOURCE_PARAM_NAME, COMPONENT_ID, USER_ID, ci); }); //then assertThat(actualException.getActionStatus()).isEqualTo(ActionStatus.CONTAINER_CANNOT_CONTAIN_INSTANCE); @@ -1728,9 +1784,9 @@ class ComponentInstanceBusinessLogicTest { // not to target the internal details too much when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); - when(containerInstanceTypeData.isAllowedForServiceComponent(eq(ResourceTypeEnum.VF))) + when(containerInstanceTypeData.isAllowedForServiceComponent(ResourceTypeEnum.VF, null)) .thenReturn(true); Mockito.doNothing().when(compositionBusinessLogic).validateAndSetDefaultCoordinates(ci); when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)) @@ -1749,7 +1805,7 @@ class ComponentInstanceBusinessLogicTest { componentInstanceBusinessLogic.createComponentInstance(ComponentTypeEnum.SERVICE_PARAM_NAME, COMPONENT_ID, USER_ID, ci); }); verify(containerInstanceTypeData, times(1)) - .isAllowedForServiceComponent(eq(ResourceTypeEnum.VF)); + .isAllowedForServiceComponent(ResourceTypeEnum.VF, null); verify(compositionBusinessLogic, times(1)).validateAndSetDefaultCoordinates(ci); verify(toscaOperationFacade, times(1)) .addComponentInstanceToTopologyTemplate(service, originComponent, ci, false, user); @@ -1770,9 +1826,9 @@ class ComponentInstanceBusinessLogicTest { // not to target the internal details too much when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) .thenReturn(Either.left(service)); - when(toscaOperationFacade.getToscaFullElement(eq(ORIGIN_COMPONENT_ID))) + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) .thenReturn(Either.left(originComponent)); - when(containerInstanceTypeData.isAllowedForServiceComponent(eq(ResourceTypeEnum.VF))) + when(containerInstanceTypeData.isAllowedForServiceComponent(ResourceTypeEnum.VF, null)) .thenReturn(true); Mockito.doNothing().when(compositionBusinessLogic).validateAndSetDefaultCoordinates(instanceToBeCreated); when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)) @@ -1795,11 +1851,369 @@ class ComponentInstanceBusinessLogicTest { assertThat(instanceToBeCreated.getComponentVersion()).isEqualTo(originComponent.getVersion()); assertThat(instanceToBeCreated.getIcon()).isEqualTo(originComponent.getIcon()); verify(containerInstanceTypeData, times(1)) - .isAllowedForServiceComponent(eq(ResourceTypeEnum.VF)); + .isAllowedForServiceComponent(ResourceTypeEnum.VF, null); verify(compositionBusinessLogic, times(1)).validateAndSetDefaultCoordinates(instanceToBeCreated); verify(toscaOperationFacade, times(1)) .addComponentInstanceToTopologyTemplate(service, originComponent, instanceToBeCreated, false, user); // Check graph db change was committed verify(janusGraphDao, times(1)).commit(); } + + @Test + void testCreateComponentInstanceServiceSubstitutionSuccess() { + ComponentInstance instanceToBeCreated = createServiceSubstitutionComponentInstance(); + Service originService = createServiceSubstitutionOriginService(); + Component serviceBaseComponent = createServiceSubstitutionServiceDerivedFromComponent(); + + Service updatedService = new Service(); + updatedService.setComponentInstances(Collections.singletonList(instanceToBeCreated)); + updatedService.setUniqueId(service.getUniqueId()); + + when(toscaOperationFacade.getToscaElement(eq(COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(service)); + when(toscaOperationFacade.getToscaFullElement(ORIGIN_COMPONENT_ID)) + .thenReturn(Either.left(originService)); + when(toscaOperationFacade.getLatestByToscaResourceName(eq(originService.getDerivedFromGenericType()), isNull())) + .thenReturn(Either.left(serviceBaseComponent)); + when(toscaOperationFacade.getToscaElement(eq(ORIGIN_COMPONENT_ID), any(ComponentParametersView.class))) + .thenReturn(Either.left(originService)); + Mockito.doNothing().when(compositionBusinessLogic).validateAndSetDefaultCoordinates(instanceToBeCreated); + when(graphLockOperation.lockComponent(COMPONENT_ID, NodeTypeEnum.Service)) + .thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.addComponentInstanceToTopologyTemplate(service, serviceBaseComponent, instanceToBeCreated, false, user)) + .thenReturn(Either.left(new ImmutablePair<>(updatedService, COMPONENT_INSTANCE_ID))); + when(artifactsBusinessLogic.getArtifacts( + "baseComponentId", NodeTypeEnum.Resource, ArtifactGroupTypeEnum.DEPLOYMENT, null)) + .thenReturn(Either.left(new HashMap<>())); + when(toscaOperationFacade + .addInformationalArtifactsToInstance(service.getUniqueId(), instanceToBeCreated, originService.getArtifacts())) + .thenReturn(StorageOperationStatus.OK); + when(janusGraphDao.commit()).thenReturn(JanusGraphOperationStatus.OK); + when(graphLockOperation.unlockComponent(COMPONENT_ID, NodeTypeEnum.Service)) + .thenReturn(StorageOperationStatus.OK); + + ComponentInstance result = componentInstanceBusinessLogic.createComponentInstance( + ComponentTypeEnum.SERVICE_PARAM_NAME, COMPONENT_ID, USER_ID, instanceToBeCreated); + assertThat(result).isEqualTo(instanceToBeCreated); + assertThat(instanceToBeCreated.getComponentVersion()).isEqualTo(originService.getVersion()); + assertThat(instanceToBeCreated.getIcon()).isEqualTo(originService.getIcon()); + verify(compositionBusinessLogic, times(1)).validateAndSetDefaultCoordinates(instanceToBeCreated); + verify(toscaOperationFacade, times(1)) + .addComponentInstanceToTopologyTemplate(service, serviceBaseComponent, instanceToBeCreated, false, user); + // Check graph db change was committed + verify(janusGraphDao, times(1)).commit(); + } + + @Test + void testGetComponentInstanceAttributesById_success() { + final ComponentInstanceAttribute componentInstanceAttribute = new ComponentInstanceAttribute(); + componentInstanceAttribute.setComponentInstanceId(TO_INSTANCE_ID); + + final HashMap> map = new HashMap<>(); + map.put(TO_INSTANCE_ID, Arrays.asList(componentInstanceAttribute)); + resource.setComponentInstancesAttributes(map); + + final Either leftServiceOp = Either.left(resource); + doReturn(leftServiceOp).when(toscaOperationFacade).getToscaElement(COMPONENT_ID); + + final List result = componentInstanceBusinessLogic + .getComponentInstanceAttributesById(RESOURCE_PARAM_NAME, COMPONENT_ID, TO_INSTANCE_ID, USER_ID); + assertThat(result).isNotNull().isNotEmpty(); + verify(toscaOperationFacade, times(1)).getToscaElement(COMPONENT_ID); + } + + @Test + void testGetComponentInstanceAttributesById_fail_missing_ComponentInstancesAttributes() { + final Either leftServiceOp = Either.left(resource); + doReturn(leftServiceOp).when(toscaOperationFacade).getToscaElement(COMPONENT_ID); + + final List result = componentInstanceBusinessLogic + .getComponentInstanceAttributesById(RESOURCE_PARAM_NAME, COMPONENT_ID, TO_INSTANCE_ID, USER_ID); + assertThat(result).isNotNull().isEmpty(); + verify(toscaOperationFacade, times(1)).getToscaElement(COMPONENT_ID); + } + + @Test + void testGetComponentInstanceAttributesById_fail_getToscaElement() { + final ComponentInstanceAttribute componentInstanceAttribute = new ComponentInstanceAttribute(); + componentInstanceAttribute.setComponentInstanceId(TO_INSTANCE_ID); + + final HashMap> map = new HashMap<>(); + map.put(TO_INSTANCE_ID, Arrays.asList(componentInstanceAttribute)); + resource.setComponentInstancesAttributes(map); + + final Either right = Either.right(StorageOperationStatus.BAD_REQUEST); + doReturn(right).when(toscaOperationFacade).getToscaElement(COMPONENT_ID); + doReturn(ActionStatus.BAD_REQUEST_MISSING_RESOURCE).when(componentsUtils).convertFromStorageResponse(StorageOperationStatus.BAD_REQUEST); + + assertThrows(ByActionStatusComponentException.class, () -> { + final List result = componentInstanceBusinessLogic + .getComponentInstanceAttributesById(RESOURCE_PARAM_NAME, COMPONENT_ID, TO_INSTANCE_ID, USER_ID); + + }); + + } + + @Test + void testGetComponentInstanceAttributesById_fail_getResourceInstanceById() { + final ComponentInstanceAttribute componentInstanceAttribute = new ComponentInstanceAttribute(); + componentInstanceAttribute.setComponentInstanceId(TO_INSTANCE_ID); + + final HashMap> map = new HashMap<>(); + map.put(TO_INSTANCE_ID, Arrays.asList(componentInstanceAttribute)); + resource.setComponentInstancesAttributes(map); + + final Either leftServiceOp = Either.left(resource); + doReturn(leftServiceOp).when(toscaOperationFacade).getToscaElement(COMPONENT_ID); + doReturn(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE).when(componentsUtils).convertFromStorageResponse(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND); + + assertThrows(ByActionStatusComponentException.class, () -> { + final List result = componentInstanceBusinessLogic + .getComponentInstanceAttributesById(RESOURCE_PARAM_NAME, COMPONENT_ID, "", USER_ID); + + }); + + } + + @Test + void updateInstanceCapabilitySuccessTest() { + var containerComponentId = "containerComponentId"; + var componentInstanceUniqueId = "componentInstanceUniqueId"; + var capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setUniqueId("uniqueId"); + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setLastUpdaterUserId(USER_ID); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + var componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(componentInstanceUniqueId); + component.setComponentInstances(Collections.singletonList(componentInstance)); + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)) + .thenReturn(Either.left(component)); + when(toscaOperationFacade.updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition)) + .thenReturn(capabilityDefinition); + when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(component)) + .thenReturn(Either.left(component)); + when(graphLockOperation.lockComponent(containerComponentId, NodeTypeEnum.Service)) + .thenReturn(StorageOperationStatus.OK); + + final Either resultEither = componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, containerComponentId, componentInstanceUniqueId, capabilityDefinition, USER_ID); + assertTrue(resultEither.isLeft()); + final CapabilityDefinition actualCapabilityDefinition = resultEither.left().value(); + assertNotEquals(capabilityDefinition, actualCapabilityDefinition); + assertEquals(capabilityDefinition.getUniqueId(), actualCapabilityDefinition.getUniqueId()); + } + + @Test + void updateInstanceCapabilityNoContainerComponentTypeTest() { + var responseFormat = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)).thenReturn(responseFormat); + final Either resultEither = componentInstanceBusinessLogic + .updateInstanceCapability(null, "containerComponentId", "componentInstanceUniqueId", new CapabilityDefinition(), USER_ID); + assertTrue(resultEither.isRight(), "Either return should be right"); + final ResponseFormat actualResponseFormat = resultEither.right().value(); + assertEquals(responseFormat, actualResponseFormat); + } + + @Test + void updateInstanceCapabilityContainerComponentNotFoundTest() { + var containerComponentId = "containerComponentId"; + when(toscaOperationFacade.getToscaFullElement(containerComponentId)).thenReturn(Either.right(null)); + var responseFormat = new ResponseFormat(); + when(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_FOUND, containerComponentId)).thenReturn(responseFormat); + final Either resultEither = componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, "containerComponentId", "componentInstanceUniqueId", new CapabilityDefinition(), USER_ID); + assertTrue(resultEither.isRight(), "Either return should be right"); + final ResponseFormat actualResponseFormat = resultEither.right().value(); + assertEquals(responseFormat, actualResponseFormat); + } + + @Test + void updateInstanceCapabilityCannotWorkOnComponentTest() { + var containerComponentId = "containerComponentId"; + var componentInstanceUniqueId = "componentInstanceUniqueId"; + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setLastUpdaterUserId("anotherUse"); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + var expectedResponseFormat = new ResponseFormat(); + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)) + .thenReturn(Either.left(component)); + when(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)) + .thenReturn(expectedResponseFormat); + + final Either resultEither = componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, containerComponentId, componentInstanceUniqueId, new CapabilityDefinition(), USER_ID); + assertTrue(resultEither.isRight(), "Either return should be right"); + final ResponseFormat actualResponseFormat = resultEither.right().value(); + assertEquals(expectedResponseFormat, actualResponseFormat); + } + + @Test + void updateInstanceCapabilityResourceInstanceNotFoundTest() { + var containerComponentId = "containerComponentId"; + var componentInstanceUniqueId = "componentInstanceUniqueId"; + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setLastUpdaterUserId(USER_ID); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + var expectedResponseFormat = new ResponseFormat(); + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)) + .thenReturn(Either.left(component)); + when(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceUniqueId, containerComponentId)) + .thenReturn(expectedResponseFormat); + + final Either resultEither = componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, containerComponentId, componentInstanceUniqueId, new CapabilityDefinition(), USER_ID); + assertTrue(resultEither.isRight(), "Either return should be right"); + final ResponseFormat actualResponseFormat = resultEither.right().value(); + assertEquals(expectedResponseFormat, actualResponseFormat); + } + + @Test + void updateInstanceCapabilityUpdateMetadataFailTest() { + var containerComponentId = "containerComponentId"; + var componentInstanceUniqueId = "componentInstanceUniqueId"; + var capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setUniqueId("uniqueId"); + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setLastUpdaterUserId(USER_ID); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + var componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(componentInstanceUniqueId); + component.setComponentInstances(Collections.singletonList(componentInstance)); + + var expectedResponseFormat = new ResponseFormat(); + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)) + .thenReturn(Either.left(component)); + when(graphLockOperation.lockComponent(containerComponentId, NodeTypeEnum.Service)) + .thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition)) + .thenReturn(capabilityDefinition); + when(toscaOperationFacade.updateComponentInstanceMetadataOfTopologyTemplate(component)) + .thenReturn(Either.right(StorageOperationStatus.GENERAL_ERROR)); + when(componentsUtils.convertFromStorageResponse(StorageOperationStatus.GENERAL_ERROR, ComponentTypeEnum.SERVICE)) + .thenReturn(ActionStatus.GENERAL_ERROR); + when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)) + .thenReturn(expectedResponseFormat); + + final Either resultEither = componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, containerComponentId, componentInstanceUniqueId, capabilityDefinition, USER_ID); + assertTrue(resultEither.isRight(), "Either return should be right"); + final ResponseFormat actualResponseFormat = resultEither.right().value(); + assertEquals(expectedResponseFormat, actualResponseFormat); + } + + @Test + void updateInstanceCapabilityBusinessExceptionHandlingTest() { + var containerComponentId = "containerComponentId"; + var componentInstanceUniqueId = "componentInstanceUniqueId"; + var capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setUniqueId("uniqueId"); + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setLastUpdaterUserId(USER_ID); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + var componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(componentInstanceUniqueId); + component.setComponentInstances(Collections.singletonList(componentInstance)); + + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)) + .thenReturn(Either.left(component)); + when(graphLockOperation.lockComponent(containerComponentId, NodeTypeEnum.Service)) + .thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition)) + .thenThrow(new OperationException(ActionStatus.GENERAL_ERROR)); + + final BusinessException businessException = assertThrows(BusinessException.class, () -> { + componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, containerComponentId, componentInstanceUniqueId, capabilityDefinition, USER_ID); + }); + assertTrue(businessException instanceof OperationException); + assertEquals(ActionStatus.GENERAL_ERROR, ((OperationException) businessException).getActionStatus()); + } + + @Test + void updateInstanceCapabilityUnknownExceptionHandlingTest() { + var containerComponentId = "containerComponentId"; + var componentInstanceUniqueId = "componentInstanceUniqueId"; + var capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setUniqueId("uniqueId"); + + final Component component = new Service(); + component.setUniqueId(containerComponentId); + component.setLastUpdaterUserId(USER_ID); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + var componentInstance = new ComponentInstance(); + componentInstance.setUniqueId(componentInstanceUniqueId); + component.setComponentInstances(Collections.singletonList(componentInstance)); + + var expectedResponseFormat = new ResponseFormat(); + + when(toscaOperationFacade.getToscaFullElement(containerComponentId)) + .thenReturn(Either.left(component)); + when(graphLockOperation.lockComponent(containerComponentId, NodeTypeEnum.Service)) + .thenReturn(StorageOperationStatus.OK); + when(toscaOperationFacade.updateComponentInstanceCapability(containerComponentId, componentInstanceUniqueId, capabilityDefinition)) + .thenThrow(new RuntimeException()); + when(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)) + .thenReturn(expectedResponseFormat); + + final Exception exception = assertThrows(BusinessException.class, () -> + componentInstanceBusinessLogic + .updateInstanceCapability(ComponentTypeEnum.SERVICE, containerComponentId, componentInstanceUniqueId, capabilityDefinition, USER_ID)); + assertTrue(exception instanceof ByResponseFormatComponentException); + final ByResponseFormatComponentException actualException = (ByResponseFormatComponentException) exception; + assertEquals(expectedResponseFormat, actualException.getResponseFormat()); + } + + private ComponentInstance createServiceSubstitutionComponentInstance() { + final ComponentInstance instanceToBeCreated = new ComponentInstance(); + instanceToBeCreated.setName(COMPONENT_INSTANCE_NAME); + instanceToBeCreated.setUniqueId(COMPONENT_INSTANCE_ID); + instanceToBeCreated.setComponentUid(ORIGIN_COMPONENT_ID); + instanceToBeCreated.setOriginType(OriginTypeEnum.ServiceSubstitution); + + return instanceToBeCreated; + } + + private Service createServiceSubstitutionOriginService() { + final Service originComponent = new Service(); + originComponent.setLifecycleState(LifecycleStateEnum.CERTIFIED); + originComponent.setVersion(ORIGIN_COMPONENT_VERSION); + originComponent.setIcon(ICON_NAME); + originComponent.setDerivedFromGenericType("org.openecomp.resource.abstract.nodes.service"); + originComponent.setName("myService"); + return originComponent; + } + + private Component createServiceSubstitutionServiceDerivedFromComponent() { + final Resource component = new Resource(); + component.setLifecycleState(LifecycleStateEnum.CERTIFIED); + component.setVersion(ORIGIN_COMPONENT_VERSION); + component.setIcon(ICON_NAME); + component.setToscaResourceName("org.openecomp.resource.abstract.nodes.service"); + component.setUniqueId("baseComponentId"); + return component; + } + } +