diff options
Diffstat (limited to 'catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java')
-rw-r--r-- | catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java | 106 |
1 files changed, 97 insertions, 9 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java index 2e5da8ddda..6f9555899b 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DefaultDerivedFromOperation.java @@ -1,25 +1,29 @@ package org.openecomp.sdc.be.model.operations.impl; +import fj.data.Either; +import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; import org.openecomp.sdc.be.dao.titan.TitanGenericDao; import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.resources.data.UniqueIdData; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import org.openecomp.sdc.common.log.wrappers.Logger; import org.springframework.stereotype.Component; -import fj.data.Either; +import java.util.*; +import java.util.function.Function; @Component public class DefaultDerivedFromOperation implements DerivedFromOperation { - private static final Logger log = LoggerFactory.getLogger(DefaultDerivedFromOperation.class); + private static final Logger log = Logger.getLogger(DefaultDerivedFromOperation.class.getName()); private TitanGenericDao titanGenericDao; public DefaultDerivedFromOperation(TitanGenericDao titanGenericDao) { @@ -28,8 +32,8 @@ public class DefaultDerivedFromOperation implements DerivedFromOperation { @Override public Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(String parentUniqueId, String derivedFromUniqueId, NodeTypeEnum nodeType) { - UniqueIdData from = new UniqueIdData(NodeTypeEnum.PolicyType, parentUniqueId); - UniqueIdData to = new UniqueIdData(NodeTypeEnum.PolicyType, derivedFromUniqueId); + UniqueIdData from = new UniqueIdData(nodeType, parentUniqueId); + UniqueIdData to = new UniqueIdData(nodeType, derivedFromUniqueId); return titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null) .right() .map(DaoStatusConverter::convertTitanStatusToStorageStatus); @@ -45,8 +49,8 @@ public class DefaultDerivedFromOperation implements DerivedFromOperation { @Override public StorageOperationStatus removeDerivedFromRelation(String uniqueId, String derivedFromUniqueId, NodeTypeEnum nodeType) { - UniqueIdData from = new UniqueIdData(NodeTypeEnum.PolicyType, uniqueId); - UniqueIdData to = new UniqueIdData(NodeTypeEnum.PolicyType, derivedFromUniqueId); + UniqueIdData from = new UniqueIdData(nodeType, uniqueId); + UniqueIdData to = new UniqueIdData(nodeType, derivedFromUniqueId); return isDerivedFromExists(from, to) .either(isRelationExist -> isRelationExist ? deleteDerivedFrom(from, to) : StorageOperationStatus.OK, DaoStatusConverter::convertTitanStatusToStorageStatus); @@ -63,6 +67,90 @@ public class DefaultDerivedFromOperation implements DerivedFromOperation { private Either<Boolean, TitanOperationStatus> isDerivedFromExists(UniqueIdData from, UniqueIdData to) { return titanGenericDao.isRelationExist(from, to, GraphEdgeLabels.DERIVED_FROM); } - + + @Override + public <T extends GraphNode> Either<Boolean, StorageOperationStatus> isTypeDerivedFrom(String childCandidateType, String parentCandidateType, String currentChildType, + NodeTypeEnum nodeType, Class<T> clazz, Function<T, String> typeProvider) { + Map<String, Object> propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.TYPE.getProperty(), childCandidateType); + + Either<List<T>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, clazz); + if (getResponse.isRight()) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } + T node = getResponse.left().value().get(0); + String childUniqueId = node.getUniqueId(); + String childType = typeProvider.apply(node); + + Set<String> travelledTypes = new HashSet<>(); + if (currentChildType != null) { + travelledTypes.add(currentChildType); + } + + do { + travelledTypes.add(childType); + Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), childUniqueId, GraphEdgeLabels.DERIVED_FROM, + nodeType, clazz); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch derived from node for type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability.", childCandidateType); + return Either.left(false); + } + } + String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); + String derivedFromType = typeProvider.apply(childrenNodes.left().value().get(0).getLeft()); + if (derivedFromType.equals(parentCandidateType)) { + log.debug("Verified that type {} derives from type {}", childCandidateType, parentCandidateType); + return Either.left(true); + } + childUniqueId = derivedFromUniqueId; + childType = derivedFromType; + } while (!travelledTypes.contains(childType)); + // this stop condition should never be used, if we use it, we have an + // illegal cycle in graph - "derived from" hierarchy cannot be cycled. + // It's here just to avoid infinite loop in case we have such cycle. + log.error("Detected a cycle of \"derived from\" edges starting at type node {}", childType); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + + + @Override + public <T extends GraphNode> StorageOperationStatus isUpdateParentAllowed(String oldTypeParent, String newTypeParent, String childType, + NodeTypeEnum nodeType, Class<T> clazz, + Function<T, String> typeProvider) { + StorageOperationStatus status; + if (oldTypeParent != null) { + + Either<Boolean, StorageOperationStatus> result = isTypeDerivedFrom(newTypeParent, oldTypeParent, childType, nodeType, clazz, typeProvider); + if (result.isRight()) { + log.debug("#isUpdateParentAllowed - failed to detect that new parent {} is derived from the current parent {}", newTypeParent, oldTypeParent); + status = result.right().value(); + } + else { + if (result.left().value()) { + log.debug("#isUpdateParentAllowed - update is allowed since new parent {} is derived from the current parent {}", newTypeParent, oldTypeParent); + status = StorageOperationStatus.OK; + } + else { + log.debug("#isUpdateParentAllowed - update is not allowed since new parent {} is not derived from the current parent {}", newTypeParent, oldTypeParent); + status = StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY; + } + } + + } + else { + log.debug("#isUpdateParentAllowed - the update is allowed since the parent still has been not set." ); + status = StorageOperationStatus.OK; + } + + return status; + } } |