X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=catalog-model%2Fsrc%2Fmain%2Fjava%2Forg%2Fopenecomp%2Fsdc%2Fbe%2Fmodel%2Fjsonjanusgraph%2Foperations%2FToscaOperationFacade.java;h=b6339e85ecd597e39103b74f021a250b69b3867c;hb=ceaf83e0f29c10e4521321abcd6dd17080d2db60;hp=385891266052ba2a95616ac869d57f205865bf2b;hpb=260a951d3431429bab9732e16225e42641ae4787;p=sdc.git diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java index 3858912660..b6339e85ec 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java @@ -17,12 +17,14 @@ * limitations under the License. * ============LICENSE_END========================================================= */ + package org.openecomp.sdc.be.model.jsonjanusgraph.operations; import static java.util.Objects.requireNonNull; import static org.apache.commons.collections.CollectionUtils.isEmpty; import static org.apache.commons.collections.CollectionUtils.isNotEmpty; import static org.janusgraph.core.attribute.Text.REGEX; +import static org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum.TOPOLOGY_TEMPLATE; import com.vdurmont.semver4j.Semver; import com.vdurmont.semver4j.Semver.SemverType; @@ -31,6 +33,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.Comparator; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; @@ -39,9 +42,13 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.TreeSet; import java.util.function.BiPredicate; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -52,9 +59,10 @@ import org.apache.tinkerpop.gremlin.structure.Edge; import org.janusgraph.graphdb.query.JanusGraphPredicate; import org.openecomp.sdc.be.config.Configuration; import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.exception.JanusGraphException; +import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphDao; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus; import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; -import org.openecomp.sdc.be.dao.jsongraph.HealingJanusGraphDao; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; @@ -64,6 +72,7 @@ import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition; @@ -78,6 +87,7 @@ import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; 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.OriginTypeEnum; import org.openecomp.sdc.be.datatypes.enums.PromoteVersionEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; @@ -98,6 +108,7 @@ import org.openecomp.sdc.be.model.DistributionStatusEnum; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.GroupInstance; import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.PolicyDefinition; @@ -112,8 +123,10 @@ import org.openecomp.sdc.be.model.catalog.CatalogComponent; import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate; import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement; +import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ToscaOperationExceptionSupplier; import org.openecomp.sdc.be.model.jsonjanusgraph.utils.ModelConverter; import org.openecomp.sdc.be.model.operations.StorageException; +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.DaoStatusConverter; import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; @@ -121,6 +134,7 @@ import org.openecomp.sdc.be.model.utils.GroupUtils; import org.openecomp.sdc.be.resources.data.ComponentMetadataData; import org.openecomp.sdc.common.jsongraph.util.CommonUtility; import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum; +import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode; import org.openecomp.sdc.common.log.wrappers.Logger; import org.openecomp.sdc.common.util.ValidationUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -132,15 +146,22 @@ public class ToscaOperationFacade { public static final String PROXY_SUFFIX = "_proxy"; // region - Fields private static final String COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch a component with and UniqueId {}, error: {}"; - private static final String FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS = "Failed to find recently added property {} on the resource {}. Status is {}. "; + private static final String FAILED_TO_FIND_RECENTLY_ADDED_PROPERTY_ON_THE_RESOURCE_STATUS_IS = + "Failed to find recently added property {} on the resource {}. Status is {}. "; private static final String FAILED_TO_GET_UPDATED_RESOURCE_STATUS_IS = "Failed to get updated resource {}. Status is {}. "; - private static final String FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS = "Failed to add the property {} to the resource {}. Status is {}. "; + private static final String FAILED_TO_ADD_THE_PROPERTY_TO_THE_RESOURCE_STATUS_IS = + "Failed to add the property {} to the resource {}. Status is {}. "; private static final String SERVICE = "service"; + private static final String VF = "VF"; private static final String NOT_SUPPORTED_COMPONENT_TYPE = "Not supported component type {}"; private static final String COMPONENT_CREATED_SUCCESSFULLY = "Component created successfully!!!"; + private static final String INPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY = "Inputs associated to component successfully!"; + private static final String OUTPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY = "Outputs associated to component successfully!"; private static final String COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR = "Couldn't fetch component with and unique id {}, error: {}"; private static final Logger log = Logger.getLogger(ToscaOperationFacade.class.getName()); @Autowired + private IGraphLockOperation graphLockOperation; + @Autowired private NodeTypeOperation nodeTypeOperation; @Autowired private TopologyTemplateOperation topologyTemplateOperation; @@ -347,19 +368,56 @@ public class ToscaOperationFacade { return ModelConverter.isAtomicComponent(component) ? nodeTypeOperation : topologyTemplateOperation; } - public Either getLatestByToscaResourceName(String toscaResourceName) { - return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName); + public Either getLatestByToscaResourceNameAndModel(final String toscaResourceName, + final String model) { + return getLatestByNameAndModel(toscaResourceName, JsonParseFlagEnum.ParseMetadata, new ComponentParametersView(), model); + } + + private Either getLatestByNameAndModel(final String nodeName, + final JsonParseFlagEnum parseFlag, + final ComponentParametersView filter, + final String model) { + Either result; + final Map propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class); + final Map propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class); + propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, nodeName); + propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); + propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true); + final Either, JanusGraphOperationStatus> highestResources = janusGraphDao + .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag, model); + if (highestResources.isRight()) { + final JanusGraphOperationStatus status = highestResources.right().value(); + log.debug("failed to find resource with name {}. status={} ", nodeName, status); + result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); + return result; + } + final List resources = highestResources.left().value(); + double version = 0.0; + GraphVertex highestResource = null; + for (final GraphVertex vertex : resources) { + final Object versionObj = vertex.getMetadataProperty(GraphPropertyEnum.VERSION); + double resourceVersion = Double.parseDouble((String) versionObj); + if (resourceVersion > version) { + version = resourceVersion; + highestResource = vertex; + } + } + return getToscaElementByOperation(highestResource, filter); + } + + public Either getLatestByToscaResourceName(String toscaResourceName, String modelName) { + return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, modelName); } public Either getFullLatestComponentByToscaResourceName(String toscaResourceName) { ComponentParametersView fetchAllFilter = new ComponentParametersView(); fetchAllFilter.setIgnoreServicePath(true); fetchAllFilter.setIgnoreCapabiltyProperties(false); - return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter); + return getLatestByName(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName, JsonParseFlagEnum.ParseAll, fetchAllFilter, null); } - public Either getLatestByName(String resourceName) { - return getLatestByName(GraphPropertyEnum.NAME, resourceName); + public Either getLatestByName(String resourceName, String modelName) { + return getLatestByName(GraphPropertyEnum.NAME, resourceName, modelName); } public StorageOperationStatus validateCsarUuidUniqueness(String csarUUID) { @@ -418,7 +476,7 @@ public class ToscaOperationFacade { props.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name()); Map> predicateCriteria = getVendorVersionPredicate(vendorRelease); Either, JanusGraphOperationStatus> getLatestRes = janusGraphDao - .getByCriteria(vertexType, props, null, predicateCriteria, parseFlag); + .getByCriteria(vertexType, props, null, predicateCriteria, parseFlag, null); if (getLatestRes.isRight() || CollectionUtils.isEmpty(getLatestRes.left().value())) { getLatestRes = janusGraphDao.getByCriteria(vertexType, props, parseFlag); } @@ -445,6 +503,28 @@ public class ToscaOperationFacade { }); } + public Either getByToscaResourceNameAndVersion(final String toscaResourceName, + final String version, final String model) { + Either result; + + Map hasProperties = new EnumMap<>(GraphPropertyEnum.class); + Map hasNotProperties = new EnumMap<>(GraphPropertyEnum.class); + + hasProperties.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaResourceName); + hasProperties.put(GraphPropertyEnum.VERSION, version); + hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true); + + Either, JanusGraphOperationStatus> getResourceRes = janusGraphDao + .getByCriteria(VertexTypeEnum.NODE_TYPE, hasProperties, hasNotProperties, JsonParseFlagEnum.ParseAll, model); + if (getResourceRes.isRight()) { + JanusGraphOperationStatus status = getResourceRes.right().value(); + log.debug("failed to find resource with toscaResourceName {}, version {}. Status is {} ", toscaResourceName, version, status); + result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); + return result; + } + return getToscaElementByOperation(getResourceRes.left().value().get(0)); + } + private Map> getVendorVersionPredicate(final String vendorRelease) { Map> predicateCriteria = new HashMap<>(); if (!"1.0".equals(vendorRelease)) { @@ -461,6 +541,28 @@ public class ToscaOperationFacade { return predicateCriteria; } + public boolean isNodeAssociatedToModel(final String model, final Resource resource) { + final List modelElementVertices = getResourceModelElementVertices(resource); + if (model == null) { + return modelElementVertices.isEmpty(); + } + return modelElementVertices.stream().anyMatch(graphVertex -> graphVertex.getMetadataProperty(GraphPropertyEnum.NAME).equals(model)); + } + + public List getResourceModelElementVertices(final Resource resource) { + final Either vertex = + janusGraphDao.getVertexById(resource.getUniqueId(), JsonParseFlagEnum.NoParse); + if (vertex.isRight() || Objects.isNull(vertex.left().value())) { + return Collections.emptyList(); + } + final Either, JanusGraphOperationStatus> nodeModelVertices = + janusGraphDao.getParentVertices(vertex.left().value(), EdgeLabelEnum.MODEL_ELEMENT, JsonParseFlagEnum.NoParse); + if (nodeModelVertices.isRight() || nodeModelVertices.left().value() == null) { + return Collections.emptyList(); + } + return nodeModelVertices.left().value(); + } + private boolean isValidForVendorRelease(final GraphVertex resource, final String vendorRelease) { if (!vendorRelease.equals("1.0")) { try { @@ -507,7 +609,7 @@ public class ToscaOperationFacade { public Either getLatestResourceByToscaResourceName(String toscaResourceName) { if (toscaResourceName != null && toscaResourceName.contains("org.openecomp.resource.vf")) { - return getLatestResourceByToscaResourceName(toscaResourceName, VertexTypeEnum.TOPOLOGY_TEMPLATE, JsonParseFlagEnum.ParseMetadata); + return getLatestResourceByToscaResourceName(toscaResourceName, TOPOLOGY_TEMPLATE, JsonParseFlagEnum.ParseMetadata); } else { return getLatestResourceByToscaResourceName(toscaResourceName, VertexTypeEnum.NODE_TYPE, JsonParseFlagEnum.ParseMetadata); } @@ -584,7 +686,7 @@ public class ToscaOperationFacade { public Either, StorageOperationStatus> associateResourceInstances(Component component, String componentId, List relations) { Either, StorageOperationStatus> reqAndCapListEither = nodeTemplateOperation - .associateResourceInstances(component, componentId, relations); + .associateResourceInstances(componentId, relations); if (component != null) { updateInstancesCapAndReqOnComponentFromDB(component); } @@ -687,7 +789,7 @@ public class ToscaOperationFacade { return updateToscaElement(componentToUpdate, new ComponentParametersView()); } - public Either updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) { + private Either updateToscaElement(T componentToUpdate, ComponentParametersView filterResult) { String componentId = componentToUpdate.getUniqueId(); Either getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.ParseAll); if (getVertexEither.isRight()) { @@ -711,13 +813,13 @@ public class ToscaOperationFacade { } private Either getLatestByName(GraphPropertyEnum property, String nodeName, - JsonParseFlagEnum parseFlag) { - return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView()); + JsonParseFlagEnum parseFlag, String modelName) { + return getLatestByName(property, nodeName, parseFlag, new ComponentParametersView(), modelName); } - // endregion private Either getLatestByName(GraphPropertyEnum property, String nodeName, - JsonParseFlagEnum parseFlag, ComponentParametersView filter) { + JsonParseFlagEnum parseFlag, ComponentParametersView filter, + String model) { Either result; Map propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class); Map propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class); @@ -725,7 +827,7 @@ public class ToscaOperationFacade { propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true); Either, JanusGraphOperationStatus> highestResources = janusGraphDao - .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag); + .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, parseFlag, model); if (highestResources.isRight()) { JanusGraphOperationStatus status = highestResources.right().value(); log.debug("failed to find resource with name {}. status={} ", nodeName, status); @@ -747,48 +849,30 @@ public class ToscaOperationFacade { } // region - Component Get By .. - private Either getLatestByName(GraphPropertyEnum property, String nodeName) { - return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata); + private Either getLatestByName(GraphPropertyEnum property, String nodeName, String modelName) { + return getLatestByName(property, nodeName, JsonParseFlagEnum.ParseMetadata, modelName); } - public Either, StorageOperationStatus> getBySystemName(ComponentTypeEnum componentType, String systemName) { - Either, StorageOperationStatus> result = null; - Either getComponentRes; - List components = new ArrayList<>(); - List componentVertices; - Map propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class); - Map propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class); + public Either getBySystemNameAndVersion(final ComponentTypeEnum componentType, + final String systemName, + final String version) { + final Map propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class); + final Map propertiesNotToMatch = new EnumMap<>(GraphPropertyEnum.class); propertiesToMatch.put(GraphPropertyEnum.SYSTEM_NAME, systemName); + propertiesToMatch.put(GraphPropertyEnum.VERSION, version); if (componentType != null) { propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name()); } propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true); - Either, JanusGraphOperationStatus> getComponentsRes = janusGraphDao - .getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll); - if (getComponentsRes.isRight()) { - JanusGraphOperationStatus status = getComponentsRes.right().value(); - log.debug("Failed to fetch the component with system name {}. Status is {} ", systemName, status); - result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); - } - if (result == null) { - componentVertices = getComponentsRes.left().value(); - for (GraphVertex componentVertex : componentVertices) { - getComponentRes = getToscaElementByOperation(componentVertex); - if (getComponentRes.isRight()) { - log.debug("Failed to get the component {}. Status is {} ", componentVertex.getJsonMetadataField(JsonPresentationFields.NAME), - getComponentRes.right().value()); - result = Either.right(getComponentRes.right().value()); - break; - } - T componentBySystemName = getComponentRes.left().value(); - log.debug("Found component, id: {}", componentBySystemName.getUniqueId()); - components.add(componentBySystemName); - } - } - if (result == null) { - result = Either.left(components); + + final Either, JanusGraphOperationStatus> getResourceResult + = janusGraphDao.getByCriteria(null, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll); + if (getResourceResult.isRight()) { + final JanusGraphOperationStatus status = getResourceResult.right().value(); + log.debug("Failed to find resource with systemName {}, version {}. Status is {} ", systemName, version, status); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); } - return result; + return getToscaElementByOperation(getResourceResult.left().value().get(0)); } public Either getComponentByNameAndVersion(ComponentTypeEnum componentType, String name, @@ -798,7 +882,6 @@ public class ToscaOperationFacade { public Either getComponentByNameAndVersion(ComponentTypeEnum componentType, String name, String version, JsonParseFlagEnum parseFlag) { - Either result; Map hasProperties = new EnumMap<>(GraphPropertyEnum.class); Map hasNotProperties = new EnumMap<>(GraphPropertyEnum.class); hasProperties.put(GraphPropertyEnum.NAME, name); @@ -812,15 +895,15 @@ public class ToscaOperationFacade { if (getResourceRes.isRight()) { JanusGraphOperationStatus status = getResourceRes.right().value(); log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status); - result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); - return result; + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); } return getToscaElementByOperation(getResourceRes.left().value().get(0)); } public Either getComponentByNameAndVendorRelease(final ComponentTypeEnum componentType, final String name, final String vendorRelease, - final JsonParseFlagEnum parseFlag) { + final JsonParseFlagEnum parseFlag, + final String modelName) { Map hasProperties = new EnumMap<>(GraphPropertyEnum.class); Map hasNotProperties = new EnumMap<>(GraphPropertyEnum.class); hasProperties.put(GraphPropertyEnum.NAME, name); @@ -829,8 +912,8 @@ public class ToscaOperationFacade { hasProperties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name()); } Map> predicateCriteria = getVendorVersionPredicate(vendorRelease); - Either, JanusGraphOperationStatus> getResourceRes = janusGraphDao - .getByCriteria(null, hasProperties, hasNotProperties, predicateCriteria, parseFlag); + Either, JanusGraphOperationStatus> getResourceRes = janusGraphDao.getByCriteria(null, hasProperties, hasNotProperties, + predicateCriteria, parseFlag, modelName); if (getResourceRes.isRight()) { JanusGraphOperationStatus status = getResourceRes.right().value(); log.debug("failed to find resource with name {}, version {}. Status is {} ", name, predicateCriteria, status); @@ -907,21 +990,117 @@ public class ToscaOperationFacade { return Either.left(checkIfInUseAndDelete(allMarked)); } - private List checkIfInUseAndDelete(List allMarked) { + public List deleteService(String invariantUUID, final boolean inTransaction) { + return deleteComponent(invariantUUID, NodeTypeEnum.Service, inTransaction); + } + + public List deleteComponent(String invariantUUID, NodeTypeEnum componentType, final boolean inTransaction) { + final List allServiceVerticesToDelete = findVertexListByInvariantUuid(invariantUUID); + List affectedComponentIds = new ArrayList<>(); + try { + checkNotUsed(allServiceVerticesToDelete); + lockAllVerticesByNodeType(allServiceVerticesToDelete, componentType); + for (GraphVertex elementV : allServiceVerticesToDelete) { + Either deleteToscaElement = deleteToscaElement(elementV); + if (deleteToscaElement.isRight()) { + log.debug("Failed to delete element UniqueID {}, Name {}, error {}", elementV.getUniqueId(), + elementV.getMetadataProperties().get(GraphPropertyEnum.NAME), deleteToscaElement.right().value()); + throwStorageException(deleteToscaElement.right().value()); + } + affectedComponentIds.add(elementV.getUniqueId()); + } + if (!inTransaction) { + janusGraphDao.commit(); + } + } catch (Exception exception) { + if (!inTransaction) { + janusGraphDao.rollback(); + } + throw exception; + } finally { + unlockAllVerticesByNodeType(allServiceVerticesToDelete, componentType); + } + return affectedComponentIds; + } + + private void checkNotUsed(List vertices) { + boolean isInUse = isAnyComponentInUse(vertices); + if (isInUse) { + Set listOfVertices = getComponentsUsingComponents(vertices); + List listOfStringComponents = new ArrayList<>(); + for (GraphVertex componentVertex : listOfVertices) { + listOfStringComponents.add( + componentVertex.getMetadataJson().get(GraphPropertyEnum.COMPONENT_TYPE.getProperty()) + " " + + componentVertex.getMetadataJson().get(GraphPropertyEnum.NAME.getProperty()) + ); + } + String stringOfComponents = String.join(", ", listOfStringComponents); + throw ToscaOperationExceptionSupplier.componentInUse(stringOfComponents).get(); + } + } + + public List findVertexListByInvariantUuid(final String invariantUuid) { + try { + return janusGraphDao.findAllVertexByInvariantUuid(invariantUuid, Collections.emptyMap()); + } catch (final JanusGraphException e) { + log.error(EcompLoggerErrorCode.DATA_ERROR, this.getClass().getName(), e.getMessage()); + throw new StorageException(e.getStatus()); + } + } + + public void commitAndCheck(String componentId) { + JanusGraphOperationStatus status = janusGraphDao.commit(); + if (!status.equals(JanusGraphOperationStatus.OK)) { + log.debug("error occurred when trying to DELETE {}. Return code is: {}", componentId, status); + throwStorageException(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status)); + } + } + + private Set getComponentsUsingComponents(List componentVertices) { + Set inUseBy = new TreeSet<>(Comparator.comparing(GraphVertex::getUniqueId)); + for (final GraphVertex elementV : componentVertices) { + List inUseByVertex = isInUse(elementV); + if (!inUseByVertex.isEmpty()) { + inUseBy.addAll(inUseByVertex); + } + } + return inUseBy; + } + + private boolean isAnyComponentInUse(List componentVertices) { + boolean isComponentInUse = false; + if (log.isDebugEnabled()) { + for (final GraphVertex graphVertex : componentVertices) { + if (!isInUse(graphVertex).isEmpty()) { + isComponentInUse = true; + } + } + } else { + isComponentInUse = componentVertices.stream().anyMatch(vertex -> !isInUse(vertex).isEmpty()); + } + return isComponentInUse; + } + + private List isInUse(GraphVertex elementV) { final List forbiddenEdgeLabelEnums = Arrays .asList(EdgeLabelEnum.INSTANCE_OF, EdgeLabelEnum.PROXY_OF, EdgeLabelEnum.ALLOTTED_OF); - List deleted = new ArrayList<>(); - for (GraphVertex elementV : allMarked) { - boolean isAllowedToDelete = true; - for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) { - Either belongingEdgeByCriteria = janusGraphDao - .getBelongingEdgeByCriteria(elementV, edgeLabelEnum, null); - if (belongingEdgeByCriteria.isLeft()) { - log.debug("Marked element {} in use. don't delete it", elementV.getUniqueId()); - isAllowedToDelete = false; - break; + for (EdgeLabelEnum edgeLabelEnum : forbiddenEdgeLabelEnums) { + Either, JanusGraphOperationStatus> inUseBy = + janusGraphDao.getParentVertices(elementV, edgeLabelEnum, JsonParseFlagEnum.ParseAll); + if (inUseBy.isLeft()) { + if (log.isDebugEnabled()) { + log.debug("Element {} in use.", elementV.getUniqueId()); } + return inUseBy.left().value(); } + } + return Collections.emptyList(); + } + + private List checkIfInUseAndDelete(List allMarked) { + List deleted = new ArrayList<>(); + for (GraphVertex elementV : allMarked) { + boolean isAllowedToDelete = !isInUse(elementV).isEmpty(); if (isAllowedToDelete) { Either deleteToscaElement = deleteToscaElement(elementV); if (deleteToscaElement.isRight()) { @@ -935,6 +1114,21 @@ public class ToscaOperationFacade { return deleted; } + private void lockAllVerticesByNodeType(List allVerticesToLock, NodeTypeEnum nodeType) { + for (GraphVertex graphVertex : allVerticesToLock) { + StorageOperationStatus storageOperationStatus = graphLockOperation.lockComponent(graphVertex.getUniqueId(), nodeType); + if (!storageOperationStatus.equals(StorageOperationStatus.OK)) { + throwStorageException(storageOperationStatus); + } + } + } + + private void unlockAllVerticesByNodeType(List allVerticesToUnlock, NodeTypeEnum nodeType) { + for (GraphVertex graphVertex : allVerticesToUnlock) { + graphLockOperation.unlockComponent(graphVertex.getUniqueId(), nodeType); + } + } + public Either, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) { Either, StorageOperationStatus> allComponentsMarkedForDeletion; switch (componentType) { @@ -1113,14 +1307,22 @@ public class ToscaOperationFacade { /** * @return max counter of component instance Id's, null if not found */ - private Integer getMaxCounterFromNamesAndIds(Component containerComponent, String normalizedName) { - List countersInNames = containerComponent.getComponentInstances().stream() + private Integer getMaxCounterFromNamesAndIds(final Component containerComponent, final String normalizedName) { + final Pattern COUNTER_PATTERN = Pattern.compile(normalizedName + "[\\s_:-]?\\d+$"); + final List countersInNames = containerComponent.getComponentInstances().stream() .filter(ci -> ci.getNormalizedName() != null && ci.getNormalizedName().startsWith(normalizedName)) - .map(ci -> ci.getNormalizedName().split(normalizedName)[1]).collect(Collectors.toList()); - List countersInIds = containerComponent.getComponentInstances().stream() - .filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName)).map(ci -> ci.getUniqueId().split(normalizedName)[1]) + .filter(ci -> !ci.getNormalizedName().equals(normalizedName)) + .map(ComponentInstance::getNormalizedName) + .map(COUNTER_PATTERN::matcher).filter(Matcher::find).map(matcher -> matcher.group(0)) + .map(nn -> nn.replaceAll("\\D", "")) + .collect(Collectors.toList()); + final List countersInIds = containerComponent.getComponentInstances().stream() + .filter(ci -> ci.getUniqueId() != null && ci.getUniqueId().contains(normalizedName)) + .map(ComponentInstance::getUniqueId) + .map(COUNTER_PATTERN::matcher).filter(Matcher::find).map(matcher -> matcher.group(0)) + .map(nn -> nn.replaceAll("\\D", "")) .collect(Collectors.toList()); - List namesAndIdsList = new ArrayList<>(countersInNames); + final List namesAndIdsList = new ArrayList<>(countersInNames); namesAndIdsList.addAll(countersInIds); return getMaxInteger(namesAndIdsList); } @@ -1135,7 +1337,6 @@ public class ToscaOperationFacade { maxCounter = currCounter; } } catch (NumberFormatException e) { - continue; } } return currCounter == null ? null : maxCounter; @@ -1143,7 +1344,7 @@ public class ToscaOperationFacade { public Either associateResourceInstances(Component component, String componentId, RequirementCapabilityRelDef requirementDef) { - return nodeTemplateOperation.associateResourceInstances(component, componentId, requirementDef); + return nodeTemplateOperation.associateResourceInstances(componentId, requirementDef); } public Either, StorageOperationStatus> createAndAssociateInputs(Map inputs, String componentId) { @@ -1157,7 +1358,7 @@ public class ToscaOperationFacade { .collect(Collectors.toMap(Map.Entry::getKey, e -> new PropertyDataDefinition(e.getValue()))); StorageOperationStatus status = topologyTemplateOperation.associateInputsToComponent(vertex, inputsMap, componentId); if (StorageOperationStatus.OK == status) { - log.debug(COMPONENT_CREATED_SUCCESSFULLY); + log.debug(INPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY); List inputsResList = null; if (inputsMap != null && !inputsMap.isEmpty()) { inputsResList = inputsMap.values().stream().map(InputDefinition::new).collect(Collectors.toList()); @@ -1167,6 +1368,28 @@ public class ToscaOperationFacade { return Either.right(status); } + public Either, StorageOperationStatus> createAndAssociateOutputs(final Map outputs, + final String componentId) { + final Either getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); + if (getVertexEither.isRight()) { + log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value()); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value())); + } + final GraphVertex vertex = getVertexEither.left().value(); + final Map outputsMap = outputs.entrySet().stream() + .collect(Collectors.toMap(Map.Entry::getKey, e -> new OutputDefinition(e.getValue()))); + final StorageOperationStatus status = topologyTemplateOperation.associateOutputsToComponent(vertex, outputsMap, componentId); + if (StorageOperationStatus.OK == status) { + log.debug(OUTPUTS_ASSOCIATED_TO_COMPONENT_SUCCESSFULLY); + List outputsResList = null; + if (MapUtils.isNotEmpty(outputsMap)) { + outputsResList = outputsMap.values().stream().map(OutputDefinition::new).collect(Collectors.toList()); + } + return Either.left(outputsResList); + } + return Either.right(status); + } + public Either, StorageOperationStatus> addInputsToComponent(Map inputs, String componentId) { Either getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); if (getVertexEither.isRight()) { @@ -1304,7 +1527,7 @@ public class ToscaOperationFacade { if (StorageOperationStatus.OK == status) { log.debug(COMPONENT_CREATED_SUCCESSFULLY); List inputsResList = null; - if (inputsAsDataDef != null && !inputsAsDataDef.isEmpty()) { + if (CollectionUtils.isNotEmpty(inputsAsDataDef)) { inputsResList = inputsAsDataDef.stream().map(InputDefinition::new).collect(Collectors.toList()); } return Either.left(inputsResList); @@ -1312,6 +1535,27 @@ public class ToscaOperationFacade { return Either.right(status); } + public Either, StorageOperationStatus> updateOutputsToComponent(List outputs, String componentId) { + Either getVertexEither = janusGraphDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); + if (getVertexEither.isRight()) { + log.debug(COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value()); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value())); + } + GraphVertex vertex = getVertexEither.left().value(); + List outputsAsDataDef = outputs.stream().map(AttributeDataDefinition::new).collect(Collectors.toList()); + StorageOperationStatus status = topologyTemplateOperation + .updateToscaDataOfToscaElement(vertex, EdgeLabelEnum.OUTPUTS, VertexTypeEnum.OUTPUTS, outputsAsDataDef, JsonPresentationFields.NAME); + if (StorageOperationStatus.OK == status) { + log.debug(COMPONENT_CREATED_SUCCESSFULLY); + List outputsResList = null; + if (!outputsAsDataDef.isEmpty()) { + outputsResList = outputsAsDataDef.stream().map(OutputDefinition::new).collect(Collectors.toList()); + } + return Either.left(outputsResList); + } + return Either.right(status); + } + // region - ComponentInstance public Either>, StorageOperationStatus> associateComponentInstancePropertiesToComponent( Map> instProperties, String componentId) { @@ -1415,6 +1659,49 @@ public class ToscaOperationFacade { return Either.right(status); } + public Either, StorageOperationStatus> associateComponentInstanceInterfacesToComponent( + Map> instInterfaces, + String componentId + ) { + Either getVertexEither = janusGraphDao.getVertexById( + componentId, + JsonParseFlagEnum.NoParse + ); + if (getVertexEither.isRight()) { + log.debug( + COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, + componentId, + getVertexEither.right().value() + ); + return Either.right( + DaoStatusConverter.convertJanusGraphStatusToStorageStatus( + getVertexEither.right().value() + ) + ); + } + GraphVertex vertex = getVertexEither.left().value(); + Map instInterfacesMap = new HashMap<>(); + if (instInterfaces != null) { + + for (Map.Entry> entryInstances : instInterfaces.entrySet()) { + Map incomingInterfacesMap = entryInstances.getValue().entrySet().stream() + .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); + MapInterfaceDataDefinition interfacesMap = new MapInterfaceDataDefinition(); + interfacesMap.setMapToscaDataDefinition(incomingInterfacesMap); + instInterfacesMap.put(entryInstances.getKey(), interfacesMap); + } + } + StorageOperationStatus status = topologyTemplateOperation.associateInstInterfacesToComponent( + vertex, + instInterfacesMap + ); + if (StorageOperationStatus.OK == status) { + log.debug(COMPONENT_CREATED_SUCCESSFULLY); + return Either.left(instInterfacesMap); + } + return Either.right(status); + } + public Either>, StorageOperationStatus> addComponentInstanceInputsToComponent( Component containerComponent, Map> instProperties) { requireNonNull(instProperties); @@ -1445,33 +1732,33 @@ public class ToscaOperationFacade { } public Either>, StorageOperationStatus> addComponentInstanceOutputsToComponent( - Component containerComponent, Map> instProperties) { - requireNonNull(instProperties); + Component containerComponent, Map> instOutputs) { + requireNonNull(instOutputs); StorageOperationStatus status; - for (final Entry> entry : instProperties.entrySet()) { - final List props = entry.getValue(); + for (final Entry> entry : instOutputs.entrySet()) { + final List outputs = entry.getValue(); final String componentInstanceId = entry.getKey(); - if (!isEmpty(props)) { - for (final ComponentInstanceOutput property : props) { - final List componentInstancesInputs = containerComponent.getComponentInstancesOutputs() + if (!isEmpty(outputs)) { + for (final ComponentInstanceOutput output : outputs) { + final List componentInstanceOutputs = containerComponent.getComponentInstancesOutputs() .get(componentInstanceId); - final Optional instanceProperty = componentInstancesInputs.stream() - .filter(p -> p.getName().equals(property.getName())).findAny(); - if (instanceProperty.isPresent()) { - status = updateComponentInstanceOutput(containerComponent, componentInstanceId, property); + final Optional componentInstanceOutput = componentInstanceOutputs.stream() + .filter(p -> p.getName().equals(output.getName())).findAny(); + if (componentInstanceOutput.isPresent()) { + status = updateComponentInstanceOutput(containerComponent, componentInstanceId, output); } else { - status = addComponentInstanceOutput(containerComponent, componentInstanceId, property); + status = addComponentInstanceOutput(containerComponent, componentInstanceId, output); } if (status != StorageOperationStatus.OK) { - log.debug("Failed to update instance input {} for instance {} error {} ", property, componentInstanceId, status); + log.debug("Failed to update instance output {} for instance {} error {} ", output, componentInstanceId, status); return Either.right(status); } else { - log.trace("instance input {} for instance {} updated", property, componentInstanceId); + log.trace("instance output {} for instance {} updated", output, componentInstanceId); } } } } - return Either.left(instProperties); + return Either.left(instOutputs); } public Either>, StorageOperationStatus> addComponentInstancePropertiesToComponent( @@ -1506,25 +1793,25 @@ public class ToscaOperationFacade { } public Either>, StorageOperationStatus> addComponentInstanceAttributesToComponent( - final Component containerComponent, final Map> instProperties) { - requireNonNull(instProperties); - for (final Entry> entry : instProperties.entrySet()) { - final List props = entry.getValue(); - if (isEmpty(props)) { + final Component containerComponent, final Map> componentInstanceAttribute) { + requireNonNull(componentInstanceAttribute); + for (final Entry> entry : componentInstanceAttribute.entrySet()) { + final List attributes = entry.getValue(); + if (isEmpty(attributes)) { continue; } final String componentInstanceId = entry.getKey(); - final List originalComponentInstProps = containerComponent.getComponentInstancesAttributes() + final List componentInstanceAttributes = containerComponent.getComponentInstancesAttributes() .get(componentInstanceId); - for (final ComponentInstanceAttribute property : props) { + for (final ComponentInstanceAttribute attribute : attributes) { final StorageOperationStatus status = updateOrAddComponentInstanceAttribute(containerComponent, componentInstanceId, - originalComponentInstProps, property); + componentInstanceAttributes, attribute); if (status != StorageOperationStatus.OK) { return Either.right(status); } } } - return Either.left(instProperties); + return Either.left(componentInstanceAttribute); } private StorageOperationStatus populateAndUpdateInstanceCapProperty(Component containerComponent, String componentInstanceId, @@ -1562,19 +1849,19 @@ public class ToscaOperationFacade { } private StorageOperationStatus updateOrAddComponentInstanceAttribute(Component containerComponent, String componentInstanceId, - List originalComponentInstProps, - ComponentInstanceAttribute property) { + List componentInstanceAttributes, + ComponentInstanceAttribute attribute) { StorageOperationStatus status; - // check if the property already exists or not - Optional instanceProperty = originalComponentInstProps.stream() - .filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny(); + // check if the attribute already exists or not + Optional instanceProperty = componentInstanceAttributes.stream() + .filter(p -> p.getUniqueId().equals(attribute.getUniqueId())).findAny(); if (instanceProperty.isPresent()) { - status = updateComponentInstanceAttribute(containerComponent, componentInstanceId, property); + status = updateComponentInstanceAttribute(containerComponent, componentInstanceId, attribute); } else { - status = addComponentInstanceAttribute(containerComponent, componentInstanceId, property); + status = addComponentInstanceAttribute(containerComponent, componentInstanceId, attribute); } if (status != StorageOperationStatus.OK) { - log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status); + log.debug("Failed to update instance attribute {} for instance {} error {} ", attribute, componentInstanceId, status); } return status; } @@ -1787,6 +2074,38 @@ public class ToscaOperationFacade { return storageOperationStatus; } + public StorageOperationStatus updateCalculatedCapabilitiesRequirements( + final Map>> instCapabilties, + final Map>> instReg, + final Component component) { + StorageOperationStatus storageOperationStatus = StorageOperationStatus.OK; + if (instCapabilties != null) { + for (Entry>> entry : instCapabilties.entrySet()) { + final Map> cap = entry.getValue(); + for (List capabilityList : cap.values()) { + for (CapabilityDefinition capability : capabilityList) { + nodeTemplateOperation.updateComponentInstanceCapabilities(component.getUniqueId(), entry.getKey().getUniqueId(), capability); + } + } + } + } + if (instReg != null) { + for (Entry>> entry : instReg.entrySet()) { + final Map> req = entry.getValue(); + for (List requirementList : req.values()) { + for (RequirementDefinition requirement : requirementList) { + storageOperationStatus = nodeTemplateOperation.updateComponentInstanceRequirement(component.getUniqueId(), + entry.getKey().getUniqueId(), requirement); + if (storageOperationStatus != StorageOperationStatus.OK) { + return storageOperationStatus; + } + } + } + } + } + return storageOperationStatus; + } + private void updateInstancesCapAndReqOnComponentFromDB(Component component) { ComponentParametersView componentParametersView = new ComponentParametersView(true); componentParametersView.setIgnoreCapabilities(false); @@ -1800,45 +2119,48 @@ public class ToscaOperationFacade { Component updatedComponent = componentEither.left().value(); component.setCapabilities(updatedComponent.getCapabilities()); component.setRequirements(updatedComponent.getRequirements()); + component.setComponentInstancesRelations(updatedComponent.getComponentInstancesRelations()); component.setComponentInstances(updatedComponent.getComponentInstances()); } private Either, StorageOperationStatus> getLatestVersionNonCheckoutServicesMetadataOnly(Map hasProps, - Map hasNotProps) { + Map hasNotProps, + String modelName) { List services = new ArrayList<>(); List states = new ArrayList<>(); // include props hasProps.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name()); hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); + if (modelName != null) { + hasProps.put(GraphPropertyEnum.MODEL, modelName); + } // exclude props states.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); hasNotProps.put(GraphPropertyEnum.STATE, states); hasNotProps.put(GraphPropertyEnum.IS_DELETED, true); hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true); - return fetchServicesByCriteria(services, hasProps, hasNotProps); + return fetchServicesByCriteria(services, hasProps, hasNotProps, modelName); } - private Either, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(boolean isAbstract, - ComponentTypeEnum componentTypeEnum, - String internalComponentType, - VertexTypeEnum vertexType) { + private Either, StorageOperationStatus> getLatestVersionNotAbstractToscaElementsMetadataOnly(final boolean isAbstract, + final ComponentTypeEnum componentTypeEnum, + final String internalComponentType, + final VertexTypeEnum vertexType, + final String modelName, + final boolean includeNormativeExtensionModels) { List services = null; Map hasProps = new EnumMap<>(GraphPropertyEnum.class); Map hasNotProps = new EnumMap<>(GraphPropertyEnum.class); - fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType); + fillPropsMap(hasProps, hasNotProps, internalComponentType, componentTypeEnum, isAbstract, vertexType, modelName); Either, JanusGraphOperationStatus> getRes = janusGraphDao - .getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata); - if (getRes.isRight()) { - if (getRes.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) { - return Either.left(new ArrayList<>()); - } else { - return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value())); - } + .getByCriteria(vertexType, hasProps, hasNotProps, JsonParseFlagEnum.ParseMetadata, modelName, includeNormativeExtensionModels); + if (getRes.isRight() && !JanusGraphOperationStatus.NOT_FOUND.equals(getRes.right().value())) { + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value())); } // region -> Fetch non checked-out services if (internalComponentType != null && internalComponentType.toLowerCase().trim().equals(SERVICE) && VertexTypeEnum.NODE_TYPE == vertexType) { Either, StorageOperationStatus> result = getLatestVersionNonCheckoutServicesMetadataOnly( - new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class)); + new EnumMap<>(GraphPropertyEnum.class), new EnumMap<>(GraphPropertyEnum.class), modelName); if (result.isRight()) { log.debug("Failed to fetch services for"); return Either.right(result.right().value()); @@ -1852,15 +2174,17 @@ public class ToscaOperationFacade { List nonAbstractLatestComponents = new ArrayList<>(); ComponentParametersView params = new ComponentParametersView(true); params.setIgnoreAllVersions(false); - for (GraphVertex vertexComponent : getRes.left().value()) { - Either componentRes = topologyTemplateOperation - .getLightComponent(vertexComponent, componentTypeEnum, params); - if (componentRes.isRight()) { - log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value()); - return Either.right(componentRes.right().value()); - } else { - Component component = ModelConverter.convertFromToscaElement(componentRes.left().value()); - nonAbstractLatestComponents.add(component); + if (getRes.isLeft()) { + for (GraphVertex vertexComponent : getRes.left().value()) { + Either componentRes = topologyTemplateOperation + .getLightComponent(vertexComponent, componentTypeEnum, params); + if (componentRes.isRight()) { + log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), componentRes.right().value()); + return Either.right(componentRes.right().value()); + } else { + Component component = ModelConverter.convertFromToscaElement(componentRes.left().value()); + nonAbstractLatestComponents.add(component); + } } } if (CollectionUtils.isNotEmpty(services)) { @@ -1954,7 +2278,7 @@ public class ToscaOperationFacade { private Either, StorageOperationStatus> getComponentUids(boolean isAbstract, ComponentTypeEnum componentTypeEnum, String internalComponentType) { Either, StorageOperationStatus> getToscaElementsRes = getLatestVersionNotAbstractMetadataOnly(isAbstract, componentTypeEnum, - internalComponentType); + internalComponentType, null, false); if (getToscaElementsRes.isRight()) { return Either.right(getToscaElementsRes.right().value()); } @@ -1987,13 +2311,9 @@ public class ToscaOperationFacade { public Either validateComponentNameUniqueness(String name, ResourceTypeEnum resourceType, ComponentTypeEnum componentType) { - VertexTypeEnum vertexType = ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : VertexTypeEnum.TOPOLOGY_TEMPLATE; String normalizedName = ValidationUtils.normaliseComponentName(name); - Map properties = new EnumMap<>(GraphPropertyEnum.class); - properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName); - properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name()); Either, JanusGraphOperationStatus> vertexEither = janusGraphDao - .getByCriteria(vertexType, properties, JsonParseFlagEnum.NoParse); + .getByCriteria(getVertexTypeEnum(resourceType), propertiesToMatch(normalizedName, componentType), JsonParseFlagEnum.NoParse); if (vertexEither.isRight() && vertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) { log.debug("failed to get vertex from graph with property normalizedName: {}", normalizedName); return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value())); @@ -2001,12 +2321,48 @@ public class ToscaOperationFacade { return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value() : null)); } + public Either validateComponentNameAndModelExists(final String resourceName, final String model, + final ResourceTypeEnum resourceType, + final ComponentTypeEnum componentType) { + Either result = validateComponentNameAndModelUniqueness(resourceName, model, resourceType, componentType); + if (result.isLeft()) { + result = Either.left(!result.left().value()); + } + return result; + } + + private Either validateComponentNameAndModelUniqueness(final String resourceName, final String modelName, + final ResourceTypeEnum resourceType, + final ComponentTypeEnum componentType) { + final String normalizedName = ValidationUtils.normaliseComponentName(resourceName); + final Either, JanusGraphOperationStatus> vertexEither = janusGraphDao + .getByCriteria(getVertexTypeEnum(resourceType), propertiesToMatch(normalizedName, componentType), null, null, JsonParseFlagEnum.NoParse, + modelName); + if (vertexEither.isRight() && vertexEither.right().value() != JanusGraphOperationStatus.NOT_FOUND) { + log.debug("failed to get vertex from graph with property normalizedName: {} and model: {}", normalizedName, modelName); + return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexEither.right().value())); + } + return Either.left(CollectionUtils.isEmpty(vertexEither.isLeft() ? vertexEither.left().value().stream() + .collect(Collectors.toList()) : null)); + } + + private VertexTypeEnum getVertexTypeEnum(final ResourceTypeEnum resourceType) { + return ModelConverter.isAtomicComponent(resourceType) ? VertexTypeEnum.NODE_TYPE : TOPOLOGY_TEMPLATE; + } + + private Map propertiesToMatch(final String normalizedName, final ComponentTypeEnum componentType) { + final Map properties = new EnumMap<>(GraphPropertyEnum.class); + properties.put(GraphPropertyEnum.NORMALIZED_NAME, normalizedName); + properties.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name()); + return properties; + } + private void fillNodeTypePropsMap(final Map hasProps, final Map hasNotProps, - final String internalComponentType) { + final String internalComponentType, String modelName) { final Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration(); final List allowedTypes; if (ComponentTypeEnum.SERVICE.getValue().equalsIgnoreCase(internalComponentType)) { - allowedTypes = containerInstanceTypesData.getComponentAllowedList(ComponentTypeEnum.SERVICE, null); + allowedTypes = containerInstanceTypesData.getServiceAllowedList(modelName); } else { final ResourceTypeEnum resourceType = ResourceTypeEnum.getTypeIgnoreCase(internalComponentType); allowedTypes = containerInstanceTypesData.getComponentAllowedList(ComponentTypeEnum.RESOURCE, resourceType); @@ -2040,15 +2396,16 @@ public class ToscaOperationFacade { } private void fillPropsMap(Map hasProps, Map hasNotProps, String internalComponentType, - ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType) { + ComponentTypeEnum componentTypeEnum, boolean isAbstract, VertexTypeEnum internalVertexType, String modelName) { hasNotProps.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); hasNotProps.put(GraphPropertyEnum.IS_DELETED, true); hasNotProps.put(GraphPropertyEnum.IS_ARCHIVED, true); hasProps.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); + if (VertexTypeEnum.NODE_TYPE == internalVertexType) { hasProps.put(GraphPropertyEnum.IS_ABSTRACT, isAbstract); if (internalComponentType != null) { - fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType); + fillNodeTypePropsMap(hasProps, hasNotProps, internalComponentType, modelName); } } else { fillTopologyTemplatePropsMap(hasProps, hasNotProps, componentTypeEnum); @@ -2060,20 +2417,23 @@ public class ToscaOperationFacade { if (ComponentTypeEnum.RESOURCE == componentTypeEnum) { internalVertexTypes.add(VertexTypeEnum.NODE_TYPE); } - if (ComponentTypeEnum.SERVICE == componentTypeEnum || SERVICE.equalsIgnoreCase(internalComponentType)) { - internalVertexTypes.add(VertexTypeEnum.TOPOLOGY_TEMPLATE); + if (ComponentTypeEnum.SERVICE == componentTypeEnum || SERVICE.equalsIgnoreCase(internalComponentType) || VF.equalsIgnoreCase( + internalComponentType)) { + internalVertexTypes.add(TOPOLOGY_TEMPLATE); } return internalVertexTypes; } public Either, StorageOperationStatus> getLatestVersionNotAbstractMetadataOnly(boolean isAbstract, - ComponentTypeEnum componentTypeEnum, - String internalComponentType) { + final ComponentTypeEnum componentTypeEnum, + final String internalComponentType, + final String modelName, + final boolean includeNormativeExtensionModels) { List internalVertexTypes = getInternalVertexTypes(componentTypeEnum, internalComponentType); List result = new ArrayList<>(); for (VertexTypeEnum vertexType : internalVertexTypes) { Either, StorageOperationStatus> listByVertexType = getLatestVersionNotAbstractToscaElementsMetadataOnly(isAbstract, - componentTypeEnum, internalComponentType, vertexType); + componentTypeEnum, internalComponentType, vertexType, modelName, includeNormativeExtensionModels); if (listByVertexType.isRight()) { return listByVertexType; } @@ -2174,7 +2534,7 @@ public class ToscaOperationFacade { } Component component = latestVersionList.size() == 1 ? latestVersionList.get(0) : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getVersion()), Double.parseDouble(c2.getVersion()))) - .get(); + .get(); return Either.left(component); } @@ -2207,7 +2567,7 @@ public class ToscaOperationFacade { } public Either getLatestByNameAndVersion(String name, String version, - JsonParseFlagEnum parseFlag) { + JsonParseFlagEnum parseFlag, String model) { Either result; Map hasProperties = new EnumMap<>(GraphPropertyEnum.class); Map hasNotProperties = new EnumMap<>(GraphPropertyEnum.class); @@ -2216,7 +2576,7 @@ public class ToscaOperationFacade { hasProperties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true); hasNotProperties.put(GraphPropertyEnum.IS_DELETED, true); Either, JanusGraphOperationStatus> getResourceRes = janusGraphDao - .getByCriteria(null, hasProperties, hasNotProperties, parseFlag); + .getByCriteria(null, hasProperties, hasNotProperties, parseFlag, model); if (getResourceRes.isRight()) { JanusGraphOperationStatus status = getResourceRes.right().value(); log.debug("failed to find resource with name {}, version {}. Status is {} ", name, version, status); @@ -2282,10 +2642,10 @@ public class ToscaOperationFacade { log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions"); return Either.right(StorageOperationStatus.GENERAL_ERROR); } - if (resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID) != null && !((String) resourceMetadataData - .getJsonMetadataField(JsonPresentationFields.CSAR_UUID)).equals(csarUUID)) { + final Object csarUuid = resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID); + if (csarUuid != null && !csarUuid.equals(csarUUID)) { log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName, - resourceMetadataData.getJsonMetadataField(JsonPresentationFields.CSAR_UUID), csarUUID); + csarUuid, csarUUID); // correct error will be returned from create flow. with all // correct audit records!!!!! @@ -2319,10 +2679,11 @@ public class ToscaOperationFacade { return null; } - public Either validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends) { + public Either validateToscaResourceNameExtends(String templateNameCurrent, String templateNameExtends, + String model) { String currentTemplateNameChecked = templateNameExtends; while (currentTemplateNameChecked != null && !currentTemplateNameChecked.equalsIgnoreCase(templateNameCurrent)) { - Either latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked); + Either latestByToscaResourceName = getLatestByToscaResourceName(currentTemplateNameChecked, model); if (latestByToscaResourceName.isRight()) { return latestByToscaResourceName.right().value() == StorageOperationStatus.NOT_FOUND ? Either.left(false) : Either.right(latestByToscaResourceName.right().value()); @@ -2419,11 +2780,11 @@ public class ToscaOperationFacade { } propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, ComponentTypeEnum.SERVICE.name()); propertiesNotToMatch.put(GraphPropertyEnum.IS_DELETED, true); - if (distStatus != null && !distStatus.isEmpty()) { + if (CollectionUtils.isNotEmpty(distStatus)) { for (DistributionStatusEnum state : distStatus) { propertiesToMatch.put(GraphPropertyEnum.DISTRIBUTION_STATUS, state.name()); Either, StorageOperationStatus> fetchServicesByCriteria = fetchServicesByCriteria(servicesAll, propertiesToMatch, - propertiesNotToMatch); + propertiesNotToMatch, null); if (fetchServicesByCriteria.isRight()) { return fetchServicesByCriteria; } else { @@ -2432,15 +2793,20 @@ public class ToscaOperationFacade { } return Either.left(servicesAll); } else { - return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch); + return fetchServicesByCriteria(servicesAll, propertiesToMatch, propertiesNotToMatch, null); } } private Either, StorageOperationStatus> fetchServicesByCriteria(List servicesAll, Map propertiesToMatch, - Map propertiesNotToMatch) { - Either, JanusGraphOperationStatus> getRes = janusGraphDao - .getByCriteria(VertexTypeEnum.TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll); + Map propertiesNotToMatch, + String modelName) { + Either, JanusGraphOperationStatus> getRes; + if (StringUtils.isEmpty(modelName)) { + getRes = janusGraphDao.getByCriteria(TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll); + } else { + getRes = janusGraphDao.getByCriteria(TOPOLOGY_TEMPLATE, propertiesToMatch, propertiesNotToMatch, JsonParseFlagEnum.ParseAll, modelName); + } if (getRes.isRight()) { if (getRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) { CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, @@ -2449,7 +2815,7 @@ public class ToscaOperationFacade { return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getRes.right().value())); } } else { - for (GraphVertex vertex : getRes.left().value()) { + for (final GraphVertex vertex : getRes.left().value()) { Either getServiceRes = topologyTemplateOperation .getLightComponent(vertex, ComponentTypeEnum.SERVICE, new ComponentParametersView(true)); if (getServiceRes.isRight()) { @@ -2494,9 +2860,9 @@ public class ToscaOperationFacade { return nodeTemplateOperation.generateCustomizationUUIDOnInstanceGroup(componentId, instanceId, groupInstances); } - public Either addPropertyToComponent(String propertyName, PropertyDefinition newPropertyDefinition, + public Either addPropertyToComponent(PropertyDefinition newPropertyDefinition, Component component) { - newPropertyDefinition.setName(propertyName); + final String propertyName = newPropertyDefinition.getName(); StorageOperationStatus status = getToscaElementOperation(component) .addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.PROPERTIES, VertexTypeEnum.PROPERTIES, newPropertyDefinition, JsonPresentationFields.NAME); @@ -2800,7 +3166,7 @@ public class ToscaOperationFacade { String componentInstanceId) { String uniqueId = componentInstance.getUniqueId(); StorageOperationStatus status = nodeTemplateOperation - .deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, VertexTypeEnum.INST_GROUPS, + .deleteToscaDataDeepElementsBlockOfToscaElement(containerComponent.getUniqueId(), EdgeLabelEnum.INST_GROUPS, uniqueId); if (status != StorageOperationStatus.OK && status != StorageOperationStatus.NOT_FOUND) { CommonUtility @@ -2933,7 +3299,7 @@ public class ToscaOperationFacade { public StorageOperationStatus updateComponentInstanceCapabilityProperties(Component containerComponent, String componentInstanceUniqueId) { return convertComponentInstanceProperties(containerComponent, componentInstanceUniqueId).map(instanceCapProps -> topologyTemplateOperation - .updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps)) + .updateComponentInstanceCapabilityProperties(containerComponent, componentInstanceUniqueId, instanceCapProps)) .orElse(StorageOperationStatus.NOT_FOUND); } @@ -2942,11 +3308,67 @@ public class ToscaOperationFacade { return nodeTemplateOperation.updateComponentInstanceRequirement(containerComponentId, componentInstanceUniqueId, requirementDataDefinition); } + public CapabilityDataDefinition updateComponentInstanceCapability(final String containerComponentId, final String componentInstanceUniqueId, + final CapabilityDataDefinition capabilityDataDefinition) { + + return nodeTemplateOperation.updateComponentInstanceCapabilities(containerComponentId, componentInstanceUniqueId, capabilityDataDefinition); + } + public StorageOperationStatus updateComponentInstanceInterfaces(Component containerComponent, String componentInstanceUniqueId) { MapInterfaceDataDefinition mapInterfaceDataDefinition = convertComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId); return topologyTemplateOperation.updateComponentInstanceInterfaces(containerComponent, componentInstanceUniqueId, mapInterfaceDataDefinition); } + public StorageOperationStatus updateComponentInterfaces(final Component component, final String componentInterfaceUpdatedKey) { + MapInterfaceDataDefinition mapInterfaceDataDefinition = convertComponentInterfaces(component.getInterfaces()); + return topologyTemplateOperation.updateComponentInterfaces(component.getUniqueId(), mapInterfaceDataDefinition, componentInterfaceUpdatedKey); + } + + public Either addInterfaceToComponent(final String interfaceName, + final InterfaceDefinition interfaceDefinition, + final Component component) { + + final boolean match = component.getInterfaces().keySet().stream().anyMatch(s -> s.equals(interfaceName)); + StorageOperationStatus status; + final ToscaElementOperation toscaElementOperation = getToscaElementOperation(component); + if (match) { + status = toscaElementOperation.updateToscaDataOfToscaElement(component.getUniqueId(), EdgeLabelEnum.INTERFACE_ARTIFACTS, + VertexTypeEnum.INTERFACE_ARTIFACTS, interfaceDefinition, JsonPresentationFields.TYPE); + } else { + status = toscaElementOperation.addToscaDataToToscaElement(component.getUniqueId(), EdgeLabelEnum.INTERFACE_ARTIFACTS, + VertexTypeEnum.INTERFACE_ARTIFACTS, interfaceDefinition, JsonPresentationFields.TYPE); + } + + if (status != StorageOperationStatus.OK) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add the interface {} to the component {}. Status is {}. ", + interfaceName, component.getName(), status); + return Either.right(status); + } + final ComponentParametersView filter = new ComponentParametersView(true); + filter.setIgnoreInterfaces(false); + filter.setIgnoreInterfaceInstances(false); + final Either getUpdatedComponentRes = getToscaElement(component.getUniqueId(), filter); + if (getUpdatedComponentRes.isRight()) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated component {}. Status is {}. ", + component.getUniqueId(), getUpdatedComponentRes.right().value()); + return Either.right(getUpdatedComponentRes.right().value()); + } + InterfaceDefinition newInterfaceDefinition = null; + final Map interfaces = (getUpdatedComponentRes.left().value()).getInterfaces(); + if (MapUtils.isNotEmpty(interfaces)) { + final Optional interfaceNameOptional = interfaces.keySet().stream().filter(key -> key.equals(interfaceName)).findAny(); + if (interfaceNameOptional.isPresent()) { + newInterfaceDefinition = interfaces.get(interfaceNameOptional.get()); + } + } + if (newInterfaceDefinition == null) { + CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find recently added interface {} on the component {}. Status is {}. ", + interfaceName, component.getUniqueId(), StorageOperationStatus.NOT_FOUND); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + return Either.left(newInterfaceDefinition); + } + public StorageOperationStatus updateComponentCalculatedCapabilitiesProperties(Component containerComponent) { Map mapCapabiltyPropertyMap = convertComponentCapabilitiesProperties(containerComponent); return nodeTemplateOperation.overrideComponentCapabilitiesProperties(containerComponent, mapCapabiltyPropertyMap); @@ -2954,14 +3376,14 @@ public class ToscaOperationFacade { public StorageOperationStatus deleteAllCalculatedCapabilitiesRequirements(String topologyTemplateId) { StorageOperationStatus status = topologyTemplateOperation - .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES, VertexTypeEnum.CALCULATED_CAPABILITIES); + .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAPABILITIES); if (status == StorageOperationStatus.OK) { status = topologyTemplateOperation - .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS, VertexTypeEnum.CALCULATED_REQUIREMENTS); + .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_REQUIREMENTS); } if (status == StorageOperationStatus.OK) { status = topologyTemplateOperation - .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, VertexTypeEnum.CALCULATED_CAP_PROPERTIES); + .removeToscaData(topologyTemplateId, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES); } return status; } @@ -3008,6 +3430,14 @@ public class ToscaOperationFacade { return mapInterfaceDataDefinition; } + private MapInterfaceDataDefinition convertComponentInterfaces(final Map interfaces) { + final MapInterfaceDataDefinition mapInterfaceDataDefinition = new MapInterfaceDataDefinition(); + if (MapUtils.isNotEmpty(interfaces)) { + interfaces.values().stream().forEach(interfaceDef -> mapInterfaceDataDefinition.put(interfaceDef.getType(), interfaceDef)); + } + return mapInterfaceDataDefinition; + } + private Map convertComponentCapabilitiesProperties(Component currComponent) { Map map = ModelConverter.extractCapabilityPropertiesFromGroups(currComponent.getGroups(), true); map.putAll(ModelConverter.extractCapabilityProperteisFromInstances(currComponent.getComponentInstances(), true)); @@ -3028,7 +3458,7 @@ public class ToscaOperationFacade { log.error(COULDNT_FETCH_A_COMPONENT_WITH_AND_UNIQUE_ID_ERROR, componentId, getVertexEither.right().value()); result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVertexEither.right().value())); } else { - if (getVertexEither.left().value().getLabel() != VertexTypeEnum.TOPOLOGY_TEMPLATE) { + if (getVertexEither.left().value().getLabel() != TOPOLOGY_TEMPLATE) { log.error("Policy association to component of Tosca type {} is not allowed. ", getVertexEither.left().value().getLabel()); result = Either.right(StorageOperationStatus.BAD_REQUEST); } @@ -3214,6 +3644,6 @@ public class ToscaOperationFacade { } public Either getLatestByServiceName(String serviceName) { - return getLatestByName(GraphPropertyEnum.NAME, serviceName); + return getLatestByName(GraphPropertyEnum.NAME, serviceName, null); } }