X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-be%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fcomponents%2Fimpl%2FResourceImportManager.java;h=d75b59be85c2be92aca235fde523fef9d2c20f66;hb=216ea4998de9ae4ee603d7f8f5f6725b218ca710;hp=787bc3e2de09b1465977e6e3ce205345f26aca79;hpb=b1fc8c337d3b9750eff6e62b626c0bc3a1467a88;p=sdc.git diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java index 787bc3e2de..d75b59be85 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java @@ -27,18 +27,23 @@ import static org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaElementO import fj.data.Either; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; 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.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -56,9 +61,15 @@ import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; @@ -69,8 +80,11 @@ import org.openecomp.sdc.be.model.AttributeDefinition; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.DefaultUploadResourceInfo; import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.NodeTypesMetadataList; +import org.openecomp.sdc.be.model.NullNodeTypeMetadata; import org.openecomp.sdc.be.model.PropertyDefinition; import org.openecomp.sdc.be.model.RequirementDefinition; import org.openecomp.sdc.be.model.Resource; @@ -79,6 +93,8 @@ import org.openecomp.sdc.be.model.User; import org.openecomp.sdc.be.model.category.CategoryDefinition; import org.openecomp.sdc.be.model.category.SubCategoryDefinition; import org.openecomp.sdc.be.model.jsonjanusgraph.operations.ToscaOperationFacade; +import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; +import org.openecomp.sdc.be.model.mapper.NodeTypeMetadataMapper; import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation; @@ -88,23 +104,24 @@ import org.openecomp.sdc.be.resources.data.auditing.model.ResourceCommonInfo; import org.openecomp.sdc.be.resources.data.auditing.model.ResourceVersionInfo; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.ThreadLocalsHolder; import org.openecomp.sdc.common.util.ValidationUtils; import org.openecomp.sdc.exception.ResponseFormat; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; import org.springframework.web.context.WebApplicationContext; import org.yaml.snakeyaml.Yaml; -@Component("resourceImportManager") +@org.springframework.stereotype.Component("resourceImportManager") public class ResourceImportManager { - static final Pattern PROPERTY_NAME_PATTERN_IGNORE_LENGTH = Pattern.compile("[\\w\\-\\_\\d\\:]+"); + static final Pattern PROPERTY_NAME_PATTERN_IGNORE_LENGTH = Pattern.compile("['\\w\\s\\-\\:]+"); private static final Logger log = Logger.getLogger(ResourceImportManager.class); private final InterfaceDefinitionHandler interfaceDefinitionHandler; private final ComponentsUtils componentsUtils; private final CapabilityTypeOperation capabilityTypeOperation; + private final JanusGraphDao janusGraphDao; private ServletContext servletContext; private AuditingManager auditingManager; private ResourceBusinessLogic resourceBusinessLogic; @@ -115,11 +132,12 @@ public class ResourceImportManager { private ResponseFormatManager responseFormatManager; @Autowired - public ResourceImportManager(ComponentsUtils componentsUtils, CapabilityTypeOperation capabilityTypeOperation, - final InterfaceDefinitionHandler interfaceDefinitionHandler) { + public ResourceImportManager(final ComponentsUtils componentsUtils, final CapabilityTypeOperation capabilityTypeOperation, + final InterfaceDefinitionHandler interfaceDefinitionHandler, final JanusGraphDao janusGraphDao) { this.componentsUtils = componentsUtils; this.capabilityTypeOperation = capabilityTypeOperation; this.interfaceDefinitionHandler = interfaceDefinitionHandler; + this.janusGraphDao = janusGraphDao; } public ServiceBusinessLogic getServiceBusinessLogic() { @@ -135,22 +153,60 @@ public class ResourceImportManager { this.toscaOperationFacade = toscaOperationFacade; } - public ImmutablePair importNormativeResource(String resourceYml, UploadResourceInfo resourceMetaData, User creator, - boolean createNewVersion, boolean needLock) { + public ImmutablePair importNormativeResource(final String resourceYml, final UploadResourceInfo resourceMetaData, + final User creator, final boolean createNewVersion, final boolean needLock, + final boolean isInTransaction) { LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(); lifecycleChangeInfo.setUserRemarks("certification on import"); Function validator = resource -> resourceBusinessLogic.validatePropertiesDefaultValues(resource); - return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, false, createNewVersion, needLock, - null, null, false, null, null, false); + return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, createNewVersion, + needLock, null, null, false, null, null, false); } - public ImmutablePair importNormativeResourceFromCsar(String resourceYml, UploadResourceInfo resourceMetaData, - User creator, boolean createNewVersion, boolean needLock) { - LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(); - lifecycleChangeInfo.setUserRemarks("certification on import"); - Function validator = resource -> resourceBusinessLogic.validatePropertiesDefaultValues(resource); - return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, false, createNewVersion, needLock, - null, null, false, null, null, false); + public void importAllNormativeResource(final String resourcesYaml, final NodeTypesMetadataList nodeTypesMetadataList, final User user, + final boolean createNewVersion, final boolean needLock) { + final Map nodeTypesYamlMap; + try { + nodeTypesYamlMap = new Yaml().load(resourcesYaml); + } catch (final Exception e) { + log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceImportManager.class.getName(), "Could not parse node types YAML", e); + throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TYPES_YAML); + } + if (!nodeTypesYamlMap.containsKey(ToscaTagNamesEnum.NODE_TYPES.getElementName())) { + return; + } + final Map nodeTypesMap = (Map) nodeTypesYamlMap.get(ToscaTagNamesEnum.NODE_TYPES.getElementName()); + importAllNormativeResource(nodeTypesMap, nodeTypesMetadataList, user, "", createNewVersion,needLock); + } + + public void importAllNormativeResource(final Map nodeTypesMap, final NodeTypesMetadataList nodeTypesMetadataList, + final User user, String model, final boolean createNewVersion, final boolean needLock) { + try { + nodeTypesMetadataList.getNodeMetadataList().forEach(nodeTypeMetadata -> { + final String nodeTypeToscaName = nodeTypeMetadata.getToscaName(); + final Map nodeTypeMap = (Map) nodeTypesMap.get(nodeTypeToscaName); + if (nodeTypeMap == null) { + log.warn(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceImportManager.class.getName(), + "Could not find given node type '{}'. The node will not be created.", nodeTypeToscaName); + } else { + final Map>> nodeTypeDefinitionMap = + Map.of(ToscaTagNamesEnum.NODE_TYPES.getElementName(), + Map.of(nodeTypeToscaName, nodeTypeMap) + ); + final String nodeTypeYaml = new Yaml().dump(nodeTypeDefinitionMap); + UploadResourceInfo uploadResourceInfo = NodeTypeMetadataMapper.mapTo(nodeTypeMetadata); + if (uploadResourceInfo instanceof DefaultUploadResourceInfo) { + uploadResourceInfo.setModel(model); + uploadResourceInfo.setContactId(user.getUserId()); + } + importNormativeResource(nodeTypeYaml, uploadResourceInfo, user, createNewVersion, needLock, true); + } + }); + janusGraphDao.commit(); + } catch (final Exception e) { + janusGraphDao.rollback(); + throw e; + } } public ImmutablePair importCertifiedResource(String resourceYml, UploadResourceInfo resourceMetaData, User creator, @@ -168,22 +224,11 @@ public class ResourceImportManager { try { boolean shouldBeCertified = nodeTypeArtifactsToHandle == null || nodeTypeArtifactsToHandle.isEmpty(); setConstantMetaData(resource, shouldBeCertified); - setMetaDataFromJson(resourceMetaData, resource); + setResourceMetaData(resource, resourceYml, resourceMetaData); populateResourceFromYaml(resourceYml, resource); validationFunction.apply(resource); - if (!createNewVersion) { - Either latestByName = toscaOperationFacade.getLatestByName(resource.getName()); - if (latestByName.isLeft()) { - throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, resource.getName()); - } - } else { - final Either component = toscaOperationFacade - .getComponentByNameAndVendorRelease(resource.getComponentType(), resource.getName(), resource.getVendorRelease(), - JsonParseFlagEnum.ParseAll); - if (component.isLeft()) { - throw new ByActionStatusComponentException(ActionStatus.COMPONENT_VERSION_ALREADY_EXIST, resource.getName()); - } - } + resource.getComponentMetadataDefinition().getMetadataDataDefinition().setNormative(resourceMetaData.isNormative()); + checkResourceExists(createNewVersion, csarInfo, resource); resource = resourceBusinessLogic .createOrUpdateResourceByImport(resource, creator, true, isInTransaction, needLock, csarInfo, nodeName, isNested).left; Resource changeStateResponse; @@ -210,6 +255,47 @@ public class ResourceImportManager { return responsePair; } + private void checkResourceExists(final boolean isCreate, final CsarInfo csarInfo, final Resource resource) { + if (isCreate) { + checkResourceExistsOnCreate(resource, csarInfo); + } else { + checkResourceExistsOnUpdate(resource); + } + } + + private void checkResourceExistsOnCreate(final Resource resource, final CsarInfo csarInfo) { + if (isCsarPresent(csarInfo)) { + return; + } + final Either resourceEither = + toscaOperationFacade.getComponentByNameAndVendorRelease(resource.getComponentType(), resource.getName(), + resource.getVendorRelease(), JsonParseFlagEnum.ParseAll, resource.getModel()); + if (resourceEither.isLeft() && toscaOperationFacade.isNodeAssociatedToModel(resource.getModel(), resource)) { + if (resource.getModel() == null) { + throw new ByActionStatusComponentException(ActionStatus.COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS, + resource.getName(), resource.getVendorRelease()); + } + throw new ByActionStatusComponentException(ActionStatus.COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS_IN_MODEL, + resource.getName(), resource.getVendorRelease(), resource.getModel()); + } + } + + private void checkResourceExistsOnUpdate(final Resource resource) { + final String model = resource.getModel(); + final Either latestByName = toscaOperationFacade.getLatestByName(resource.getName(), model); + if (latestByName.isLeft() && toscaOperationFacade.isNodeAssociatedToModel(model, resource)) { + if (model == null) { + throw new ByActionStatusComponentException(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, + resource.getResourceType().name(), resource.getName()); + } + throw new ByActionStatusComponentException(ActionStatus.COMPONENT_WITH_MODEL_ALREADY_EXIST, resource.getName(), model); + } + } + + private boolean isCsarPresent(final CsarInfo csarInfo) { + return csarInfo != null && StringUtils.isNotEmpty(csarInfo.getCsarUUID()); + } + private String getLatestCertifiedResourceId(Resource resource) { Map allVersions = resource.getAllVersions(); Double latestCertifiedVersion = 0.0; @@ -236,12 +322,16 @@ public class ResourceImportManager { resource.setIcon(resourceMetaData.getResourceIconPath()); resource.setResourceVendorModelNumber(resourceMetaData.getResourceVendorModelNumber()); resource.setResourceType(ResourceTypeEnum.valueOf(resourceMetaData.getResourceType())); + resource.setTenant(resourceMetaData.getTenant()); if (resourceMetaData.getVendorName() != null) { resource.setVendorName(resourceMetaData.getVendorName()); } if (resourceMetaData.getVendorRelease() != null) { resource.setVendorRelease(resourceMetaData.getVendorRelease()); } + if (resourceMetaData.getModel() != null) { + resource.setModel(resourceMetaData.getModel()); + } } } @@ -252,15 +342,13 @@ public class ResourceImportManager { try { setMetaDataFromJson(resourceMetaData, resource); populateResourceFromYaml(resourceYml, resource); - // currently import VF isn't supported. In future will be supported - - // import VF only with CSAR file!! + // currently import VF isn't supported. In future will be supported import VF only with CSAR file!! if (ResourceTypeEnum.VF == resource.getResourceType()) { log.debug("Now import VF isn't supported. It will be supported in future with CSAR file only"); throw new ByActionStatusComponentException(ActionStatus.RESTRICTED_OPERATION); } resourceBusinessLogic.validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE); - Boolean validatePropertiesTypes = resourceBusinessLogic.validatePropertiesDefaultValues(resource); + resourceBusinessLogic.validatePropertiesDefaultValues(resource); responsePair = resourceBusinessLogic.createOrUpdateResourceByImport(resource, creator, false, isInTransaction, true, null, null, false); } catch (RuntimeException e) { handleImportResourceException(resourceMetaData, creator, false, e); @@ -268,17 +356,15 @@ public class ResourceImportManager { return responsePair; } - private void populateResourceFromYaml(String resourceYml, Resource resource) { + private void populateResourceFromYaml(final String resourceYml, Resource resource) { @SuppressWarnings("unchecked") Object ymlObj = new Yaml().load(resourceYml); if (ymlObj instanceof Map) { - Map toscaJsonAll = (Map) ymlObj; + final Either existingResource = getExistingResource(resource); + final Map toscaJsonAll = (Map) ymlObj; Map toscaJson = toscaJsonAll; - // Checks if exist and builds the node_types map - if (toscaJsonAll.containsKey(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName()) - && resource.getResourceType() != ResourceTypeEnum.CVFC) { + if (toscaJsonAll.containsKey(ToscaTagNamesEnum.NODE_TYPES.getElementName()) && resource.getResourceType() != ResourceTypeEnum.CVFC) { toscaJson = new HashMap<>(); - toscaJson.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), - toscaJsonAll.get(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName())); + toscaJson.put(ToscaTagNamesEnum.NODE_TYPES.getElementName(), toscaJsonAll.get(ToscaTagNamesEnum.NODE_TYPES.getElementName())); } final List foundElements = new ArrayList<>(); final Either, ResultStatusEnum> toscaElements = ImportUtils @@ -286,55 +372,113 @@ public class ResourceImportManager { if (toscaElements.isLeft()) { final Map toscaAttributes = (Map) foundElements.get(0); if (MapUtils.isNotEmpty(toscaAttributes)) { - resource.setDataTypes(extractDataTypeFromJson(resourceBusinessLogic, toscaAttributes)); + resource.setDataTypes(extractDataTypeFromJson(resourceBusinessLogic, toscaAttributes, resource.getModel())); } } - // Derived From - Resource parentResource = setDerivedFrom(toscaJson, resource); + final Resource parentResource = setDerivedFrom(toscaJson, resource); if (StringUtils.isEmpty(resource.getToscaResourceName())) { setToscaResourceName(toscaJson, resource); } setCapabilities(toscaJson, resource, parentResource); - setProperties(toscaJson, resource); + setProperties(toscaJson, resource, existingResource); setAttributes(toscaJson, resource); setRequirements(toscaJson, resource, parentResource); - setInterfaceLifecycle(toscaJson, resource); + setInterfaceLifecycle(toscaJson, resource, existingResource); } else { throw new ByActionStatusComponentException(ActionStatus.GENERAL_ERROR); } } + private Either getExistingResource(final Resource resource) { + final Either, JanusGraphOperationStatus> byCriteria = janusGraphDao.getByCriteria( + getVertexTypeEnum(resource.getResourceType()), propertiesToMatch(resource), propertiesToNotMatch(), + JsonParseFlagEnum.ParseAll, resource.getModel(), false); + if (byCriteria.isLeft() && CollectionUtils.isNotEmpty(byCriteria.left().value())) { + final List graphVertexList = byCriteria.left().value(); + if (graphVertexList.size() == 1) { + return toscaOperationFacade.getToscaElement(graphVertexList.get(0).getUniqueId()); + } else { + final Optional vertex = graphVertexList.stream() + .max(Comparator.comparing(graphVertex -> (String) graphVertex.getMetadataProperties().get(GraphPropertyEnum.VERSION))); + if (vertex.isPresent()) { + return toscaOperationFacade.getToscaElement(vertex.get().getUniqueId()); + } + } + } + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + private VertexTypeEnum getVertexTypeEnum(final ResourceTypeEnum resourceType) { + return ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : VertexTypeEnum.TOPOLOGY_TEMPLATE; + } + + private Map propertiesToMatch(final Resource resource) { + final Map graphProperties = new EnumMap<>(GraphPropertyEnum.class); + graphProperties.put(GraphPropertyEnum.NORMALIZED_NAME, ValidationUtils.normaliseComponentName(resource.getName())); + graphProperties.put(GraphPropertyEnum.COMPONENT_TYPE, resource.getComponentType().name()); + graphProperties.put(GraphPropertyEnum.RESOURCE_TYPE, resource.getResourceType().name()); + graphProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); + return graphProperties; + } + + private Map propertiesToNotMatch() { + final Map graphProperties = new EnumMap<>(GraphPropertyEnum.class); + graphProperties.put(GraphPropertyEnum.IS_DELETED, true); + graphProperties.put(GraphPropertyEnum.IS_ARCHIVED, true); + return graphProperties; + } + private void setToscaResourceName(Map toscaJson, Resource resource) { + resource.setToscaResourceName(getToscaResourceName(toscaJson)); + } + + private String getToscaResourceName(Map toscaJson) { Either, ResultStatusEnum> toscaElement = ImportUtils - .findFirstToscaMapElement(toscaJson, TypeUtils.ToscaTagNamesEnum.NODE_TYPES); - if (toscaElement.isLeft() || toscaElement.left().value().size() == 1) { + .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.NODE_TYPES); + if (toscaElement.isLeft() && toscaElement.left().value().size() == 1) { String toscaResourceName = toscaElement.left().value().keySet().iterator().next(); - resource.setToscaResourceName(toscaResourceName); + return toscaResourceName; } + return null; } - private void setInterfaceLifecycle(Map toscaJson, Resource resource) { - Either, ResultStatusEnum> toscaInterfaces = ImportUtils - .findFirstToscaMapElement(toscaJson, TypeUtils.ToscaTagNamesEnum.INTERFACES); + private void setInterfaceLifecycle(Map toscaJson, Resource resource, Either existingResource) { + final Either, ResultStatusEnum> toscaInterfaces = ImportUtils + .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.INTERFACES); + final Map moduleInterfaces = new HashMap<>(); + final Map map; if (toscaInterfaces.isLeft()) { - Map jsonInterfaces = toscaInterfaces.left().value(); - Map moduleInterfaces = new HashMap<>(); - for (final Entry interfaceNameValue : jsonInterfaces.entrySet()) { - final Either eitherInterface = createModuleInterface(interfaceNameValue.getValue()); + map = toscaInterfaces.left().value(); + for (final Entry interfaceNameValue : map.entrySet()) { + final Either eitherInterface = createModuleInterface(interfaceNameValue.getValue(), + resource.getModel()); if (eitherInterface.isRight()) { log.info("error when creating interface:{}, for resource:{}", interfaceNameValue.getKey(), resource.getName()); } else { final InterfaceDefinition interfaceDefinition = eitherInterface.left().value(); - moduleInterfaces.put(interfaceNameValue.getKey(), interfaceDefinition); + moduleInterfaces.put(interfaceDefinition.getType(), interfaceDefinition); } } - if (!moduleInterfaces.isEmpty()) { - resource.setInterfaces(moduleInterfaces); + } else { + map = Collections.emptyMap(); + } + if (existingResource.isLeft()) { + final Map userCreatedInterfaceDefinitions = + existingResource.left().value().getInterfaces().entrySet().stream() + .filter(i -> i.getValue().isUserCreated()) + .filter(i -> !map.containsKey(i.getValue().getType())) + .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); + if (MapUtils.isNotEmpty(userCreatedInterfaceDefinitions)) { + moduleInterfaces.putAll(userCreatedInterfaceDefinitions); } } + + if (MapUtils.isNotEmpty(moduleInterfaces)) { + resource.setInterfaces(moduleInterfaces); + } } - private Either createModuleInterface(final Object interfaceJson) { + private Either createModuleInterface(final Object interfaceJson, final String model) { try { if (interfaceJson instanceof String) { final InterfaceDefinition interfaceDefinition = new InterfaceDefinition(); @@ -343,7 +487,7 @@ public class ResourceImportManager { } if (interfaceJson instanceof Map) { final Map interfaceJsonMap = (Map) interfaceJson; - final InterfaceDefinition interfaceDefinition = interfaceDefinitionHandler.create(interfaceJsonMap); + final InterfaceDefinition interfaceDefinition = interfaceDefinitionHandler.create(interfaceJsonMap, model); return Either.left(interfaceDefinition); } return Either.right(ResultStatusEnum.GENERAL_ERROR); @@ -357,15 +501,13 @@ public class ResourceImportManager { private void setRequirements(Map toscaJson, Resource resource, Resource parentResource) {// Note that parentResource can be null Either, ResultStatusEnum> toscaRequirements = ImportUtils - .findFirstToscaListElement(toscaJson, TypeUtils.ToscaTagNamesEnum.REQUIREMENTS); + .findFirstToscaListElement(toscaJson, ToscaTagNamesEnum.REQUIREMENTS); if (toscaRequirements.isLeft()) { List jsonRequirements = toscaRequirements.left().value(); Map> moduleRequirements = new HashMap<>(); // Checking for name duplication Set reqNames = new HashSet<>(); - // Getting flattened list of capabilities of parent node - cap name - - // to cap type + // Getting flattened list of capabilities of parent node - cap name to cap type Map reqName2TypeMap = getReqName2Type(parentResource); for (Object jsonRequirementObj : jsonRequirements) { // Requirement @@ -408,17 +550,17 @@ public class ResourceImportManager { requirement.setCapability(requirementJsonString); } else if (requirementJson instanceof Map) { Map requirementJsonMap = (Map) requirementJson; - if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.CAPABILITY.getElementName())) { - requirement.setCapability((String) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.CAPABILITY.getElementName())); + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.CAPABILITY.getElementName())) { + requirement.setCapability((String) requirementJsonMap.get(ToscaTagNamesEnum.CAPABILITY.getElementName())); } - if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.NODE.getElementName())) { - requirement.setNode((String) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.NODE.getElementName())); + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.NODE.getElementName())) { + requirement.setNode((String) requirementJsonMap.get(ToscaTagNamesEnum.NODE.getElementName())); } - if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.RELATIONSHIP.getElementName())) { - requirement.setRelationship((String) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.RELATIONSHIP.getElementName())); + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.RELATIONSHIP.getElementName())) { + requirement.setRelationship((String) requirementJsonMap.get(ToscaTagNamesEnum.RELATIONSHIP.getElementName())); } - if (requirementJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) { - List occurrencesList = (List) requirementJsonMap.get(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName()); + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.OCCURRENCES.getElementName())) { + List occurrencesList = (List) requirementJsonMap.get(ToscaTagNamesEnum.OCCURRENCES.getElementName()); validateOccurrences(occurrencesList); requirement.setMinOccurrences(occurrencesList.get(0).toString()); requirement.setMaxOccurrences(occurrencesList.get(1).toString()); @@ -429,33 +571,53 @@ public class ResourceImportManager { return requirement; } - private void setProperties(Map toscaJson, Resource resource) { - Map reducedToscaJson = new HashMap<>(toscaJson); + private void setProperties(final Map toscaJson, final Resource resource, + final Either existingResource) { + final Map reducedToscaJson = new HashMap<>(toscaJson); ImportUtils.removeElementFromJsonMap(reducedToscaJson, "capabilities"); - Either, ResultStatusEnum> properties = ImportUtils.getProperties(reducedToscaJson); + final Either, ResultStatusEnum> properties = ImportUtils.getProperties(reducedToscaJson); if (properties.isLeft()) { - List propertiesList = new ArrayList<>(); - Map value = properties.left().value(); - if (value != null) { - for (Entry entry : value.entrySet()) { - String name = entry.getKey(); - if (!PROPERTY_NAME_PATTERN_IGNORE_LENGTH.matcher(name).matches()) { - log.debug("The property with invalid name {} occured upon import resource {}. ", name, resource.getName()); - throw new ByActionStatusComponentException( - componentsUtils.convertFromResultStatusEnum(ResultStatusEnum.INVALID_PROPERTY_NAME, JsonPresentationFields.PROPERTY)); + final Map propertyDefinitionMap = properties.left().value(); + if (MapUtils.isNotEmpty(propertyDefinitionMap)) { + final List propertiesList = new ArrayList<>(); + for (final Entry entry : propertyDefinitionMap.entrySet()) { + addPropertyToList(resource.getName(), propertiesList, entry); + } + if (existingResource.isLeft()) { + if ( CollectionUtils.isNotEmpty(existingResource.left().value().getProperties())) { + final List userCreatedResourceProperties = + existingResource.left().value().getProperties().stream() + .filter(PropertyDataDefinition::isUserCreated) + .filter(propertyDefinition -> !propertyDefinitionMap.containsKey(propertyDefinition.getName())) + .collect(Collectors.toList()); + if (CollectionUtils.isNotEmpty(userCreatedResourceProperties)) { + propertiesList.addAll(userCreatedResourceProperties); + } } - PropertyDefinition propertyDefinition = entry.getValue(); - propertyDefinition.setName(name); - propertiesList.add(propertyDefinition); } + + resource.setProperties(propertiesList); } - resource.setProperties(propertiesList); } else if (properties.right().value() != ResultStatusEnum.ELEMENT_NOT_FOUND) { throw new ByActionStatusComponentException( componentsUtils.convertFromResultStatusEnum(properties.right().value(), JsonPresentationFields.PROPERTY)); } } + private void addPropertyToList(final String resourceName, + final List propertiesList, + final Entry entry) { + final String propertyName = entry.getKey(); + if (!PROPERTY_NAME_PATTERN_IGNORE_LENGTH.matcher(propertyName).matches()) { + log.debug("The property with invalid name {} occured upon import resource {}. ", propertyName, resourceName); + throw new ByActionStatusComponentException( + componentsUtils.convertFromResultStatusEnum(ResultStatusEnum.INVALID_PROPERTY_NAME, JsonPresentationFields.PROPERTY)); + } + final PropertyDefinition propertyDefinition = entry.getValue(); + propertyDefinition.setName(propertyName); + propertiesList.add(propertyDefinition); + } + private void setAttributes(final Map originalToscaJsonMap, final Resource resource) { final Map toscaJsonMap = new HashMap<>(originalToscaJsonMap); ImportUtils.removeElementFromJsonMap(toscaJsonMap, "capabilities"); @@ -481,6 +643,11 @@ public class ResourceImportManager { } final AttributeDefinition attributeDefinition = entry.getValue(); attributeDefinition.setName(name); + if (attributeDefinition.getEntry_schema() != null && attributeDefinition.getEntry_schema().getType() != null) { + attributeDefinition.setSchema(new SchemaDefinition()); + attributeDefinition.getSchema().setProperty(new PropertyDataDefinition()); + attributeDefinition.getSchema().getProperty().setType(entry.getValue().getEntry_schema().getType()); + } attributeDefinitionList.add(attributeDefinition); } resource.setAttributes(attributeDefinitionList); @@ -488,13 +655,14 @@ public class ResourceImportManager { private Resource setDerivedFrom(Map toscaJson, Resource resource) { Either toscaDerivedFromElement = ImportUtils - .findFirstToscaStringElement(toscaJson, TypeUtils.ToscaTagNamesEnum.DERIVED_FROM); + .findFirstToscaStringElement(toscaJson, ToscaTagNamesEnum.DERIVED_FROM); Resource derivedFromResource = null; if (toscaDerivedFromElement.isLeft()) { String derivedFrom = toscaDerivedFromElement.left().value(); log.debug("Derived from TOSCA name is {}", derivedFrom); resource.setDerivedFrom(Arrays.asList(new String[]{derivedFrom})); - Either latestByToscaResourceName = toscaOperationFacade.getLatestByToscaResourceName(derivedFrom); + Either latestByToscaResourceName = toscaOperationFacade.getLatestByToscaResourceName(derivedFrom, + resource.getModel()); if (latestByToscaResourceName.isRight()) { StorageOperationStatus operationStatus = latestByToscaResourceName.right().value(); if (operationStatus == StorageOperationStatus.NOT_FOUND) { @@ -513,7 +681,7 @@ public class ResourceImportManager { private void setCapabilities(Map toscaJson, Resource resource, Resource parentResource) {// Note that parentResource can be null Either, ResultStatusEnum> toscaCapabilities = ImportUtils - .findFirstToscaMapElement(toscaJson, TypeUtils.ToscaTagNamesEnum.CAPABILITIES); + .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.CAPABILITIES); if (toscaCapabilities.isLeft()) { Map jsonCapabilities = toscaCapabilities.left().value(); Map> moduleCapabilities = new HashMap<>(); @@ -640,25 +808,25 @@ public class ResourceImportManager { } else if (capabilityJson instanceof Map) { Map capabilityJsonMap = (Map) capabilityJson; // Type - if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) { - capabilityDefinition.setType((String) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())); + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + capabilityDefinition.setType((String) capabilityJsonMap.get(ToscaTagNamesEnum.TYPE.getElementName())); } // ValidSourceTypes - if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())) { + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())) { capabilityDefinition - .setValidSourceTypes((List) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())); + .setValidSourceTypes((List) capabilityJsonMap.get(ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())); } // ValidSourceTypes - if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName())) { - capabilityDefinition.setDescription((String) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.DESCRIPTION.getElementName())); + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.DESCRIPTION.getElementName())) { + capabilityDefinition.setDescription((String) capabilityJsonMap.get(ToscaTagNamesEnum.DESCRIPTION.getElementName())); } - if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName())) { - List occurrencesList = (List) capabilityJsonMap.get(TypeUtils.ToscaTagNamesEnum.OCCURRENCES.getElementName()); + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.OCCURRENCES.getElementName())) { + List occurrencesList = (List) capabilityJsonMap.get(ToscaTagNamesEnum.OCCURRENCES.getElementName()); validateOccurrences(occurrencesList); capabilityDefinition.setMinOccurrences(occurrencesList.get(0).toString()); capabilityDefinition.setMaxOccurrences(occurrencesList.get(1).toString()); } - if (capabilityJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.PROPERTIES.getElementName())) { + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.PROPERTIES.getElementName())) { Either, ResultStatusEnum> propertiesRes = ImportUtils.getProperties(capabilityJsonMap); if (propertiesRes.isRight()) { throw new ByActionStatusComponentException(ActionStatus.PROPERTY_NOT_FOUND); @@ -718,6 +886,18 @@ public class ResourceImportManager { getAuditingManager().auditEvent(factory); } + private void setResourceMetaData(Resource resource, String resourceYml, UploadResourceInfo resourceMetaData) { + Map ymlObj = new Yaml().load(resourceYml); + String toscaName = getToscaResourceName(ymlObj); + final Either latestByToscaName = toscaOperationFacade + .getLatestByToscaResourceName(toscaName, resourceMetaData.getModel()); + if (latestByToscaName.isLeft() && resourceMetaData instanceof DefaultUploadResourceInfo) { + setMetaDataFromLatestResource(resource, latestByToscaName.left().value()); + } else { + setMetaDataFromJson(resourceMetaData, resource); + } + } + private void setMetaDataFromJson(final UploadResourceInfo resourceMetaData, final Resource resource) { this.populateResourceMetadata(resourceMetaData, resource); resource.setCreatorUserId(resourceMetaData.getContactId()); @@ -729,6 +909,34 @@ public class ResourceImportManager { calculateResourceIsAbstract(resource, categories); } + private void setMetaDataFromLatestResource(Resource resource, Resource latestResource) { + if (resource != null && latestResource != null) { + resource.setCreatorUserId(latestResource.getContactId()); + resource.setDescription(latestResource.getDescription()); + resource.setTags(latestResource.getTags()); + resource.setCategories(latestResource.getCategories()); + resource.setContactId(latestResource.getContactId()); + resource.setName(latestResource.getName()); + resource.setIcon(latestResource.getIcon()); + resource.setResourceVendorModelNumber(latestResource.getResourceVendorModelNumber()); + resource.setResourceType(latestResource.getResourceType()); + if (latestResource.getVendorName() != null) { + resource.setVendorName(latestResource.getVendorName()); + } + if (latestResource.getVendorRelease() != null) { + resource.setVendorRelease(latestResource.getVendorRelease()); + } + if (latestResource.getModel() != null) { + resource.setModel(latestResource.getModel()); + } + if (latestResource.getToscaVersion() != null) { + resource.setToscaVersion(latestResource.getToscaVersion()); + } + final List categories = latestResource.getCategories(); + calculateResourceIsAbstract(resource, categories); + } + } + private Map decodePayload(final String payloadData) { final String decodedPayload = new String(Base64.decodeBase64(payloadData)); return (Map) new Yaml().load(decodedPayload); @@ -737,7 +945,7 @@ public class ResourceImportManager { private String getToscaVersion(final String payloadData) { final Map mappedToscaTemplate = decodePayload(payloadData); final Either findFirstToscaStringElement = ImportUtils - .findFirstToscaStringElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.TOSCA_VERSION); + .findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION); if (findFirstToscaStringElement.isLeft()) { return findFirstToscaStringElement.left().value(); } else { @@ -810,7 +1018,7 @@ public class ResourceImportManager { log.debug("Invalid occurrenses format. Max occurrence is {}", maxObj); throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES); } - if (maxOccurrences <= 0 || maxOccurrences < minOccurrences) { + if (maxOccurrences < 0 || maxOccurrences < minOccurrences) { log.debug("Invalid occurrenses format. min occurrence is {}, Max occurrence is {}", minOccurrences, maxOccurrences); throw new ByActionStatusComponentException(ActionStatus.INVALID_OCCURRENCES); } @@ -880,10 +1088,12 @@ public class ResourceImportManager { } private List extractDataTypeFromJson(final ResourceBusinessLogic resourceBusinessLogic, - final Map foundElements) { + final Map foundElements, + final String model) { final List dataTypeDefinitionList = new ArrayList<>(); if (MapUtils.isNotEmpty(foundElements)) { - final Either, JanusGraphOperationStatus> dataTypeCacheAll = resourceBusinessLogic.dataTypeCache.getAll(); + final Either, JanusGraphOperationStatus> dataTypeCacheAll = + resourceBusinessLogic.applicationDataTypeCache.getAll(model); if (dataTypeCacheAll.isLeft()) { for (final Entry attributeNameValue : foundElements.entrySet()) { final Object value = attributeNameValue.getValue();