summaryrefslogtreecommitdiffstats
path: root/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java')
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java1674
1 files changed, 1674 insertions, 0 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java
new file mode 100644
index 0000000000..e8892ad333
--- /dev/null
+++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java
@@ -0,0 +1,1674 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model.operations.impl;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import com.thinkaurelius.titan.core.TitanTransaction;
+import com.thinkaurelius.titan.core.TitanVertex;
+
+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.CapabiltyInstance;
+import org.openecomp.sdc.be.model.Point;
+import org.openecomp.sdc.be.model.PropertyDefinition;
+import org.openecomp.sdc.be.model.RequirementDefinition;
+import org.openecomp.sdc.be.model.RequirementImplDef;
+import org.openecomp.sdc.be.model.operations.api.IRequirementOperation;
+import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.resources.data.CapabilityData;
+import org.openecomp.sdc.be.resources.data.CapabilityInstData;
+import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
+import org.openecomp.sdc.be.resources.data.PropertyValueData;
+import org.openecomp.sdc.be.resources.data.RequirementData;
+import org.openecomp.sdc.be.resources.data.RequirementImplData;
+import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
+import org.openecomp.sdc.be.resources.data.UniqueIdData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import fj.data.Either;
+
+@Component("requirement-operation")
+public class RequirementOperation implements IRequirementOperation {
+
+ private static final String NA = "NA";
+
+ private static final String EQUAL_SIGN = "=";
+
+ private static final String EMPTY_STRING = "";
+
+ public RequirementOperation() {
+ super();
+ }
+
+ private static Logger log = LoggerFactory.getLogger(RequirementOperation.class.getName());
+
+ @javax.annotation.Resource
+ private CapabilityOperation capabilityOperation;
+
+ @javax.annotation.Resource
+ private CapabilityTypeOperation capabilityTypeOperation;
+
+ @javax.annotation.Resource
+ private TitanGenericDao titanGenericDao;
+
+ /**
+ * FOR TEST ONLY
+ *
+ * @param titanGenericDao
+ */
+ public void setTitanGenericDao(TitanGenericDao titanGenericDao) {
+ this.titanGenericDao = titanGenericDao;
+ }
+
+ protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) {
+ log.debug("The object returned after create capability is " + capabilityTypeData);
+
+ CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition(
+ capabilityTypeData.getCapabilityTypeDataDefinition());
+
+ return capabilityTypeDefResult;
+ }
+
+ /**
+ * FOR TEST ONLY
+ *
+ * @param capabilityOperation
+ */
+ public void setCapabilityOperation(CapabilityOperation capabilityOperation) {
+ this.capabilityOperation = capabilityOperation;
+ }
+
+ public void setCapabilityTypeOperation(CapabilityTypeOperation capabilityTypeOperation) {
+ this.capabilityTypeOperation = capabilityTypeOperation;
+ }
+
+ @Override
+ public Either<RequirementDefinition, StorageOperationStatus> addRequirementToResource(String reqName,
+ RequirementDefinition reqDefinition, String resourceId) {
+
+ return addRequirementToResource(reqName, reqDefinition, resourceId, false);
+ }
+
+ private Either<GraphRelation, TitanOperationStatus> associateRequirementToRelationshipType(RequirementData reqData,
+ RequirementDefinition reqDefinition) {
+
+ String relationship = reqDefinition.getRelationship();
+
+ if (relationship == null) {
+ log.debug("The provided relationship is null.");
+ return Either.right(TitanOperationStatus.NOT_FOUND);
+ }
+ UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.RelationshipType, relationship);
+ Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(reqData,
+ uniqueIdData, GraphEdgeLabels.RELATIONSHIP_TYPE, null);
+
+ return createRelation;
+
+ }
+
+ /**
+ * Associate the requirement node to its capability type
+ *
+ * @param reqData
+ * @param reqDefinition
+ * @return
+ */
+ private Either<GraphRelation, TitanOperationStatus> associateRequirementToCapabilityType(RequirementData reqData,
+ RequirementDefinition reqDefinition) {
+
+ String capability = reqDefinition.getCapability();
+
+ UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, capability);
+ Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(reqData,
+ uniqueIdData, GraphEdgeLabels.CAPABILITY_TYPE, null);
+
+ log.debug("After associating requirementData " + reqData + " to capability " + capability + ". status is "
+ + createRelation);
+
+ return createRelation;
+ }
+
+ private TitanOperationStatus associateRequirementToCapabilityType(TitanVertex reqData,
+ RequirementDefinition reqDefinition) {
+
+ String capability = reqDefinition.getCapability();
+
+ UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, capability);
+ TitanOperationStatus createRelation = titanGenericDao.createEdge(reqData, uniqueIdData,
+ GraphEdgeLabels.CAPABILITY_TYPE, null);
+
+ log.debug("After associating requirementData {} to capability {}. status is {}" + reqData, capability,
+ createRelation);
+
+ return createRelation;
+ }
+
+ /**
+ * Associate requirement impl node to capability instance node
+ *
+ * @param reqImplData
+ * @param capabilityInstData
+ * @param capabilityName
+ * @return
+ */
+ private Either<GraphRelation, TitanOperationStatus> associateRequirementImplToCapabilityInst(
+ RequirementImplData reqImplData, CapabilityInstData capabilityInstData, String capabilityName) {
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName);
+
+ log.debug(
+ "Before associating requirement impl " + reqImplData + " to capability instance " + capabilityInstData);
+ Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(reqImplData,
+ capabilityInstData, GraphEdgeLabels.CAPABILITY_INST, props);
+ log.debug("After associating requirement impl " + reqImplData + " to capability instance " + capabilityInstData
+ + ".status is " + createRelation);
+
+ return createRelation;
+
+ }
+
+ /**
+ * Add requirement node to graph
+ *
+ * @param resourceId
+ * @param reqName
+ * @param reqDefinition
+ * @return
+ */
+ private Either<RequirementData, TitanOperationStatus> addRequirementData(String resourceId, String reqName,
+ RequirementDefinition reqDefinition) {
+
+ ResourceMetadataData resourceData = new ResourceMetadataData();
+ resourceData.getMetadataDataDefinition().setUniqueId(resourceId);
+
+ RequirementData requirementData = buildRequirementData(resourceId, reqName, reqDefinition);
+
+ log.debug("Before adding requirement data to graph {}", requirementData);
+ Either<RequirementData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(requirementData,
+ RequirementData.class);
+
+ log.debug("After adding requirement to graph {}", requirementData);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add requirement " + reqName + " [ " + requirementData + " ] " + " to graph. status is "
+ + operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ TitanOperationStatus status = associateResourceDataToRequirementData(resourceId, reqName, resourceData,
+ requirementData);
+ if (status != TitanOperationStatus.OK) {
+ return Either.right(status);
+ }
+
+ return Either.left(createNodeResult.left().value());
+
+ }
+
+ private Either<TitanVertex, TitanOperationStatus> addRequirementData(TitanVertex vertex, String resourceId,
+ String reqName, RequirementDefinition reqDefinition) {
+
+ RequirementData requirementData = buildRequirementData(resourceId, reqName, reqDefinition);
+
+ log.debug("Before adding requirement data to graph {}", requirementData);
+ Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(requirementData);
+
+ log.debug("After adding requirement to graph {}", requirementData);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add requirement " + reqName + " [ " + requirementData + " ] " + " to graph. status is "
+ + operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ TitanOperationStatus status = associateResourceDataToRequirementData(resourceId, reqName, vertex,
+ createNodeResult.left().value());
+ if (!status.equals(TitanOperationStatus.OK)) {
+ return Either.right(status);
+ }
+ return Either.left(createNodeResult.left().value());
+ }
+
+ /**
+ * Asssociate resource node to requirement node with REQUIREMENT label and
+ * requirement name as property on the edge.
+ *
+ * @param resourceId
+ * @param reqName
+ * @param resourceData
+ * @param requirementData
+ * @return
+ */
+ private TitanOperationStatus associateResourceDataToRequirementData(String resourceId, String reqName,
+ ResourceMetadataData resourceData, RequirementData requirementData) {
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName);
+ Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData,
+ requirementData, GraphEdgeLabels.REQUIREMENT, props);
+ log.debug("After creatin edge between resource " + resourceId + " to requirement " + requirementData);
+ if (createRelResult.isRight()) {
+ TitanOperationStatus operationStatus = createRelResult.right().value();
+ log.error("Failed to associate resource " + resourceId + " to requirement " + reqName + "[ "
+ + requirementData + "] in graph. status is " + operationStatus);
+ }
+ return TitanOperationStatus.OK;
+ }
+
+ private TitanOperationStatus associateResourceDataToRequirementData(String resourceId, String reqName,
+ TitanVertex resourceVertex, TitanVertex requirementVertex) {
+
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName);
+ TitanOperationStatus createRelResult = titanGenericDao.createEdge(resourceVertex, requirementVertex,
+ GraphEdgeLabels.REQUIREMENT, props);
+ log.debug("After creatin edge between resource {} to requirement {}", resourceId, requirementVertex);
+ if (!createRelResult.equals(TitanOperationStatus.OK)) {
+ log.error("Failed to associate resource {} to requirement {} in graph. status is " + resourceId, reqName,
+ createRelResult);
+ }
+ return TitanOperationStatus.OK;
+ }
+
+ private RequirementData buildRequirementData(String resourceId, String reqName,
+ RequirementDefinition reqDefinition) {
+
+ RequirementData requirementData = new RequirementData();
+ requirementData.setNode(reqDefinition.getNode());
+ requirementData.setUniqueId(UniqueIdBuilder.buildRequirementUid(resourceId, reqName));
+ Long creationTime = System.currentTimeMillis();
+ requirementData.setCreationTime(creationTime);
+ requirementData.setModificationTime(creationTime);
+ requirementData.setRelationshipType(reqDefinition.getRelationship());
+ requirementData.setMinOccurrences(reqDefinition.getMinOccurrences());
+ requirementData.setMaxOccurrences(reqDefinition.getMaxOccurrences());
+
+ return requirementData;
+ }
+
+ /**
+ * build requirement impl node associate it to resource, requirement &
+ * implementation resource
+ *
+ * [RESOURCE] --> [REQUIREMENT IMPL] --> [ RESOURCE IMPL ] | V [REQUIREMENT]
+ *
+ * @param resourceLabel
+ * @param resourceId
+ * @param reqName
+ * @param requirementUid
+ * @param reqImplDefinition
+ * @return
+ */
+ private Either<RequirementImplData, TitanOperationStatus> addRequirementImplData(NodeTypeEnum resourceLabel,
+ String resourceId, String reqName, String requirementUid, RequirementImplDef reqImplDefinition) {
+
+ RequirementImplData requirementImplData = buildRequirementImplData(resourceId, reqName, reqImplDefinition);
+
+ log.debug("Before adding requirement impl data to graph " + requirementImplData);
+ Either<RequirementImplData, TitanOperationStatus> createNodeResult = titanGenericDao
+ .createNode(requirementImplData, RequirementImplData.class);
+ log.debug("After adding requirement to graph " + requirementImplData + ". status is " + createNodeResult);
+ if (createNodeResult.isRight()) {
+ TitanOperationStatus operationStatus = createNodeResult.right().value();
+ log.error("Failed to add requirement " + reqName + " [ " + requirementImplData + " ] "
+ + " to graph. status is " + operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ Either<GraphRelation, TitanOperationStatus> createRelResult = associateReqImplRoResource(resourceLabel,
+ resourceId, reqName, requirementImplData);
+ if (createRelResult.isRight()) {
+ TitanOperationStatus operationStatus = createRelResult.right().value();
+ log.error("Failed to associate resource " + resourceId + " to requirement impl " + requirementImplData
+ + "[ " + requirementImplData + "] in graph. status is " + operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ Either<GraphRelation, TitanOperationStatus> associateToResourceImpl = associateReqImplToImplResource(
+ requirementImplData, reqImplDefinition.getNodeId());
+ if (associateToResourceImpl.isRight()) {
+ TitanOperationStatus operationStatus = associateToResourceImpl.right().value();
+ log.error("Failed to associate requirement impl " + requirementImplData + " to resource impl "
+ + reqImplDefinition.getNodeId() + "[ " + requirementImplData + "] in graph. status is "
+ + operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ Either<GraphRelation, TitanOperationStatus> associateToRequirement = associateReqImplToRequirement(
+ requirementImplData, requirementUid);
+ if (associateToRequirement.isRight()) {
+ TitanOperationStatus operationStatus = associateToRequirement.right().value();
+ log.error("Failed to associate requirement impl " + requirementImplData + " to requirement " + reqName
+ + " in graph. status is " + operationStatus);
+ return Either.right(operationStatus);
+ }
+
+ return Either.left(createNodeResult.left().value());
+
+ }
+
+ private RequirementImplData buildRequirementImplData(String resourceId, String reqName,
+ RequirementImplDef reqImplDefinition) {
+ String reqImplUid = UniqueIdBuilder.buildRequirementImplUid(resourceId, reqName);
+ RequirementImplData requirementImplData = new RequirementImplData();
+ requirementImplData.setName(reqName);
+ requirementImplData.setUniqueId(reqImplUid);
+ Long creationTime = System.currentTimeMillis();
+ requirementImplData.setCreationTime(creationTime);
+ requirementImplData.setModificationTime(creationTime);
+ Point point = reqImplDefinition.getPoint();
+ if (point != null) {
+ requirementImplData.setPosX(point.getX());
+ requirementImplData.setPosY(point.getY());
+ }
+ return requirementImplData;
+ }
+
+ /**
+ * associate requirement impl node to the source requirement. The source
+ * requirement maybe belongs to one of parents.
+ *
+ * @param requirementImplData
+ * @param requirementUid
+ * @return
+ */
+ private Either<GraphRelation, TitanOperationStatus> associateReqImplToRequirement(
+ RequirementImplData requirementImplData, String requirementUid) {
+
+ UniqueIdData to = new UniqueIdData(NodeTypeEnum.Requirement, requirementUid);
+ log.debug("Before creating edge between requirement impl " + requirementImplData + " to requirement "
+ + requirementUid);
+ Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao
+ .createRelation(requirementImplData, to, GraphEdgeLabels.IMPLEMENTATION_OF, null);
+ log.debug("Before creating edge between requirement impl " + requirementImplData + " to requirement "
+ + requirementUid + ". status is " + createRelResult);
+
+ return createRelResult;
+ }
+
+ /**
+ * Associate requirement impl node to the node which supply this
+ * requirement.
+ *
+ * @param requirementImplData
+ * @param nodeId
+ * @return
+ */
+ private Either<GraphRelation, TitanOperationStatus> associateReqImplToImplResource(
+ RequirementImplData requirementImplData, String nodeId) {
+
+ UniqueIdData nodeImpl = new UniqueIdData(NodeTypeEnum.Resource, nodeId);
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), nodeId);
+ log.debug("Before creating edge between requirement impl " + requirementImplData + " to node impl " + nodeId);
+ Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao
+ .createRelation(requirementImplData, nodeImpl, GraphEdgeLabels.NODE_IMPL, props);
+ log.debug("After creating edge between requirement " + requirementImplData + " to node impl " + nodeId
+ + ". status is " + createRelResult);
+
+ return createRelResult;
+ }
+
+ /**
+ * create an edge between the requirement impl node to the implementation
+ * resource.
+ *
+ * @param resourceLabel
+ * @param resourceId
+ * @param reqName
+ * @param requirementImplData
+ * @return
+ */
+ private Either<GraphRelation, TitanOperationStatus> associateReqImplRoResource(NodeTypeEnum resourceLabel,
+ String resourceId, String reqName, RequirementImplData requirementImplData) {
+
+ UniqueIdData resource = new UniqueIdData(resourceLabel, resourceId);
+ Map<String, Object> props = new HashMap<String, Object>();
+ props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName);
+ log.debug(
+ "Before creating edge between resource " + resourceId + " to requirement impl " + requirementImplData);
+ Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resource,
+ requirementImplData, GraphEdgeLabels.REQUIREMENT_IMPL, props);
+ log.debug("After creating edge between to requirement impl " + requirementImplData + " to resource " + resource
+ + ". status is " + createRelResult);
+
+ return createRelResult;
+ }
+
+ private void validateNodeExists(String node) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public Either<RequirementDefinition, StorageOperationStatus> addRequirementToResource(String reqName,
+ RequirementDefinition reqDefinition, String resourceId, boolean inTransaction) {
+
+ Either<RequirementDefinition, StorageOperationStatus> result = null;
+ try {
+
+ log.debug("Going to add requirement " + reqName + " to resource " + resourceId
+ + ". requirement definition is " + reqDefinition);
+
+ validateNodeExists(reqDefinition.getNode());
+
+ // 1. add requirement node in graph and associate it to the resource
+ log.debug("Going to add requirement node in graph and associate it to the resource");
+ Either<RequirementData, TitanOperationStatus> addRequirementData = addRequirementData(resourceId, reqName,
+ reqDefinition);
+ if (addRequirementData.isRight()) {
+ log.error("Failed to add requirement " + reqName + " node to graph. status is " + addRequirementData);
+ result = Either.right(
+ DaoStatusConverter.convertTitanStatusToStorageStatus(addRequirementData.right().value()));
+ return result;
+ }
+
+ RequirementData requirementData = addRequirementData.left().value();
+
+ log.debug("Going to associate the requirement to the appriopriate capability type");
+ Either<GraphRelation, TitanOperationStatus> associateReqToCapabilityType = associateRequirementToCapabilityType(
+ requirementData, reqDefinition);
+ if (associateReqToCapabilityType.isRight()) {
+ log.error("Failed to associate requirement data node " + requirementData
+ + " to the capability type node " + reqDefinition.getCapability());
+ result = Either.right(DaoStatusConverter
+ .convertTitanStatusToStorageStatus(associateReqToCapabilityType.right().value()));
+ return result;
+ }
+
+ // TODO: esofer associate requirement to the relationship type
+ /*
+ * Either<GraphRelation, TitanOperationStatus>
+ * associateReqToRelshipType =
+ * associateRequirementToRelationshipType( requirementData,
+ * reqDefinition);
+ *
+ * if (associateReqToRelshipType.isRight() &&
+ * associateReqToRelshipType.right().value() !=
+ * TitanOperationStatus.NOT_FOUND) {
+ * log.error("Failed to associate requirement data node " +
+ * requirementData + " to the relationship type node " +
+ * reqDefinition.getRelationship()); result = Either
+ * .right(TitanStatusConverter
+ * .convertTitanStatusToStorageStatus(associateReqToRelshipType
+ * .right().value())); return result; }
+ */
+
+ log.debug("Going to fetch the requirement " + reqName + " from graph");
+ Either<RequirementDefinition, TitanOperationStatus> requirementDefinitionRes = getRequirement(
+ requirementData.getUniqueId());
+ if (requirementDefinitionRes.isRight()) {
+ result = Either.right(
+ DaoStatusConverter.convertTitanStatusToStorageStatus(requirementDefinitionRes.right().value()));
+ return result;
+ }
+
+ result = Either.left(requirementDefinitionRes.left().value());
+
+ 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();
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public StorageOperationStatus addRequirementToResource(TitanVertex metadataVertex, String reqName,
+ RequirementDefinition reqDefinition, String resourceId, boolean inTransaction) {
+
+ StorageOperationStatus result = StorageOperationStatus.OK;
+ try {
+
+ log.debug("Going to add requirement {} to resource . requirement definition is ", reqName, resourceId,
+ reqDefinition);
+
+ validateNodeExists(reqDefinition.getNode());
+
+ // 1. add requirement node in graph and associate it to the resource
+ log.debug("Going to add requirement node in graph and associate it to the resource");
+ Either<TitanVertex, TitanOperationStatus> addRequirementData = addRequirementData(metadataVertex,
+ resourceId, reqName, reqDefinition);
+ if (addRequirementData.isRight()) {
+ log.error("Failed to add requirement {} node to graph. status is {}", reqName,
+ addRequirementData.right().value());
+ result = DaoStatusConverter.convertTitanStatusToStorageStatus(addRequirementData.right().value());
+ return result;
+ }
+
+ log.debug("Going to associate the requirement to the appriopriate capability type");
+ TitanOperationStatus associateReqToCapabilityType = associateRequirementToCapabilityType(
+ addRequirementData.left().value(), reqDefinition);
+ if (!associateReqToCapabilityType.equals(TitanOperationStatus.OK)) {
+ log.error("Failed to associate requirement data node {} to the capability type node {}" + reqDefinition,
+ reqDefinition.getCapability());
+ result = DaoStatusConverter.convertTitanStatusToStorageStatus(associateReqToCapabilityType);
+ return result;
+ }
+ return result;
+
+ } finally {
+ if (false == inTransaction) {
+ if (result == null || !result.equals(TitanOperationStatus.OK)) {
+ log.error("Going to execute rollback on graph.");
+ titanGenericDao.rollback();
+ } else {
+ log.debug("Going to execute commit on graph.");
+ titanGenericDao.commit();
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Fetch requirement from graph
+ *
+ * @param uniqueId
+ * - the uniqueid of the requirement in the graph
+ * @return
+ */
+ public Either<RequirementDefinition, TitanOperationStatus> getRequirement(String uniqueId) {
+
+ log.debug("Going to fetch the requirement {} from graph.", uniqueId);
+ Either<RequirementData, TitanOperationStatus> reqDataResult = titanGenericDao
+ .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), uniqueId, RequirementData.class);
+
+ if (reqDataResult.isRight()) {
+ log.error("Failed to find requirement node in graph " + uniqueId + ". status is " + reqDataResult);
+ return Either.right(reqDataResult.right().value());
+ }
+
+ log.debug("Going to fetch the capability type associate to requirement {}", uniqueId);
+ Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> capabilityTypeRes = titanGenericDao
+ .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.CAPABILITY_TYPE,
+ NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+
+ if (capabilityTypeRes.isRight()) {
+ log.error("Cannot find the capability of a given requirement " + uniqueId + ". status is "
+ + capabilityTypeRes);
+ return Either.right(capabilityTypeRes.right().value());
+ }
+
+ ImmutablePair<CapabilityTypeData, GraphEdge> capability = capabilityTypeRes.left().value();
+
+ String capabilityType = capability.getKey().getCapabilityTypeDataDefinition().getType();
+
+ // TODO: esofer add relationship as edge
+ /*
+ * Either<List<ImmutablePair<RelationshipTypeData, GraphEdge>>,
+ * TitanOperationStatus> relationshipRes = titanGenericDao
+ * .getChildrenNodes( GraphPropertiesDictionary.UNIQUE_ID.getProperty(),
+ * uniqueId, GraphEdgeLabels.RELATIONSHIP_TYPE,
+ * NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+ *
+ * if (relationshipRes.isRight() && relationshipRes.right().value() !=
+ * TitanOperationStatus.NOT_FOUND) {
+ * log.error("Cannot find the capability of a given requirement " +
+ * uniqueId + ". status is " + capabilityTypesRes); return
+ * Either.right(relationshipRes.right().value()); }
+ *
+ * String relationshipType = null; if (relationshipRes.isLeft()) {
+ * List<ImmutablePair<RelationshipTypeData, GraphEdge>> rstPairs =
+ * relationshipRes .left().value(); if (rstPairs == null || true ==
+ * rstPairs.isEmpty()) { log.error(
+ * "Cannot find the capability of a given requirement " + uniqueId);
+ * return Either.right(TitanOperationStatus.NOT_FOUND); }
+ *
+ * ImmutablePair<RelationshipTypeData, GraphEdge> relationship =
+ * rstPairs .get(0); relationshipType = relationship.getKey().getType();
+ * }
+ */
+
+ log.debug("Going to fetch the capability type associate to requirement {}", uniqueId);
+ Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao
+ .getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.REQUIREMENT,
+ NodeTypeEnum.Resource, ResourceMetadataData.class);
+ if (parentNode.isRight()) {
+ log.error("Cannot find the parent resource for a given requirement " + uniqueId + ". status is "
+ + parentNode.right().value());
+ return Either.right(parentNode.right().value());
+ }
+
+ RequirementData requirementData = reqDataResult.left().value();
+
+ RequirementDefinition requirementDefinition = new RequirementDefinition();
+ requirementDefinition.setOwnerId(parentNode.left().value().getLeft().getMetadataDataDefinition().getUniqueId());
+ requirementDefinition.setNode(requirementData.getNode());
+ requirementDefinition.setUniqueId(requirementData.getUniqueId());
+ requirementDefinition.setCapability(capabilityType);
+ requirementDefinition.setRelationship(requirementData.getRelationshipType());
+ requirementDefinition.setMinOccurrences(requirementData.getMinOccurrences());
+ requirementDefinition.setMaxOccurrences(requirementData.getMaxOccurrences());
+
+ return Either.left(requirementDefinition);
+
+ }
+
+ @Override
+ public Either<RequirementDefinition, StorageOperationStatus> getRequirementOfResource(String reqName,
+ String resourceId) {
+
+ return getRequirementOfResource(reqName, resourceId, false);
+ }
+
+ @Override
+ public Either<RequirementDefinition, StorageOperationStatus> getRequirementOfResource(String reqName,
+ String resourceId, boolean inTransaction) {
+
+ Either<RequirementDefinition, StorageOperationStatus> result = null;
+
+ try {
+ String reqUniqueId = UniqueIdBuilder.buildRequirementUid(resourceId, reqName);
+ Either<RequirementDefinition, TitanOperationStatus> requirementRes = getRequirement(reqUniqueId);
+
+ if (requirementRes.isRight()) {
+ log.debug("Failed to retrieve requirement " + reqName + " associated to resource " + resourceId);
+ result = Either
+ .right(DaoStatusConverter.convertTitanStatusToStorageStatus(requirementRes.right().value()));
+ } else {
+ result = Either.left(requirementRes.left().value());
+ }
+
+ 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();
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public Either<RequirementDefinition, StorageOperationStatus> addRequirementImplToResource(String reqName,
+ RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId) {
+
+ return addRequirementImplToResource(reqName, reqDefinition, resourceId, parentReqUniqueId, false);
+
+ }
+
+ @Override
+ public Either<RequirementDefinition, StorageOperationStatus> addRequirementImplToResource(String reqName,
+ RequirementImplDef reqImplDefinition, String resourceId, String parentReqUniqueId, boolean inTransaction) {
+
+ Either<RequirementDefinition, StorageOperationStatus> result = null;
+
+ try {
+
+ // find the requirement defined at the resource itself or under one
+ // of its parents
+ Either<RequirementDefinition, TitanOperationStatus> findReq = getRequirement(parentReqUniqueId);
+ log.debug("After looking for requirement " + parentReqUniqueId + ". status is " + findReq);
+ if (findReq.isRight()) {
+ TitanOperationStatus status = findReq.right().value();
+ log.error("The requirment " + parentReqUniqueId + " was not found in the graph. status is "
+ + findReq.right().value());
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ return result;
+ }
+
+ RequirementDefinition reqDefinition = findReq.left().value();
+ String reqNode = reqDefinition.getNode();
+ String reqCapability = reqDefinition.getCapability();
+
+ String nodeIdImpl = reqImplDefinition.getNodeId();
+
+ checkNodeIdImplementsRequirementNode(nodeIdImpl, reqNode);
+
+ Either<RequirementImplData, TitanOperationStatus> addRequirementImplData = addRequirementImplData(
+ NodeTypeEnum.Resource, resourceId, reqName, parentReqUniqueId, reqImplDefinition);
+
+ if (addRequirementImplData.isRight()) {
+ TitanOperationStatus status = addRequirementImplData.right().value();
+ log.error("Failed to add requirement data impl node in the graph. status is "
+ + addRequirementImplData.right().value());
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ return result;
+ }
+ RequirementImplData requirementImplData = addRequirementImplData.left().value();
+
+ log.debug("Add the properties of the capabilities of the target node " + nodeIdImpl
+ + " to the requirement impl node " + requirementImplData.getUniqueId() + " in graph.");
+ Map<String, CapabiltyInstance> requirementPropertiesPerCapability = reqImplDefinition
+ .getRequirementProperties();
+ TitanOperationStatus addPropsResult = addCapabilityPropertiesToReqImpl(requirementImplData, reqCapability,
+ nodeIdImpl, requirementPropertiesPerCapability);
+
+ if (addPropsResult != TitanOperationStatus.OK) {
+ log.error("Failed to add capabilities properties to Requirement impl " + requirementImplData);
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropsResult));
+ return result;
+ }
+
+ result = Either.left(reqDefinition);
+
+ } 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();
+ }
+ }
+ }
+
+ return result;
+ }
+
+ private Either<RequirementImplDef, TitanOperationStatus> getRequirementImplOfResource(String reqName,
+ String resourceId) {
+
+ RequirementImplDef requirementImplDef = new RequirementImplDef();
+
+ Either<List<ImmutablePair<RequirementImplData, GraphEdge>>, TitanOperationStatus> reqImplNodesRes = titanGenericDao
+ .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId,
+ GraphEdgeLabels.REQUIREMENT_IMPL, NodeTypeEnum.RequirementImpl, RequirementImplData.class);
+ log.debug("After looking for requirement impl edge of resource " + resourceId);
+ if (reqImplNodesRes.isRight()) {
+ TitanOperationStatus status = reqImplNodesRes.right().value();
+ return Either.right(status);
+ }
+
+ boolean found = false;
+ List<ImmutablePair<RequirementImplData, GraphEdge>> reqImplNodes = reqImplNodesRes.left().value();
+ for (ImmutablePair<RequirementImplData, GraphEdge> entry : reqImplNodes) {
+ GraphEdge graphEdge = entry.getValue();
+ String edgeType = (String) graphEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty());
+ if (reqName.equals(edgeType)) {
+ found = true;
+ RequirementImplData requirementImplData = entry.getKey();
+
+ requirementImplDef.setUniqueId(requirementImplData.getUniqueId());
+
+ Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> nodeImplRes = titanGenericDao
+ .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RequirementImpl),
+ requirementImplData.getUniqueId(), GraphEdgeLabels.NODE_IMPL, NodeTypeEnum.Resource,
+ ResourceMetadataData.class);
+
+ if (nodeImplRes.isRight()) {
+ TitanOperationStatus status = nodeImplRes.right().value();
+ log.debug("No implementation resource was found under requirement impl "
+ + requirementImplData.getUniqueId() + ". status is " + status);
+
+ return Either.right(status);
+ }
+ String nodeImpl = nodeImplRes.left().value().getKey().getMetadataDataDefinition().getUniqueId();
+ requirementImplDef.setNodeId(nodeImpl);
+
+ String posX = requirementImplData.getPosX();
+ String posY = requirementImplData.getPosY();
+ if (posX != null && posY != null) {
+ Point point = new Point(posX, posY);
+ requirementImplDef.setPoint(point);
+ }
+
+ Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> capaInstDataRes = titanGenericDao
+ .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RequirementImpl),
+ requirementImplData.getUniqueId(), GraphEdgeLabels.CAPABILITY_INST,
+ NodeTypeEnum.CapabilityInst, CapabilityInstData.class);
+ if (capaInstDataRes.isRight()) {
+ TitanOperationStatus status = capaInstDataRes.right().value();
+ log.debug("No capability instance was found under requirement impl "
+ + requirementImplData.getUniqueId() + ". status is " + status);
+
+ return Either.right(status);
+ }
+
+ Map<String, CapabiltyInstance> requirementProperties = new HashMap<String, CapabiltyInstance>();
+
+ List<ImmutablePair<CapabilityInstData, GraphEdge>> list = capaInstDataRes.left().value();
+ for (ImmutablePair<CapabilityInstData, GraphEdge> capabilityInst : list) {
+ CapabilityInstData capabilityInstData = capabilityInst.getKey();
+ GraphEdge edge = capabilityInst.getValue();
+ Map<String, Object> properties = edge.getProperties();
+ if (properties == null) {
+ log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty()
+ + " on the edge " + edge);
+ return Either.right(TitanOperationStatus.INVALID_ELEMENT);
+ }
+ String capabilityName = (String) properties.get(GraphPropertiesDictionary.NAME.getProperty());
+ if (capabilityName == null) {
+ log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty()
+ + " on the edge " + edge);
+ return Either.right(TitanOperationStatus.INVALID_ELEMENT);
+ }
+
+ // List<String> keyValuePropertiesList = capabilityInstData
+ // .getProperties();
+ // Map<String, String> actualValues = new HashMap<String,
+ // String>();
+ // fillMapFromKeyValueList(keyValuePropertiesList,
+ // actualValues);
+ CapabiltyInstance capabiltyInstance = new CapabiltyInstance();
+ capabiltyInstance.setUniqueId(capabilityInstData.getUniqueId());
+ // capabiltyInstance.setProperties(actualValues);
+ requirementProperties.put(capabilityName, capabiltyInstance);
+
+ Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyValueNodesRes = titanGenericDao
+ .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst),
+ capabilityInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE,
+ NodeTypeEnum.PropertyValue, PropertyValueData.class);
+
+ if (propertyValueNodesRes.isRight()) {
+ TitanOperationStatus status = propertyValueNodesRes.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to find the property values of capability instance " + capabilityInstData
+ + ". status is " + status);
+ return Either.right(status);
+ }
+ } else {
+ List<ImmutablePair<PropertyValueData, GraphEdge>> propertyValueNodes = propertyValueNodesRes
+ .left().value();
+
+ if (propertyValueNodes != null) {
+
+ Map<String, String> actualValues = new HashMap<String, String>();
+ TitanOperationStatus fillPropertiesResult = fillPropertiesMapFromNodes(propertyValueNodes,
+ actualValues);
+
+ if (fillPropertiesResult != TitanOperationStatus.OK) {
+ log.error("Failed to fetch properties of capability " + capabilityName);
+ return Either.right(fillPropertiesResult);
+ }
+
+ if (false == actualValues.isEmpty()) {
+ capabiltyInstance.setProperties(actualValues);
+ }
+ }
+ }
+
+ }
+
+ requirementImplDef.setRequirementProperties(requirementProperties);
+
+ break;
+ } else {
+ continue;
+ }
+ }
+
+ if (false == found) {
+ log.debug("Cannot find requirement impl under resource " + resourceId);
+ return Either.right(TitanOperationStatus.NOT_FOUND);
+ }
+
+ return Either.left(requirementImplDef);
+ }
+
+ private void fillMapFromKeyValueList(List<String> keyValuePropertiesList, Map<String, String> actualValues) {
+
+ if (keyValuePropertiesList != null) {
+ for (String keyValue : keyValuePropertiesList) {
+ int equalSignLocation = keyValue.indexOf(EQUAL_SIGN);
+ if (equalSignLocation > -1) {
+ String key = keyValue.substring(0, equalSignLocation);
+ String value = EMPTY_STRING;
+ if (equalSignLocation + 1 < keyValue.length()) {
+ value = keyValue.substring(equalSignLocation + 1);
+ }
+ actualValues.put(key, value);
+ }
+ }
+ }
+
+ }
+
+ private TitanOperationStatus fillPropertiesMapFromNodes(
+ List<ImmutablePair<PropertyValueData, GraphEdge>> propertyValueNodes, Map<String, String> actualValues) {
+ if (propertyValueNodes != null) {
+ for (ImmutablePair<PropertyValueData, GraphEdge> propertyValuePair : propertyValueNodes) {
+ PropertyValueData propertyValueData = propertyValuePair.getKey();
+ GraphEdge propertyValueEdge = propertyValuePair.getValue();
+ Map<String, Object> propertyEdgeProps = propertyValueEdge.getProperties();
+ if (propertyEdgeProps == null) {
+ log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty()
+ + " on the edge " + propertyValueEdge);
+ return TitanOperationStatus.INVALID_ELEMENT;
+ }
+ String paramName = (String) propertyEdgeProps.get(GraphPropertiesDictionary.NAME.getProperty());
+ if (paramName == null) {
+ log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty()
+ + " on the edge " + propertyValueEdge);
+ return TitanOperationStatus.INVALID_ELEMENT;
+ }
+ actualValues.put(paramName, propertyValueData.getValue());
+ }
+ }
+ return TitanOperationStatus.OK;
+ }
+
+ private TitanOperationStatus addCapabilityPropertiesToReqImpl(RequirementImplData reqImplData, String reqCapability,
+ String nodeIdImpl, Map<String, CapabiltyInstance> propertiesValuePerCapability) {
+
+ TitanOperationStatus result = null;
+
+ Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> allCapabilities = capabilityOperation
+ .getAllCapabilitiesPairs(nodeIdImpl);
+ log.trace("Atter looking for the capabilities of resource " + nodeIdImpl + ". result is " + allCapabilities);
+ if (allCapabilities.isRight()) {
+ TitanOperationStatus status = allCapabilities.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to find capabilities of resource " + nodeIdImpl + ". status is " + status);
+ return status;
+ }
+ } else {
+
+ List<ImmutablePair<CapabilityData, GraphEdge>> capabilitiesValue = allCapabilities.left().value();
+ checkImplNodeContainsReqCapability(reqCapability, capabilitiesValue);
+
+ for (ImmutablePair<CapabilityData, GraphEdge> entry : capabilitiesValue) {
+
+ CapabilityData capabilityData = entry.getKey();
+
+ GraphEdge graphEdge = entry.getValue();
+
+ Either<String, TitanOperationStatus> capabilityNameResult = findCapabilityName(capabilityData,
+ graphEdge);
+
+ if (capabilityNameResult.isRight()) {
+ TitanOperationStatus status = capabilityNameResult.right().value();
+ log.error(
+ "Failed to find capability name from the edge associated to capability " + capabilityData);
+ return status;
+ }
+
+ String capabilityName = capabilityNameResult.left().value();
+ log.debug("Going to set properties of capability " + capabilityName);
+ String cabilityDataUid = capabilityData.getUniqueId();
+
+ Either<CapabilityTypeData, TitanOperationStatus> ctDataResult = capabilityOperation
+ .getCapabilityTypeOfCapability(cabilityDataUid);
+
+ if (ctDataResult.isRight()) {
+ log.error("Cannot find capability type of capbility " + cabilityDataUid + ". status is "
+ + ctDataResult);
+ TitanOperationStatus status = ctDataResult.right().value();
+ return status;
+ }
+
+ CapabilityTypeData capabilityTypeData = ctDataResult.left().value();
+
+ Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesStatus = findPropertiesOfCapability(
+ capabilityTypeData);
+ if (propertiesStatus.isRight()) {
+ TitanOperationStatus status = propertiesStatus.right().value();
+ log.error("Failed to fetch properties definitions from capability. status is " + status);
+ return status;
+ }
+
+ Map<String, PropertyDefinition> properties = propertiesStatus.left().value();
+
+ CapabiltyInstance capabiltyInstance = null;
+ if (propertiesValuePerCapability != null) {
+ capabiltyInstance = propertiesValuePerCapability.get(capabilityName);
+ }
+
+ Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceNode = createCapabilityInstanceNode(
+ capabilityName, reqImplData);
+ if (createCapabilityInstanceNode.isRight()) {
+ TitanOperationStatus status = createCapabilityInstanceNode.right().value();
+ log.error("Failed to create capability instance node (" + capabilityName + ") in graph. status is "
+ + status);
+
+ return status;
+ }
+ CapabilityInstData capabilityInstData = createCapabilityInstanceNode.left().value();
+
+ Either<List<GraphRelation>, TitanOperationStatus> instanceProperties = addPropertiesToCapabilityInstance(
+ properties, capabiltyInstance, capabilityInstData);
+
+ if (instanceProperties.isRight()) {
+ TitanOperationStatus status = instanceProperties.right().value();
+ log.debug("Failed to add properties to capability instance. status is " + status);
+ return status;
+ }
+
+ Either<GraphRelation, TitanOperationStatus> associateCapabilityInstToCapabilityType = associateCapabilityInstToCapabilityType(
+ capabilityInstData, capabilityTypeData);
+ if (associateCapabilityInstToCapabilityType.isRight()) {
+ TitanOperationStatus status = associateCapabilityInstToCapabilityType.right().value();
+ log.error("Failed to associate capability instance " + capabilityInstData
+ + " to capability type node " + capabilityTypeData + " in graph. status is " + status);
+
+ return status;
+ }
+
+ Either<GraphRelation, TitanOperationStatus> associateCapabilityInst = associateRequirementImplToCapabilityInst(
+ reqImplData, capabilityInstData, capabilityName);
+ if (associateCapabilityInst.isRight()) {
+ TitanOperationStatus status = associateCapabilityInst.right().value();
+ log.error("Failed to associate requirement impl " + reqImplData + " to capability instance node "
+ + capabilityInstData + " of capability " + capabilityName + ") in graph. status is "
+ + status);
+
+ return status;
+ }
+
+ }
+ result = TitanOperationStatus.OK;
+ }
+ return result;
+ }
+
+ private Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfCapability(
+ CapabilityTypeData capabilityTypeData) {
+ String capabilityTypeUid = capabilityTypeData.getUniqueId();
+
+ Either<CapabilityTypeDefinition, TitanOperationStatus> capabilityTypeResult = capabilityTypeOperation
+ .getCapabilityTypeByUid(capabilityTypeUid);
+
+ if (capabilityTypeResult.isRight()) {
+ log.error("Failed to find capabilityType " + capabilityTypeUid + " in the graph. status is "
+ + capabilityTypeResult);
+ return Either.right(capabilityTypeResult.right().value());
+ }
+
+ CapabilityTypeDefinition capabilityTypeDef = capabilityTypeResult.left().value();
+ Map<String, PropertyDefinition> properties = capabilityTypeDef.getProperties();
+
+ return Either.left(properties);
+ }
+
+ private Either<String, TitanOperationStatus> findCapabilityName(CapabilityData capabilityData,
+ GraphEdge graphEdge) {
+ Map<String, Object> edgeProps = graphEdge.getProperties();
+ String capabilityName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty());
+
+ if (capabilityName == null) {
+ log.debug("Cannot find the name of the capability associated to node " + capabilityData);
+ return Either.right(TitanOperationStatus.NOT_FOUND);
+ }
+ return Either.left(capabilityName);
+ }
+
+ private Either<GraphRelation, TitanOperationStatus> associateCapabilityInstToCapabilityType(
+ CapabilityInstData capabilityInstData, CapabilityTypeData capabilityTypeData) {
+
+ Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(capabilityInstData,
+ capabilityTypeData, GraphEdgeLabels.INSTANCE_OF, null);
+
+ return createRelation;
+
+ }
+
+ /**
+ * add property value node with default value of override value and
+ * associate it to the capability instance node
+ *
+ * @param properties
+ * - properties definition. old also default value
+ * @param capabilityInstance
+ * - hold also properties new value(if exists)
+ * @param capabilityInstData
+ * - the graph node which we associate the properties value node
+ * to.
+ * @return
+ */
+ private Either<List<GraphRelation>, TitanOperationStatus> addPropertiesToCapabilityInstance(
+ Map<String, PropertyDefinition> properties, CapabiltyInstance capabilityInstance,
+ CapabilityInstData capabilityInstData) {
+
+ List<GraphRelation> relationsResult = new ArrayList<GraphRelation>();
+
+ if (properties != null) {
+ for (Entry<String, PropertyDefinition> entry : properties.entrySet()) {
+
+ String paramName = entry.getKey();
+
+ PropertyDefinition propertyDefinition = entry.getValue();
+
+ String propertyValue = setPropertyValue(capabilityInstance, paramName, propertyDefinition);
+
+ PropertyValueData propertyValueData = buildPropertyValueData(capabilityInstData.getUniqueId(),
+ paramName, propertyValue);
+
+ log.debug("Before creating property value data node " + propertyValueData + " in graph.");
+ Either<PropertyValueData, TitanOperationStatus> createNode = titanGenericDao
+ .createNode(propertyValueData, PropertyValueData.class);
+ log.debug("Before creating property value data node " + propertyValueData + " in graph. status is "
+ + createNode);
+ if (createNode.isRight()) {
+ TitanOperationStatus status = createNode.right().value();
+ log.error("Failed to create property value node in graph " + propertyValueData + ". status is "
+ + status);
+ return Either.right(status);
+ }
+
+ PropertyValueData propertyValueDataCreated = createNode.left().value();
+
+ Either<GraphRelation, TitanOperationStatus> createRelation = associateCapabilityInstToPropertyValue(
+ capabilityInstData, paramName, propertyValueDataCreated);
+
+ if (createRelation.isRight()) {
+ TitanOperationStatus status = createNode.right().value();
+ log.error("Failed to create relation between capability instance "
+ + capabilityInstData.getUniqueId() + " to property value "
+ + propertyValueDataCreated.getUniqueId() + " in graph. status is " + status);
+ return Either.right(status);
+ }
+
+ relationsResult.add(createRelation.left().value());
+
+ }
+ }
+
+ return Either.left(relationsResult);
+ }
+
+ private Either<GraphRelation, TitanOperationStatus> associateCapabilityInstToPropertyValue(
+ CapabilityInstData capabilityInstData, String paramName, PropertyValueData propertyValueDataCreated) {
+
+ Map<String, Object> edgeProps = new HashMap<String, Object>();
+ edgeProps.put(GraphPropertiesDictionary.NAME.getProperty(), paramName);
+ log.debug("Begin creating relation between capability instance " + capabilityInstData + " to property value "
+ + propertyValueDataCreated + " in graph.");
+ Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(capabilityInstData,
+ propertyValueDataCreated, GraphEdgeLabels.PROPERTY_VALUE, edgeProps);
+ log.debug("After creating relation between capability instance " + capabilityInstData + " to property value "
+ + propertyValueDataCreated + " in graph. status is " + createRelation);
+
+ return createRelation;
+ }
+
+ private String setPropertyValue(CapabiltyInstance capabilityInstance, String paramName,
+ PropertyDefinition propertyDefinition) {
+ String propertyValue = NA;
+ if (propertyDefinition.getDefaultValue() != null) {
+ propertyValue = propertyDefinition.getDefaultValue();
+ }
+ Map<String, String> propertiesValue = null;
+ if (capabilityInstance != null) {
+ propertiesValue = capabilityInstance.getProperties();
+ if (propertiesValue != null) {
+ String tmpValue = propertiesValue.get(paramName);
+ if (tmpValue != null) {
+ propertyValue = tmpValue;
+ }
+ }
+ }
+ return propertyValue;
+ }
+
+ private String buildPropertykeyValue(String paramName, String paramValue) {
+ return paramName + EQUAL_SIGN + paramValue;
+ }
+
+ private PropertyValueData buildPropertyValueData(String capabilityInstDataUid, String paramName,
+ String propertyValue) {
+ PropertyValueData propertyValueData = new PropertyValueData();
+ propertyValueData.setValue(propertyValue);
+ String uid = UniqueIdBuilder.buildPropertyValueUniqueId(capabilityInstDataUid, paramName);
+ propertyValueData.setUniqueId(uid);
+ Long creationDate = System.currentTimeMillis();
+ propertyValueData.setCreationTime(creationDate);
+ propertyValueData.setModificationTime(creationDate);
+ return propertyValueData;
+ }
+
+ private Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceNode(String capabilityName,
+ RequirementImplData reqImplData) {
+
+ CapabilityInstData capabilityInstData = new CapabilityInstData();
+ String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(reqImplData.getUniqueId(), capabilityName);
+
+ capabilityInstData.setUniqueId(uniqueId);
+ // capabilityInstData.setProperties(instanceProperties);
+ Long creationDate = System.currentTimeMillis();
+ capabilityInstData.setCreationTime(creationDate);
+ capabilityInstData.setModificationTime(creationDate);
+
+ log.debug("Before creating capability instance node in graph " + capabilityInstData);
+ Either<CapabilityInstData, TitanOperationStatus> createNode = titanGenericDao.createNode(capabilityInstData,
+ CapabilityInstData.class);
+ log.debug(
+ "After creating capability instance node in graph " + capabilityInstData + ". status is " + createNode);
+
+ return createNode;
+ }
+
+ private void checkNodeIdImplementsRequirementNode(String nodeIdImpl, String reqNode) {
+ // TODO Auto-generated method stub
+
+ }
+
+ private void checkImplNodeContainsReqCapability(String reqCapability,
+ List<ImmutablePair<CapabilityData, GraphEdge>> capabilitiesValue) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Either<Map<String, List<RequirementDefinition>>, StorageOperationStatus> getAllRequirementsOfResourceOnly(
+ String resourceId, boolean inTransaction) {
+
+ Either<Map<String, List<RequirementDefinition>>, StorageOperationStatus> result = null;
+
+ try {
+
+ Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>();
+ Set<String> caseInsensitiveReqNames = new HashSet<>();
+ TitanOperationStatus status = findAllRequirementsNonRecursive(resourceId, requirements,
+ caseInsensitiveReqNames);
+
+ if (status != TitanOperationStatus.OK) {
+ log.error("Failed to get all requirements of resource " + resourceId + ". status is " + status);
+ return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ } else {
+ // TODO handle requirementImpl
+ result = Either.left(convertRequirementMap(requirements, null, null));
+ }
+ 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();
+ }
+ }
+ }
+ }
+
+ @Override
+ public Either<Map<String, RequirementDefinition>, TitanOperationStatus> getResourceRequirements(String resourceId) {
+
+ Either<Map<String, RequirementDefinition>, TitanOperationStatus> result = null;
+
+ Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>();
+ Set<String> caseInsensitiveReqNames = new HashSet<>();
+
+ TitanOperationStatus status = findAllRequirementsRecursively(resourceId, requirements, caseInsensitiveReqNames);
+ if (status != TitanOperationStatus.OK) {
+ log.error("Failed to get all requirements of resource " + resourceId + ". status is " + status);
+ return Either.right(status);
+ } else {
+ log.debug("The requirements returned for resource {} are {}", resourceId, requirements);
+
+ if (requirements != null) {
+ for (Entry<String, RequirementDefinition> entry : requirements.entrySet()) {
+ String reqName = entry.getKey();
+ Either<RequirementImplDef, TitanOperationStatus> reqImplRes = this
+ .getRequirementImplOfResource(reqName, resourceId);
+ if (reqImplRes.isRight()) {
+
+ TitanOperationStatus reqImplResStatus = reqImplRes.right().value();
+ if (reqImplResStatus == TitanOperationStatus.NOT_FOUND) {
+ log.debug("Cannot find implementation of requirement {} under resource {}", reqName,
+ resourceId);
+ } else {
+ log.error("Cannot find implementation of requirement {} under resource {}", reqName,
+ resourceId);
+ return Either.right(reqImplResStatus);
+ }
+ } else {
+ RequirementDefinition requirementDefinition = entry.getValue();
+ // RequirementImplDef requirementImplDef =
+ // reqImplRes.left().value();
+ // requirementDefinition.setRequirementImpl(requirementImplDef);
+ }
+ }
+ }
+ log.debug("The requirements returned for resource {} after fetching requirement impl are {}", resourceId,
+ requirements);
+
+ result = Either.left(requirements);
+
+ return result;
+ }
+
+ }
+
+ @Override
+ public Either<Map<String, RequirementDefinition>, StorageOperationStatus> getAllResourceRequirements(
+ String resourceId, boolean inTransaction) {
+
+ Either<Map<String, RequirementDefinition>, StorageOperationStatus> result = null;
+
+ try {
+
+ Either<Map<String, RequirementDefinition>, TitanOperationStatus> internalResult = getResourceRequirements(
+ resourceId);
+ if (internalResult.isRight()) {
+ TitanOperationStatus status = internalResult.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to fetch requirements of resource {} . status is {}", resourceId, status);
+ }
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ return result;
+ }
+
+ Map<String, RequirementDefinition> value = internalResult.left().value();
+
+ result = Either.left(value);
+ return result;
+
+ // Map<String, RequirementDefinition> requirements = new
+ // HashMap<String, RequirementDefinition>();
+ // TitanOperationStatus status = findAllRequirementsRecursively(
+ // resourceId, requirements);
+ // if (status != TitanOperationStatus.OK) {
+ // log.error("Failed to get all requirements of resource "
+ // + resourceId + ". status is " + status);
+ // return Either.right(TitanStatusConverter
+ // .convertTitanStatusToStorageStatus(status));
+ // } else {
+ // log.debug("The requirements returned for resource "
+ // + resourceId + " are " + requirements);
+ //
+ // if (requirements != null) {
+ // for (Entry<String, RequirementDefinition> entry : requirements
+ // .entrySet()) {
+ // String reqName = entry.getKey();
+ // Either<RequirementImplDef, TitanOperationStatus> reqImplRes =
+ // this
+ // .getRequirementImplOfResource(reqName,
+ // resourceId);
+ // if (reqImplRes.isRight()) {
+ //
+ // TitanOperationStatus reqImplResStatus = reqImplRes
+ // .right().value();
+ // if (reqImplResStatus == TitanOperationStatus.NOT_FOUND) {
+ // log.warn("Cannot find implementation of requirement "
+ // + reqName
+ // + " under resource "
+ // + resourceId);
+ // } else {
+ // log.error("Cannot find implementation of requirement "
+ // + reqName
+ // + " under resource "
+ // + resourceId);
+ // return Either
+ // .right(TitanStatusConverter
+ // .convertTitanStatusToStorageStatus(reqImplResStatus));
+ // }
+ // } else {
+ // RequirementDefinition requirementDefinition = entry
+ // .getValue();
+ // RequirementImplDef requirementImplDef = reqImplRes
+ // .left().value();
+ // requirementDefinition
+ // .setRequirementImpl(requirementImplDef);
+ // }
+ // }
+ // }
+ // log.debug("The requirements returned for resource "
+ // + resourceId + " after fetching requirement impl are "
+ // + requirements);
+ //
+ // result = Either.left(requirements);
+ //
+ // 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();
+ }
+ }
+ }
+
+ }
+
+ public Either<Map<String, RequirementDefinition>, StorageOperationStatus> getAllResourceRequirements(
+ String resourceId) {
+
+ return getAllResourceRequirements(resourceId, false);
+
+ }
+
+ public TitanOperationStatus findAllRequirementsRecursively(String resourceId,
+ Map<String, RequirementDefinition> requirements, Set<String> caseInsensitiveReqNames) {
+
+ TitanOperationStatus nonRecursiveResult = findAllRequirementsNonRecursive(resourceId, requirements,
+ caseInsensitiveReqNames);
+ if (!nonRecursiveResult.equals(TitanOperationStatus.OK)
+ && !nonRecursiveResult.equals(TitanOperationStatus.NOT_FOUND)) {
+ return nonRecursiveResult;
+ }
+
+ Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao
+ .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId,
+ GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class);
+
+ if (parentNodes.isRight()) {
+ TitanOperationStatus parentNodesStatus = parentNodes.right().value();
+ if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) {
+ log.debug("Finish to lookup for parnet requirements");
+ return TitanOperationStatus.OK;
+ } else {
+ log.error("Failed to find parent requirements of resource {} . status is {}", resourceId,
+ parentNodesStatus);
+ return parentNodesStatus;
+ }
+ }
+ ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value();
+ String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId();
+ TitanOperationStatus addParentReqStatus = findAllRequirementsRecursively(parentUniqueId, requirements,
+ caseInsensitiveReqNames);
+
+ if (addParentReqStatus != TitanOperationStatus.OK) {
+ log.error("Failed to fetch all requirements of resource {}", parentUniqueId);
+ return addParentReqStatus;
+ }
+
+ return TitanOperationStatus.OK;
+ }
+
+ private TitanOperationStatus findAllRequirementsNonRecursive(String resourceId,
+ Map<String, RequirementDefinition> requirements, Set<String> caseInsensitiveReqNames) {
+ Either<List<ImmutablePair<RequirementData, GraphEdge>>, TitanOperationStatus> requirementNodes = titanGenericDao
+ .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId,
+ GraphEdgeLabels.REQUIREMENT, NodeTypeEnum.Requirement, RequirementData.class);
+
+ if (requirementNodes.isRight()) {
+ TitanOperationStatus status = requirementNodes.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ return status;
+ }
+ } else {
+ List<ImmutablePair<RequirementData, GraphEdge>> requirementList = requirementNodes.left().value();
+ if (requirementList != null) {
+ for (ImmutablePair<RequirementData, GraphEdge> requirementPair : requirementList) {
+ String reqUniqueId = requirementPair.getKey().getUniqueId();
+ Map<String, Object> edgeProps = requirementPair.getValue().getProperties();
+ String reqName = null;
+ if (edgeProps != null) {
+ reqName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty());
+ if (reqName == null) {
+ log.error("The requirement name is missing on the edge of requirement " + reqUniqueId);
+ return TitanOperationStatus.INVALID_ELEMENT;
+ }
+ } else {
+ log.error("The requirement name is missing on the edge of requirement " + reqUniqueId);
+ return TitanOperationStatus.INVALID_ELEMENT;
+ }
+ Either<RequirementDefinition, TitanOperationStatus> requirementDefRes = this
+ .getRequirement(reqUniqueId);
+ if (requirementDefRes.isRight()) {
+ TitanOperationStatus status = requirementDefRes.right().value();
+ log.error("Failed to get requirement properties of requirement " + reqUniqueId);
+ return status;
+ }
+
+ RequirementDefinition requirementDefinition = requirementDefRes.left().value();
+ requirementDefinition.setName(reqName);
+ // US631462
+ if (caseInsensitiveReqNames.contains(reqName.toLowerCase())) {
+ log.debug(
+ "The requirement {} was already defined in derived resource (case insensitive). Ignore {} from resource {}",
+ reqName, reqName, resourceId);
+ } else {
+ requirements.put(reqName, requirementDefinition);
+ caseInsensitiveReqNames.add(reqName.toLowerCase());
+ }
+
+ }
+ }
+ }
+ return TitanOperationStatus.OK;
+ }
+
+ public StorageOperationStatus deleteRequirementFromGraph(String requirementId) {
+ log.debug("Before deleting requirement from graph " + requirementId);
+ Either<RequirementData, TitanOperationStatus> deleteNodeStatus = titanGenericDao.deleteNode(
+ UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementId, RequirementData.class);
+ if (deleteNodeStatus.isRight()) {
+ log.error("failed to delete requirement with id {}. status={}", requirementId,
+ deleteNodeStatus.right().value());
+ return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNodeStatus.right().value());
+ }
+ return StorageOperationStatus.OK;
+ }
+
+ public Either<Map<String, RequirementDefinition>, StorageOperationStatus> deleteAllRequirements(String resourceId) {
+
+ return getAllResourceRequirements(resourceId, false);
+
+ }
+
+ public Either<Map<String, RequirementDefinition>, StorageOperationStatus> deleteAllRequirements(String resourceId,
+ boolean inTransaction) {
+
+ Either<Map<String, RequirementDefinition>, StorageOperationStatus> result = null;
+
+ try {
+ Either<Map<String, RequirementDefinition>, TitanOperationStatus> deleteAllRes = deleteAllRequirementsOfResource(
+ resourceId);
+ if (deleteAllRes.isRight()) {
+ TitanOperationStatus status = deleteAllRes.right().value();
+ if (status != TitanOperationStatus.NOT_FOUND) {
+ log.error("Failed to delete requirements of resource " + resourceId + ". status is " + status);
+ }
+ result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
+ return result;
+ }
+
+ Map<String, RequirementDefinition> value = deleteAllRes.left().value();
+ result = Either.left(value);
+
+ 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();
+ }
+ }
+ }
+
+ }
+
+ public Either<Map<String, RequirementDefinition>, TitanOperationStatus> deleteAllRequirementsOfResource(
+ String resourceId) {
+
+ Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>();
+ Set<String> caseInsensitiveReqNames = new HashSet<>();
+ TitanOperationStatus requirementsRes = findAllRequirementsNonRecursive(resourceId, requirements,
+ caseInsensitiveReqNames);
+ if (requirementsRes != TitanOperationStatus.OK) {
+ return Either.right(requirementsRes);
+ }
+
+ if (requirements.isEmpty()) {
+ return Either.right(TitanOperationStatus.NOT_FOUND);
+ }
+
+ for (Entry<String, RequirementDefinition> entry : requirements.entrySet()) {
+ RequirementDefinition requirementDefinition = entry.getValue();
+
+ String requirementUid = requirementDefinition.getUniqueId();
+
+ Either<RequirementData, TitanOperationStatus> deleteNodeRes = titanGenericDao.deleteNode(
+ UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementUid, RequirementData.class);
+ if (deleteNodeRes.isRight()) {
+ TitanOperationStatus status = deleteNodeRes.right().value();
+ log.error("Failed to delete requirement " + requirementUid + " of resource " + resourceId);
+ return Either.right(status);
+ }
+ }
+
+ return Either.left(requirements);
+
+ }
+
+ public Map<String, List<RequirementDefinition>> convertRequirementMap(
+ Map<String, RequirementDefinition> requirementMap, String ownerId, String ownerName) {
+
+ Map<String, List<RequirementDefinition>> typeToRequirementMap = new HashMap<String, List<RequirementDefinition>>();
+ requirementMap.forEach((reqName, requirement) -> {
+ // requirement.setOwnerId(ownerId);
+ // requirement.setOwnerName(ownerName);
+ if (typeToRequirementMap.containsKey(requirement.getCapability())) {
+ typeToRequirementMap.get(requirement.getCapability()).add(requirement);
+ } else {
+ List<RequirementDefinition> list = new ArrayList<RequirementDefinition>();
+ list.add(requirement);
+ typeToRequirementMap.put(requirement.getCapability(), list);
+ }
+ });
+ return typeToRequirementMap;
+ }
+
+}