Support adding capability types to model 76/121676/2
authorMichaelMorris <michael.morris@est.tech>
Fri, 28 May 2021 11:29:13 +0000 (12:29 +0100)
committerChristophe Closset <christophe.closset@intl.att.com>
Mon, 14 Jun 2021 08:01:13 +0000 (08:01 +0000)
Signed-off-by: MichaelMorris <michael.morris@est.tech>
Issue-ID: SDC-3612
Change-Id: I5d3713ba420c2392dd232b5651aef4d51560ab4a

catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManager.java
catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManagerTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.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/CapabilityTypeOperationTest.java

index df7650f..4ce08ea 100644 (file)
@@ -22,11 +22,13 @@ package org.openecomp.sdc.be.components.impl;
 import fj.data.Either;
 import java.util.List;
 import java.util.Map;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.dao.api.ActionStatus;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation;
+import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.model.utils.TypeCompareUtils;
 import org.openecomp.sdc.be.utils.TypeUtils;
 import org.openecomp.sdc.common.log.wrappers.Logger;
@@ -47,19 +49,23 @@ public class CapabilityTypeImportManager {
         this.commonImportManager = commonImportManager;
     }
 
-    public Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> createCapabilityTypes(String capabilityTypesYml) {
-        return commonImportManager.createElementTypes(capabilityTypesYml, this::createCapabilityTypesFromYml, this::upsertCapabilityTypesByDao,
+    public Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> createCapabilityTypes(final String capabilityTypesYml, final String modelName) {
+        return commonImportManager.createElementTypes(capabilityTypesYml, capabilityTypesFromYml -> createCapabilityTypesFromYml(capabilityTypesYml, modelName), this::upsertCapabilityTypesByDao,
             CommonImportManager.ElementTypeEnum.CAPABILITY_TYPE);
     }
 
-    private Either<List<CapabilityTypeDefinition>, ActionStatus> createCapabilityTypesFromYml(String capabilityTypesYml) {
-        return commonImportManager.createElementTypesFromYml(capabilityTypesYml, this::createCapabilityType);
+    private Either<List<CapabilityTypeDefinition>, ActionStatus> createCapabilityTypesFromYml(final String capabilityTypesYml, final String modelName) {
+        final Either<List<CapabilityTypeDefinition>, ActionStatus> capabilityTypes = commonImportManager.createElementTypesFromYml(capabilityTypesYml, this::createCapabilityType);
+        if (capabilityTypes.isLeft() && StringUtils.isNotEmpty(modelName)){
+           capabilityTypes.left().value().forEach(capabilityType -> capabilityType.setModel(modelName));
+        }
+        return capabilityTypes;
     }
 
     private Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> upsertCapabilityTypesByDao(
         List<CapabilityTypeDefinition> capabilityTypesToCreate) {
         return commonImportManager.createElementTypesByDao(capabilityTypesToCreate, capabilityType -> Either.left(ActionStatus.OK),
-            capabilityType -> new ImmutablePair<>(CommonImportManager.ElementTypeEnum.CAPABILITY_TYPE, capabilityType.getType()),
+            capabilityType -> new ImmutablePair<>(CommonImportManager.ElementTypeEnum.CAPABILITY_TYPE, UniqueIdBuilder.buildCapabilityTypeUid(capabilityType.getModel(), capabilityType.getType())),
             capabilityTypeOperation::getCapabilityType, capabilityTypeOperation::addCapabilityType, this::updateCapabilityType);
     }
 
index fed26cc..9656550 100644 (file)
@@ -130,10 +130,11 @@ public class TypesUploadServlet extends AbstractValidationsServlet {
         @ApiResponse(responseCode = "409", description = "Capability Type already exist")})
     @PermissionAllowed(AafPermission.PermNames.INTERNAL_ALL_VALUE)
     public Response uploadCapabilityType(@Parameter(description = "FileInputStream") @FormDataParam("capabilityTypeZip") File file,
-                                         @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) {
-        ConsumerTwoParam<Wrapper<Response>, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper,
-            () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload));
-        return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.CapabilityType.name());
+                                         @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator,
+                                         @Parameter(description = "model") @FormDataParam("model") String modelName) {
+        ConsumerThreeParam<Wrapper<Response>, String, String> createElementsMethod = (responseWrapper, ymlPayload, model) -> createElementsType(responseWrapper,
+            () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload, modelName));
+        return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.CapabilityType.name(), modelName);
     }
 
     @POST
index 7de4296..a684e21 100644 (file)
@@ -81,7 +81,7 @@ public class CapabilityTypeImportManagerTest {
     @Test
     public void testCreateCapabilityTypes() throws IOException {
         String ymlContent = getCapabilityTypesYml();
-        Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> createCapabilityTypes = manager.createCapabilityTypes(ymlContent);
+        Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> createCapabilityTypes = manager.createCapabilityTypes(ymlContent, "testModel");
         assertTrue(createCapabilityTypes.isLeft());
 
         List<ImmutablePair<CapabilityTypeDefinition, Boolean>> capabilityTypesList = createCapabilityTypes.left().value();
index 214d1a7..395bee3 100644 (file)
@@ -37,6 +37,7 @@ import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.eclipse.jetty.http.HttpStatus;
 import org.glassfish.hk2.utilities.binding.AbstractBinder;
 import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.media.multipart.FormDataBodyPart;
 import org.glassfish.jersey.media.multipart.FormDataMultiPart;
 import org.glassfish.jersey.media.multipart.MultiPart;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
@@ -129,7 +130,7 @@ class TypesUploadServletTest extends JerseyTest {
     @Test
     void creatingCapabilityTypeSuccessTest() {
         final Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(emptyList());
-        when(importManager.createCapabilityTypes(Mockito.anyString())).thenReturn(either);
+        when(importManager.createCapabilityTypes(Mockito.anyString(), Mockito.isNull())).thenReturn(either);
         final FileDataBodyPart filePart = new FileDataBodyPart("capabilityTypeZip", new File("src/test/resources/types/capabilityTypes.zip"));
         MultiPart multipartEntity = new FormDataMultiPart();
         multipartEntity.bodyPart(filePart);
@@ -139,6 +140,21 @@ class TypesUploadServletTest extends JerseyTest {
 
         assertEquals(HttpStatus.CREATED_201, response.getStatus());
     }
+    
+    @Test
+    void creatingCapabilityTypeWithModelSuccessTest() {
+        final Either<List<ImmutablePair<CapabilityTypeDefinition, Boolean>>, ResponseFormat> either = Either.left(emptyList());
+        when(importManager.createCapabilityTypes(Mockito.anyString(), Mockito.eq("testModel"))).thenReturn(either);
+        final FileDataBodyPart filePart = new FileDataBodyPart("capabilityTypeZip", new File("src/test/resources/types/capabilityTypes.zip"));
+        FormDataMultiPart multipartEntity = new FormDataMultiPart();
+        multipartEntity.bodyPart(filePart);
+        multipartEntity.field("model", "testModel");
+
+        final Response response = target().path("/v1/catalog/uploadType/capability").request(MediaType.APPLICATION_JSON)
+            .post(Entity.entity(multipartEntity, MediaType.MULTIPART_FORM_DATA), Response.class);
+
+        assertEquals(HttpStatus.CREATED_201, response.getStatus());
+    }
 
     @Override
     protected void configureClient(ClientConfig config) {
index b3fb2c4..435b876 100644 (file)
@@ -39,6 +39,7 @@ public class CapabilityTypeDefinition extends CapabilityTypeDataDefinition {
 
     private String derivedFrom;
     private Map<String, PropertyDefinition> properties;
+    private String model;
 
     public CapabilityTypeDefinition(CapabilityTypeDataDefinition p) {
         super(p);
index e845f4d..0763559 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.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -28,10 +31,12 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
 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.dao.neo4j.GraphPropertiesDictionary;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
 import org.openecomp.sdc.be.model.PropertyDefinition;
@@ -40,7 +45,9 @@ import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation;
 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.api.TypeOperations;
 import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
+import org.openecomp.sdc.be.resources.data.ModelData;
 import org.openecomp.sdc.be.resources.data.PropertyData;
+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;
@@ -100,15 +107,21 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
     }
 
     public Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(
-        String firstParentType) {
-        return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentType, NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
+        final String firstParentUid) {
+        return propertyOperation.getAllTypePropertiesFromAllDerivedFrom(firstParentUid, NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
     }
 
     public Either<CapabilityTypeDefinition, StorageOperationStatus> validateUpdateProperties(CapabilityTypeDefinition capabilityTypeDefinition) {
         JanusGraphOperationStatus error = null;
         if (MapUtils.isNotEmpty(capabilityTypeDefinition.getProperties()) && capabilityTypeDefinition.getDerivedFrom() != null) {
+            final Either<CapabilityTypeData, JanusGraphOperationStatus> derivedFromNode = janusGraphGenericDao.getNode(GraphPropertiesDictionary.TYPE.getProperty(), 
+                capabilityTypeDefinition.getDerivedFrom(), CapabilityTypeData.class, capabilityTypeDefinition.getModel());
+            if (derivedFromNode.isRight()) {
+                log.error(BUSINESS_PROCESS_ERROR, "Failed to find the derived from type for  {}. status is {}", capabilityTypeDefinition.getType(), derivedFromNode.right().value());
+                return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(derivedFromNode.right().value()));
+            }
             Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> allPropertiesRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(
-                capabilityTypeDefinition.getDerivedFrom());
+                derivedFromNode.left().value().getUniqueId());
             if (allPropertiesRes.isRight() && !allPropertiesRes.right().value().equals(JanusGraphOperationStatus.NOT_FOUND)) {
                 error = allPropertiesRes.right().value();
                 log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", capabilityTypeDefinition.getType(), error);
@@ -146,7 +159,7 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
      */
     private Either<CapabilityTypeData, StorageOperationStatus> addCapabilityTypeToGraph(CapabilityTypeDefinition capabilityTypeDefinition) {
         log.debug("Got capability type {}", capabilityTypeDefinition);
-        String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType());
+        String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getModel(), capabilityTypeDefinition.getType());
         CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId);
         log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData);
         Either<CapabilityTypeData, JanusGraphOperationStatus> createCTResult = janusGraphGenericDao
@@ -165,8 +178,25 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
             log.error("Failed add properties {} to capability {}", propertiesMap, capabilityTypeDefinition.getType());
             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(addPropertiesToCapablityType.right().value()));
         }
+        
+        final Either<GraphRelation, StorageOperationStatus> modelRelationship = addCapabilityTypeToModel(capabilityTypeDefinition);
+        if (modelRelationship.isRight()) {
+            return Either.right(modelRelationship.right().value());
+        } 
+        
         return addDerivedFromRelation(capabilityTypeDefinition, ctUniqueId).left().map(updatedDerivedFrom -> createCTResult.left().value());
     }
+    
+    private Either<GraphRelation, StorageOperationStatus> addCapabilityTypeToModel(final CapabilityTypeDefinition capabilityTypeDefinition) {
+        final String model = capabilityTypeDefinition.getModel();
+        if (model == null) {
+            return Either.left(null);
+        }
+        final GraphNode from = new UniqueIdData(NodeTypeEnum.Model, UniqueIdBuilder.buildModelUid(model));
+        final GraphNode to = new UniqueIdData(NodeTypeEnum.CapabilityType, capabilityTypeDefinition.getUniqueId());
+        log.info("Connecting model {} to type {}", from, to);
+        return janusGraphGenericDao.createRelation(from , to, GraphEdgeLabels.MODEL_ELEMENT, Collections.emptyMap()).right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
+    }
 
     private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, String ctUniqueId) {
         CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition);
@@ -207,6 +237,17 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
         // Optimization: In case of Capability Type its unique ID is the same as type
         return getCapabilityTypeByUid(capabilityType);
     }
+    
+    public Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeByType(final String capabilityType, final String model) {
+        final Either<CapabilityTypeData, JanusGraphOperationStatus> capabilityTypesRes = janusGraphGenericDao
+            .getNode(GraphPropertiesDictionary.TYPE.getProperty(), capabilityType, CapabilityTypeData.class, model);
+        if (capabilityTypesRes.isRight()) {
+            final JanusGraphOperationStatus status = capabilityTypesRes.right().value();
+            log.debug("Capability type {} cannot be found in graph. status is {}", capabilityType, status);
+            return Either.right(status);
+        }
+        return getCapabilityTypeDefinition(capabilityTypesRes.left().value());
+    }
 
     /**
      * Build Capability type object from graph by unique id
@@ -223,27 +264,29 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
             log.debug("Capability type {} cannot be found in graph. status is {}", uniqueId, status);
             return Either.right(status);
         }
-        CapabilityTypeData ctData = capabilityTypesRes.left().value();
+        return getCapabilityTypeDefinition(capabilityTypesRes.left().value());
+    }
+    
+    private Either<CapabilityTypeDefinition, JanusGraphOperationStatus> getCapabilityTypeDefinition(final CapabilityTypeData ctData) {
         CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition(ctData.getCapabilityTypeDataDefinition());
         Either<Map<String, PropertyDefinition>, JanusGraphOperationStatus> propertiesStatus = OperationUtils
-            .fillProperties(uniqueId, propertyOperation, NodeTypeEnum.CapabilityType);
+            .fillProperties(ctData.getUniqueId(), propertyOperation, NodeTypeEnum.CapabilityType);
         if (propertiesStatus.isRight() && propertiesStatus.right().value() != JanusGraphOperationStatus.OK) {
-            log.error("Failed to fetch properties of capability type {}", uniqueId);
+            log.error(BUSINESS_PROCESS_ERROR, "Failed to fetch properties of capability type {}", ctData.getUniqueId());
             return Either.right(propertiesStatus.right().value());
         }
         if (propertiesStatus.isLeft()) {
             capabilityTypeDefinition.setProperties(propertiesStatus.left().value());
         }
         Either<ImmutablePair<CapabilityTypeData, GraphEdge>, JanusGraphOperationStatus> parentNode = janusGraphGenericDao
-            .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, GraphEdgeLabels.DERIVED_FROM,
+            .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), ctData.getUniqueId(), GraphEdgeLabels.DERIVED_FROM,
                 NodeTypeEnum.CapabilityType, CapabilityTypeData.class);
-        log.debug("After retrieving DERIVED_FROM node of {}. status is {}", uniqueId, parentNode);
+        log.debug("After retrieving DERIVED_FROM node of {}. status is {}", ctData.getUniqueId(), parentNode);
         if (parentNode.isRight()) {
             JanusGraphOperationStatus janusGraphOperationStatus = parentNode.right().value();
             if (janusGraphOperationStatus != JanusGraphOperationStatus.NOT_FOUND) {
-                log.error("Failed to find the parent capability of capability type {}. status is {}", uniqueId, janusGraphOperationStatus);
-                result = Either.right(janusGraphOperationStatus);
-                return result;
+                log.error(BUSINESS_PROCESS_ERROR, "Failed to find the parent capability of capability type {}. status is {}", ctData.getUniqueId(), janusGraphOperationStatus);
+                return Either.right(janusGraphOperationStatus);
             }
         } else {
             // derived from node was found
@@ -251,8 +294,15 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
             CapabilityTypeData parentCT = immutablePair.getKey();
             capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType());
         }
-        result = Either.left(capabilityTypeDefinition);
-        return result;
+        
+        final Either<ImmutablePair<ModelData, GraphEdge>, JanusGraphOperationStatus> model = janusGraphGenericDao.getParentNode(
+            UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), ctData.getUniqueId(), GraphEdgeLabels.MODEL_ELEMENT, 
+            NodeTypeEnum.Model, ModelData.class);
+        if (model.isLeft()) {
+            capabilityTypeDefinition.setModel(model.left().value().getLeft().getName());
+        }
+        
+        return Either.left(capabilityTypeDefinition);
     }
 
     public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, String parentCandidateType) {
@@ -319,8 +369,10 @@ public class CapabilityTypeOperation extends AbstractOperation implements ICapab
         }
         log.debug("#addDerivedFromRelationBefore - adding derived from relation between capability type {} to its parent {}",
             capabilityTypeDef.getType(), derivedFrom);
-        return this.getCapabilityType(derivedFrom, true).left().bind(derivedFromCapabilityType -> derivedFromOperation
-            .addDerivedFromRelation(ptUniqueId, derivedFromCapabilityType.getUniqueId(), NodeTypeEnum.CapabilityType));
+        return this.getCapabilityTypeByType(derivedFrom, capabilityTypeDef.getModel())
+            .right().map(DaoStatusConverter::convertJanusGraphStatusToStorageStatus)
+            .left().bind(derivedFromCapabilityType -> derivedFromOperation
+                .addDerivedFromRelation(ptUniqueId, derivedFromCapabilityType.getUniqueId(), NodeTypeEnum.CapabilityType));
     }
 
     private StorageOperationStatus deleteDerivedFromCapabilityType(String capabilityTypeId, String derivedFromType) {
index 6e3d968..72fdffa 100644 (file)
@@ -89,8 +89,8 @@ public class UniqueIdBuilder {
         return generateUUID();
     }
 
-    static String buildCapabilityTypeUid(String type) {
-        return type;
+    public static String buildCapabilityTypeUid(final String modelName, String type) {
+        return StringUtils.isEmpty(modelName) ? type : modelName + DOT + type;
     }
 
     public static String buildRelationshipTypeUid(final String modelName, final String type) {
index 5391410..af4715f 100644 (file)
@@ -49,6 +49,7 @@ import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
 import org.openecomp.sdc.be.model.CapabilityTypeDefinition;
+import org.openecomp.sdc.be.model.Model;
 import org.openecomp.sdc.be.model.ModelTestBase;
 import org.openecomp.sdc.be.model.PropertyConstraint;
 import org.openecomp.sdc.be.model.PropertyDefinition;
@@ -73,6 +74,9 @@ public class CapabilityTypeOperationTest extends ModelTestBase {
 
     @Resource(name = "capability-type-operation")
     private CapabilityTypeOperation capabilityTypeOperation;
+    
+    @Resource(name = "model-operation")
+    private ModelOperation modelOperation;
 
     @BeforeClass
     public static void setupBeforeClass() {
@@ -123,6 +127,40 @@ public class CapabilityTypeOperationTest extends ModelTestBase {
         assertEquals("check returned error", StorageOperationStatus.SCHEMA_VIOLATION, addCapabilityType2.right().value());
 
     }
+    
+    @Test
+    public void testAddCapabilityTypeWithModel() {
+
+        CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition();
+        capabilityTypeDefinition.setDescription("desc1");
+        capabilityTypeDefinition.setType("tosca.capabilities.Container1");
+        capabilityTypeDefinition.setModel("testModel");
+        
+        Model model = new Model("testModel");
+        modelOperation.createModel(model , true);
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType1 = capabilityTypeOperation.addCapabilityType(capabilityTypeDefinition, true);
+        assertTrue("check capability type added", addCapabilityType1.isLeft());
+
+        CapabilityTypeDefinition capabilityTypeAdded = addCapabilityType1.left().value();
+        compareBetweenCreatedToSent(capabilityTypeDefinition, capabilityTypeAdded);
+
+        Either<CapabilityTypeDefinition, JanusGraphOperationStatus> capabilityTypeByUid = capabilityTypeOperation.getCapabilityTypeByUid(capabilityTypeAdded.getUniqueId());
+        compareBetweenCreatedToSent(capabilityTypeByUid.left().value(), capabilityTypeDefinition);
+        
+        CapabilityTypeDefinition capabilityTypeWithDerivedFrom = new CapabilityTypeDefinition();
+        capabilityTypeWithDerivedFrom.setDescription("desc2");
+        capabilityTypeWithDerivedFrom.setType("tosca.capabilities.Container2");
+        capabilityTypeWithDerivedFrom.setDerivedFrom("tosca.capabilities.Container1");
+        capabilityTypeWithDerivedFrom.setModel("testModel");
+
+        Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType2 = capabilityTypeOperation.addCapabilityType(capabilityTypeWithDerivedFrom, true);
+        assertTrue("check capability type added", addCapabilityType2.isLeft());
+        
+        capabilityTypeAdded = addCapabilityType2.left().value();
+        compareBetweenCreatedToSent(capabilityTypeWithDerivedFrom, capabilityTypeAdded);
+
+    }
 
     @Test
     public void testAddDerviedCapabilityType() {
@@ -500,6 +538,7 @@ public class CapabilityTypeOperationTest extends ModelTestBase {
         assertTrue(compareValue(x.getDerivedFrom(), y.getDerivedFrom()));
         assertTrue(compareValue(x.getType(), y.getType()));
         assertTrue(compareValue(x.getDescription(), y.getDescription()));
+        assertTrue(compareValue(x.getModel(), y.getModel()));
 
     }