From 0c274e9356fc77c53340828b0ec18869dad71631 Mon Sep 17 00:00:00 2001 From: aribeiro Date: Sun, 2 Feb 2020 19:47:39 +0000 Subject: [PATCH] Support import of custom node type name Issue-ID: SDC-2760 Signed-off-by: aribeiro Change-Id: I3645c737ba367a3576d58afb581c8118eb0f6011 --- .../templates/default/BE-configuration.yaml.erb | 3 + .../be/components/impl/ResourceBusinessLogic.java | 560 ++++++++++++--------- .../be/servlets/AbstractValidationsServlet.java | 68 ++- .../src/main/resources/config/configuration.yaml | 3 + .../components/impl/ResourceBusinessLogicTest.java | 60 ++- .../sdc/be/servlets/ResourceServletTest.java | 16 +- .../resources/config/catalog-be/configuration.yaml | 4 +- .../org/openecomp/sdc/be/config/Configuration.java | 9 + docs/configuration.rst | 3 + 9 files changed, 436 insertions(+), 290 deletions(-) diff --git a/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb b/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb index 932d6122fe..754bdf34a5 100644 --- a/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb +++ b/catalog-be/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb @@ -950,3 +950,6 @@ cadiFilterParams: cadi_truststore: <%= node['access_restriction']['cadi_truststore'] %> cadi_truststore_password: <%= node['access_restriction']['cadi_truststore_password'] %> +# This configuration entry lists all node type names prefix that shall be allowed on SDC. +definedResourceNamespace: + - org.openecomp.resource. \ No newline at end of file diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 99f4dc6ddd..cd0f8a0f61 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -20,8 +20,36 @@ package org.openecomp.sdc.be.components.impl; +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static java.util.stream.Collectors.toSet; +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; +import static org.apache.commons.collections.MapUtils.isEmpty; +import static org.apache.commons.collections.MapUtils.isNotEmpty; +import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement; +import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue; +import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN; +import static org.openecomp.sdc.common.api.Constants.DEFAULT_GROUP_VF_MODULE; + import com.google.common.annotations.VisibleForTesting; import fj.data.Either; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import javax.servlet.ServletContext; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -158,35 +186,6 @@ import org.springframework.web.context.WebApplicationContext; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; -import javax.servlet.ServletContext; -import java.util.ArrayList; -import java.util.Collection; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; -import static java.util.stream.Collectors.toSet; -import static org.apache.commons.collections.CollectionUtils.isNotEmpty; -import static org.apache.commons.collections.MapUtils.isEmpty; -import static org.apache.commons.collections.MapUtils.isNotEmpty; -import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement; -import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue; -import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN; -import static org.openecomp.sdc.common.api.Constants.DEFAULT_GROUP_VF_MODULE; - @org.springframework.stereotype.Component("resourceBusinessLogic") public class ResourceBusinessLogic extends ComponentBusinessLogic { @@ -219,7 +218,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { private final CsarBusinessLogic csarBusinessLogic; private final PropertyBusinessLogic propertyBusinessLogic; - @Autowired + @Autowired public ResourceBusinessLogic(IElementOperation elementDao, IGroupOperation groupOperation, IGroupInstanceOperation groupInstanceOperation, @@ -808,23 +807,23 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } private Either>>, ResponseFormat> findNodeTypesArtifactsToHandle( - Map nodeTypesInfo, CsarInfo csarInfo, Resource oldResource) { + final Map nodeTypesInfo, final CsarInfo csarInfo, final Resource oldResource) { - Map>> nodeTypesArtifactsToHandle = new HashMap<>(); - Either>>, ResponseFormat> nodeTypesArtifactsToHandleRes = Either - .left(nodeTypesArtifactsToHandle); + final Map>> nodeTypesArtifactsToHandle = new HashMap<>(); + Either>>, ResponseFormat> + nodeTypesArtifactsToHandleRes = Either.left(nodeTypesArtifactsToHandle); try { - Map> extractedVfcsArtifacts = CsarUtils - .extractVfcsArtifactsFromCsar(csarInfo.getCsar()); - Map> extractedVfcToscaNames = extractVfcToscaNames(nodeTypesInfo, - oldResource.getName(), csarInfo); + final Map> extractedVfcsArtifacts = CsarUtils + .extractVfcsArtifactsFromCsar(csarInfo.getCsar()); + final Map> extractedVfcToscaNames = extractVfcToscaNames( + nodeTypesInfo, oldResource.getName(), csarInfo); log.debug("Going to fetch node types for resource with name {} during import csar with UUID {}. ", - oldResource.getName(), csarInfo.getCsarUUID()); + oldResource.getName(), csarInfo.getCsarUUID()); extractedVfcToscaNames.forEach((namespace, vfcToscaNames) -> findAddNodeTypeArtifactsToHandle(csarInfo, - nodeTypesArtifactsToHandle, oldResource, extractedVfcsArtifacts, namespace, vfcToscaNames)); + nodeTypesArtifactsToHandle, oldResource, extractedVfcsArtifacts, namespace, vfcToscaNames)); } catch (Exception e) { - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); nodeTypesArtifactsToHandleRes = Either.right(responseFormat); log.debug("Exception occurred when findNodeTypesUpdatedArtifacts, error is:{}", e.getMessage(), e); } @@ -1093,24 +1092,24 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { return handleNodeTypeArtifactsRes; } - private Map> extractVfcToscaNames(Map nodeTypesInfo, - String vfResourceName, CsarInfo csarInfo) { - Map> vfcToscaNames = new HashMap<>(); + private Map> extractVfcToscaNames(final Map nodeTypesInfo, + final String vfResourceName, + final CsarInfo csarInfo) { + final Map> vfcToscaNames = new HashMap<>(); - Map nodes = extractAllNodes(nodeTypesInfo, csarInfo); + final Map nodes = extractAllNodes(nodeTypesInfo, csarInfo); if (!nodes.isEmpty()) { - Iterator> nodesNameEntry = nodes.entrySet() - .iterator(); + final Iterator> nodesNameEntry = nodes.entrySet().iterator(); while (nodesNameEntry.hasNext()) { - Entry nodeType = nodesNameEntry.next(); - ImmutablePair toscaResourceName = buildNestedToscaResourceName( - ResourceTypeEnum.VFC.name(), vfResourceName, nodeType.getKey()); + final Entry nodeType = nodesNameEntry.next(); + final ImmutablePair toscaResourceName = buildNestedToscaResourceName( + ResourceTypeEnum.VFC.name(), vfResourceName, nodeType.getKey()); vfcToscaNames.put(nodeType.getKey(), toscaResourceName); } } - for (NodeTypeInfo cvfc : nodeTypesInfo.values()) { - vfcToscaNames.put(cvfc.getType(), - buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), vfResourceName, cvfc.getType())); + for (final NodeTypeInfo cvfc : nodeTypesInfo.values()) { + vfcToscaNames.put(cvfc.getType(), buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), + vfResourceName, cvfc.getType())); } return vfcToscaNames; } @@ -1298,51 +1297,43 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { return resource; } - private Resource handleComplexVfc(Resource resource, - Map>> nodesArtifactsToHandle, - List createdArtifacts, Map nodesInfo, CsarInfo csarInfo, - String nodeName, String yamlName) { + private Resource handleComplexVfc(final Resource resource, + final Map>> + nodesArtifactsToHandle, + final List + createdArtifacts, Map nodesInfo, CsarInfo csarInfo, + final String nodeName, final String yamlName) { Resource oldComplexVfc = null; Resource newComplexVfc = buildValidComplexVfc(resource, csarInfo, nodeName, nodesInfo); Either oldComplexVfcRes = toscaOperationFacade - .getFullLatestComponentByToscaResourceName(newComplexVfc.getToscaResourceName()); - if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right() - .value() == StorageOperationStatus.NOT_FOUND) { + .getFullLatestComponentByToscaResourceName(newComplexVfc.getToscaResourceName()); + if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() == StorageOperationStatus.NOT_FOUND) { oldComplexVfcRes = toscaOperationFacade.getFullLatestComponentByToscaResourceName( - buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName) - .getRight()); + buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getRight()); } - if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right() - .value() != StorageOperationStatus.NOT_FOUND) { + if (oldComplexVfcRes.isRight() && oldComplexVfcRes.right().value() != StorageOperationStatus.NOT_FOUND) { log.debug("Failed to fetch previous complex VFC by tosca resource name {}. Status is {}. ", - newComplexVfc.getToscaResourceName(), oldComplexVfcRes.right() - .value()); + newComplexVfc.getToscaResourceName(), oldComplexVfcRes.right().value()); throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); } else if (oldComplexVfcRes.isLeft()) { log.debug(VALIDATE_DERIVED_BEFORE_UPDATE); - Either eitherValidation = validateNestedDerivedFromDuringUpdate( - oldComplexVfcRes.left() - .value(), - newComplexVfc, ValidationUtils.hasBeenCertified(oldComplexVfcRes.left() - .value() - .getVersion())); + final Either eitherValidation = validateNestedDerivedFromDuringUpdate( + oldComplexVfcRes.left().value(), + newComplexVfc, ValidationUtils.hasBeenCertified(oldComplexVfcRes.left().value().getVersion())); if (eitherValidation.isLeft()) { - oldComplexVfc = oldComplexVfcRes.left() - .value(); + oldComplexVfc = oldComplexVfcRes.left().value(); } } newComplexVfc = handleComplexVfc(nodesArtifactsToHandle, createdArtifacts, nodesInfo, csarInfo, nodeName, - yamlName, oldComplexVfc, newComplexVfc); - csarInfo.getCreatedNodesToscaResourceNames() - .put(nodeName, newComplexVfc.getToscaResourceName()); - LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT, - LifecycleChanceActionEnum.CREATE_FROM_CSAR); + yamlName, oldComplexVfc, newComplexVfc); + csarInfo.getCreatedNodesToscaResourceNames().put(nodeName, newComplexVfc.getToscaResourceName()); + final LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(CERTIFICATION_ON_IMPORT, + LifecycleChanceActionEnum.CREATE_FROM_CSAR); log.debug("Going to certify cvfc {}. ", newComplexVfc.getName()); - Resource result = propagateStateToCertified(csarInfo.getModifier(), newComplexVfc, + final Resource result = propagateStateToCertified(csarInfo.getModifier(), newComplexVfc, lifecycleChangeInfo, true, false, true); - csarInfo.getCreatedNodes() - .put(nodeName, result); + csarInfo.getCreatedNodes().put(nodeName, result); csarInfo.removeNodeFromQueue(); return result; } @@ -1383,39 +1374,47 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { true, csarInfo); } - private String getNodeTypeActualName(String fullName) { - String nameWithouNamespacePrefix = fullName - .substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); - String[] findTypes = nameWithouNamespacePrefix.split("\\."); - String resourceType = findTypes[0]; + private String getNodeTypeActualName(final String nodeTypefullName, final String nodeTypeNamePrefix) { + + final String nameWithouNamespacePrefix = nodeTypefullName.substring(nodeTypeNamePrefix.length()); + final String[] findTypes = nameWithouNamespacePrefix.split("\\."); + final String resourceType = findTypes[0]; return nameWithouNamespacePrefix.substring(resourceType.length()); } - private ImmutablePair createNodeTypeResourceFromYaml(String yamlName, - Entry nodeNameValue, User user, Map mapToConvert, Resource resourceVf, - boolean needLock, Map> nodeTypeArtifactsToHandle, - List nodeTypesNewCreatedArtifacts, boolean forceCertificationAllowed, CsarInfo csarInfo, - boolean isNested) { + private ImmutablePair createNodeTypeResourceFromYaml(final String yamlName, + final Entry nodeNameValue, + User user, + final Map mapToConvert, + final Resource resourceVf, + final boolean needLock, + final Map> nodeTypeArtifactsToHandle, + final List nodeTypesNewCreatedArtifacts, + final boolean forceCertificationAllowed, + final CsarInfo csarInfo, + final boolean isNested) { - UploadResourceInfo resourceMetaData = fillResourceMetadata(yamlName, resourceVf, nodeNameValue.getKey(), user); + final UploadResourceInfo resourceMetaData = fillResourceMetadata( + yamlName, resourceVf, nodeNameValue.getKey(), user); - String singleVfcYaml = buildNodeTypeYaml(nodeNameValue, mapToConvert, resourceMetaData.getResourceType(), - csarInfo); + final String singleVfcYaml = buildNodeTypeYaml(nodeNameValue, mapToConvert, resourceMetaData.getResourceType(), csarInfo); user = validateUser(user, "CheckIn Resource", resourceVf, AuditingActionEnum.CHECKIN_RESOURCE, true); return createResourceFromNodeType(singleVfcYaml, resourceMetaData, user, true, needLock, nodeTypeArtifactsToHandle, nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeNameValue.getKey(), isNested); } - private String buildNodeTypeYaml(Entry nodeNameValue, Map mapToConvert, - String nodeResourceType, CsarInfo csarInfo) { + private String buildNodeTypeYaml(final Entry nodeNameValue, + final Map mapToConvert, + final String nodeResourceType, + final CsarInfo csarInfo) { // We need to create a Yaml from each node_types in order to create // resource from each node type using import normative flow. - DumperOptions options = new DumperOptions(); + final DumperOptions options = new DumperOptions(); options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); - Yaml yaml = new Yaml(options); + final Yaml yaml = new Yaml(options); - Map node = new HashMap<>(); + final Map node = new HashMap<>(); node.put(buildNestedToscaResourceName(nodeResourceType, csarInfo.getVfResourceName(), nodeNameValue.getKey()) .getLeft(), nodeNameValue.getValue()); mapToConvert.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), node); @@ -1443,45 +1442,71 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { nodeTypesNewCreatedArtifacts, forceCertificationAllowed, csarInfo, nodeName, isNested); } - /*private ImmutablePair failOnCertification(ResponseFormat error) { - throw new ByResponseFormatComponentException(); - }*/ + /** + * Validates if a given node type name has a valid prefix. + * + * @param nodeName node name from definition file + * @param definedResourceNamespaceList is a list of all node type name prefix allowed + * @return a valid node type name prefix if it`s found + */ + public Optional validateNodeTypeNamePrefix(final String nodeName, + final List definedResourceNamespaceList) { + for (final String validNamespace : definedResourceNamespaceList) { + if (nodeName.startsWith(validNamespace)) { + return Optional.of(validNamespace); + } + } + return Optional.empty(); + } + + private List getDefinedNodeTypeNamespaceList() { + return ConfigurationManager.getConfigurationManager().getConfiguration().getDefinedResourceNamespace(); + } + + private UploadResourceInfo fillResourceMetadata(final String yamlName, final Resource resourceVf, + final String nodeName, final User user) { + + final UploadResourceInfo resourceMetaData = new UploadResourceInfo(); - private UploadResourceInfo fillResourceMetadata(String yamlName, Resource resourceVf, String nodeName, User user) { - UploadResourceInfo resourceMetaData = new UploadResourceInfo(); + final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeName); + log.debug("Node type Name prefix {}", nodeTypeNamePrefix); - // validate nodetype name prefix - if (!nodeName.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX)) { - log.debug("invalid nodeName:{} does not start with {}.", nodeName, - Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX); - throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), - nodeName); + if (!nodeName.startsWith(nodeTypeNamePrefix)) { + log.debug("invalid nodeName:{} does not start with {}.", nodeName, getDefinedNodeTypeNamespaceList()); + throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, + resourceMetaData.getName(), nodeName); } - String actualName = this.getNodeTypeActualName(nodeName); - String namePrefix = nodeName.replace(actualName, ""); - String resourceType = namePrefix.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); + final String actualName = this.getNodeTypeActualName(nodeName, nodeTypeNamePrefix); + final String namePrefix = nodeName.replace(actualName, ""); + String resourceType = namePrefix.substring(nodeTypeNamePrefix.length()); + log.debug("initial namePrefix:{} resourceType {}. nodeName {} , actualName {} prefix {}", namePrefix, + resourceType, nodeName, actualName, nodeTypeNamePrefix); // if we import from csar, the node_type name can be // org.openecomp.resource.abstract.node_name - in this case we always // create a vfc if (resourceType.equals(Constants.ABSTRACT)) { - resourceType = ResourceTypeEnum.VFC.name() - .toLowerCase(); + resourceType = ResourceTypeEnum.VFC.name().toLowerCase(); } + + if (!ResourceTypeEnum.containsIgnoreCase(resourceType)) { + resourceType = ResourceTypeEnum.VFC.name().toLowerCase(); + } + // validating type if (!ResourceTypeEnum.containsName(resourceType.toUpperCase())) { - log.debug("invalid resourceType:{} the type is not one of the valide types:{}.", resourceType.toUpperCase(), - ResourceTypeEnum.values()); - throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), - nodeName); + log.debug("invalid resourceType:{} the type is not one of the valide types:{}.", + resourceType.toUpperCase(), ResourceTypeEnum.values()); + throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, + resourceMetaData.getName(), nodeName); } // Setting name - resourceMetaData.setName(resourceVf.getSystemName() + actualName); + resourceMetaData.setName(new StringBuilder(resourceVf.getSystemName()).append(actualName).toString()); // Setting type from name - String type = resourceType.toUpperCase(); + final String type = resourceType.toUpperCase(); resourceMetaData.setResourceType(type); resourceMetaData.setDescription(ImportUtils.Constants.INNER_VFC_DESCRIPTION); @@ -1491,27 +1516,29 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { resourceMetaData.setVendorRelease(resourceVf.getVendorRelease()); // Setting tag - List tags = new ArrayList<>(); + final List tags = new ArrayList<>(); tags.add(resourceMetaData.getName()); resourceMetaData.setTags(tags); // Setting category - CategoryDefinition category = new CategoryDefinition(); + final CategoryDefinition category = new CategoryDefinition(); category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME); - SubCategoryDefinition subCategory = new SubCategoryDefinition(); + final SubCategoryDefinition subCategory = new SubCategoryDefinition(); subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY); category.addSubCategory(subCategory); - List categories = new ArrayList<>(); + final List categories = new ArrayList<>(); categories.add(category); resourceMetaData.setCategories(categories); return resourceMetaData; } - private Resource buildComplexVfcMetadata(Resource resourceVf, CsarInfo csarInfo, String nodeName, - Map nodesInfo) { - Resource cvfc = new Resource(); - NodeTypeInfo nodeTypeInfo = nodesInfo.get(nodeName); + private Resource buildComplexVfcMetadata(final Resource resourceVf, + final CsarInfo csarInfo, + final String nodeName, + final Map nodesInfo) { + final Resource cvfc = new Resource(); + final NodeTypeInfo nodeTypeInfo = nodesInfo.get(nodeName); cvfc.setName(buildCvfcName(csarInfo.getVfResourceName(), nodeName)); cvfc.setNormalizedName(ValidationUtils.normaliseComponentName(cvfc.getName())); cvfc.setSystemName(ValidationUtils.convertToSystemName(cvfc.getName())); @@ -1527,21 +1554,20 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { cvfc.setVendorName(resourceVf.getVendorName()); cvfc.setVendorRelease(resourceVf.getVendorRelease()); cvfc.setResourceVendorModelNumber(resourceVf.getResourceVendorModelNumber()); - cvfc.setToscaResourceName( - buildNestedToscaResourceName(ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName) - .getLeft()); + cvfc.setToscaResourceName(buildNestedToscaResourceName( + ResourceTypeEnum.CVFC.name(), csarInfo.getVfResourceName(), nodeName).getLeft()); cvfc.setInvariantUUID(UniqueIdBuilder.buildInvariantUUID()); - List tags = new ArrayList<>(); + final List tags = new ArrayList<>(); tags.add(cvfc.getName()); cvfc.setTags(tags); - CategoryDefinition category = new CategoryDefinition(); + final CategoryDefinition category = new CategoryDefinition(); category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME); SubCategoryDefinition subCategory = new SubCategoryDefinition(); subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY); category.addSubCategory(subCategory); - List categories = new ArrayList<>(); + final List categories = new ArrayList<>(); categories.add(category); cvfc.setCategories(categories); @@ -1552,26 +1578,34 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { return cvfc; } - private String buildCvfcName(String resourceVfName, String nodeName) { - String nameWithouNamespacePrefix = nodeName - .substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); + private String buildCvfcName(final String resourceVfName, final String nodeName) { + + String nameWithouNamespacePrefix = + nodeName.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); String[] findTypes = nameWithouNamespacePrefix.split("\\."); String resourceType = findTypes[0]; String resourceName = resourceVfName + "-" + nameWithouNamespacePrefix.substring(resourceType.length() + 1); return addCvfcSuffixToResourceName(resourceName); } - private Resource createResourceAndRIsFromYaml(String yamlName, Resource resource, - ParsedToscaYamlInfo parsedToscaYamlInfo, AuditingActionEnum actionEnum, boolean isNormative, - List createdArtifacts, String topologyTemplateYaml, - Map nodeTypesInfo, CsarInfo csarInfo, - Map>> nodeTypesArtifactsToCreate, - boolean shouldLock, boolean inTransaction, String nodeName) { + private Resource createResourceAndRIsFromYaml(final String yamlName, + Resource resource, + final ParsedToscaYamlInfo parsedToscaYamlInfo, + final AuditingActionEnum actionEnum, + final boolean isNormative, + final List createdArtifacts, + final String topologyTemplateYaml, + final Map nodeTypesInfo, + final CsarInfo csarInfo, + final Map>> nodeTypesArtifactsToCreate, + final boolean shouldLock, + final boolean inTransaction, + final String nodeName) { - List nodeTypesNewCreatedArtifacts = new ArrayList<>(); + final List nodeTypesNewCreatedArtifacts = new ArrayList<>(); if (shouldLock) { - Either lockResult = lockComponentByName(resource.getSystemName(), resource, + final Either lockResult = lockComponentByName(resource.getSystemName(), resource, CREATE_RESOURCE); if (lockResult.isRight()) { rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); @@ -1583,8 +1617,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { log.trace("************* createResourceFromYaml before full create resource {}", yamlName); loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS,resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,"Starting to add inputs from yaml: {}",yamlName); final Resource genericResource = fetchAndSetDerivedFromGenericType(resource); - resource = createResourceTransaction(resource, - csarInfo.getModifier(), isNormative); + resource = createResourceTransaction(resource, csarInfo.getModifier(), isNormative); log.trace("************* createResourceFromYaml after full create resource {}", yamlName); log.trace("************* Going to add inputs from yaml {}", yamlName); if (resource.shouldGenerateInputs()) @@ -1593,11 +1626,13 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { final Map inputs = parsedToscaYamlInfo.getInputs(); resource = createInputsOnResource(resource, inputs); log.trace("************* Finish to add inputs from yaml {}", yamlName); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS,resource.getComponentMetadataForSupportLog(), - StatusCode.COMPLETE,"Finish to add inputs from yaml: {}",yamlName); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_INPUTS, + resource.getComponentMetadataForSupportLog(), + StatusCode.COMPLETE,"Finish to add inputs from yaml: {}",yamlName); if (resource.getResourceType() == ResourceTypeEnum.PNF) { log.trace("************* Adding generic properties to PNF"); - resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, genericResource.getProperties()); + resource = (Resource) propertyBusinessLogic.copyPropertyToComponent(resource, + genericResource.getProperties()); log.trace("************* Adding software information to PNF"); softwareInformationBusinessLogic.setSoftwareInformation(resource, csarInfo); log.trace("************* Removing non-mano software information file from PNF"); @@ -1608,68 +1643,70 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } } - Map uploadComponentInstanceInfoMap = parsedToscaYamlInfo - .getInstances(); + final Map uploadComponentInstanceInfoMap = parsedToscaYamlInfo + .getInstances(); log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName); loggerSupportability.log(LoggerSupportabilityActions.CREATE_RESOURCE_FROM_YAML,resource.getComponentMetadataForSupportLog(), StatusCode.STARTED,"Start create nodes, RI and Relations from yaml: {}",yamlName); resource = createRIAndRelationsFromYaml(yamlName, resource, uploadComponentInstanceInfoMap, - topologyTemplateYaml, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, - nodeTypesArtifactsToCreate, nodeName); + topologyTemplateYaml, nodeTypesNewCreatedArtifacts, nodeTypesInfo, csarInfo, nodeTypesArtifactsToCreate, + nodeName); log.trace("************* Finished to create nodes, RI and Relation from yaml {}", yamlName); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS,resource.getComponentMetadataForSupportLog(), StatusCode.COMPLETE,"Finished to create nodes, RI and Relation from yaml: {}",yamlName); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_RELATIONS, + resource.getComponentMetadataForSupportLog(), + StatusCode.COMPLETE,"Finished to create nodes, RI and Relation from yaml: {}",yamlName); // validate update vf module group names - Either, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic - .validateUpdateVfGroupNames(parsedToscaYamlInfo.getGroups(), resource.getSystemName()); + final Either, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic + .validateUpdateVfGroupNames(parsedToscaYamlInfo.getGroups(), resource.getSystemName()); if (validateUpdateVfGroupNamesRes.isRight()) { rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); throw new ByResponseFormatComponentException(validateUpdateVfGroupNamesRes.right().value()); } // add groups to resource - Map groups; + final Map groups; log.trace("************* Going to add groups from yaml {}", yamlName); loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS,resource.getComponentMetadataForSupportLog(), - StatusCode.STARTED,"Start to add groups from yaml: {}",yamlName); + StatusCode.STARTED,"Start to add groups from yaml: {}",yamlName); if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) { groups = validateUpdateVfGroupNamesRes.left().value(); } else { groups = parsedToscaYamlInfo.getGroups(); } - Either createGroupsOnResource = createGroupsOnResource(resource, groups); + final Either createGroupsOnResource = createGroupsOnResource(resource, groups); if (createGroupsOnResource.isRight()) { rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS,resource.getComponentMetadataForSupportLog(), - StatusCode.ERROR,"ERROR while adding groups from yaml: {}",yamlName); - throw new ByResponseFormatComponentException(createGroupsOnResource.right() - .value()); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, + resource.getComponentMetadataForSupportLog(), + StatusCode.ERROR,"ERROR while adding groups from yaml: {}",yamlName); + throw new ByResponseFormatComponentException(createGroupsOnResource.right().value()); } - resource = createGroupsOnResource.left() - .value(); + resource = createGroupsOnResource.left().value(); log.trace("************* Finished to add groups from yaml {}", yamlName); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS,resource.getComponentMetadataForSupportLog(), - StatusCode.COMPLETE,"Finished to add groups from yaml: {}",yamlName); - + loggerSupportability.log(LoggerSupportabilityActions.CREATE_GROUPS, + resource.getComponentMetadataForSupportLog(), + StatusCode.COMPLETE,"Finished to add groups from yaml: {}", yamlName); log.trace("************* Going to add artifacts from yaml {}", yamlName); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS,resource.getComponentMetadataForSupportLog(), - StatusCode.STARTED,"Started to add artifacts from yaml: {}",yamlName); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, + resource.getComponentMetadataForSupportLog(), + StatusCode.STARTED,"Started to add artifacts from yaml: {}",yamlName); - NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = new NodeTypeInfoToUpdateArtifacts(nodeName, - nodeTypesArtifactsToCreate); + final NodeTypeInfoToUpdateArtifacts nodeTypeInfoToUpdateArtifacts = + new NodeTypeInfoToUpdateArtifacts(nodeName, nodeTypesArtifactsToCreate); - Either createArtifactsEither = createOrUpdateArtifacts( - ArtifactOperationEnum.CREATE, createdArtifacts, yamlName, csarInfo, resource, - nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock); + final Either createArtifactsEither = createOrUpdateArtifacts( + ArtifactOperationEnum.CREATE, createdArtifacts, yamlName, csarInfo, resource, + nodeTypeInfoToUpdateArtifacts, inTransaction, shouldLock); if (createArtifactsEither.isRight()) { rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); - loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS,resource.getComponentMetadataForSupportLog(), - StatusCode.ERROR,"error happened {}",createArtifactsEither.right() - .value()); - throw new ByResponseFormatComponentException(createArtifactsEither.right() - .value()); - } - loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS,resource.getComponentMetadataForSupportLog(), - StatusCode.COMPLETE,"Finished to add artifacts from yaml: "+resource.getToscaResourceName()); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, + resource.getComponentMetadataForSupportLog(), StatusCode.ERROR,"error happened {}", + createArtifactsEither.right().value()); + throw new ByResponseFormatComponentException(createArtifactsEither.right().value()); + } + loggerSupportability.log(LoggerSupportabilityActions.CREATE_ARTIFACTS, + resource.getComponentMetadataForSupportLog(), + StatusCode.COMPLETE,"Finished to add artifacts from yaml: "+resource.getToscaResourceName()); + final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); componentsUtils.auditResource(responseFormat, csarInfo.getModifier(), resource, actionEnum); ASDCKpiApi.countCreatedResourcesKPI(); return resource; @@ -1680,8 +1717,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } catch (final ToscaOperationException e) { log.error("An error has occurred during resource and resource instance creation", e); rollback(inTransaction, resource, createdArtifacts, nodeTypesNewCreatedArtifacts); - log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR - , ResourceBusinessLogic.class.getName(), "catalog-be", e.getMessage()); + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceBusinessLogic.class.getName(), + "catalog-be", e.getMessage()); throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); } catch (final BusinessLogicException e) { log.error("An error has occurred during resource and resource instance creation", e); @@ -1693,7 +1730,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } if (shouldLock) { graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), - NodeTypeEnum.Resource); + NodeTypeEnum.Resource); } } } @@ -3771,27 +3808,30 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { needLock); } - public ImmutablePair createOrUpdateResourceByImport(Resource resource, User user, - boolean isNormative, boolean isInTransaction, boolean needLock, CsarInfo csarInfo, String nodeName, - boolean isNested) { + public ImmutablePair createOrUpdateResourceByImport(final Resource resource, + final User user, + final boolean isNormative, + final boolean isInTransaction, + final boolean needLock, + final CsarInfo csarInfo, + final String nodeName, + final boolean isNested) { ImmutablePair result = null; // check if resource already exists (search by tosca name = type) - boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName); - Either latestByToscaName = toscaOperationFacade - .getLatestByToscaResourceName(resource.getToscaResourceName()); + final boolean isNestedResource = isNestedResourceUpdate(csarInfo, nodeName); + final Either latestByToscaName = toscaOperationFacade + .getLatestByToscaResourceName(resource.getToscaResourceName()); if (latestByToscaName.isLeft()) { - Resource foundResource = latestByToscaName.left() - .value(); + Resource foundResource = latestByToscaName.left().value(); // we don't allow updating names of top level types if (!isNestedResource && !StringUtils.equals(resource.getName(), foundResource.getName())) { - BeEcompErrorManager.getInstance() - .logBeComponentMissingError("Create / Update resource by import", - ComponentTypeEnum.RESOURCE.getValue(), resource.getName()); + BeEcompErrorManager.getInstance().logBeComponentMissingError("Create / Update resource by import", + ComponentTypeEnum.RESOURCE.getValue(), resource.getName()); log.debug("resource already exist new name={} old name={} same type={}", resource.getName(), - foundResource.getName(), resource.getToscaResourceName()); - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS); + foundResource.getName(), resource.getToscaResourceName()); + final ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS); componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE); throwComponentException(responseFormat); } @@ -3799,17 +3839,15 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } else if (isNotFound(latestByToscaName)) { if (isNestedResource) { result = createOrUpdateNestedResource(resource, user, isNormative, isInTransaction, needLock, csarInfo, - isNested, nodeName); + isNested, nodeName); } else { result = createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo); } } else { - StorageOperationStatus status = latestByToscaName.right() - .value(); + StorageOperationStatus status = latestByToscaName.right().value(); log.debug("failed to get latest version of resource {}. status={}", resource.getName(), status); - ResponseFormat responseFormat = componentsUtils - .getResponseFormatByResource(componentsUtils.convertFromStorageResponse(latestByToscaName.right() - .value()), resource); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils + .convertFromStorageResponse(latestByToscaName.right().value()), resource); componentsUtils.auditResource(responseFormat, user, resource, AuditingActionEnum.IMPORT_RESOURCE); throwComponentException(responseFormat); } @@ -3820,18 +3858,22 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { return csarInfo != null && csarInfo.isUpdate() && nodeName != null; } - private ImmutablePair createOrUpdateNestedResource(Resource resource, User user, - boolean isNormative, boolean isInTransaction, boolean needLock, CsarInfo csarInfo, boolean isNested, - String nodeName) { - Either latestByToscaName = toscaOperationFacade - .getLatestByToscaResourceName(buildNestedToscaResourceName(resource.getResourceType() - .name(), csarInfo.getVfResourceName(), nodeName).getRight()); + private ImmutablePair createOrUpdateNestedResource(final Resource resource, + final User user, + final boolean isNormative, + final boolean isInTransaction, + final boolean needLock, + final CsarInfo csarInfo, + final boolean isNested, + final String nodeName) { + final Either latestByToscaName = toscaOperationFacade + .getLatestByToscaResourceName(buildNestedToscaResourceName(resource.getResourceType() + .name(), csarInfo.getVfResourceName(), nodeName).getRight()); if (latestByToscaName.isLeft()) { - Resource nestedResource = (Resource) latestByToscaName.left() - .value(); + final Resource nestedResource = (Resource) latestByToscaName.left().value(); log.debug(VALIDATE_DERIVED_BEFORE_UPDATE); - Either eitherValidation = validateNestedDerivedFromDuringUpdate(nestedResource, - resource, ValidationUtils.hasBeenCertified(nestedResource.getVersion())); + final Either eitherValidation = validateNestedDerivedFromDuringUpdate(nestedResource, + resource, ValidationUtils.hasBeenCertified(nestedResource.getVersion())); if (eitherValidation.isRight()) { return createResourceByImport(resource, user, isNormative, isInTransaction, csarInfo); } @@ -4089,9 +4131,8 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { } else { resourceSystemName = resource.getSystemName(); } - resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(resource.getResourceType() - .name() - .toLowerCase(), resourceSystemName)); + resource.setToscaResourceName(CommonBeUtils + .generateToscaResourceName(resource.getResourceType().name().toLowerCase(), resourceSystemName)); } // Generate invariant UUID - must be here and not in operation since it @@ -5837,49 +5878,80 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { return nodeTypeArtifactsToHandleRes; } - ImmutablePair buildNestedToscaResourceName(String nodeResourceType, String vfResourceName, - String nodeTypeFullName) { + ImmutablePair buildNestedToscaResourceName(final String nodeResourceType, + final String vfResourceName, + final String nodeTypeFullName) { String actualType; String actualVfName; if (ResourceTypeEnum.CVFC.name() - .equals(nodeResourceType)) { + .equals(nodeResourceType)) { actualVfName = vfResourceName + ResourceTypeEnum.CVFC.name(); actualType = ResourceTypeEnum.VFC.name(); } else { actualVfName = vfResourceName; actualType = nodeResourceType; } - String nameWithouNamespacePrefix; + String nameWithouNamespacePrefix; try { - StringBuilder toscaResourceName = new StringBuilder(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX); - if (!nodeTypeFullName.contains(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX)){ - nameWithouNamespacePrefix = nodeTypeFullName; - } else { - nameWithouNamespacePrefix = nodeTypeFullName - .substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); - } String[] findTypes = nameWithouNamespacePrefix.split("\\."); - String resourceType = findTypes[0]; - String actualName = nameWithouNamespacePrefix.substring(resourceType.length()); + final String nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName); + log.debug("####### buildNestedToscaResourceName nodeResourceType {}, vfResourceName {}, " + + "nodeTypeFullName {}, actualType {}, vfResourceName {} ", nodeResourceType, vfResourceName, + nodeTypeFullName, actualType, vfResourceName); + final StringBuilder toscaResourceName = new StringBuilder(nodeTypeNamePrefix); + + if (!nodeTypeFullName.contains(nodeTypeNamePrefix)) { + nameWithouNamespacePrefix = nodeTypeFullName; + } else { + nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.length()); + } + final String[] findTypes = nameWithouNamespacePrefix.split("\\."); + String actualName; + if (nodeResourceType.equalsIgnoreCase(findTypes[0])){ + actualName = nameWithouNamespacePrefix.substring(nodeResourceType.length()); + } else { + actualName = "." + nameWithouNamespacePrefix; + } if (actualName.startsWith(Constants.ABSTRACT)) { - toscaResourceName.append(resourceType.toLowerCase()).append('.') - .append(ValidationUtils.convertToSystemName(actualVfName)); + toscaResourceName.append(nodeResourceType.toLowerCase()).append('.') + .append(ValidationUtils.convertToSystemName(actualVfName)); } else { toscaResourceName.append(actualType.toLowerCase()).append('.') - .append(ValidationUtils.convertToSystemName(actualVfName)).append('.').append(Constants.ABSTRACT); + .append(ValidationUtils.convertToSystemName(actualVfName)).append('.').append(Constants.ABSTRACT); + } + final StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName); + final String[] actualNames = actualName.split("\\."); + if (actualNames.length < 3) { + return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(), + previousToscaResourceName.append(actualName).toString()); } - StringBuilder previousToscaResourceName = new StringBuilder(toscaResourceName); return new ImmutablePair<>(toscaResourceName.append(actualName.toLowerCase()).toString(), - previousToscaResourceName - .append(actualName.substring(actualName.split("\\.")[1].length() + 1).toLowerCase()) - .toString()); - } catch (Exception e) { - ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE); + previousToscaResourceName.append(actualName.substring(actualNames[1].length() + 1) + .toLowerCase()).toString()); + } catch (final Exception e) { log.debug("Exception occured when buildNestedToscaResourceName, error is:{}", e.getMessage(), e); throw new ByActionStatusComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE, vfResourceName); } } + /** + * Extracts a Node Type Name prefix from the given Node Type Name. + * + * @param fullName Node Type Name + * @return Node Type Name Prefix + */ + private String getNodeTypeNamePrefix(final String fullName) { + String tempPrefix = Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX; + final List definedNodeTypeNamespaceList = getDefinedNodeTypeNamespaceList(); + log.debug("************* getPrefiX fullName {} FROM {}", fullName, definedNodeTypeNamespaceList); + final Optional validNameSpace = validateNodeTypeNamePrefix(fullName, definedNodeTypeNamespaceList); + if (validNameSpace.isPresent()) { + tempPrefix = validNameSpace.get(); + } + log.debug("************* getNodeTypeNamePrefix return fullName {} ", tempPrefix); + return tempPrefix; + } + @Override public Either getUiComponentDataTransferByComponentId(String resourceId, List dataParamsToReturn) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java index c0f75311f7..580fb737ec 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java @@ -26,6 +26,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.gson.Gson; import com.google.gson.JsonSyntaxException; import fj.data.Either; +import java.util.Optional; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections4.MapUtils; import org.apache.commons.io.IOUtils; @@ -41,6 +42,7 @@ import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentEx import org.openecomp.sdc.be.components.impl.exceptions.ByResponseFormatComponentException; import org.openecomp.sdc.be.components.impl.exceptions.ComponentException; import org.openecomp.sdc.be.config.BeEcompErrorManager; +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; @@ -378,33 +380,65 @@ public abstract class AbstractValidationsServlet extends BeGenericServlet { } } - protected void validatePayloadNameSpace(Wrapper responseWrapper, UploadResourceInfo resourceInfo, User user, String toscaPayload) { + /** + * Gets the Resource type from the given node type name. + * + * @param nodeTypeFullName - Node type Name + * @return Resource Type name + */ + private String getResourceType(final String nodeTypeFullName) { + + final Optional nodeTypeNamePrefix = getNodeTypeNamePrefix(nodeTypeFullName); + if (nodeTypeNamePrefix.isPresent()) { + final String nameWithouNamespacePrefix = nodeTypeFullName.substring(nodeTypeNamePrefix.get().length()); + final String[] findTypes = nameWithouNamespacePrefix.split("\\."); + if (findTypes.length > 0) { + final ResourceTypeEnum resourceType = ResourceTypeEnum.getType(findTypes[0].toUpperCase()); + if (resourceType != null) { + return resourceType.name(); + } + } + } + return ResourceTypeEnum.VFC.name(); + } + + /** + * Extracts the Node Type Name prefix from the given Node Type Name. + * @param nodeName - Node Type Name + * @return Node Type Name prefix + */ + private Optional getNodeTypeNamePrefix(final String nodeName) { + final List definedNodeTypeNamespaceList = ConfigurationManager.getConfigurationManager() + .getConfiguration().getDefinedResourceNamespace(); + for (final String validNamespace : definedNodeTypeNamespaceList) { + if (nodeName.startsWith(validNamespace)) { + return Optional.of(validNamespace); + } + } + return Optional.empty(); + } + + protected void validatePayloadNameSpace(final Wrapper responseWrapper, + final UploadResourceInfo resourceInfo, + final User user, final String toscaPayload) { boolean isValid; - String nameSpace = ""; - Map mappedToscaTemplate = (Map) new Yaml().load(toscaPayload); - Either, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES); + String namespace = ""; + final Map mappedToscaTemplate = (Map) new Yaml().load(toscaPayload); + final Either, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES); if (toscaElement.isRight() || toscaElement.left().value().size() != 1) { isValid = false; } else { - nameSpace = toscaElement.left().value().keySet().iterator().next(); - isValid = nameSpace.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX); + namespace = toscaElement.left().value().keySet().iterator().next(); + isValid = getNodeTypeNamePrefix(namespace).isPresent(); } if (!isValid) { - ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE); - Response errorResponse = buildErrorResponse(responseFormat); + final ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE); + final Response errorResponse = buildErrorResponse(responseFormat); getComponentsUtils().auditResource(responseFormat, user, resourceInfo.getName(), AuditingActionEnum.IMPORT_RESOURCE); responseWrapper.setInnerElement(errorResponse); } else { - String str1 = nameSpace.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); - String[] findTypes = str1.split("\\."); - if (ResourceTypeEnum.containsName(findTypes[0].toUpperCase())) { - String type = findTypes[0].toUpperCase(); - resourceInfo.setResourceType(type); - } else { - resourceInfo.setResourceType(ResourceTypeEnum.VFC.name()); - } + resourceInfo.setResourceType(getResourceType(namespace)); } - } private void validatePayloadIsSingleResource(Wrapper responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) { diff --git a/catalog-be/src/main/resources/config/configuration.yaml b/catalog-be/src/main/resources/config/configuration.yaml index 36e81916bc..678b3998fe 100644 --- a/catalog-be/src/main/resources/config/configuration.yaml +++ b/catalog-be/src/main/resources/config/configuration.yaml @@ -916,3 +916,6 @@ cadiFilterParams: AFT_ENVIRONMENT: AFTUAT cadiX509Issuers: "CN=intermediateCA_1, OU=OSAAF, O=ONAP, C=US" +# This configuration entry lists all node type names prefix that shall be allowed on SDC. +definedResourceNamespace: + - org.openecomp.resource. \ No newline at end of file diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java index da3955e560..69b3f1d660 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java @@ -20,7 +20,31 @@ package org.openecomp.sdc.be.components.impl; +import static org.assertj.core.api.Java6Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.when; + import fj.data.Either; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.servlet.ServletContext; import org.apache.commons.lang3.tuple.ImmutablePair; import org.junit.Assert; import org.junit.Before; @@ -113,30 +137,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.context.WebApplicationContext; -import javax.servlet.ServletContext; -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.when; - public class ResourceBusinessLogicTest { ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), "src/test/resources/config/catalog-be"); @@ -1584,6 +1584,18 @@ public class ResourceBusinessLogicTest { } + @Test + public void testIfNodeTypeNameHasValidPrefix() { + final List definedNodeTypeNamespaceList = ConfigurationManager.getConfigurationManager() + .getConfiguration().getDefinedResourceNamespace(); + + definedNodeTypeNamespaceList.parallelStream().forEach(validNodeTypePrefix -> { + final String nodeName = validNodeTypePrefix + "." + "abc"; + final Optional result = bl.validateNodeTypeNamePrefix(nodeName, definedNodeTypeNamespaceList); + assertTrue(result.isPresent()); + }); + } + @Test public void updateNestedResource_typeIsNew() throws IOException { Resource resourceToUpdate = createResourceObject(false); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceServletTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceServletTest.java index 284cc3fb47..af28aca26b 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceServletTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceServletTest.java @@ -42,6 +42,7 @@ import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.ConfigurationManager; import org.openecomp.sdc.be.config.SpringConfig; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; @@ -56,8 +57,10 @@ import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; import org.openecomp.sdc.be.user.Role; import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.ConfigurationSource; import org.openecomp.sdc.common.api.Constants; import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.common.util.GeneralUtility; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.context.ApplicationContext; @@ -107,6 +110,9 @@ public class ResourceServletTest extends JerseyTest { private static final ResponseFormat noContentResponseFormat = new ResponseFormat(HttpStatus.SC_NO_CONTENT); private static final ResponseFormat notFoundResponseFormat = new ResponseFormat(HttpStatus.SC_NOT_FOUND); private static final ResponseFormat badRequestResponseFormat = new ResponseFormat(HttpStatus.SC_BAD_REQUEST); + private static final ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration + .getChangeListener(), "src/test/resources/config/catalog-be"); + private static final ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); private static final String RESOURCE_NAME = "resourceName"; private static final String VERSION = "version"; private static final String RESOURCE_ID = "resourceId"; @@ -162,11 +168,12 @@ public class ResourceServletTest extends JerseyTest { @Test public void testHappyScenarioTest() { - when(componentUtils.getResponseFormat(ActionStatus.OK)) .thenReturn(createdResponseFormat); + when(componentUtils.getResponseFormat(ActionStatus.OK)).thenReturn(createdResponseFormat); UploadResourceInfo validJson = buildValidJson(); setMD5OnRequest(true, validJson); - Response response = target().path("/v1/catalog/resources").request(MediaType.APPLICATION_JSON).post(Entity.json(gson.toJson(validJson)), Response.class); + Response response = target().path("/v1/catalog/resources").request(MediaType.APPLICATION_JSON) + .post(Entity.json(gson.toJson(validJson)), Response.class); Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(Mockito.any(ActionStatus.class)); Mockito.verify(componentUtils, Mockito.times(1)).getResponseFormat(ActionStatus.OK); assertEquals(HttpStatus.SC_CREATED, response.getStatus()); @@ -250,11 +257,12 @@ public class ResourceServletTest extends JerseyTest { public void testNonValidNameSpaceInPayloadFail() { UploadResourceInfo mdJson = buildValidJson(); - String payload = "tosca_definitions_version: tosca_simple_yaml_1_0_0\r\n" + "node_types: \r\n" + " org.openecomp.resourceX.importResource4test:\r\n" + " derived_from: tosca.nodes.Root\r\n" + " description: update update"; + String payload = "tosca_definitions_version: tosca_simple_yaml_1_0_0\r\n" + "node_types: \r\n" + + " org.openecomp.resourceX.importResource4test:\r\n" + " derived_from: tosca.nodes.Root\r\n" + + " description: update update"; encodeAndSetPayload(mdJson, payload); runAndVerifyActionStatusError(mdJson, ActionStatus.INVALID_RESOURCE_NAMESPACE); - } @Test 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 647b322185..e759748808 100644 --- a/catalog-be/src/test/resources/config/catalog-be/configuration.yaml +++ b/catalog-be/src/test/resources/config/catalog-be/configuration.yaml @@ -744,4 +744,6 @@ cadiFilterParams: cadi_truststore: /opt/app/jetty/base/be/etc/cadi_truststore.jks cadi_truststore_password: changeit - +# This configuration entry lists all node type names prefix that shall be allowed on SDC. +definedResourceNamespace: + - org.openecomp.resource. \ No newline at end of file diff --git a/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java b/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java index 6226e4aa68..368a27ed8b 100644 --- a/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java +++ b/common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java @@ -100,6 +100,7 @@ public class Configuration extends BasicConfiguration { private List artifactTypes; private List licenseTypes; + private List definedResourceNamespace; private Integer additionalInformationMaxNumberOfKeys; private HeatDeploymentArtifactTimeout heatArtifactDeploymentTimeout; @@ -549,6 +550,14 @@ public class Configuration extends BasicConfiguration { this.licenseTypes = licenseTypes; } + public List getDefinedResourceNamespace() { + return definedResourceNamespace; + } + + public void setDefinedResourceNamespace(List definedResourceNamespace) { + this.definedResourceNamespace = definedResourceNamespace; + } + public Integer getAdditionalInformationMaxNumberOfKeys() { return additionalInformationMaxNumberOfKeys; } diff --git a/docs/configuration.rst b/docs/configuration.rst index 6d8d52490d..aebd149c99 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -997,6 +997,9 @@ BE-configuration.yaml - DMAAP - DCAE + # This configuration entry lists all node type names prefix that shall be allowed on SDC. + definedResourceNamespace: + - org.openecomp.resource. BE-distribution-engine-configuration.yaml ***************************************** -- 2.16.6