aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java')
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java734
1 files changed, 378 insertions, 356 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
index 9b31c71787..97f3e80e2a 100644
--- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java
@@ -20,379 +20,401 @@
package org.openecomp.sdc.be.model.operations.impl;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
+import fj.data.Either;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
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;
import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
import org.openecomp.sdc.be.model.PropertyDefinition;
-import org.openecomp.sdc.be.model.operations.api.ICapabilityOperation;
+import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.model.operations.api.TypeOperations;
import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
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.openecomp.sdc.common.log.wrappers.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
-import fj.data.Either;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
@Component("capability-type-operation")
public class CapabilityTypeOperation extends AbstractOperation implements ICapabilityTypeOperation {
- @Autowired
- private PropertyOperation propertyOperation;
- @Autowired
- private ICapabilityOperation capabilityOperation;
-
- public CapabilityTypeOperation() {
- super();
- }
-
- private static Logger log = LoggerFactory.getLogger(CapabilityTypeOperation.class.getName());
-
- /**
- * FOR TEST ONLY
- *
- * @param titanGenericDao
- */
- public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
- this.titanGenericDao = titanGenericDao;
- }
-
- @Override
- public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) {
-
- Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
-
- try {
- Either<CapabilityTypeDefinition, TitanOperationStatus> validationRes = validateUpdateProperties(capabilityTypeDefinition);
- if (validationRes.isRight()) {
- log.error("One or all properties of capability type {} not valid. status is {}", capabilityTypeDefinition, validationRes.right().value().name());
- result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(validationRes.right().value()));
- return result;
- }
- Either<CapabilityTypeData, TitanOperationStatus> eitherStatus = addCapabilityTypeToGraph(capabilityTypeDefinition);
-
- if (eitherStatus.isRight()) {
- log.error("Failed to add capability {} to Graph. status is {}", capabilityTypeDefinition, eitherStatus.right().value().name());
- result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value()));
- return result;
- } else {
- CapabilityTypeData capabilityTypeData = eitherStatus.left().value();
-
- CapabilityTypeDefinition capabilityTypeDefResult = convertCTDataToCTDefinition(capabilityTypeData);
- log.debug("The returned CapabilityTypeDefinition is {}", capabilityTypeDefResult);
- result = Either.left(capabilityTypeDefResult);
- return result;
- }
- }
-
- finally {
- if (false == inTransaction) {
- if (result == null || result.isRight()) {
- log.error("Going to execute rollback on graph.");
- titanGenericDao.rollback();
- } else {
- log.debug("Going to execute commit on graph.");
- titanGenericDao.commit();
- }
- }
- }
-
- }
-
- private Either<CapabilityTypeDefinition, TitanOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) {
- TitanOperationStatus error = null;
- if (capabilityTypeDefinition.getProperties() != null && !capabilityTypeDefinition.getProperties().isEmpty() && capabilityTypeDefinition.getDerivedFrom() != null) {
- Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes = capabilityOperation.getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom());
- if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
- error = allPropertiesRes.right().value();
- log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", capabilityTypeDefinition.getType(), error);
- }
- if (error == null && !allPropertiesRes.left().value().isEmpty()) {
- Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
- capabilityTypeDefinition.getProperties().entrySet().stream().filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
- .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
-
- Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes = capabilityOperation.validatePropertyUniqueness(allPropertiesRes.left().value(),
- capabilityTypeDefinition.getProperties().values().stream().collect(Collectors.toList()));
- if (validatePropertiesRes.isRight()) {
- error = validatePropertiesRes.right().value();
- }
- }
- }
- if (error == null) {
- return Either.left(capabilityTypeDefinition);
- }
- return Either.right(error);
- }
-
- /**
- *
- * 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;
- }
-
- /**
- *
- * Add capability type to graph.
- *
- * 1. Add capability 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 capabilityTypeDefinition
- * @return
- */
- private Either<CapabilityTypeData, TitanOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
-
- log.debug("Got capability type {}", capabilityTypeDefinition);
-
- String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
- // capabilityTypeDefinition.setUniqueId(ctUniqueId);
-
- CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
-
- log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData);
- Either<CapabilityTypeData, TitanOperationStatus> createCTResult = titanGenericDao.createNode(capabilityTypeData, CapabilityTypeData.class);
- log.debug("After adding capability type to graph. status is = {}", createCTResult);
-
- if (createCTResult.isRight()) {
- TitanOperationStatus operationStatus = createCTResult.right().value();
- log.error("Failed to capability type {} to graph. status is {}", capabilityTypeDefinition.getType(), operationStatus);
- return Either.right(operationStatus);
- }
-
- CapabilityTypeData resultCTD = createCTResult.left().value();
- Map<String, PropertyDefinition> propertiesMap = capabilityTypeDefinition.getProperties();
- Collection<PropertyDefinition> properties = propertiesMap != null ? propertiesMap.values() : null;
- Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap);
- if (addPropertiesToCapablityType.isRight()) {
- log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType());
- return Either.right(addPropertiesToCapablityType.right().value());
- }
-
- String derivedFrom = capabilityTypeDefinition.getDerivedFrom();
- if (derivedFrom != null) {
- log.debug("Before creating relation between capability 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(createCTResult.left().value());
-
- }
-
- private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
-
- CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
-
- capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId);
- Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime();
- if (creationDate == null) {
- creationDate = System.currentTimeMillis();
- }
- capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate);
- capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate);
- return capabilityTypeData;
- }
-
- @Override
- public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction) {
-
- Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
- try {
-
- Either<CapabilityTypeDefinition, TitanOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId);
-
- if (ctResult.isRight()) {
- TitanOperationStatus status = ctResult.right().value();
- if (status != TitanOperationStatus.NOT_FOUND) {
- log.error("Failed to retrieve information on capability type {}. status is {}", uniqueId, status);
- }
- result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
- return result;
- }
-
- result = Either.left(ctResult.left().value());
-
- return result;
- } finally {
- if (false == inTransaction) {
- log.debug("Going to execute commit on graph.");
- titanGenericDao.commit();
- }
- }
- }
-
-
- public Either<CapabilityTypeData, TitanOperationStatus> getCapabilityTypeByType(String capabilityType) {
- Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityType, CapabilityTypeData.class);
-
- if (capabilityTypesRes.isRight()) {
- TitanOperationStatus status = capabilityTypesRes.right().value();
- log.debug("Capability type {} cannot be found in graph. status is {}", capabilityType, status);
-
- return Either.right(status);
- }
-
- CapabilityTypeData ctData = capabilityTypesRes.left().value();
- return Either.left(ctData);
- }
-
- /**
- * Build Capability type object from graph by unique id
- *
- * @param uniqueId
- * @return
- */
- public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByUid(String uniqueId) {
-
- Either<CapabilityTypeDefinition, TitanOperationStatus> result = null;
-
- Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class);
-
- if (capabilityTypesRes.isRight()) {
- TitanOperationStatus status = capabilityTypesRes.right().value();
- log.debug("Capability type {} cannot be found in graph. status is {}", uniqueId, status);
- return Either.right(status);
- }
-
- CapabilityTypeData ctData = capabilityTypesRes.left().value();
- CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
-
- TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition);
- if (propertiesStatus != TitanOperationStatus.OK) {
- log.error("Failed to fetch properties of capability type {}", uniqueId);
- return Either.right(propertiesStatus);
- }
-
- Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
- NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
- log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
- if (parentNode.isRight()) {
- TitanOperationStatus titanOperationStatus = parentNode.right().value();
- if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
- log.error("Failed to find the parent capability of capability type {}. status is {}", uniqueId, titanOperationStatus);
- result = Either.right(titanOperationStatus);
- return result;
- }
- } else {
- // derived from node was found
- ImmutablePair<CapabilityTypeData, GraphEdge> immutablePair = parentNode.left().value();
- CapabilityTypeData parentCT = immutablePair.getKey();
- capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType());
- }
- result = Either.left(capabilityTypeDefinition);
-
- return result;
- }
-
- private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) {
-
- Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId);
- if (findPropertiesOfNode.isRight()) {
- TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
- log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
- if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
- return TitanOperationStatus.OK;
- } else {
- return titanOperationStatus;
- }
- } else {
- Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
- capabilityTypeDefinition.setProperties(properties);
- return TitanOperationStatus.OK;
- }
- }
-
- 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<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition) {
-
- return addCapabilityType(capabilityTypeDefinition, false);
- }
-
- @Override
- public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
- return getCapabilityType(uniqueId, false);
- }
-
+ @Autowired
+ private PropertyOperation propertyOperation;
+ @Autowired
+ private DerivedFromOperation derivedFromOperation;
+
+ public CapabilityTypeOperation() {
+ super();
+ }
+
+ private static final Logger log = Logger.getLogger(CapabilityTypeOperation.class.getName());
+
+ /**
+ * FOR TEST ONLY
+ *
+ * @param titanGenericDao
+ */
+ public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+ this.titanGenericDao = titanGenericDao;
+ }
+
+ @Override
+ public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) {
+
+ Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
+
+ try {
+ Either<CapabilityTypeDefinition, StorageOperationStatus> validationRes = validateUpdateProperties(capabilityTypeDefinition);
+ if (validationRes.isRight()) {
+ log.error("#addCapabilityType - One or all properties of capability type {} not valid. status is {}", capabilityTypeDefinition, validationRes.right().value());
+ return result;
+ }
+
+ Either<CapabilityTypeData, StorageOperationStatus> eitherStatus = addCapabilityTypeToGraph(capabilityTypeDefinition);
+
+ result = eitherStatus.left()
+ .map(CapabilityTypeData::getUniqueId)
+ .left()
+ .bind(uniqueId -> getCapabilityType(uniqueId, inTransaction));
+
+ if(result.isLeft()) {
+ log.debug("#addCapabilityType - The returned CapabilityTypeDefinition is {}", result.left().value());
+ }
+
+ return result;
+ }
+
+ finally {
+ if (!inTransaction) {
+ if (result == null || result.isRight()) {
+ log.error("#addCapabilityType - Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("#addCapabilityType - Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ public Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) {
+ return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+ }
+
+ public Either<CapabilityTypeDefinition, StorageOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) {
+ TitanOperationStatus error = null;
+ if (MapUtils.isNotEmpty(capabilityTypeDefinition.getProperties()) && capabilityTypeDefinition.getDerivedFrom() != null) {
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes =
+ getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom());
+ if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) {
+ error = allPropertiesRes.right().value();
+ log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", capabilityTypeDefinition.getType(), error);
+ }
+ if (error == null && !allPropertiesRes.left().value().isEmpty()) {
+ Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value();
+ capabilityTypeDefinition.getProperties().entrySet().stream().filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null)
+ .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType()));
+
+ List<PropertyDefinition> properties = capabilityTypeDefinition.getProperties().values().stream().collect(Collectors.toList());
+ Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes = propertyOperation.validatePropertiesUniqueness(allPropertiesRes.left().value(),
+ properties);
+ if (validatePropertiesRes.isRight()) {
+ error = validatePropertiesRes.right().value();
+ }
+ }
+ }
+ if (error == null) {
+ return Either.left(capabilityTypeDefinition);
+ }
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
+ }
+
+
+ /**
+ *
+ * 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);
+
+ return new CapabilityTypeDefinition(capabilityTypeData.getCapabilityTypeDataDefinition());
+ }
+
+ /**
+ *
+ * Add capability type to graph.
+ *
+ * 1. Add capability 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 capabilityTypeDefinition
+ * @return
+ */
+ private Either<CapabilityTypeData, StorageOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
+
+ log.debug("Got capability type {}", capabilityTypeDefinition);
+
+ String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
+ CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
+
+ log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData);
+ Either<CapabilityTypeData, TitanOperationStatus> createCTResult = titanGenericDao.createNode(capabilityTypeData, CapabilityTypeData.class);
+ log.debug("After adding capability type to graph. status is = {}", createCTResult);
+
+ if (createCTResult.isRight()) {
+ TitanOperationStatus operationStatus = createCTResult.right().value();
+ log.error("Failed to capability type {} to graph. status is {}", capabilityTypeDefinition.getType(), operationStatus);
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus));
+ }
+
+ CapabilityTypeData resultCTD = createCTResult.left().value();
+ Map<String, PropertyDefinition> propertiesMap = capabilityTypeDefinition.getProperties();
+ Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation.addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap);
+ if (addPropertiesToCapablityType.isRight()) {
+ log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType());
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToCapablityType.right().value()));
+ }
+
+ return addDerivedFromRelation(capabilityTypeDefinition, ctUniqueId)
+ .left()
+ .map(updatedDerivedFrom -> createCTResult.left().value());
+
+
+ }
+
+ private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
+
+ CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
+
+ capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId);
+ Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime();
+ if (creationDate == null) {
+ creationDate = System.currentTimeMillis();
+ }
+ capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate);
+ capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate);
+ return capabilityTypeData;
+ }
+
+ @Override
+ public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, boolean inTransaction) {
+
+ Either<CapabilityTypeDefinition, StorageOperationStatus> result = null;
+ try {
+
+ Either<CapabilityTypeDefinition, TitanOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId);
+
+ if (ctResult.isRight()) {
+ TitanOperationStatus status = ctResult.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to retrieve information on capability type {}. status is {}", uniqueId, status);
+ }
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value()));
+ return result;
+ }
+
+ result = Either.left(ctResult.left().value());
+
+ return result;
+ } finally {
+ if (!inTransaction) {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+
+ public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByType(String capabilityType) {
+ // Optimization: In case of Capability Type its unique ID is the same as type
+ return getCapabilityTypeByUid(capabilityType);
+ }
+
+ /**
+ * Build Capability type object from graph by unique id
+ *
+ * @param uniqueId
+ * @return
+ */
+ public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByUid(String uniqueId) {
+
+ Either<CapabilityTypeDefinition, TitanOperationStatus> result = null;
+
+ Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class);
+
+ if (capabilityTypesRes.isRight()) {
+ TitanOperationStatus status = capabilityTypesRes.right().value();
+ log.debug("Capability type {} cannot be found in graph. status is {}", uniqueId, status);
+ return Either.right(status);
+ }
+
+ CapabilityTypeData ctData = capabilityTypesRes.left().value();
+ CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
+
+ TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition);
+ if (propertiesStatus != TitanOperationStatus.OK) {
+ log.error("Failed to fetch properties of capability type {}", uniqueId);
+ return Either.right(propertiesStatus);
+ }
+
+ Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
+ NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+ log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
+ if (parentNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = parentNode.right().value();
+ if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to find the parent capability of capability type {}. status is {}", uniqueId, titanOperationStatus);
+ result = Either.right(titanOperationStatus);
+ return result;
+ }
+ } else {
+ // derived from node was found
+ ImmutablePair<CapabilityTypeData, GraphEdge> immutablePair = parentNode.left().value();
+ CapabilityTypeData parentCT = immutablePair.getKey();
+ capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType());
+ }
+ result = Either.left(capabilityTypeDefinition);
+
+ return result;
+ }
+
+ private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) {
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId);
+ if (findPropertiesOfNode.isRight()) {
+ TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value();
+ log.debug("After looking for properties of vertex {}. status is {}", uniqueId, titanOperationStatus);
+ if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) {
+ return TitanOperationStatus.OK;
+ } else {
+ return titanOperationStatus;
+ }
+ } else {
+ Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value();
+ capabilityTypeDefinition.setProperties(properties);
+ return TitanOperationStatus.OK;
+ }
+ }
+
+ public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
+ return derivedFromOperation.isTypeDerivedFrom(childCandidateType, parentCandidateType, null, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
+ }
+
+
+ @Override
+ public Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityType(CapabilityTypeDefinition capabilityTypeDefNew,
+ CapabilityTypeDefinition capabilityTypeDefOld) {
+ log.debug("updating capability type {}", capabilityTypeDefNew.getType());
+ updateCapabilityTypeData(capabilityTypeDefNew, capabilityTypeDefOld);
+ return updateCapabilityTypeOnGraph(capabilityTypeDefNew, capabilityTypeDefOld);
+ }
+
+
+ private Either<CapabilityTypeDefinition, StorageOperationStatus> updateCapabilityTypeOnGraph(CapabilityTypeDefinition capabilityTypeDefinitionNew, CapabilityTypeDefinition capabilityTypeDefinitionOld) {
+ return titanGenericDao.updateNode(new CapabilityTypeData(capabilityTypeDefinitionNew), CapabilityTypeData.class)
+ .right()
+ .map(DaoStatusConverter::convertTitanStatusToStorageStatus)
+ .left()
+ .bind(updatedNode -> updateProperties(capabilityTypeDefinitionNew.getUniqueId(), capabilityTypeDefinitionNew.getProperties()))
+ .left()
+ .bind(updatedProperties -> updateDerivedFrom(capabilityTypeDefinitionNew, capabilityTypeDefinitionOld.getDerivedFrom()))
+ .right()
+ .bind(result -> TypeOperations.mapOkStatus(result, null))
+ .left()
+ .map(updatedDerivedFrom -> capabilityTypeDefinitionNew);
+ }
+
+ private Either<Map<String, PropertyData>, StorageOperationStatus> updateProperties(String capabilityTypeId, Map<String, PropertyDefinition> properties) {
+ log.debug("#updateCapabilityTypeProperties - updating properties for capability type with id {}", capabilityTypeId);
+ return propertyOperation.mergePropertiesAssociatedToNode(NodeTypeEnum.CapabilityType, capabilityTypeId, properties)
+ .right()
+ .map(DaoStatusConverter::convertTitanStatusToStorageStatus);
+ }
+
+ private Either<GraphRelation, StorageOperationStatus> updateDerivedFrom(CapabilityTypeDefinition updatedCapabilityType, String currDerivedFromCapabilityType) {
+ if( StringUtils.equals(updatedCapabilityType.getDerivedFrom(), currDerivedFromCapabilityType)) {
+ return Either.right(StorageOperationStatus.OK);
+ }
+
+ StorageOperationStatus status = isLegalToReplaceParent(currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom(), updatedCapabilityType.getType());
+ if ( status != StorageOperationStatus.OK) {
+ return Either.right(status);
+ }
+
+ String capabilityTypeId = updatedCapabilityType.getUniqueId();
+ log.debug("#updateCapabilityTypeDerivedFrom - updating capability type derived from relation for capability type with id {}. old derived type {}. new derived type {}", capabilityTypeId, currDerivedFromCapabilityType, updatedCapabilityType.getDerivedFrom());
+ StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromCapabilityType(capabilityTypeId, currDerivedFromCapabilityType);
+ if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
+ return Either.right(deleteDerivedRelationStatus);
+ }
+ return addDerivedFromRelation(updatedCapabilityType, capabilityTypeId);
+ }
+
+ private StorageOperationStatus isLegalToReplaceParent(String oldTypeParent, String newTypeParent, String childType) {
+ return derivedFromOperation.isUpdateParentAllowed(oldTypeParent, newTypeParent, childType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class, t -> t.getCapabilityTypeDataDefinition().getType());
+ }
+
+ private Either<GraphRelation, StorageOperationStatus> addDerivedFromRelation(CapabilityTypeDefinition capabilityTypeDef, String ptUniqueId) {
+ String derivedFrom = capabilityTypeDef.getDerivedFrom();
+ if (derivedFrom == null) {
+ return Either.left(null);
+ }
+ log.debug("#addDerivedFromRelationBefore - adding derived from relation between capability type {} to its parent {}", capabilityTypeDef.getType(), derivedFrom);
+ return this.getCapabilityType(derivedFrom, true)
+ .left()
+ .bind(derivedFromCapabilityType -> derivedFromOperation.addDerivedFromRelation(ptUniqueId, derivedFromCapabilityType.getUniqueId(), NodeTypeEnum.CapabilityType));
+ }
+
+ private StorageOperationStatus deleteDerivedFromCapabilityType(String capabilityTypeId, String derivedFromType) {
+ if (derivedFromType == null) {
+ return StorageOperationStatus.OK;
+ }
+ log.debug("#deleteDerivedFromCapabilityType - deleting derivedFrom relation for capability type with id {} and its derived type {}", capabilityTypeId, derivedFromType);
+ return getCapabilityType(derivedFromType, true)
+ .either(derivedFromNode -> derivedFromOperation.removeDerivedFromRelation(capabilityTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.CapabilityType),
+ err -> err);
+ }
+
+ private void updateCapabilityTypeData(CapabilityTypeDefinition updatedTypeDefinition, CapabilityTypeDefinition currTypeDefinition) {
+ updatedTypeDefinition.setUniqueId(currTypeDefinition.getUniqueId());
+ updatedTypeDefinition.setCreationTime(currTypeDefinition.getCreationTime());
+ }
+
+
+ /**
+ * FOR TEST ONLY
+ *
+ * @param propertyOperation
+ */
+ public void setPropertyOperation(PropertyOperation propertyOperation) {
+ this.propertyOperation = propertyOperation;
+ }
+
+ @Override
+ public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType(CapabilityTypeDefinition capabilityTypeDefinition) {
+
+ return addCapabilityType(capabilityTypeDefinition, true);
+ }
+
+ @Override
+ public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) {
+ return getCapabilityType(uniqueId, true);
+ }
}