diff options
Diffstat (limited to 'catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java')
-rw-r--r-- | catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java | 662 |
1 files changed, 397 insertions, 265 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java index 413ce4c2fa..e9236fc9af 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java @@ -7,9 +7,9 @@ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,15 +20,15 @@ package org.openecomp.sdc.be.model.operations.impl; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - +import com.google.common.base.Strings; +import com.thinkaurelius.titan.graphdb.query.TitanPredicate; +import fj.data.Either; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +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; @@ -38,318 +38,450 @@ import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; import org.openecomp.sdc.be.model.CapabilityTypeDefinition; import org.openecomp.sdc.be.model.GroupTypeDefinition; import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.StorageException; import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.openecomp.sdc.be.resources.data.CapabilityTypeData; import org.openecomp.sdc.be.resources.data.GroupTypeData; import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; -import fj.data.Either; +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import static org.openecomp.sdc.be.dao.titan.TitanUtils.buildNotInPredicate; @Component("group-type-operation") public class GroupTypeOperation extends AbstractOperation implements IGroupTypeOperation { + @Resource + private CapabilityTypeOperation capabilityTypeOperation; + + private static final Logger log = LoggerFactory.getLogger(GroupTypeOperation.class); - String CREATE_FLOW_CONTEXT = "CreateGroupType"; - String GET_FLOW_CONTEXT = "GetGroupType"; + private static final String CREATE_FLOW_CONTEXT = "CreateGroupType"; + private static final String GET_FLOW_CONTEXT = "GetGroupType"; - private PropertyOperation propertyOperation; - - private TitanGenericDao titanGenericDao; + private PropertyOperation propertyOperation; - public GroupTypeOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao, @Qualifier("property-operation")PropertyOperation propertyOperation) { - super(); - this.propertyOperation = propertyOperation; - this.titanGenericDao = titanGenericDao; - } + private TitanGenericDao titanGenericDao; - private static Logger log = LoggerFactory.getLogger(GroupTypeOperation.class.getName()); + public GroupTypeOperation(@Qualifier("titan-generic-dao") TitanGenericDao titanGenericDao, @Qualifier("property-operation") PropertyOperation propertyOperation) { + super(); + this.propertyOperation = propertyOperation; + this.titanGenericDao = titanGenericDao; + } - /** - * FOR TEST ONLY - * - * @param titanGenericDao - */ - public void setTitanGenericDao(TitanGenericDao titanGenericDao) { - this.titanGenericDao = titanGenericDao; - } + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition) { + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition) { - return addGroupType(groupTypeDefinition, false); - } + return addGroupType(groupTypeDefinition, false); + } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition, boolean inTransaction) { + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition, boolean inTransaction) { - Either<GroupTypeDefinition, StorageOperationStatus> result = null; + Either<GroupTypeDefinition, StorageOperationStatus> result = null; - try { + try { - Either<GroupTypeData, TitanOperationStatus> eitherStatus = addGroupTypeToGraph(groupTypeDefinition); + Either<GroupTypeData, TitanOperationStatus> eitherStatus = addGroupTypeToGraph(groupTypeDefinition); - if (eitherStatus.isRight()) { - BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, groupTypeDefinition.getType(), eitherStatus.right().value().name()); - result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + if (eitherStatus.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, groupTypeDefinition.getType(), eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); - } else { - GroupTypeData groupTypeData = eitherStatus.left().value(); + } else { + GroupTypeData groupTypeData = eitherStatus.left().value(); - String uniqueId = groupTypeData.getUniqueId(); - Either<GroupTypeDefinition, StorageOperationStatus> groupTypeRes = this.getGroupType(uniqueId, true); + String uniqueId = groupTypeData.getUniqueId(); + Either<GroupTypeDefinition, StorageOperationStatus> groupTypeRes = this.getGroupType(uniqueId, true); - if (groupTypeRes.isRight()) { - BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, groupTypeDefinition.getType(), eitherStatus.right().value().name()); - } + if (groupTypeRes.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, groupTypeDefinition.getType(), eitherStatus.right().value().name()); + } else { + List<CapabilityTypeDefinition> groupCapTypes = groupTypeDefinition.getCapabilityTypes(); + if (!CollectionUtils.isEmpty(groupCapTypes)) { + Optional<TitanOperationStatus> firstFailure = connectToCapabilityType(groupTypeData, groupCapTypes); + if (firstFailure.isPresent()) { + groupTypeRes = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(firstFailure.get())); + } + } + } - result = groupTypeRes; + result = groupTypeRes; - } + } - return result; + return result; - } finally { - handleTransactionCommitRollback(inTransaction, result); - } + } finally { + handleTransactionCommitRollback(inTransaction, result); + } - } + } - public Either<GroupTypeDefinition, TitanOperationStatus> getGroupTypeByUid(String uniqueId) { - Either<GroupTypeDefinition, TitanOperationStatus> result = null; + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> upgradeGroupType(GroupTypeDefinition groupTypeDefinitionNew, GroupTypeDefinition groupTypeDefinitionOld) { + return upgradeGroupType(groupTypeDefinitionOld, groupTypeDefinitionNew, false); + } - Either<GroupTypeData, TitanOperationStatus> groupTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), uniqueId, GroupTypeData.class); + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> upgradeGroupType(GroupTypeDefinition groupTypeDefinitionNew, GroupTypeDefinition groupTypeDefinitionOld, boolean inTransaction) { + Either<GroupTypeDefinition, StorageOperationStatus> result = Either.left(groupTypeDefinitionNew); - if (groupTypesRes.isRight()) { - TitanOperationStatus status = groupTypesRes.right().value(); - log.debug("Group type {} cannot be found in graph. status is {}", uniqueId, status); - return Either.right(status); - } + try { + // dr2032: + // Right now upgrade Group is used only to ensure that already existing group type is connected by DERRIVED_FROM edge with it's parent + // We don't need to use for a while new node definition since following group type upgrade is not supported. + if (!Strings.isNullOrEmpty(groupTypeDefinitionOld.getDerivedFrom())) { + result = ensureExsitanceDerivedFromEdge(groupTypeDefinitionOld); + } + } finally { + handleTransactionCommitRollback(inTransaction, result); + } - GroupTypeData gtData = groupTypesRes.left().value(); - GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition(gtData.getGroupTypeDataDefinition()); + return result; + } - TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, properList -> groupTypeDefinition.setProperties(properList)); + private Optional<TitanOperationStatus> connectToCapabilityType(GroupTypeData groupTypeData, List<CapabilityTypeDefinition> groupCapTypes) { + return groupCapTypes.stream() + .map(groupCapTypeDef -> connectTo(groupTypeData, groupCapTypeDef)) + .filter(Either::isRight) + .findFirst() + .map(either -> either.right().value()); + } - if (propertiesStatus != TitanOperationStatus.OK) { - log.error("Failed to fetch properties of capability type {}", uniqueId); - return Either.right(propertiesStatus); - } + private Either<GraphRelation, TitanOperationStatus> connectTo(GroupTypeData groupTypeData, CapabilityTypeDefinition groupCapTypeDef) { + Either<CapabilityTypeData, TitanOperationStatus> eitherCapData = capabilityTypeOperation.getCapabilityTypeByType(groupCapTypeDef.getType()); + if (eitherCapData.isLeft()) { + return titanGenericDao.createRelation(groupTypeData, eitherCapData.left().value(), GraphEdgeLabels.GROUP_TYPE_CAPABILITY_TYPE, null); + } - result = Either.left(groupTypeDefinition); + return Either.right(eitherCapData.right().value()); + } - return result; - } + public List<GroupTypeDefinition> getAllGroupTypes(Set<String> excludedGroupTypes) { + Map<String, Map.Entry<TitanPredicate, Object>> predicateCriteria = buildNotInPredicate(GraphPropertiesDictionary.TYPE.getProperty(), excludedGroupTypes); + List<GroupTypeData> groupTypes = titanGenericDao.getByCriteriaWithPredicate(NodeTypeEnum.GroupType, predicateCriteria, GroupTypeData.class) + .left() + .on(this::onTitanAccessError); - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId) { + return convertGroupTypesToDefinition(groupTypes); + } - return getGroupType(uniqueId, false); - } + private List<GroupTypeDefinition> convertGroupTypesToDefinition(List<GroupTypeData> groupTypes) { + return groupTypes.stream() + .map(type -> new GroupTypeDefinition(type.getGroupTypeDataDefinition())) + .collect(Collectors.toList()); + } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction) { - return getElementType(this::getGroupTypeByUid, uniqueId, inTransaction); - } + private List<GroupTypeData> onTitanAccessError(TitanOperationStatus toe) { + throw new StorageException( + DaoStatusConverter.convertTitanStatusToStorageStatus(toe)); + } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type) { - return getLatestGroupTypeByType(type, false); - } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type, boolean inTransaction) { - Map<String, Object> mapCriteria = new HashMap<>(); - mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); - mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + public Either<GroupTypeDefinition, TitanOperationStatus> getGroupTypeByUid(String uniqueId) { + + Either<GroupTypeDefinition, TitanOperationStatus> result = null; + + Either<GroupTypeData, TitanOperationStatus> groupTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), uniqueId, GroupTypeData.class); + + if (groupTypesRes.isRight()) { + TitanOperationStatus status = groupTypesRes.right().value(); + log.debug("Group type {} cannot be found in graph. status is {}", uniqueId, status); + return Either.right(status); + } + + GroupTypeData gtData = groupTypesRes.left().value(); + GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition(gtData.getGroupTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, NodeTypeEnum.GroupType, properList -> groupTypeDefinition.setProperties(properList)); + + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability type {}", uniqueId); + return Either.right(propertiesStatus); + } - return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + result = Either.left(groupTypeDefinition); - } + return result; + } - public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByCriteria(String type, Map<String, Object> properties, boolean inTransaction) { - Either<GroupTypeDefinition, StorageOperationStatus> result = null; - try { - if (type == null || type.isEmpty()) { - log.error("type is empty"); - result = Either.right(StorageOperationStatus.INVALID_ID); - return result; - } + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId) { + + return getGroupType(uniqueId, false); + + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction) { + return getElementType(this::getGroupTypeByUid, uniqueId, inTransaction); + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type) { + return getLatestGroupTypeByType(type, false); + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type, boolean inTransaction) { + Map<String, Object> mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + + } - Either<List<GroupTypeData>, TitanOperationStatus> groupTypeEither = titanGenericDao.getByCriteria(NodeTypeEnum.GroupType, properties, GroupTypeData.class); - if (groupTypeEither.isRight()) { - result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupTypeEither.right().value())); - } else { - GroupTypeDataDefinition dataDefinition = groupTypeEither.left().value().stream().map(e -> e.getGroupTypeDataDefinition()).findFirst().get(); - result = getGroupType(dataDefinition.getUniqueId(), inTransaction); - } + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByCriteria(String type, Map<String, Object> properties, boolean inTransaction) { + Either<GroupTypeDefinition, StorageOperationStatus> result = null; + try { + if (type == null || type.isEmpty()) { + log.error("type is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Either<List<GroupTypeData>, TitanOperationStatus> groupTypeEither = titanGenericDao.getByCriteria(NodeTypeEnum.GroupType, properties, GroupTypeData.class); + if (groupTypeEither.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupTypeEither.right().value())); + } else { + GroupTypeDataDefinition dataDefinition = groupTypeEither.left().value().stream().map(e -> e.getGroupTypeDataDefinition()).findFirst().get(); + result = getGroupType(dataDefinition.getUniqueId(), inTransaction); + } - return result; + return result; - } finally { - handleTransactionCommitRollback(inTransaction, result); - } - } + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, String version) { - return getGroupTypeByTypeAndVersion(type, version, false); - } + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, String version) { + return getGroupTypeByTypeAndVersion(type, version, false); + } - @Override - public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, String version, boolean inTransaction) { - Map<String, Object> mapCriteria = new HashMap<>(); - mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); - mapCriteria.put(GraphPropertiesDictionary.VERSION.getProperty(), version); - - return getGroupTypeByCriteria(type, mapCriteria, inTransaction); - } - - /** - * - * Add group type to graph. - * - * 1. Add group type node - * - * 2. Add edge between the former node to its parent(if exists) - * - * 3. Add property node and associate it to the node created at #1. (per property & if exists) - * - * @param groupTypeDefinition - * @return - */ - private Either<GroupTypeData, TitanOperationStatus> addGroupTypeToGraph(GroupTypeDefinition groupTypeDefinition) { - - log.debug("Got group type {}", groupTypeDefinition); - - String ctUniqueId = UniqueIdBuilder.buildGroupTypeUid(groupTypeDefinition.getType(), groupTypeDefinition.getVersion()); - // capabilityTypeDefinition.setUniqueId(ctUniqueId); - - GroupTypeData groupTypeData = buildGroupTypeData(groupTypeDefinition, ctUniqueId); - - log.debug("Before adding group type to graph. groupTypeData = {}", groupTypeData); - - Either<GroupTypeData, TitanOperationStatus> createGTResult = titanGenericDao.createNode(groupTypeData, GroupTypeData.class); - log.debug("After adding group type to graph. status is = {}", createGTResult); - - if (createGTResult.isRight()) { - TitanOperationStatus operationStatus = createGTResult.right().value(); - log.error("Failed to add group type {} to graph. status is {}", groupTypeDefinition.getType(), operationStatus); - return Either.right(operationStatus); - } - - GroupTypeData resultCTD = createGTResult.left().value(); - List<PropertyDefinition> properties = groupTypeDefinition.getProperties(); - Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.GroupType, properties); - if (addPropertiesToCapablityType.isRight()) { - log.error("Failed add properties {} to capability {}", properties, groupTypeDefinition.getType()); - return Either.right(addPropertiesToCapablityType.right().value()); - } - - String derivedFrom = groupTypeDefinition.getDerivedFrom(); - if (derivedFrom != null) { - - // TODO: Need to find the parent. need to take the latest one since - // we may have many versions of the same type - /* - * log.debug("Before creating relation between group type {} to its parent {}", ctUniqueId, derivedFrom); UniqueIdData from = new UniqueIdData(NodeTypeEnum.CapabilityType, ctUniqueId); UniqueIdData to = new - * UniqueIdData(NodeTypeEnum.CapabilityType, derivedFrom); Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao .createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null); - * log.debug("After create relation between capability type {} to its parent {}. status is {}", ctUniqueId, derivedFrom, createRelation); if (createRelation.isRight()) { return Either.right(createRelation.right().value()); } - * - */ - } - - return Either.left(createGTResult.left().value()); - - } - - /** - * - * convert between graph Node object to Java object - * - * @param capabilityTypeData - * @return - */ - protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { - log.debug("The object returned after create capability is {}", capabilityTypeData); - - CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition(capabilityTypeData.getCapabilityTypeDataDefinition()); - - return capabilityTypeDefResult; - } - - private GroupTypeData buildGroupTypeData(GroupTypeDefinition groupTypeDefinition, String ctUniqueId) { - - GroupTypeData groupTypeData = new GroupTypeData(groupTypeDefinition); - - groupTypeData.getGroupTypeDataDefinition().setUniqueId(ctUniqueId); - Long creationDate = groupTypeData.getGroupTypeDataDefinition().getCreationTime(); - if (creationDate == null) { - creationDate = System.currentTimeMillis(); - } - groupTypeData.getGroupTypeDataDefinition().setCreationTime(creationDate); - groupTypeData.getGroupTypeDataDefinition().setModificationTime(creationDate); - - return groupTypeData; - } - - public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) { - Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); - propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType); - Either<List<CapabilityTypeData>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class); - if (getResponse.isRight()) { - TitanOperationStatus titanOperationStatus = getResponse.right().value(); - log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus); - return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); - } - String childUniqueId = getResponse.left().value().get(0).getUniqueId(); - Set<String> travelledTypes = new HashSet<>(); - do { - travelledTypes.add(childUniqueId); - Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, GraphEdgeLabels.DERIVED_FROM, - NodeTypeEnum.CapabilityType, CapabilityTypeData.class); - if (childrenNodes.isRight()) { - if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { - TitanOperationStatus titanOperationStatus = getResponse.right().value(); - log.debug("Couldn't fetch derived from node for capability 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."); - return Either.left(false); - } - } - String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); - if (derivedFromUniqueId.equals(parentCandidateType)) { - log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, parentCandidateType); - return Either.left(true); - } - childUniqueId = derivedFromUniqueId; - } while (!travelledTypes.contains(childUniqueId)); - // 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 capability type node {}", childUniqueId); - return Either.right(StorageOperationStatus.GENERAL_ERROR); - } - - /** - * FOR TEST ONLY - * - * @param propertyOperation - */ - public void setPropertyOperation(PropertyOperation propertyOperation) { - this.propertyOperation = propertyOperation; - } - - @Override - public Either<GroupTypeData, TitanOperationStatus> getLatestGroupTypeByNameFromGraph(String name) { - - return null; - } + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, String version, boolean inTransaction) { + Map<String, Object> mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + + return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + } + + /** + * Add group type to graph. + * <p> + * 1. Add group type node + * <p> + * 2. Add edge between the former node to its parent(if exists) + * <p> + * 3. Add property node and associate it to the node created at #1. (per property & if exists) + * + * @param groupTypeDefinition + * @return + */ + private Either<GroupTypeData, TitanOperationStatus> addGroupTypeToGraph(GroupTypeDefinition groupTypeDefinition) { + + log.debug("Got group type {}", groupTypeDefinition); + + String ctUniqueId = UniqueIdBuilder.buildGroupTypeUid(groupTypeDefinition.getType(), groupTypeDefinition.getVersion()); + + GroupTypeData groupTypeData = buildGroupTypeData(groupTypeDefinition, ctUniqueId); + + log.debug("Before adding group type to graph. groupTypeData = {}", groupTypeData); + + Either<GroupTypeData, TitanOperationStatus> createGTResult = titanGenericDao.createNode(groupTypeData, GroupTypeData.class); + log.debug("After adding group type to graph. status is = {}", createGTResult); + + if (createGTResult.isRight()) { + TitanOperationStatus operationStatus = createGTResult.right().value(); + log.error("Failed to add group type {} to graph. status is {}", groupTypeDefinition.getType(), operationStatus); + return Either.right(operationStatus); + } + + GroupTypeData resultCTD = createGTResult.left().value(); + List<PropertyDefinition> properties = groupTypeDefinition.getProperties(); + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.GroupType, properties); + if (addPropertiesToCapablityType.isRight()) { + log.error("Failed add properties {} to capability {}", properties, groupTypeDefinition.getType()); + return Either.right(addPropertiesToCapablityType.right().value()); + } + + String derivedFrom = groupTypeDefinition.getDerivedFrom(); + if (derivedFrom != null) { + Either<GraphRelation, TitanOperationStatus> createRelation = connectToDerivedFrom(ctUniqueId, derivedFrom); + if (createRelation.isRight()) { + return Either.right(createRelation.right().value()); + } + } + + return Either.left(createGTResult.left().value()); + + } + + + private Either<GraphRelation, TitanOperationStatus> connectToDerivedFrom(String ctUniqueId, String derivedFrom) { + log.debug("Before creating relation between Group Type with id {} to its parent {}", ctUniqueId, derivedFrom); + + Either<GroupTypeData, TitanOperationStatus> derivedFromGroupTypeResult = + titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), derivedFrom, GroupTypeData.class); + + if (derivedFromGroupTypeResult.isLeft()) { + UniqueIdData from = new UniqueIdData(NodeTypeEnum.GroupType, ctUniqueId); + GroupTypeData to = derivedFromGroupTypeResult.left().value(); + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null); + log.debug("After create relation between Group Type with id {} to its parent {}, status is {}.", ctUniqueId, derivedFrom, createRelation); + return createRelation; + } else { + TitanOperationStatus status = derivedFromGroupTypeResult.right().value(); + log.debug("Failed to found parent Group Type {}, stauts is {}.", derivedFrom, status); + return Either.right(status); + } + } + + + private Either<GroupTypeDefinition, StorageOperationStatus> ensureExsitanceDerivedFromEdge(GroupTypeDefinition groupTypeDefinition) { + Either<GroupTypeDefinition, StorageOperationStatus> result = Either.left(groupTypeDefinition); + + GroupTypeData childGroupType = null; + GroupTypeData parentGroupType = null; + + Either<GroupTypeData, TitanOperationStatus> childGroupTypeResult = + titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getType(), GroupTypeData.class); + if (childGroupTypeResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childGroupTypeResult.right().value())); + log.debug("Filed to find GroupType with type {}, status is {}.", groupTypeDefinition.getType(), childGroupTypeResult); + } else { + childGroupType = childGroupTypeResult.left().value(); + } + + + if (result.isLeft()) { + Either<GroupTypeData, TitanOperationStatus> parentGroupTypeResult = + titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), groupTypeDefinition.getDerivedFrom(), GroupTypeData.class); + if (parentGroupTypeResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentGroupTypeResult.right().value())); + log.debug("Filed to find GroupType with type {}, status is {}.", groupTypeDefinition.getDerivedFrom(), parentGroupTypeResult); + } else { + parentGroupType = parentGroupTypeResult.left().value(); + } + } + + + if (childGroupType != null && parentGroupType != null) { + Either<Edge, TitanOperationStatus> edgeDerivedFromResult = titanGenericDao.getEdgeByNodes(childGroupType, parentGroupType, GraphEdgeLabels.DERIVED_FROM); + if (edgeDerivedFromResult.isLeft()) { + log.debug("It was found relation {}. Don't need to create the edge.", edgeDerivedFromResult.left().value()); + } else { + Either<GraphRelation, TitanOperationStatus> createRelationResult = titanGenericDao.createRelation(childGroupType, parentGroupType, GraphEdgeLabels.DERIVED_FROM, null); + log.debug("After create relation between Group Type with id {} to its parent with id {}, status is {}.", + childGroupType.getKeyValueId().getValue(), parentGroupType.getKeyValueId().getValue(), createRelationResult); + if (createRelationResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationResult.right().value())); + } + } + + } + + + return result; + } + + + private GroupTypeData buildGroupTypeData(GroupTypeDefinition groupTypeDefinition, String ctUniqueId) { + + GroupTypeData groupTypeData = new GroupTypeData(groupTypeDefinition); + + groupTypeData.getGroupTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = groupTypeData.getGroupTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + groupTypeData.getGroupTypeDataDefinition().setCreationTime(creationDate); + groupTypeData.getGroupTypeDataDefinition().setModificationTime(creationDate); + + return groupTypeData; + } + + public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) { + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType); + Either<List<CapabilityTypeData>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class); + if (getResponse.isRight()) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } + String childUniqueId = getResponse.left().value().get(0).getUniqueId(); + Set<String> travelledTypes = new HashSet<>(); + do { + travelledTypes.add(childUniqueId); + Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch derived from node for capability 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."); + return Either.left(false); + } + } + String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); + if (derivedFromUniqueId.equals(parentCandidateType)) { + log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, parentCandidateType); + return Either.left(true); + } + childUniqueId = derivedFromUniqueId; + } while (!travelledTypes.contains(childUniqueId)); + // 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 capability type node {}", childUniqueId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + /** + * FOR TEST ONLY + * + * @param propertyOperation + */ + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + @Override + public Either<GroupTypeData, TitanOperationStatus> getLatestGroupTypeByNameFromGraph(String name) { + + return null; + } } |