diff options
Diffstat (limited to 'catalog-be/src/main')
9 files changed, 165 insertions, 75 deletions
diff --git a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb index 69fd11da97..3b9d437ba6 100644 --- a/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb +++ b/catalog-be/src/main/docker/backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb @@ -1017,9 +1017,16 @@ genericAssetNodeTypes: Service: org.openecomp.resource.abstract.nodes.service ETSI NFV Network Service: tosca.nodes.nfv.NS -serviceNodeTypes: +# Defines the base types for Services +# <category name>: +# required: <boolean> //if the base type is mandatory or not +# baseTypes: <list of TOSCA types> //the base types. Required if the base type is required. +# If not provided, the category will have no base type. +serviceBaseNodeTypes: ETSI NFV Network Service: - - tosca.nodes.nfv.NS + required: true + baseTypes: + - tosca.nodes.nfv.NS workloadContext: Production diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java index 42fa95e642..caea46aae8 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java @@ -1291,6 +1291,16 @@ public class ElementBusinessLogic extends BaseBusinessLogic { if (ActionStatus.OK != status) { return Either.right(status); } - return Either.left(elementOperation.getBaseTypes(categoryName, modelName)); + return Either.left(elementOperation.getServiceBaseTypes(categoryName, modelName)); + } + + /** + * Checks if a category requires a base type. + * + * @param categoryName the category name + * @return {@code true} if a base type is required, {@code false} otherwise. + */ + public boolean isBaseTypeRequired(final String categoryName) { + return elementOperation.isBaseTypeRequired(categoryName); } } 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 50cf5d8c65..e51aeefa55 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,9 +701,11 @@ public class ServiceBusinessLogic extends ComponentBusinessLogic { createMandatoryArtifactsData(service, user); createServiceApiArtifactsData(service, user); setToscaArtifactsPlaceHolders(service, user); - final Resource genericType = fetchAndSetDerivedFromGenericType(service); - generatePropertiesFromGenericType(service, genericType); - generateAndAddInputsFromGenericTypeProperties(service, genericType); + if (service.isSubstituteCandidate()) { + final Resource genericType = fetchAndSetDerivedFromGenericType(service); + generatePropertiesFromGenericType(service, genericType); + generateAndAddInputsFromGenericTypeProperties(service, genericType); + } beforeCreate(service); Either<Service, StorageOperationStatus> dataModelResponse = toscaOperationFacade.createToscaComponent(service); if (dataModelResponse.isLeft()) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/exception/ToscaExportException.java b/catalog-be/src/main/java/org/openecomp/sdc/be/exception/ToscaExportException.java index d38f08f376..aec931a02a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/exception/ToscaExportException.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/exception/ToscaExportException.java @@ -18,9 +18,21 @@ */ package org.openecomp.sdc.be.exception; +import lombok.Getter; +import org.openecomp.sdc.be.tosca.ToscaError; + public class ToscaExportException extends Exception { + @Getter + private final ToscaError toscaError; + public ToscaExportException(String message) { super(message); + toscaError = null; + } + + public ToscaExportException(final String message, final ToscaError toscaError) { + super(message); + this.toscaError = toscaError; } } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java index 45f99a931e..f11bd8187a 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java @@ -216,6 +216,7 @@ public class ElementServlet extends BeGenericServlet { } else { final Map<String, Object> baseTypesMap = new HashMap<>(); baseTypesMap.put("baseTypes", either.left().value()); + baseTypesMap.put("required", elementBL.isBaseTypeRequired(categoryName)); return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), baseTypesMap); } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java index bf42af8322..a074eb8145 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabilityRequirementConverter.java @@ -56,7 +56,6 @@ import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.utils.ComponentUtilities; import org.openecomp.sdc.be.tosca.ToscaUtils.SubstitutionEntry; -import org.openecomp.sdc.be.tosca.model.SubstitutionMapping; import org.openecomp.sdc.be.tosca.model.ToscaCapability; import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate; import org.openecomp.sdc.be.tosca.model.ToscaNodeType; @@ -198,24 +197,22 @@ public class CapabilityRequirementConverter { /** * Allows to convert component requirements to the tosca template substitution mappings requirements * - * @param componentsCache * @param component - * @param substitutionMappings + * @param componentsCache * @return */ - public Either<SubstitutionMapping, ToscaError> convertSubstitutionMappingRequirements(Map<String, Component> componentsCache, Component component, - SubstitutionMapping substitutionMappings) { - Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings); + public Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingRequirements(final Component component, + final Map<String, Component> componentsCache) { Either<Map<String, String[]>, ToscaError> toscaRequirementsRes = convertSubstitutionMappingRequirementsAsMap(componentsCache, component); if (toscaRequirementsRes.isRight()) { - result = Either.right(toscaRequirementsRes.right().value()); logger.debug("Failed convert requirements for the component {}. ", component.getName()); - } else if (MapUtils.isNotEmpty(toscaRequirementsRes.left().value())) { - substitutionMappings.setRequirements(toscaRequirementsRes.left().value()); - result = Either.left(substitutionMappings); + return Either.right(toscaRequirementsRes.right().value()); + } + if (MapUtils.isNotEmpty(toscaRequirementsRes.left().value())) { logger.debug("Finish convert requirements for the component {}. ", component.getName()); + return Either.left(toscaRequirementsRes.left().value()); } - return result; + return Either.left(Collections.emptyMap()); } /** diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java index 1f17a6fdc5..f9662cc96e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java @@ -431,9 +431,9 @@ public class CsarUtils { LifecycleStateEnum lifecycleState = component.getLifecycleState(); addServiceMf(component, zip, lifecycleState, isInCertificationRequest, fileName, mainYaml); //US798487 - Abstraction of complex types - if (!ModelConverter.isAtomicComponent(component)) { + if (hasToWriteComponentSubstitutionType(component)) { log.debug("Component {} is complex - generating abstract type for it..", component.getName()); - dependencies.addAll(writeComponentInterface(component, zip, fileName, false)); + dependencies.addAll(writeComponentInterface(component, zip, fileName)); } //UID <cassandraId,filename,component> Either<ZipOutputStream, ResponseFormat> zipOutputStreamOrResponseFormat = getZipOutputStreamResponseFormatEither(zip, dependencies); @@ -648,13 +648,20 @@ public class CsarUtils { zip.putNextEntry(value._2); zip.write(value._1); // add component interface to zip - if (!ModelConverter.isAtomicComponent(innerComponent)) { - writeComponentInterface(innerComponent, zip, icFileName, true); + if (hasToWriteComponentSubstitutionType(innerComponent)) { + writeComponentInterface(innerComponent, zip, icFileName); } } return null; } + private boolean hasToWriteComponentSubstitutionType(final Component component) { + if (component instanceof Service) { + return !ModelConverter.isAtomicComponent(component) && ((Service) component).isSubstituteCandidate(); + } + return !ModelConverter.isAtomicComponent(component); + } + private Either<Tuple2<byte[], ZipEntry>, ResponseFormat> toZipEntry(ImmutableTriple<String, String, Component> cachedEntry) { String cassandraId = cachedEntry.getLeft(); String fileName = cachedEntry.getMiddle(); @@ -767,22 +774,18 @@ public class CsarUtils { return componentRI; } - private List<Triple<String, String, Component>> writeComponentInterface(Component component, - ZipOutputStream zip, - String fileName, - boolean isAssociatedComponent - ){ + private List<Triple<String, String, Component>> writeComponentInterface(final Component component, final ZipOutputStream zip, + final String fileName) { final Either<ToscaRepresentation, ToscaError> interfaceRepresentation = toscaExportUtils.exportComponentInterface(component, false); - writeComponentInterface(interfaceRepresentation, zip, fileName, false); + writeComponentInterface(interfaceRepresentation, zip, fileName); return interfaceRepresentation.left().value().getDependencies().getOrElse(new ArrayList<>()); } - private Either<ZipOutputStream, ResponseFormat> writeComponentInterface( - Either<ToscaRepresentation,ToscaError> interfaceRepresentation, ZipOutputStream zip, String fileName, - boolean isAssociatedComponent) { + private Either<ZipOutputStream, ResponseFormat> writeComponentInterface(Either<ToscaRepresentation, ToscaError> interfaceRepresentation, + ZipOutputStream zip, String fileName) { // TODO: This should not be done but we need this to keep the refactoring small enough to be easily reviewable - return writeComponentInterface(interfaceRepresentation, fileName, isAssociatedComponent, ZipWriter.live(zip)) + return writeComponentInterface(interfaceRepresentation, fileName, ZipWriter.live(zip)) .map(void0 -> Either.<ZipOutputStream, ResponseFormat>left(zip)).recover(th -> { log.error("#writeComponentInterface - zip writing failed with error: ", th); return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); @@ -790,7 +793,7 @@ public class CsarUtils { } private Try<Void> writeComponentInterface( - Either<ToscaRepresentation,ToscaError> interfaceRepresentation, String fileName, boolean isAssociatedComponent, ZipWriter zw) { + Either<ToscaRepresentation,ToscaError> interfaceRepresentation, String fileName, ZipWriter zw) { Either<byte[], ToscaError> yml = interfaceRepresentation.left() .map(ToscaRepresentation::getMainYaml); return fromEither(yml, ToscaErrorException::new).flatMap(zw.write(DEFINITIONS_PATH + ToscaExportHandler.getInterfaceFilename(fileName))); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java index 3c44c4fec9..d228db5f4b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -385,8 +385,6 @@ public class ToscaExportHandler { if (!relationshipTemplatesMap.isEmpty()) { topologyTemplate.setRelationshipTemplates(relationshipTemplatesMap); } - SubstitutionMapping substitutionMapping = new SubstitutionMapping(); - convertSubstitutionMappingFilter(component, substitutionMapping); addGroupsToTopologyTemplate(component, topologyTemplate); try { addPoliciesToTopologyTemplate(component, topologyTemplate); @@ -394,48 +392,86 @@ public class ToscaExportHandler { log.debug("Fail to add policies to topology template:", e); return Either.right(ToscaError.GENERAL_ERROR); } - String toscaResourceName; + try { + createSubstitutionMapping(component, componentCache).ifPresent(topologyTemplate::setSubstitution_mappings); + } catch (final ToscaExportException e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ToscaExportHandler.class.getName(), e.getMessage()); + return Either.right(e.getToscaError()); + } + if (!topologyTemplate.isEmpty()) { + toscaNode.setTopology_template(topologyTemplate); + } + return Either.left(toscaNode); + } + + private Either<String, ToscaError> createComponentToscaName(final Component component) { switch (component.getComponentType()) { case RESOURCE: - toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()) - .getToscaResourceName(); - break; + final ResourceMetadataDataDefinition resourceMetadata = + (ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition(); + return Either.left(resourceMetadata.getToscaResourceName()); case SERVICE: - toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName(); - break; + return Either.left(SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName()); default: log.debug(NOT_SUPPORTED_COMPONENT_TYPE, component.getComponentType()); return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE); } + } + + private Optional<SubstitutionMapping> createSubstitutionMapping(final Component component, + final Map<String, Component> componentCache) throws ToscaExportException { + if (component instanceof Service && !((Service) component).isSubstituteCandidate()) { + return Optional.empty(); + } + + final Either<String, ToscaError> toscaResourceNameEither = createComponentToscaName(component); + if (toscaResourceNameEither.isRight()) { + throw new ToscaExportException("Could not create component TOSCA name", toscaResourceNameEither.right().value()); + } + final String toscaResourceName = toscaResourceNameEither.left().value(); + + final SubstitutionMapping substitutionMapping = new SubstitutionMapping(); substitutionMapping.setNode_type(toscaResourceName); - Either<SubstitutionMapping, ToscaError> capabilities = convertCapabilities(component, substitutionMapping, componentCache); - if (capabilities.isRight()) { - return Either.right(capabilities.right().value()); + convertSubstitutionMappingFilter(component).ifPresent(substitutionMapping::setSubstitution_filter); + + final Either<Map<String, String[]>, ToscaError> capabilitiesEither = convertSubstitutionMappingCapabilities(component, componentCache); + if (capabilitiesEither.isRight()) { + throw new ToscaExportException("Could not convert substitution mapping capabilities", capabilitiesEither.right().value()); } - substitutionMapping = capabilities.left().value(); - Either<SubstitutionMapping, ToscaError> requirements = capabilityRequirementConverter - .convertSubstitutionMappingRequirements(componentCache, component, substitutionMapping); + final Map<String, String[]> capabilityMap = capabilitiesEither.left().value(); + if (!capabilityMap.isEmpty()) { + substitutionMapping.setCapabilities(capabilityMap); + } + + final Either<Map<String, String[]>, ToscaError> requirements = + capabilityRequirementConverter.convertSubstitutionMappingRequirements(component, componentCache); if (requirements.isRight()) { - return Either.right(requirements.right().value()); + throw new ToscaExportException("Could not convert substitution mapping requirements", requirements.right().value()); + } + final Map<String, String[]> requirementMap = requirements.left().value(); + if (!requirementMap.isEmpty()) { + substitutionMapping.setRequirements(requirementMap); } - substitutionMapping = requirements.left().value(); + final Map<String, String[]> propertyMappingMap = buildSubstitutionMappingPropertyMapping(component); if (!propertyMappingMap.isEmpty()) { substitutionMapping.setProperties(propertyMappingMap); } + final Map<String, String[]> attributesMappingMap = buildSubstitutionMappingAttributesMapping(component); if (!attributesMappingMap.isEmpty()) { substitutionMapping.setAttributes(attributesMappingMap); } - topologyTemplate.setSubstitution_mappings(substitutionMapping); - toscaNode.setTopology_template(topologyTemplate); - return Either.left(toscaNode); + + return Optional.of(substitutionMapping); } - private void convertSubstitutionMappingFilter(final Component component, final SubstitutionMapping substitutionMapping) { - if (component.getSubstitutionFilter() != null && (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() != null) { - substitutionMapping.setSubstitution_filter(convertToSubstitutionFilterComponent(component.getSubstitutionFilter())); + private Optional<NodeFilter> convertSubstitutionMappingFilter(final Component component) { + if (component.getSubstitutionFilter() == null || (component.getSubstitutionFilter().getProperties()).getListToscaDataDefinition() == null) { + return Optional.empty(); } + + return Optional.ofNullable(convertToSubstitutionFilterComponent(component.getSubstitutionFilter())); } private void addGroupsToTopologyTemplate(Component component, ToscaTopolgyTemplate topologyTemplate) { @@ -544,18 +580,9 @@ public class ToscaExportHandler { toscaTemplate.getImports() == null ? new ArrayList<>(defaultToscaImportConfig) : new ArrayList<>(toscaTemplate.getImports()); List<Triple<String, String, Component>> dependencies = new ArrayList<>(); Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts(); - if (isNotEmpty(toscaArtifacts)) { - ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); - if (artifactDefinition != null) { - Map<String, Map<String, String>> importsListMember = new HashMap<>(); - Map<String, String> interfaceFiles = new HashMap<>(); - interfaceFiles.put(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName())); - StringBuilder keyNameBuilder = new StringBuilder(); - keyNameBuilder.append(component.getComponentType().toString().toLowerCase()).append("-").append(component.getName()) - .append("-interface"); - importsListMember.put(keyNameBuilder.toString(), interfaceFiles); - additionalImports.add(importsListMember); - } + final Map<String, Map<String, String>> substituteTypeImportEntry = generateComponentSubstituteTypeImport(component, toscaArtifacts); + if (!substituteTypeImportEntry.isEmpty()) { + additionalImports.add(substituteTypeImportEntry); } List<ComponentInstance> componentInstances = component.getComponentInstances(); if (componentInstances != null && !componentInstances.isEmpty()) { @@ -569,6 +596,25 @@ public class ToscaExportHandler { return Either.left(new ImmutablePair<>(toscaTemplate, componentCache)); } + private Map<String, Map<String, String>> generateComponentSubstituteTypeImport(final Component component, + final Map<String, ArtifactDefinition> toscaArtifacts) { + + if (component instanceof Service && !((Service) component).isSubstituteCandidate()) { + return Collections.emptyMap(); + } + if (MapUtils.isEmpty(toscaArtifacts)) { + return Collections.emptyMap(); + } + final ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); + if (artifactDefinition == null) { + return Collections.emptyMap(); + } + final var importEntryName = component.getComponentType().toString().toLowerCase() + "-" + component.getName() + "-interface"; + return Map.of(importEntryName, + Map.of(IMPORTS_FILE_KEY, getInterfaceFilename(artifactDefinition.getArtifactName())) + ); + } + private List<Map<String, Map<String, String>>> getDefaultToscaImportConfig() { return getConfiguration().getDefaultImports(); } @@ -1459,20 +1505,21 @@ public class ToscaExportHandler { return component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.CVFC; } - private Either<SubstitutionMapping, ToscaError> convertCapabilities(Component component, SubstitutionMapping substitutionMappings, - Map<String, Component> componentCache) { - Either<SubstitutionMapping, ToscaError> result = Either.left(substitutionMappings); - Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = capabilityRequirementConverter - .convertSubstitutionMappingCapabilities(componentCache, component); + private Either<Map<String, String[]>, ToscaError> convertSubstitutionMappingCapabilities(final Component component, + final Map<String, Component> componentCache) { + Either<Map<String, String[]>, ToscaError> toscaCapabilitiesRes = + capabilityRequirementConverter.convertSubstitutionMappingCapabilities(componentCache, component); if (toscaCapabilitiesRes.isRight()) { - result = Either.right(toscaCapabilitiesRes.right().value()); log.debug("Failed convert capabilities for the component {}. ", component.getName()); - } else if (isNotEmpty(toscaCapabilitiesRes.left().value())) { - substitutionMappings.setCapabilities(toscaCapabilitiesRes.left().value()); + return Either.right(toscaCapabilitiesRes.right().value()); + } + if (isNotEmpty(toscaCapabilitiesRes.left().value())) { log.debug("Finish convert capabilities for the component {}. ", component.getName()); + return Either.left(toscaCapabilitiesRes.left().value()); } log.debug("Finished to convert capabilities for the component {}. ", component.getName()); - return result; + + return Either.left(Collections.emptyMap()); } private Either<ToscaNodeType, ToscaError> convertCapabilities(Map<String, Component> componentsCache, Component component, ToscaNodeType nodeType, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java index a2dc5091e9..b9fb5b10cf 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java @@ -23,6 +23,7 @@ import java.util.HashMap; import java.util.Map; import lombok.Getter; import lombok.Setter; +import org.apache.commons.collections.MapUtils; @Getter public class ToscaTopolgyTemplate { @@ -53,4 +54,14 @@ public class ToscaTopolgyTemplate { } this.policies.putAll(policiesMap); } + + public boolean isEmpty() { + return substitution_mappings == null && + MapUtils.isEmpty(inputs) && + MapUtils.isEmpty(outputs) && + MapUtils.isEmpty(node_templates) && + MapUtils.isEmpty(groups) && + MapUtils.isEmpty(policies) && + MapUtils.isEmpty(relationshipTemplates); + } } |