From f2eb0c84057d745b8cc7e77a027dcd47122a7a5b Mon Sep 17 00:00:00 2001 From: "andre.schmid" Date: Tue, 23 Nov 2021 21:35:12 +0000 Subject: Set default base type when none is provided Sets a default base type (substitution type) when no base type is provided during the creation of a service with a category that requires a base type. Previous to the introduction of the optional base type, the system would always add a base type to a Service. Change-Id: I32e892fc23719fd569062ee806eb0be7b5af4ac6 Issue-ID: SDC-3791 Signed-off-by: andre.schmid --- .../be/components/impl/ServiceBusinessLogic.java | 3 +- .../impl/generic/GenericTypeBusinessLogic.java | 38 ++++++- .../impl/generic/GenericTypeBusinessLogicTest.java | 122 +++++++++++++++++---- .../resources/config/catalog-be/configuration.yaml | 9 ++ 4 files changed, 145 insertions(+), 27 deletions(-) (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java index e51aeefa55..24ba0ead46 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -701,7 +701,8 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { createMandatoryArtifactsData(service, user); createServiceApiArtifactsData(service, user); setToscaArtifactsPlaceHolders(service, user); - if (service.isSubstituteCandidate()) { + + if (service.isSubstituteCandidate() || genericTypeBusinessLogic.hasMandatorySubstitutionType(service)) { final Resource genericType = fetchAndSetDerivedFromGenericType(service); generatePropertiesFromGenericType(service, genericType); generateAndAddInputsFromGenericTypeProperties(service, genericType); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java index 07d71eabb4..600f7fa3eb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogic.java @@ -22,9 +22,12 @@ package org.openecomp.sdc.be.components.impl.generic; import fj.data.Either; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.config.CategoryBaseTypeConfig; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; @@ -33,6 +36,7 @@ import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.common.log.wrappers.Logger; @@ -42,7 +46,7 @@ import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Component public class GenericTypeBusinessLogic { - private final static Logger log = Logger.getLogger(GenericTypeBusinessLogic.class); + private static final Logger log = Logger.getLogger(GenericTypeBusinessLogic.class); private final ComponentsUtils componentsUtils; private final ToscaOperationFacade toscaOperationFacade; @@ -66,7 +70,7 @@ public class GenericTypeBusinessLogic { Either genericType; if (StringUtils.isEmpty(component.getDerivedFromGenericVersion())){ genericType = toscaOperationFacade - .getLatestCertifiedNodeTypeByToscaResourceName(genericTypeToscaName); + .getLatestCertifiedNodeTypeByToscaResourceName(genericTypeToscaName); if (genericType.isRight()) { log.debug("Failed to fetch certified node type by tosca resource name {}", genericTypeToscaName); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERIC_TYPE_NOT_FOUND, component.assetType(), genericTypeToscaName)); @@ -91,6 +95,36 @@ public class GenericTypeBusinessLogic { return fetchDerivedFromGenericType(component); } + /** + * Checks if the component requires a substitution type. + * + * @param component the component to test + * @return {@code true} if the component requires a substitution type, {@code false} otherwise. + */ + public boolean hasMandatorySubstitutionType(final Component component) { + if (!component.isService()) { + return true; + } + + final Map serviceBaseNodeTypes = + ConfigurationManager.getConfigurationManager().getConfiguration().getServiceBaseNodeTypes(); + if (serviceBaseNodeTypes == null) { + return true; + } + + if (CollectionUtils.isEmpty(component.getCategories())) { + throw new IllegalArgumentException("The Service must contain at least one category"); + } + final CategoryDefinition categoryDefinition = component.getCategories().get(0); + + final CategoryBaseTypeConfig categoryBaseTypeConfig = serviceBaseNodeTypes.get(categoryDefinition.getName()); + if (categoryBaseTypeConfig == null) { + return true; + } + + return categoryBaseTypeConfig.isRequired(); + } + /** * @param genericType the generic node type * @return the generic type properties as inputs diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogicTest.java index 11b4fa0556..564e02dca5 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/generic/GenericTypeBusinessLogicTest.java @@ -21,29 +21,36 @@ */ package org.openecomp.sdc.be.components.impl.generic; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import fj.data.Either; -import org.junit.Before; -import org.junit.Test; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import org.mockito.InjectMocks; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.be.config.CategoryBaseTypeConfig; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; import org.openecomp.sdc.exception.ResponseFormat; -import java.util.Arrays; -import java.util.List; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.when; - -public class GenericTypeBusinessLogicTest { +class GenericTypeBusinessLogicTest { @InjectMocks private GenericTypeBusinessLogic testInstance; @@ -54,37 +61,52 @@ public class GenericTypeBusinessLogicTest { @Mock private ComponentsUtils componentsUtils; - @Before - public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); testInstance = new GenericTypeBusinessLogic(componentsUtils, toscaOperationFacadeMock); + final var configurationManager = new ConfigurationManager(); + + final var configuration = new Configuration(); + CategoryBaseTypeConfig categoryBaseTypeConfig1 = new CategoryBaseTypeConfig(); + categoryBaseTypeConfig1.setRequired(true); + CategoryBaseTypeConfig categoryBaseTypeConfig2 = new CategoryBaseTypeConfig(); + categoryBaseTypeConfig2.setRequired(false); + Map serviceBaseNodeTypeMap = Map.of( + "category1", categoryBaseTypeConfig1, + "category2", categoryBaseTypeConfig2 + ); + configuration.setServiceBaseNodeTypes(serviceBaseNodeTypeMap); + configurationManager.setConfiguration(configuration); } @Test - public void fetchDerivedFromGenericType_cvfv_getGenericResourceTypeFromDerivedFrom() throws Exception { + void fetchDerivedFromGenericType_cvfv_getGenericResourceTypeFromDerivedFrom() { Resource cvfc = new Resource(); cvfc.setResourceType(ResourceTypeEnum.CVFC); cvfc.setDerivedFrom(Arrays.asList("genericType", "someOtherType")); cvfc.setDerivedFromGenericType("genericType"); Resource genericResource = new Resource(); - when(toscaOperationFacadeMock.getLatestCertifiedNodeTypeByToscaResourceName("genericType")).thenReturn(Either.left(genericResource)); + when(toscaOperationFacadeMock.getLatestCertifiedNodeTypeByToscaResourceName(cvfc.getDerivedFromGenericType())) + .thenReturn(Either.left(genericResource)); Either fetchedGenericType = testInstance.fetchDerivedFromGenericType(cvfc); assertEquals(genericResource, fetchedGenericType.left().value()); } @Test - public void fetchDerivedFromGenericType_getGenericResourceTypeFromConfiguration() throws Exception { - Resource resource = Mockito.mock(Resource.class); + void fetchDerivedFromGenericType_getGenericResourceTypeFromConfiguration() { + Resource resource = mock(Resource.class); when(resource.getResourceType()).thenReturn(ResourceTypeEnum.VF); - when(resource.fetchGenericTypeToscaNameFromConfig()).thenReturn("genericType"); + final var genericType = "genericType"; + when(resource.fetchGenericTypeToscaNameFromConfig()).thenReturn(genericType); Resource genericResource = new Resource(); - when(toscaOperationFacadeMock.getLatestCertifiedNodeTypeByToscaResourceName("genericType")).thenReturn(Either.left(genericResource)); + when(toscaOperationFacadeMock.getLatestCertifiedNodeTypeByToscaResourceName(genericType)).thenReturn(Either.left(genericResource)); Either fetchedGenericType = testInstance.fetchDerivedFromGenericType(resource); assertEquals(genericResource, fetchedGenericType.left().value()); } @Test - public void generateInputsFromGenericTypeProperties() throws Exception { + void generateInputsFromGenericTypeProperties() { Resource genericNodeType = new Resource(); genericNodeType.setUniqueId("genericUid"); PropertyDefinition propertyDefinition = generatePropDefinition("prop1"); @@ -99,13 +121,66 @@ public class GenericTypeBusinessLogicTest { } @Test - public void generateInputsFromGenericTypeProperties_genericHasNoProps() throws Exception { + void generateInputsFromGenericTypeProperties_genericHasNoProps() { Resource genericNodeType = new Resource(); assertTrue(testInstance.generateInputsFromGenericTypeProperties(genericNodeType).isEmpty()); } + @Test + void hasMandatorySubstitutionForServiceTest() { + final var component = mock(Component.class); + when(component.isService()).thenReturn(true); + final var categoryDefinition = new CategoryDefinition(); + categoryDefinition.setName("category1"); + when(component.getCategories()).thenReturn(List.of(categoryDefinition)); + assertTrue(testInstance.hasMandatorySubstitutionType(component)); + } + + @Test + void hasMandatorySubstitutionForServiceWithNotRequiredCategoryTest() { + final var component = mock(Component.class); + when(component.isService()).thenReturn(true); + final var categoryDefinition = new CategoryDefinition(); + categoryDefinition.setName("category2"); + when(component.getCategories()).thenReturn(List.of(categoryDefinition)); + assertFalse(testInstance.hasMandatorySubstitutionType(component)); + } + + @Test + void hasMandatorySubstitutionForServiceWithNotConfiguredCategoryTest() { + final var component = mock(Component.class); + when(component.isService()).thenReturn(true); + final var categoryDefinition = new CategoryDefinition(); + categoryDefinition.setName("category3"); + when(component.getCategories()).thenReturn(List.of(categoryDefinition)); + assertTrue(testInstance.hasMandatorySubstitutionType(component)); + } + + @Test + void hasMandatorySubstitutionForServiceWithNonExistentConfigTest() { + final var configurationManager = new ConfigurationManager(); + configurationManager.setConfiguration(new Configuration()); + final var component = mock(Component.class); + when(component.isService()).thenReturn(true); + assertTrue(testInstance.hasMandatorySubstitutionType(component)); + } + + @Test + void hasMandatorySubstitutionServiceMissingCategoryTest() { + final Component component = mock(Component.class); + when(component.isService()).thenReturn(true); + assertThrows(IllegalArgumentException.class, () -> testInstance.hasMandatorySubstitutionType(component)); + } + + @Test + void hasMandatorySubstitutionTypeForNonServiceComponentTest() { + final Component component = mock(Component.class); + when(component.isService()).thenReturn(false); + assertTrue(testInstance.hasMandatorySubstitutionType(component)); + } + private void assertInput(InputDefinition inputDefinition, PropertyDefinition propertyDefinition) { - assertEquals(inputDefinition.getOwnerId(), "genericUid"); + assertEquals("genericUid", inputDefinition.getOwnerId()); assertEquals(inputDefinition.getValue(), propertyDefinition.getValue()); assertEquals(inputDefinition.getName(), propertyDefinition.getName()); } @@ -117,5 +192,4 @@ public class GenericTypeBusinessLogicTest { return propertyDefinition; } - } \ No newline at end of file diff --git a/catalog-be/src/test/resources/config/catalog-be/configuration.yaml b/catalog-be/src/test/resources/config/catalog-be/configuration.yaml index 4692342722..f33259903b 100644 --- a/catalog-be/src/test/resources/config/catalog-be/configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/configuration.yaml @@ -417,6 +417,15 @@ genericAssetNodeTypes: PNF: org.openecomp.resource.abstract.nodes.PNF Service: org.openecomp.resource.abstract.nodes.service +# Defines the base types for Services +# : +# required: //if the base type is mandatory or not +# baseTypes: //the base types. Required if the base type is required. +# If not provided, the category will have no base type. +serviceBaseNodeTypes: + cat_name: + required: false + workloadContext: Production environmentContext: -- cgit 1.2.3-korg