Support adding of relationship type to model 64/121664/3
authorMichaelMorris <michael.morris@est.tech>
Wed, 19 May 2021 16:23:13 +0000 (17:23 +0100)
committerChristophe Closset <christophe.closset@intl.att.com>
Tue, 8 Jun 2021 06:57:34 +0000 (06:57 +0000)
Signed-off-by: MichaelMorris <michael.morris@est.tech>
Issue-ID: SDC-3610
Change-Id: If315e21fa40e491cb1977dd9ceaf3e9b607e2f6f

catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RelationshipTypeImportManager.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/RelationshipTypeImportManagerTest.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/janusgraph/JanusGraphGenericDao.java
catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java
catalog-dao/src/test/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabelsTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipTypeDefinition.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java
catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RelationshipTypeOperationTest.java
common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/FunctionalInterfaces.java

index 6e4d554..dafd791 100644 (file)
@@ -25,6 +25,7 @@ import org.openecomp.sdc.be.impl.ComponentsUtils;
 import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
 import org.openecomp.sdc.be.model.operations.impl.RelationshipTypeOperation;
+import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.utils.TypeUtils;
 import org.openecomp.sdc.exception.ResponseFormat;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -45,27 +46,31 @@ public class RelationshipTypeImportManager {
         this.componentsUtils = componentsUtils;
     }
 
-    public Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypes(String relationshipYml) {
-        return createRelationshipTypes(relationshipYml, false);
+    public Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypes(final String relationshipYml, final String modelName) {
+        return createRelationshipTypes(relationshipYml, modelName, false);
     }
 
-    private Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypes(String relationshipTypeYml,
-                                                                                                                     boolean inTransaction) {
+    private Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypes(final String relationshipTypeYml,
+                                                                                                                     final String modelName, final boolean inTransaction) {
         return commonImportManager
-            .createElementTypes(relationshipTypeYml, relationshipTypesFromYml -> createRelationshipTypesFromYml(relationshipTypeYml),
+            .createElementTypes(relationshipTypeYml, relationshipTypesFromYml -> createRelationshipTypesFromYml(relationshipTypeYml, modelName),
                 relationshipTypesToCreate -> createRelationshipTypesByDao(relationshipTypesToCreate, inTransaction),
                 ElementTypeEnum.RELATIONSHIP_TYPE);
     }
 
-    private Either<List<RelationshipTypeDefinition>, ActionStatus> createRelationshipTypesFromYml(String relationshipTypeYml) {
-        return commonImportManager.createElementTypesFromYml(relationshipTypeYml, this::createRelationshipType);
+    private Either<List<RelationshipTypeDefinition>, ActionStatus> createRelationshipTypesFromYml(final String relationshipTypeYml, final String modelName) {
+        final Either<List<RelationshipTypeDefinition>, ActionStatus> relationshipTypes =  commonImportManager.createElementTypesFromYml(relationshipTypeYml, this::createRelationshipType);
+        if (relationshipTypes.isLeft()){
+            relationshipTypes.left().value().forEach(relationshipType -> relationshipType.setModel(modelName));
+        }
+        return relationshipTypes;
     }
 
     private Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat> createRelationshipTypesByDao(
         List<RelationshipTypeDefinition> relationshipTypesToCreate, boolean inTransaction) {
         return commonImportManager.createElementTypesByDao(relationshipTypesToCreate, this::validateRelationshipType,
-            relationshipType -> new ImmutablePair<>(ElementTypeEnum.RELATIONSHIP_TYPE, relationshipType.getType()),
-            relationshipTypeName -> relationshipTypeOperation.getRelationshipTypeByName(relationshipTypeName).right()
+            relationshipType -> new ImmutablePair<>(ElementTypeEnum.RELATIONSHIP_TYPE, UniqueIdBuilder.buildRelationshipTypeUid(relationshipType.getModel(), relationshipType.getType())),
+            relationshipTypeUid -> relationshipTypeOperation.getRelationshipTypeByUid(relationshipTypeUid).right()
                 .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus),
             relationshipType -> relationshipTypeOperation.addRelationshipType(relationshipType, inTransaction),
             (newRelationshipType, oldRelationshipType) -> relationshipTypeOperation
index d98928c..1ca1833 100644 (file)
@@ -76,6 +76,7 @@ import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.normatives.ToscaTypeMetadata;
 import org.openecomp.sdc.be.user.UserBusinessLogic;
 import org.openecomp.sdc.common.api.Constants;
+import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerThreeParam;
 import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerTwoParam;
 import org.openecomp.sdc.common.datastructure.Wrapper;
 import org.openecomp.sdc.common.log.wrappers.Logger;
@@ -145,8 +146,9 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
         @ApiResponse(responseCode = "409", description = "Relationship Type already exist")})
     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
     public Response uploadRelationshipType(@Parameter(description = "FileInputStream") @FormDataParam("relationshipTypeZip") File file,
-                                           @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) {
-        return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator, NodeTypeEnum.RelationshipType.getName());
+                                           @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
+                                           @Parameter(description = "model") @FormDataParam("model") String modelName) {
+        return uploadElementTypeServletLogic(this::createRelationshipTypes, file, request, creator, NodeTypeEnum.RelationshipType.getName(), modelName);
     }
 
     @POST
@@ -234,7 +236,7 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
     }
 
     private Response uploadElementTypeServletLogic(ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod, File file,
-                                                   final HttpServletRequest request, String creator, String elementTypeName) {
+            final HttpServletRequest request, String creator, String elementTypeName) {
         init();
         String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
         try {
@@ -255,6 +257,29 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
             return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
         }
     }
+    
+    private Response uploadElementTypeServletLogic(final ConsumerThreeParam<Wrapper<Response>, String, String> createElementsMethod,
+            final File file, final HttpServletRequest request, final String creator, final String elementTypeName, final String modelName) {
+        init();
+        final String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER);
+        try {
+            final Wrapper<String> yamlStringWrapper = new Wrapper<>();
+            final String url = request.getMethod() + " " + request.getRequestURI();
+            log.debug("Start handle request of {}", url);
+            final Wrapper<Response> responseWrapper = doUploadTypeValidations(request, userId, file);
+            if (responseWrapper.isEmpty()) {
+                fillZipContents(yamlStringWrapper, file);
+            }
+            if (responseWrapper.isEmpty()) {
+                createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement(), modelName);
+            }
+            return responseWrapper.getInnerElement();
+        } catch (final Exception e) {
+            log.debug("create {} failed with exception:", elementTypeName, e);
+            BeEcompErrorManager.getInstance().logBeRestApiGeneralError(CREATE + elementTypeName);
+            return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR));
+        }
+    }
 
     private Wrapper<Response> doUploadTypeValidations(final HttpServletRequest request, String userId, File file) {
         Wrapper<Response> responseWrapper = new Wrapper<>();
@@ -384,9 +409,9 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
     }
 
     // relationship types
-    private void createRelationshipTypes(Wrapper<Response> responseWrapper, String relationshipTypesYml) {
+    private void createRelationshipTypes(final Wrapper<Response> responseWrapper, final String relationshipTypesYml, final String modelName) {
         final Supplier<Either<List<ImmutablePair<RelationshipTypeDefinition, Boolean>>, ResponseFormat>> generateElementTypeFromYml = () -> relationshipTypeImportManager
-            .createRelationshipTypes(relationshipTypesYml);
+            .createRelationshipTypes(relationshipTypesYml, modelName);
         buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.RELATIONSHIP_TYPE_ALREADY_EXIST,
             NodeTypeEnum.RelationshipType.name());
     }
index 0fb17c4..a4ee779 100644 (file)
@@ -41,7 +41,7 @@ public class RelationshipTypeImportManagerTest {
     public void shouldInvokeCreateElementTypes() {
         RelationshipTypeImportManager relationshipTypeImportManager =
             new RelationshipTypeImportManager(relationshipTypeOperation, commonImportManager, componentsUtils);
-        relationshipTypeImportManager.createRelationshipTypes("anyYaml");
+        relationshipTypeImportManager.createRelationshipTypes("anyYaml", "anyModel");
         Mockito.verify(commonImportManager).createElementTypes(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
 
     }
index 0b2a8e1..19f78ce 100644 (file)
@@ -26,9 +26,12 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.StreamSupport;
 import javax.validation.constraints.NotNull;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.ImmutableTriple;
 import org.apache.tinkerpop.gremlin.structure.Direction;
@@ -51,6 +54,7 @@ import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint;
+import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -313,17 +317,38 @@ public class JanusGraphGenericDao {
      * @return
      */
     public <T extends GraphNode> Either<T, JanusGraphOperationStatus> getNode(String keyName, Object keyValue, Class<T> clazz) {
+      log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue);
+      Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
+      if (vertexByProperty.isLeft()) {
+          try {
+              Vertex vertex = vertexByProperty.left().value();
+              Map<String, Object> properties = getProperties(vertex);
+              T node = GraphElementFactory
+                  .createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties,
+                      clazz);
+              return Either.left(node);
+          } catch (Exception e) {
+              log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e);
+              return Either.right(JanusGraphClient.handleJanusGraphException(e));
+          }
+      } else {
+          log.debug("Failed to get node for key [{}] with value [{}]  ", keyName, keyValue, vertexByProperty.right().value());
+          return Either.right(vertexByProperty.right().value());
+      }
+    }
+    
+    public <T extends GraphNode> Either<T, JanusGraphOperationStatus> getNode(final String keyName, final Object keyValue, final Class<T> clazz, final String model) {
         log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue);
-        Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
+        final Either<JanusGraphVertex, JanusGraphOperationStatus> vertexByProperty = getVertexByPropertyForModel(keyName, keyValue, model);
         if (vertexByProperty.isLeft()) {
             try {
-                Vertex vertex = vertexByProperty.left().value();
-                Map<String, Object> properties = getProperties(vertex);
-                T node = GraphElementFactory
+                final Vertex vertex = vertexByProperty.left().value();
+                final Map<String, Object> properties = getProperties(vertex);
+                final T node = GraphElementFactory
                     .createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties,
                         clazz);
                 return Either.left(node);
-            } catch (Exception e) {
+            } catch (final Exception e) {
                 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e);
                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
             }
@@ -601,23 +626,48 @@ public class JanusGraphGenericDao {
             return Either.right(graph.right().value());
         }
     }
+    
+    public Either<JanusGraphVertex, JanusGraphOperationStatus> getVertexByPropertyForModel(final String name, final Object value, final String model) {
+        final Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> vertices = getVerticesByProperty(name, value);
+              
+        if (vertices.isLeft()) {
+            final Predicate<? super JanusGraphVertex> filterPredicate = StringUtils.isEmpty(model) ? this::vertexNotConnectedToAnyModel : vertex -> vertexValidForModel(vertex, model);
+            final List<JanusGraphVertex> verticesForModel = StreamSupport.stream(vertices.left().value().spliterator(), false).filter(filterPredicate).collect(Collectors.toList());
+        
+            if (CollectionUtils.isEmpty(verticesForModel)) {
+                if (log.isDebugEnabled()) {
+                    log.debug("No vertex in graph for key ={} and value = {}", name, value);
+                }
+                return Either.right(JanusGraphOperationStatus.NOT_FOUND);
+            }
+            return Either.left(verticesForModel.get(0));
+        }
+        return Either.right(vertices.right().value());
+    }
+    
+    public Either<JanusGraphVertex, JanusGraphOperationStatus> getVertexByProperty(final String name, final Object value) {
+        final Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> vertices = getVerticesByProperty(name, value);
+        if (vertices.isLeft()) {
+            return Either.left(vertices.left().value().iterator().next());
+        }
+        return Either.right(vertices.right().value());
+    }
 
-    public Either<JanusGraphVertex, JanusGraphOperationStatus> getVertexByProperty(String name, Object value) {
-        Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
+    
+    public Either<Iterable<JanusGraphVertex>, JanusGraphOperationStatus> getVerticesByProperty(final String name, final Object value) {
+        final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
         if (value == null) {
             if (log.isDebugEnabled()) {
                 log.debug("No vertex in graph for key = {} and value = {}", name, value);
             }
-            return Either.right(JanusGraphOperationStatus.NOT_FOUND);
+          return Either.right(JanusGraphOperationStatus.NOT_FOUND);
         }
         if (graph.isLeft()) {
             try {
-                JanusGraph tGraph = graph.left().value();
-                @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertecies = tGraph.query().has(name, value).vertices();
-                java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
-                if (iterator.hasNext()) {
-                    JanusGraphVertex vertex = iterator.next();
-                    return Either.left(vertex);
+                final JanusGraph tGraph = graph.left().value();
+                @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = tGraph.query().has(name, value).vertices();
+                if (vertices.iterator().hasNext()) {
+                    return Either.left(vertices);
                 } else {
                     if (log.isDebugEnabled()) {
                         log.debug("No vertex in graph for key ={} and value = {}", name, value);
@@ -637,6 +687,24 @@ public class JanusGraphGenericDao {
             return Either.right(graph.right().value());
         }
     }
+    
+    private boolean vertexValidForModel(final JanusGraphVertex vertex, final String model) {
+        final Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> modelVertices = getParentVerticies(vertex, GraphEdgeLabels.MODEL_ELEMENT);
+
+        if (modelVertices.isLeft()) {
+            for (ImmutablePair<JanusGraphVertex, Edge> vertexPair : modelVertices.left().value()) {
+                if (model.equals((String)vertexPair.getLeft().property("name").value())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+    
+    private boolean vertexNotConnectedToAnyModel(final JanusGraphVertex vertex) {
+        return !vertex.edges(Direction.IN, EdgeLabelEnum.MODEL_ELEMENT.name()).hasNext();
+    }
+
 
     public <T extends GraphNode> Either<List<T>, JanusGraphOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> hasProps,
                                                                                           Map<String, Object> hasNotProps, Class<T> clazz) {
@@ -1220,12 +1288,27 @@ public class JanusGraphGenericDao {
         if (vertices == null || !vertices.iterator().hasNext()) {
             return Either.right(JanusGraphOperationStatus.INVALID_ID);
         }
-        Vertex rootVertex = vertices.iterator().next();
-        Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
+        return getChildrenVerticies(vertices.iterator().next(), edgeType);
+    }
+    
+    public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getChildrenVerticies(
+            final JanusGraphVertex rootVertex, final GraphEdgeLabels edgeType) {
+        return getEdgeVerticies(rootVertex, Direction.OUT, edgeType);
+    }
+       
+    public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getParentVerticies(
+            final JanusGraphVertex rootVertex, final GraphEdgeLabels edgeType) {
+        return getEdgeVerticies(rootVertex, Direction.IN, edgeType);
+    }
+       
+    public Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getEdgeVerticies(
+            final JanusGraphVertex rootVertex, final Direction direction, final GraphEdgeLabels edgeType) {
+        final List<ImmutablePair<JanusGraphVertex, Edge>> immutablePairs = new ArrayList<>();
+        final Iterator<Edge> edgesCreatorIterator = rootVertex.edges(direction, edgeType.getProperty());
         if (edgesCreatorIterator != null) {
             while (edgesCreatorIterator.hasNext()) {
                 Edge edge = edgesCreatorIterator.next();
-                JanusGraphVertex vertex = (JanusGraphVertex) edge.inVertex();
+                JanusGraphVertex vertex = Direction.OUT.equals(direction)? (JanusGraphVertex) edge.inVertex() : (JanusGraphVertex) edge.outVertex();
                 ImmutablePair<JanusGraphVertex, Edge> immutablePair = new ImmutablePair<>(vertex, edge);
                 immutablePairs.add(immutablePair);
             }
index 2ebfbe0..7dbcc87 100644 (file)
@@ -70,6 +70,7 @@ public enum GraphEdgeLabels {
     GENERATED_FROM("GENERATED_FROM"),
     PARAMETER_VALUE("PARAMETER_VALUE"),
     PARAMETER_IMPL("PARAMETER_IMPL"),
+    MODEL_ELEMENT("MODEL_ELEMENT"),
     // VF additions
     CALCULATED_REQUIREMENT("CALCULATED_REQUIREMENT"),
     CALCULATED_CAPABILITY("CALCULATED_CAPABILITY"),
index c5723b1..bfa9409 100644 (file)
@@ -28,7 +28,7 @@ import static org.junit.jupiter.api.Assertions.assertNull;
 public class GraphEdgeLabelsTest {
        @Test
        public void testGetAllProperties() throws Exception {
-               assertEquals(55, GraphEdgeLabels.getAllProperties().size());
+               assertEquals(56, GraphEdgeLabels.getAllProperties().size());
        }
 
        @Test
index fd988fa..08a0442 100644 (file)
@@ -18,14 +18,21 @@ package org.openecomp.sdc.be.model;
 import java.util.Map;
 import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
 import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
+import lombok.Getter;
+import lombok.Setter;
+import lombok.ToString;
 
 /**
  * Specifies the capabilities that the Node Type exposes.
  */
+@Getter
+@Setter
+@ToString(callSuper = true)
 public class RelationshipTypeDefinition extends RelationshipInstDataDefinition {
 
     private String derivedFrom;
     private Map<String, PropertyDefinition> properties;
+    private String model;
 
     public RelationshipTypeDefinition() {
         super();
@@ -42,24 +49,4 @@ public class RelationshipTypeDefinition extends RelationshipInstDataDefinition {
         this.setValidSourceTypes(relationshipTypeData.getRelationshipTypeDataDefinition().getValidSourceTypes());
     }
 
-    public String getDerivedFrom() {
-        return derivedFrom;
-    }
-
-    public void setDerivedFrom(String derivedFrom) {
-        this.derivedFrom = derivedFrom;
-    }
-
-    public Map<String, PropertyDefinition> getProperties() {
-        return properties;
-    }
-
-    public void setProperties(Map<String, PropertyDefinition> properties) {
-        this.properties = properties;
-    }
-
-    @Override
-    public String toString() {
-        return super.toString() + " [ derivedFrom=" + derivedFrom + ", properties=" + properties + " ]";
-    }
 }
index 7fab326..f02fc2d 100644 (file)
  */
 package org.openecomp.sdc.be.model.operations.impl;
 
+import static org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR;
+
 import fj.data.Either;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
+import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.RelationshipTypeDefinition;
 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
+import org.openecomp.sdc.be.resources.data.ModelData;
 import org.openecomp.sdc.be.resources.data.PropertyData;
 import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
+import org.openecomp.sdc.be.resources.data.UniqueIdData;
 import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
@@ -53,19 +60,6 @@ public class RelationshipTypeOperation extends AbstractOperation {
     @Autowired
     private DerivedFromOperation derivedFromOperation;
 
-    public Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeByName(String name) {
-        String uid = UniqueIdBuilder.buildRelationshipTypeUid(name);
-        Either<RelationshipTypeDefinition, JanusGraphOperationStatus> result = getRelationshipTypeByUid(uid);
-        if (result.isRight()) {
-            JanusGraphOperationStatus status = result.right().value();
-            if (status != JanusGraphOperationStatus.NOT_FOUND) {
-                logger.error("Failed to get information on relationship type {} status is {}", name, status);
-            }
-            return Either.right(status);
-        }
-        return Either.left(result.left().value());
-    }
-
     public Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeByUid(String uniqueId) {
         Either<RelationshipTypeDefinition, JanusGraphOperationStatus> result;
         Either<RelationshipTypeData, JanusGraphOperationStatus> relationshipTypesRes = janusGraphGenericDao
@@ -75,28 +69,30 @@ public class RelationshipTypeOperation extends AbstractOperation {
             logger.debug("Relationship type {} cannot be found in graph. status is {}", uniqueId, status);
             return Either.right(status);
         }
-        RelationshipTypeData relationshipTypeData = relationshipTypesRes.left().value();
+        return getRelationshipTypeDefinition(relationshipTypesRes.left().value());
+    }
+    
+    public Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeDefinition(final RelationshipTypeData relationshipTypeData) {
         RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition(
             relationshipTypeData.getRelationshipTypeDataDefinition());
         Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus = OperationUtils
-            .fillProperties(uniqueId, propertyOperation, NodeTypeEnum.RelationshipType);
+            .fillProperties(relationshipTypeData.getUniqueId(), propertyOperation, NodeTypeEnum.RelationshipType);
         if (propertiesStatus.isRight() && propertiesStatus.right().value() != JanusGraphOperationStatus.OK) {
-            logger.error("Failed to fetch properties of relationship type {}", uniqueId);
+            logger.error(BUSINESS_PROCESS_ERROR, "Failed to fetch properties of relationship type {}", relationshipTypeData.getUniqueId());
             return Either.right(propertiesStatus.right().value());
         }
         if (propertiesStatus.isLeft()) {
             relationshipTypeDefinition.setProperties(propertiesStatus.left().value());
         }
         Either<ImmutablePair<RelationshipTypeData, GraphEdge>, JanusGraphOperationStatus> parentNode = janusGraphGenericDao
-            .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
+            .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), relationshipTypeData.getUniqueId(), GraphEdgeLabels.DERIVED_FROM,
                 NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
-        logger.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
+        logger.debug("After retrieving DERIVED_FROM node of {}. status is {}", relationshipTypeData.getUniqueId(), parentNode);
         if (parentNode.isRight()) {
             JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
             if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
-                logger.error("Failed to find the parent relationship of relationship type {}. status is {}", uniqueId, janusGraphOperationStatus);
-                result = Either.right(janusGraphOperationStatus);
-                return result;
+                logger.error(BUSINESS_PROCESS_ERROR, "Failed to find the parent relationship of relationship type {}. status is {}", relationshipTypeData.getUniqueId(), janusGraphOperationStatus);
+                return Either.right(janusGraphOperationStatus);
             }
         } else {
             // derived from node was found
@@ -104,16 +100,28 @@ public class RelationshipTypeOperation extends AbstractOperation {
             RelationshipTypeData parentCT = immutablePair.getKey();
             relationshipTypeDefinition.setDerivedFrom(parentCT.getRelationshipTypeDataDefinition().getType());
         }
-        result = Either.left(relationshipTypeDefinition);
-        return result;
+        
+        final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> model = janusGraphGenericDao.getParentNode(
+            UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipType), relationshipTypeData.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, 
+            NodeTypeEnum.Model, ModelData.class);
+        if (model.isLeft()) {
+            relationshipTypeDefinition.setModel(model.left().value().getLeft().getName());
+        }
+        return Either.left(relationshipTypeDefinition);
     }
 
     private Either<RelationshipTypeDefinition, StorageOperationStatus> validateUpdateProperties(
         RelationshipTypeDefinition relationshipTypeDefinition) {
         JanusGraphOperationStatus error = null;
         if (MapUtils.isNotEmpty(relationshipTypeDefinition.getProperties()) && relationshipTypeDefinition.getDerivedFrom() != null) {
+            final Either<RelationshipTypeData, JanusGraphOperationStatus> derivedFromNode = janusGraphGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), 
+                relationshipTypeDefinition.getDerivedFrom(), RelationshipTypeData.class, relationshipTypeDefinition.getModel());
+            if (derivedFromNode.isRight()) {
+                logger.error(BUSINESS_PROCESS_ERROR, "Failed to find the derived from type for  {}. status is {}", relationshipTypeDefinition.getUniqueId(), derivedFromNode.right().value());
+                return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(derivedFromNode.right().value()));
+            }
             Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesRes = getAllRelationshipTypePropertiesFromAllDerivedFrom(
-                relationshipTypeDefinition.getDerivedFrom());
+                derivedFromNode.left().value().getUniqueId());
             if (allPropertiesRes.isRight() && !JanusGraphOperationStatus.NOT_FOUND.equals(allPropertiesRes.right().value())) {
                 error = allPropertiesRes.right().value();
                 logger.debug("Couldn't fetch derived from property nodes for relationship type {}, error: {}", relationshipTypeDefinition.getType(),
@@ -146,8 +154,8 @@ public class RelationshipTypeOperation extends AbstractOperation {
     }
 
     private Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getAllRelationshipTypePropertiesFromAllDerivedFrom(
-        String firstParentType) {
-        return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+        String firstParentUid) {
+        return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentUid, NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
     }
 
     public Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType(RelationshipTypeDefinition relationshipTypeDefinition,
@@ -204,7 +212,7 @@ public class RelationshipTypeOperation extends AbstractOperation {
 
     private Either<RelationshipTypeData, StorageOperationStatus> addRelationshipTypeToGraph(RelationshipTypeDefinition relationshipTypeDefinition) {
         logger.debug("Got relationship type {}", relationshipTypeDefinition);
-        String ctUniqueId = UniqueIdBuilder.buildRelationshipTypeUid(relationshipTypeDefinition.getType());
+        String ctUniqueId = UniqueIdBuilder.buildRelationshipTypeUid(relationshipTypeDefinition.getModel(), relationshipTypeDefinition.getType());
         RelationshipTypeData relationshipTypeData = buildRelationshipTypeData(relationshipTypeDefinition, ctUniqueId);
         logger.debug("Before adding relationship type to graph. relationshipTypeData = {}", relationshipTypeData);
         Either<RelationshipTypeData, JanusGraphOperationStatus> createCTResult = janusGraphGenericDao
@@ -223,6 +231,11 @@ public class RelationshipTypeOperation extends AbstractOperation {
             logger.error("Failed add properties {} to relationship {}", propertiesMap, relationshipTypeDefinition.getType());
             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToRelationshipType.right().value()));
         }
+        final Either<GraphRelation, StorageOperationStatus> modelRelationship = addRelationshipToModel(relationshipTypeDefinition);
+        if (modelRelationship.isRight()) {
+            return Either.right(modelRelationship.right().value());
+        }
+
         return addDerivedFromRelation(relationshipTypeDefinition, ctUniqueId).left().map(updatedDerivedFrom -> createCTResult.left().value());
     }
 
@@ -246,14 +259,31 @@ public class RelationshipTypeOperation extends AbstractOperation {
         }
         logger.debug("#addDerivedFromRelation - adding derived from relation between relationship type {} to its parent " + "{}",
             relationshipTypeDefinition.getType(), derivedFrom);
-        return getRelationshipTypeByType(derivedFrom).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus).left().bind(
+        return getRelationshipTypeByTypeAndModel(derivedFrom, relationshipTypeDefinition.getModel()).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus).left().bind(
             derivedFromRelationship -> derivedFromOperation
                 .addDerivedFromRelation(relationshipTypeUniqueId, derivedFromRelationship.getUniqueId(), NodeTypeEnum.RelationshipType));
     }
+    
+    private Either<GraphRelation, StorageOperationStatus> addRelationshipToModel(final RelationshipTypeDefinition relationshipTypeDefinition) {
+        final String model = relationshipTypeDefinition.getModel();
+        if (model == null) {
+            return Either.left(null);
+        }
+        final GraphNode from = new UniqueIdData(NodeTypeEnum.Model, UniqueIdBuilder.buildModelUid(model));
+        final GraphNode to = new UniqueIdData(NodeTypeEnum.RelationshipType, relationshipTypeDefinition.getUniqueId());
+        logger.info("Connecting model {} to type {}", from, to);
+        return janusGraphGenericDao.createRelation(from , to, GraphEdgeLabels.MODEL_ELEMENT, Collections.emptyMap()).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
+    }
 
-    private Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeByType(String relationshipType) {
-        // Optimization: In case of Relationship Type its unique ID is the same as type
-        return getRelationshipTypeByUid(relationshipType);
+    private Either<RelationshipTypeDefinition, JanusGraphOperationStatus> getRelationshipTypeByTypeAndModel(final String relationshipType, final String model) {
+        final Either<RelationshipTypeData, JanusGraphOperationStatus> relationshipTypesRes = janusGraphGenericDao
+            .getNode(GraphPropertiesDictionary.TYPE.getProperty(), relationshipType, RelationshipTypeData.class, model);
+        if (relationshipTypesRes.isRight()) {
+            final JanusGraphOperationStatus status = relationshipTypesRes.right().value();
+            logger.debug("Relationship type {} cannot be found in graph. status is {}", relationshipType, status);
+            return Either.right(status);
+        }
+        return getRelationshipTypeDefinition(relationshipTypesRes.left().value());
     }
 
     public Either<RelationshipTypeDefinition, StorageOperationStatus> updateRelationshipType(RelationshipTypeDefinition newRelationshipTypeDefinition,
@@ -300,7 +330,7 @@ public class RelationshipTypeOperation extends AbstractOperation {
         logger.debug("#updateRelationshipTypeDerivedFrom - updating relationship derived from relation for relationship "
                 + "type with id {}. old derived type {}. new derived type {}", relationshipTypeId, currDerivedFromRelationshipType,
             newRelationshipTypeDefinition.getDerivedFrom());
-        StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromRelationshipType(relationshipTypeId, currDerivedFromRelationshipType);
+        StorageOperationStatus deleteDerivedRelationStatus = deleteDerivedFromRelationshipType(relationshipTypeId, newRelationshipTypeDefinition.getModel(), currDerivedFromRelationshipType);
         if (deleteDerivedRelationStatus != StorageOperationStatus.OK) {
             return Either.right(deleteDerivedRelationStatus);
         }
@@ -322,14 +352,14 @@ public class RelationshipTypeOperation extends AbstractOperation {
             .map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
     }
 
-    private StorageOperationStatus deleteDerivedFromRelationshipType(String relationshipTypeId, String derivedFromType) {
+    private StorageOperationStatus deleteDerivedFromRelationshipType(final String relationshipTypeId, final String modelName, final String derivedFromType) {
         if (derivedFromType == null) {
             return StorageOperationStatus.OK;
         }
         logger
             .debug("#deleteDerivedFromRelationshipType - deleting derivedFrom relation for relationship type with id " + "{} and its derived type {}",
                 relationshipTypeId, derivedFromType);
-        return getRelationshipTypeByType(derivedFromType).either(derivedFromNode -> derivedFromOperation
+        return getRelationshipTypeByTypeAndModel(derivedFromType, modelName).either(derivedFromNode -> derivedFromOperation
                 .removeDerivedFromRelation(relationshipTypeId, derivedFromNode.getUniqueId(), NodeTypeEnum.RelationshipType),
             DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
     }
index 62404aa..77b28c7 100644 (file)
@@ -22,6 +22,7 @@ package org.openecomp.sdc.be.model.operations.impl;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
+import org.apache.commons.lang.StringUtils;
 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
@@ -92,8 +93,8 @@ public class UniqueIdBuilder {
         return type;
     }
 
-    static String buildRelationshipTypeUid(String type) {
-        return type;
+    public static String buildRelationshipTypeUid(final String modelName, final String type) {
+        return StringUtils.isEmpty(modelName) ? type : modelName + DOT + type;
     }
 
     public static String buildAttributeUid(String resourceId, String attName) {
index 30463e9..1cc1336 100644 (file)
@@ -43,9 +43,11 @@ import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
 import org.mockito.Spy;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
 import org.openecomp.sdc.be.dao.janusgraph.HealingJanusGraphGenericDao;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
+import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.datatypes.elements.RelationshipInstDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.ModelTestBase;
@@ -58,6 +60,7 @@ import org.openecomp.sdc.be.model.tosca.ToscaType;
 import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint;
 import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint;
 import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint;
+import org.openecomp.sdc.be.resources.data.ModelData;
 import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -68,6 +71,8 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
 
     private static final String PROP = "prop";
 
+    private static final String DOT = ".";
+
     @Mock
     HealingJanusGraphGenericDao janusGraphGenericDao;
 
@@ -104,16 +109,6 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
         Mockito.doReturn(JanusGraphOperationStatus.OK).when(janusGraphGenericDao).rollback();
     }
 
-    @Test
-    public void getRelationshipTypeByNameNotCreated() {
-        Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_CREATED))
-                .when(relationshipTypeOperation).getRelationshipTypeByUid(Mockito.anyString());
-
-        Either<RelationshipTypeDefinition, JanusGraphOperationStatus> either =
-                relationshipTypeOperation.getRelationshipTypeByName("name");
-        assertTrue(either.isRight());
-    }
-
     @Test
     public void testDummy() {
         assertNotNull(relationshipTypeOperation);
@@ -124,6 +119,12 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
         Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_CONNECTED))
                 .when(propertyOperation)
                 .getAllTypePropertiesFromAllDerivedFrom(Mockito.anyString(), Mockito.any(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition)))
+                .when(janusGraphGenericDao).getNode(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(Collections.singletonMap("derivedFromProp1", new PropertyDefinition()))).when(propertyOperation)
+                .findPropertiesOfNode(Mockito.any(), Mockito.anyString());
 
 
         Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType =
@@ -138,6 +139,12 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
                 .getAllTypePropertiesFromAllDerivedFrom(Mockito.anyString(), Mockito.any(), Mockito.any());
         Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)).when(propertyOperation)
                 .validatePropertiesUniqueness(Mockito.any(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition)))
+                .when(janusGraphGenericDao).getNode(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(Collections.singletonMap("derivedFromProp1", new PropertyDefinition()))).when(propertyOperation)
+                .findPropertiesOfNode(Mockito.any(), Mockito.anyString());
 
         Either<RelationshipTypeDefinition, StorageOperationStatus> addRelationshipType =
                 relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, false);
@@ -346,6 +353,8 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
         RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition(relationshipTypeData);
         relationshipTypeDefinition.setProperties(createPropertyData("prop1"));
         relationshipTypeDefinition.setDerivedFrom("tosca.relationships.Root");
+       
+
 
         Mockito.doReturn(Either.left(Collections.singletonMap("prop1", new PropertyDefinition()))).when(propertyOperation)
                 .getAllTypePropertiesFromAllDerivedFrom(Mockito.anyString(), Mockito.any(), Mockito.any());
@@ -355,7 +364,7 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
 
         Mockito.doReturn(Either.left(relationshipTypeData)).when(janusGraphGenericDao)
                 .createNode(Mockito.any(), Mockito.eq(RelationshipTypeData.class));
-
+        
         Mockito.doReturn(Either.left(new HashMap())).when(propertyOperation)
                 .addPropertiesToElementType(Mockito.anyString(), Mockito.any(), Mockito.anyMap());
 
@@ -369,6 +378,98 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
         Mockito.doReturn(Either.left(relationshipTypeDefinition))
                 .when(relationshipTypeOperation).getRelationshipType(Mockito.anyString(), Mockito.anyBoolean());
 
+        Mockito.doReturn(Either.left(Collections.singletonMap("derivedFromProp1", new PropertyDefinition()))).when(propertyOperation)
+                .findPropertiesOfNode(Mockito.any(), Mockito.anyString());
+        
+        Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)).when(janusGraphGenericDao)
+                .getChild(Mockito.any(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.eq(RelationshipTypeData.class));
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition)))
+                .when(janusGraphGenericDao).getNode(Mockito.anyString(), Mockito.any(), Mockito.eq(RelationshipTypeData.class), Mockito.any()); 
+        
+        
+        ModelData modelData = new ModelData("modelA", "modelA");
+        ImmutablePair<ModelData, GraphEdge> pair = new ImmutablePair<>(modelData, new GraphEdge());
+        Mockito.doReturn(Either.left(pair))
+                .when(janusGraphGenericDao).getParentNode("uid", relationshipInstDataDefinition1.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class); 
+        
+        Either<RelationshipTypeDefinition, StorageOperationStatus> either =
+                relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, true);
+
+        assertTrue(either.isLeft());
+    }
+    
+    @Test
+    public void testAddRelationshipTypeToModel() {
+      
+        final String relationshipName = "tosca.relationships.MyRelationship";
+        final String derivedFromRelationshipName = "tosca.relationships.Root";
+        final String modelName = "modelA";
+
+        RelationshipTypeDefinition relationshipTypeDefinition = new RelationshipTypeDefinition();
+        relationshipTypeDefinition.setProperties(createPropertyData("prop1"));
+        relationshipTypeDefinition.setUniqueId(modelName + DOT + relationshipName);
+        relationshipTypeDefinition.setType(relationshipName);
+        relationshipTypeDefinition.setModel(modelName);
+        relationshipTypeDefinition.setDerivedFrom(derivedFromRelationshipName);
+        
+        RelationshipTypeData derivedFromRelationshipTypeData = new RelationshipTypeData();
+        RelationshipInstDataDefinition dervideFromRelationshipInstDataDefinition = new RelationshipInstDataDefinition();
+        dervideFromRelationshipInstDataDefinition.setUniqueId("modelA.tosca.relationships.Root");
+        dervideFromRelationshipInstDataDefinition.setType("tosca.relationships.Root");
+        derivedFromRelationshipTypeData.setRelationshipTypeDataDefinition(dervideFromRelationshipInstDataDefinition);
+        
+        Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND))
+                .when(janusGraphGenericDao).getNode("uid", relationshipTypeDefinition.getUniqueId(), RelationshipTypeData.class); 
+        
+        Mockito.doReturn(Either.left(derivedFromRelationshipTypeData))
+                .when(janusGraphGenericDao).getNode("type", "tosca.relationships.Root", RelationshipTypeData.class, "modelA"); 
+        
+        Mockito.doReturn(Either.left(Collections.singletonMap("prop1", new PropertyDefinition()))).when(propertyOperation)
+                .getAllTypePropertiesFromAllDerivedFrom(modelName + DOT + derivedFromRelationshipName, NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+        
+        Mockito.doReturn(Either.left(new ArrayList<>(relationshipTypeDefinition.getProperties().values()))).when(propertyOperation)
+                .validatePropertiesUniqueness(Mockito.any(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition))).when(janusGraphGenericDao)
+                .createNode(Mockito.any(), Mockito.eq(RelationshipTypeData.class));
+        
+        Mockito.doReturn(Either.left(new HashMap())).when(propertyOperation)
+                .addPropertiesToElementType(Mockito.anyString(), Mockito.any(), Mockito.anyMap());
+        
+        Mockito.doReturn(Either.left(new GraphRelation())).when(janusGraphGenericDao)
+                .createRelation(Mockito.any(), Mockito.any(), Mockito.eq(GraphEdgeLabels.MODEL_ELEMENT), Mockito.any());
+        
+        Mockito.doReturn(Either.left(Collections.singletonMap("derivedFromProp1", new PropertyDefinition()))).when(propertyOperation)
+                .findPropertiesOfNode(NodeTypeEnum.RelationshipType, derivedFromRelationshipTypeData.getUniqueId());
+        
+        Mockito.doReturn(Either.left(Collections.singletonMap("prop1", new PropertyDefinition()))).when(propertyOperation)
+                .findPropertiesOfNode(NodeTypeEnum.RelationshipType, relationshipTypeDefinition.getUniqueId());
+        
+        Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)).when(janusGraphGenericDao)
+                .getChild("uid", derivedFromRelationshipTypeData.getUniqueId(), GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+        
+        Mockito.doReturn(Either.left(new ImmutablePair(new RelationshipTypeData(relationshipTypeDefinition), null))).when(janusGraphGenericDao)
+                .getChild("uid", relationshipTypeDefinition.getUniqueId(), GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.RelationshipType, RelationshipTypeData.class);
+        
+        
+        Mockito.doReturn(Either.left(new GraphRelation())).when(derivedFromOperation)
+                .addDerivedFromRelation(relationshipTypeDefinition.getUniqueId(), derivedFromRelationshipTypeData.getUniqueId(), NodeTypeEnum.RelationshipType);
+        
+        ModelData modelData = new ModelData("modelA", "modelA");
+        ImmutablePair<ModelData, GraphEdge> pair = new ImmutablePair<>(modelData, new GraphEdge());
+        Mockito.doReturn(Either.left(pair))
+                .when(janusGraphGenericDao).getParentNode("uid", dervideFromRelationshipInstDataDefinition.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class); 
+        
+        Mockito.doReturn(Either.left(pair))
+                .when(janusGraphGenericDao).getParentNode("uid", relationshipTypeDefinition.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class); 
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition)))
+                .when(janusGraphGenericDao).getNode("uid", relationshipTypeDefinition.getUniqueId(), RelationshipTypeData.class); 
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition)))
+                .when(janusGraphGenericDao).getNode("type", relationshipTypeDefinition.getUniqueId(), RelationshipTypeData.class, "modelA"); 
+        
         Either<RelationshipTypeDefinition, StorageOperationStatus> either =
                 relationshipTypeOperation.addRelationshipType(relationshipTypeDefinition, true);
 
@@ -425,6 +526,20 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
         Mockito.doReturn(Either.left(new GraphRelation()))
                 .when(derivedFromOperation)
                 .addDerivedFromRelation(Mockito.anyString(), Mockito.anyString(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(new RelationshipTypeData(relationshipTypeDefinition)))
+                .when(janusGraphGenericDao).getNode(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.any());
+        
+        Mockito.doReturn(Either.left(Collections.singletonMap("derivedFromProp1", new PropertyDefinition()))).when(propertyOperation)
+                .findPropertiesOfNode(Mockito.any(), Mockito.anyString());
+        
+        Mockito.doReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)).when(janusGraphGenericDao)
+                .getChild(Mockito.any(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.eq(RelationshipTypeData.class));
+        
+        ModelData modelData = new ModelData("modelA", "modelA");
+        ImmutablePair<ModelData, GraphEdge> pair = new ImmutablePair<>(modelData, new GraphEdge());
+        Mockito.doReturn(Either.left(pair))
+                .when(janusGraphGenericDao).getParentNode("uid", newRelationshipTypeDefinition.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class); 
 
         Either<RelationshipTypeDefinition, StorageOperationStatus> either =
                 relationshipTypeOperation.updateRelationshipType(relationshipTypeDefinition,
@@ -450,6 +565,11 @@ public class RelationshipTypeOperationTest extends ModelTestBase {
             janusGraphGenericDao)
                 .getChild(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(),
                         Mockito.eq(RelationshipTypeData.class));
+        
+        ModelData modelData = new ModelData("modelA", "modelA");
+        ImmutablePair<ModelData, GraphEdge> pair = new ImmutablePair<>(modelData, new GraphEdge());
+        Mockito.doReturn(Either.left(pair))
+                .when(janusGraphGenericDao).getParentNode("uid", relationshipTypeDefinition.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, NodeTypeEnum.Model, ModelData.class); 
 
         Either<RelationshipTypeDefinition, JanusGraphOperationStatus> either =
                 relationshipTypeOperation.getRelationshipTypeByUid("tosca.relationships.Container1");
index 1cd0306..d03ff05 100644 (file)
@@ -79,6 +79,19 @@ public class FunctionalInterfaces {
          */
         void accept(T1 t1, T2 t2);
     }
+    
+    @FunctionalInterface
+    public interface ConsumerThreeParam<T1, T2, T3> {
+
+        /**
+         * Same Accept method, but takes three parameters
+         *
+         * @param t1
+         * @param t2
+         * @param t3
+         */
+        void accept(T1 t1, T2 t2, T3 t3);
+    }
 
     /**
      * @param <T1>