atlas-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shweth...@apache.org
Subject [2/5] incubator-atlas git commit: ATLAS-622 Introduce soft delete (shwethags)
Date Sat, 16 Apr 2016 03:58:11 GMT
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/40ee9492/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteEntitiesTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteEntitiesTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteEntitiesTest.java
deleted file mode 100644
index 975d530..0000000
--- a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteEntitiesTest.java
+++ /dev/null
@@ -1,613 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.
- */
-
-package org.apache.atlas.repository.graph;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.thinkaurelius.titan.core.TitanGraph;
-import com.thinkaurelius.titan.core.util.TitanCleanup;
-import com.tinkerpop.blueprints.Vertex;
-
-import org.apache.atlas.RepositoryMetadataModule;
-import org.apache.atlas.TestUtils;
-import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
-import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.RepositoryException;
-import org.apache.atlas.typesystem.IStruct;
-import org.apache.atlas.typesystem.ITypedReferenceableInstance;
-import org.apache.atlas.typesystem.ITypedStruct;
-import org.apache.atlas.typesystem.Referenceable;
-import org.apache.atlas.typesystem.Struct;
-import org.apache.atlas.typesystem.TypesDef;
-import org.apache.atlas.typesystem.exception.EntityNotFoundException;
-import org.apache.atlas.typesystem.persistence.Id;
-import org.apache.atlas.typesystem.types.AttributeDefinition;
-import org.apache.atlas.typesystem.types.ClassType;
-import org.apache.atlas.typesystem.types.DataTypes;
-import org.apache.atlas.typesystem.types.EnumTypeDefinition;
-import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
-import org.apache.atlas.typesystem.types.Multiplicity;
-import org.apache.atlas.typesystem.types.StructTypeDefinition;
-import org.apache.atlas.typesystem.types.TraitType;
-import org.apache.atlas.typesystem.types.TypeSystem;
-import org.apache.atlas.typesystem.types.TypeUtils.Pair;
-import org.apache.atlas.typesystem.types.utils.TypesUtil;
-import org.testng.Assert;
-import org.testng.annotations.AfterClass;
-import org.testng.annotations.BeforeClass;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
-
-import javax.inject.Inject;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Test for GraphBackedMetadataRepository.deleteEntities
- *
- * Guice loads the dependencies and injects the necessary objects
- *
- */
-@Guice(modules = RepositoryMetadataModule.class)
-public class GraphBackedMetadataRepositoryDeleteEntitiesTest {
-
-    @Inject
-    private GraphProvider<TitanGraph> graphProvider;
-
-    @Inject
-    private GraphBackedMetadataRepository repositoryService;
-
-    @Inject
-    private GraphBackedDiscoveryService discoveryService;
-
-    private TypeSystem typeSystem;
-
-    @BeforeClass
-    public void setUp() throws Exception {
-        typeSystem = TypeSystem.getInstance();
-        typeSystem.reset();
-
-        new GraphBackedSearchIndexer(graphProvider);
-
-        TestUtils.defineDeptEmployeeTypes(typeSystem);
-        TestUtils.createHiveTypes(typeSystem);
-    }
-
-
-    @AfterClass
-    public void tearDown() throws Exception {
-        TypeSystem.getInstance().reset();
-        try {
-            graphProvider.get().shutdown();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        try {
-            TitanCleanup.clear(graphProvider.get());
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-
-
-
-    /**
-     * Verify deleting entities with composite references to other entities.
-     * The composite entities should also be deleted.
-     */
-    @Test
-    public void testDeleteEntitiesWithCompositeArrayReference() throws Exception {
-        String hrDeptGuid = createHrDeptGraph();
-
-        ITypedReferenceableInstance hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
-        Object refValue = hrDept.get("employees");
-        Assert.assertTrue(refValue instanceof List);
-        List<Object> employees = (List<Object>)refValue;
-        Assert.assertEquals(employees.size(), 4);
-
-        List<String> employeeGuids = new ArrayList(4);
-        for (Object listValue : employees) {
-            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
-            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
-            employeeGuids.add(employee.getId()._getId());
-        }
-        
-        // There should be 4 vertices for Address structs (one for each Person.address attribute value).
-        int vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "Address");
-        Assert.assertEquals(vertexCount, 4);
-        vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "SecurityClearance");
-        Assert.assertEquals(vertexCount, 1);
-        
-        Pair<List<String>, List<ITypedReferenceableInstance>> deletedEntities = repositoryService.deleteEntities(Arrays.asList(hrDeptGuid));
-        Assert.assertTrue(deletedEntities.left.contains(hrDeptGuid));
-        
-        // Verify Department entity and its contained Person entities were deleted.
-        verifyEntityDoesNotExist(hrDeptGuid);
-        for (String employeeGuid : employeeGuids) {
-            verifyEntityDoesNotExist(employeeGuid);
-        }
-
-        // Verify all Person.address struct vertices were removed.
-        vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "Address");
-        Assert.assertEquals(vertexCount, 0);
-        
-        // Verify all SecurityClearance trait vertices were removed.
-        vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "SecurityClearance");
-        Assert.assertEquals(vertexCount, 0);
-    }
-
-    @Test
-    public void testDeleteEntitiesWithCompositeMapReference() throws Exception {
-        // Define type for map value.
-        HierarchicalTypeDefinition<ClassType> mapValueDef = TypesUtil.createClassTypeDef("CompositeMapValue", 
-            ImmutableSet.<String>of(),
-            TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
-        
-        // Define type with map where the value is a composite class reference to MapValue.
-        HierarchicalTypeDefinition<ClassType> mapOwnerDef = TypesUtil.createClassTypeDef("CompositeMapOwner", 
-            ImmutableSet.<String>of(),
-            new AttributeDefinition("map", DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(),
-                        "CompositeMapValue"), Multiplicity.OPTIONAL, true, null));
-        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(),
-            ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(),
-            ImmutableList.of(mapOwnerDef, mapValueDef));
-        typeSystem.defineTypes(typesDef);
-        ClassType mapOwnerType = typeSystem.getDataType(ClassType.class, "CompositeMapOwner");
-        ClassType mapValueType = typeSystem.getDataType(ClassType.class, "CompositeMapValue");
-        
-        // Create instances of MapOwner and MapValue.
-        // Set MapOwner.map with one entry that references MapValue instance.
-        ITypedReferenceableInstance mapOwnerInstance = mapOwnerType.createInstance();
-        ITypedReferenceableInstance mapValueInstance = mapValueType.createInstance();
-        mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance));
-        List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance);
-        Assert.assertEquals(createEntitiesResult.size(), 2);
-        List<String> guids = repositoryService.getEntityList("CompositeMapOwner");
-        Assert.assertEquals(guids.size(), 1);
-        String mapOwnerGuid = guids.get(0);
-        
-        // Verify MapOwner.map attribute has expected value.
-        mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
-        Object object = mapOwnerInstance.get("map");
-        Assert.assertNotNull(object);
-        Assert.assertTrue(object instanceof Map);
-        Map<String, ITypedReferenceableInstance> map = (Map<String, ITypedReferenceableInstance>)object;
-        Assert.assertEquals(map.size(), 1);
-        mapValueInstance = map.get("value1");
-        Assert.assertNotNull(mapValueInstance);
-        String mapValueGuid = mapValueInstance.getId()._getId();
-        String edgeLabel = GraphHelper.getEdgeLabel(mapOwnerType, mapOwnerType.fieldMapping.fields.get("map"));
-        String mapEntryLabel = edgeLabel + "." + "value1";
-        AtlasEdgeLabel atlasEdgeLabel = new AtlasEdgeLabel(mapEntryLabel);
-        Vertex mapOwnerVertex = GraphHelper.getInstance().getVertexForGUID(mapOwnerGuid);
-        object = mapOwnerVertex.getProperty(atlasEdgeLabel.getQualifiedMapKey());
-        Assert.assertNotNull(object);
-        
-        Pair<List<String>, List<ITypedReferenceableInstance>> deleteEntitiesResult = 
-            repositoryService.deleteEntities(Arrays.asList(mapOwnerGuid));
-        Assert.assertEquals(deleteEntitiesResult.left.size(), 2);
-        Assert.assertTrue(deleteEntitiesResult.left.containsAll(guids));
-        verifyEntityDoesNotExist(mapOwnerGuid);
-        verifyEntityDoesNotExist(mapValueGuid);
-    }
-    
-    /**
-     * Verify deleting an entity which is contained by another
-     * entity through a bi-directional composite reference.
-     * 
-     * @throws Exception
-     */
-    @Test(dependsOnMethods = "testDeleteEntitiesWithCompositeArrayReference")
-    public void testDisconnectBidirectionalReferences() throws Exception {
-        String hrDeptGuid = createHrDeptGraph();
-        ITypedReferenceableInstance hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
-        Object refValue = hrDept.get("employees");
-        Assert.assertTrue(refValue instanceof List);
-        List<Object> employees = (List<Object>)refValue;
-        Assert.assertEquals(employees.size(), 4);
-        String employeeGuid = null;
-        for (Object listValue : employees) {
-            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
-            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
-            if (employee.get("name").equals("Max")) {
-                employeeGuid = employee.getId()._getId();
-            }
-        }
-        Assert.assertNotNull(employeeGuid);
-        
-        // Verify that Max is one of Jane's subordinates.
-        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Manager", "name", "Jane");
-        refValue = jane.get("subordinates");
-        Assert.assertTrue(refValue instanceof List);
-        List<Object> subordinates = (List<Object>)refValue;
-        Assert.assertEquals(subordinates.size(), 2);
-        List<String> subordinateIds = new ArrayList<>(2);
-        for (Object listValue : employees) {
-            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
-            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
-            subordinateIds.add(employee.getId()._getId());
-        }
-        Assert.assertTrue(subordinateIds.contains(employeeGuid));
-        
-        Pair<List<String>, List<ITypedReferenceableInstance>> deletedEntities = repositoryService.deleteEntities(Arrays.asList(employeeGuid));
-        Assert.assertTrue(deletedEntities.left.contains(employeeGuid));
-        verifyEntityDoesNotExist(employeeGuid);
-        
-        // Verify that the Department.employees reference to the deleted employee
-        // was disconnected.
-        hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
-        refValue = hrDept.get("employees");
-        Assert.assertTrue(refValue instanceof List);
-        employees = (List<Object>)refValue;
-        Assert.assertEquals(employees.size(), 3);
-        for (Object listValue : employees) {
-            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
-            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
-            Assert.assertNotEquals(employee.getId()._getId(), employeeGuid);
-        }
-        
-        // Verify that the Manager.subordinates reference to the deleted employee
-        // Max was disconnected.
-        jane = repositoryService.getEntityDefinition("Manager", "name", "Jane");
-        refValue = jane.get("subordinates");
-        Assert.assertTrue(refValue instanceof List);
-        subordinates = (List<Object>)refValue;
-        Assert.assertEquals(subordinates.size(), 1);
-        Object listValue = subordinates.get(0);
-        Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
-        ITypedReferenceableInstance subordinate = (ITypedReferenceableInstance) listValue;
-        String subordinateGuid = subordinate.getId()._getId();
-        Assert.assertNotEquals(subordinateGuid, employeeGuid);
-        
-        // Verify that max's Person.mentor unidirectional reference to john was disconnected.
-        ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Manager", "name", "John");
-        refValue = john.get("mentor");
-        Assert.assertNull(refValue);
-        
-        // Now delete jane - this should disconnect the manager reference from her
-        // subordinate.
-        String janeGuid = jane.getId()._getId();
-        deletedEntities = repositoryService.deleteEntities(Arrays.asList(janeGuid));
-        Assert.assertTrue(deletedEntities.left.contains(janeGuid));
-        verifyEntityDoesNotExist(janeGuid);
-        subordinate = repositoryService.getEntityDefinition(subordinateGuid);
-        Assert.assertNull(subordinate.get("manager"));
-    }
-
-    /**
-     * Verify deleting entity that is the target of a unidirectional class array reference
-     * from a class instance.
-     */
-    @Test
-    public void testDisconnectUnidirectionalArrayReferenceFromClassType() throws Exception {
-        createDbTableGraph();
-        
-        // Get the guid for one of the table's columns.
-        ITypedReferenceableInstance table = repositoryService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", TestUtils.TABLE_NAME);
-        String tableGuid = table.getId()._getId();
-        Object refValues = table.get("columns");
-        Assert.assertTrue(refValues instanceof List);
-        List<Object> refList = (List<Object>) refValues;
-        Assert.assertEquals(refList.size(), 5);
-        Assert.assertTrue(refList.get(0) instanceof ITypedReferenceableInstance);
-        ITypedReferenceableInstance column = (ITypedReferenceableInstance) refList.get(0);
-        String columnGuid = column.getId()._getId();
-        
-        // Delete the column.
-        Pair<List<String>, List<ITypedReferenceableInstance>> deletedEntities = 
-            repositoryService.deleteEntities(Arrays.asList(columnGuid));
-        Assert.assertEquals(deletedEntities.left.size(), 1);
-        Assert.assertEquals(deletedEntities.right.size(), 1);
-        verifyEntityDoesNotExist(columnGuid);
-        
-        // Verify table.columns reference to the deleted column has been disconnected.
-        table = repositoryService.getEntityDefinition(tableGuid);
-        refList = (List<Object>) table.get("columns");
-        Assert.assertEquals(refList.size(), 4);
-        for (Object refValue : refList) {
-            Assert.assertTrue(refValue instanceof ITypedReferenceableInstance);
-            column = (ITypedReferenceableInstance)refValue;
-            Assert.assertFalse(column.getId()._getId().equals(columnGuid));
-        }
-    }
-    
-    /**
-     * Verify deleting entities that are the target of a unidirectional class array reference
-     * from a struct or trait instance.
-     */
-    @Test
-    public void testDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes() throws Exception {
-        // Define class types.
-        HierarchicalTypeDefinition<ClassType> structTargetDef = TypesUtil.createClassTypeDef("StructTarget", 
-            ImmutableSet.<String>of(), TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
-        HierarchicalTypeDefinition<ClassType> traitTargetDef = TypesUtil.createClassTypeDef("TraitTarget", 
-            ImmutableSet.<String>of(), TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
-        HierarchicalTypeDefinition<ClassType> structContainerDef = TypesUtil.createClassTypeDef("StructContainer", 
-            ImmutableSet.<String>of(), TypesUtil.createOptionalAttrDef("struct", "TestStruct"));
-        
-        // Define struct and trait types which have a unidirectional array reference
-        // to a class type.
-        StructTypeDefinition structDef = TypesUtil.createStructTypeDef("TestStruct", 
-            new AttributeDefinition("target", DataTypes.arrayTypeName("StructTarget"), Multiplicity.OPTIONAL, false, null),
-            new AttributeDefinition("nestedStructs", DataTypes.arrayTypeName("NestedStruct"), Multiplicity.OPTIONAL, false, null));
-        StructTypeDefinition nestedStructDef = TypesUtil.createStructTypeDef("NestedStruct", 
-            TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
-        HierarchicalTypeDefinition<TraitType> traitDef = TypesUtil.createTraitTypeDef("TestTrait", ImmutableSet.<String>of(), 
-            new AttributeDefinition("target", DataTypes.arrayTypeName("TraitTarget"), Multiplicity.OPTIONAL, false, null));
-        
-        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.of(structDef, nestedStructDef),
-            ImmutableList.of(traitDef), ImmutableList.of(structTargetDef, traitTargetDef, structContainerDef));
-        typeSystem.defineTypes(typesDef);
-        
-        // Create instances of class, struct, and trait types.
-        Referenceable structTargetEntity = new Referenceable("StructTarget");
-        Referenceable traitTargetEntity = new Referenceable("TraitTarget");
-        Referenceable structContainerEntity = new Referenceable("StructContainer");
-        Referenceable structInstance = new Referenceable("TestStruct");
-        Referenceable nestedStructInstance = new Referenceable("NestedStruct");
-        Referenceable traitInstance = new Referenceable("TestTrait");
-        structContainerEntity.set("struct", structInstance);
-        structInstance.set("target", ImmutableList.of(structTargetEntity));
-        structInstance.set("nestedStructs", ImmutableList.of(nestedStructInstance));
-        
-        ClassType structTargetType = typeSystem.getDataType(ClassType.class, "StructTarget");
-        ClassType traitTargetType = typeSystem.getDataType(ClassType.class, "TraitTarget");
-        ClassType structContainerType = typeSystem.getDataType(ClassType.class, "StructContainer");
-        
-        ITypedReferenceableInstance structTargetConvertedEntity = 
-            structTargetType.convert(structTargetEntity, Multiplicity.REQUIRED);
-        ITypedReferenceableInstance traitTargetConvertedEntity = 
-            traitTargetType.convert(traitTargetEntity, Multiplicity.REQUIRED);
-        ITypedReferenceableInstance structContainerConvertedEntity =
-            structContainerType.convert(structContainerEntity, Multiplicity.REQUIRED);
-        
-        List<String> guids = repositoryService.createEntities(
-            structTargetConvertedEntity, traitTargetConvertedEntity, structContainerConvertedEntity);
-        Assert.assertEquals(guids.size(), 3);
-        
-        guids = repositoryService.getEntityList("StructTarget");
-        Assert.assertEquals(guids.size(), 1);
-        String structTargetGuid = guids.get(0);
-        
-        guids = repositoryService.getEntityList("TraitTarget");
-        Assert.assertEquals(guids.size(), 1);
-        String traitTargetGuid = guids.get(0);
-
-        guids = repositoryService.getEntityList("StructContainer");
-        Assert.assertEquals(guids.size(), 1);
-        String structContainerGuid = guids.get(0);
-        
-        // Add TestTrait to StructContainer instance
-        traitInstance.set("target", ImmutableList.of(new Id(traitTargetGuid, 0, "TraitTarget")));
-        TraitType traitType = typeSystem.getDataType(TraitType.class, "TestTrait");
-        ITypedStruct convertedTrait = traitType.convert(traitInstance, Multiplicity.REQUIRED);
-        repositoryService.addTrait(structContainerGuid, convertedTrait);
-        
-        // Verify that the unidirectional references from the struct and trait instances
-        // are pointing at the target entities.
-        structContainerConvertedEntity = repositoryService.getEntityDefinition(structContainerGuid);
-        Object object = structContainerConvertedEntity.get("struct");
-        Assert.assertNotNull(object);
-        Assert.assertTrue(object instanceof ITypedStruct);
-        ITypedStruct struct = (ITypedStruct) object;
-        object = struct.get("target");
-        Assert.assertNotNull(object);
-        Assert.assertTrue(object instanceof List);
-        List<ITypedReferenceableInstance> refList = (List<ITypedReferenceableInstance>)object;
-        Assert.assertEquals(refList.size(), 1);
-        Assert.assertEquals(refList.get(0).getId()._getId(), structTargetGuid);
-        
-        IStruct trait = structContainerConvertedEntity.getTrait("TestTrait");
-        Assert.assertNotNull(trait);
-        object = trait.get("target");
-        Assert.assertNotNull(object);
-        Assert.assertTrue(object instanceof List);
-        refList = (List<ITypedReferenceableInstance>)object;
-        Assert.assertEquals(refList.size(), 1);
-        Assert.assertEquals(refList.get(0).getId()._getId(), traitTargetGuid);
-        
-        // Delete the entities that are targets of the struct and trait instances.
-        Pair<List<String>, List<ITypedReferenceableInstance>> deleteEntitiesResult = 
-            repositoryService.deleteEntities(Arrays.asList(structTargetGuid, traitTargetGuid));
-        verifyEntityDoesNotExist(structTargetGuid);
-        verifyEntityDoesNotExist(traitTargetGuid);
-        Assert.assertEquals(deleteEntitiesResult.left.size(), 2);
-        Assert.assertTrue(deleteEntitiesResult.left.containsAll(Arrays.asList(structTargetGuid, traitTargetGuid)));
-        
-        // Verify that the unidirectional references from the struct and trait instances
-        // to the deleted entities were disconnected.
-        structContainerConvertedEntity = repositoryService.getEntityDefinition(structContainerGuid);
-        object = structContainerConvertedEntity.get("struct");
-        Assert.assertNotNull(object);
-        Assert.assertTrue(object instanceof ITypedStruct);
-        struct = (ITypedStruct) object;
-        Assert.assertNull(struct.get("target"));
-        trait = structContainerConvertedEntity.getTrait("TestTrait");
-        Assert.assertNotNull(trait);
-        Assert.assertNull(trait.get("target"));
-        
-        // Delete the entity which contains nested structs and has the TestTrait trait.
-        deleteEntitiesResult = 
-            repositoryService.deleteEntities(Arrays.asList(structContainerGuid));
-        verifyEntityDoesNotExist(structContainerGuid);
-        Assert.assertEquals(deleteEntitiesResult.left.size(), 1);
-        Assert.assertTrue(deleteEntitiesResult.left.contains(structContainerGuid));
-        
-        // Verify all TestStruct struct vertices were removed.
-        int vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "TestStruct");
-        Assert.assertEquals(vertexCount, 0);
-        
-        // Verify all NestedStruct struct vertices were removed.
-        vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "NestedStruct");
-        Assert.assertEquals(vertexCount, 0);
-
-        // Verify all TestTrait trait vertices were removed.
-        vertexCount = countVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "TestTrait");
-        Assert.assertEquals(vertexCount, 0);
-    }
-    
-    /**
-     * Verify deleting entities that are the target of class map references.
-     */
-    @Test
-    public void testDisconnectMapReferenceFromClassType() throws Exception {
-        // Define type for map value.
-        HierarchicalTypeDefinition<ClassType> mapValueDef = TypesUtil.createClassTypeDef("MapValue", 
-            ImmutableSet.<String>of(),
-            new AttributeDefinition("biMapOwner", "MapOwner", Multiplicity.OPTIONAL, false, "biMap"));
-        
-        // Define type with unidirectional and bidirectional map references,
-        // where the map value is a class reference to MapValue.
-        HierarchicalTypeDefinition<ClassType> mapOwnerDef = TypesUtil.createClassTypeDef("MapOwner", 
-            ImmutableSet.<String>of(),
-            new AttributeDefinition("map", DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(),
-                        "MapValue"), Multiplicity.OPTIONAL, false, null),
-            new AttributeDefinition("biMap", DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(),
-                "MapValue"), Multiplicity.OPTIONAL, false, "biMapOwner"));
-        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(),
-            ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(),
-            ImmutableList.of(mapOwnerDef, mapValueDef));
-        typeSystem.defineTypes(typesDef);
-        ClassType mapOwnerType = typeSystem.getDataType(ClassType.class, "MapOwner");
-        ClassType mapValueType = typeSystem.getDataType(ClassType.class, "MapValue");
-        
-        // Create instances of MapOwner and MapValue.
-        // Set MapOwner.map and MapOwner.biMap with one entry that references MapValue instance.
-        ITypedReferenceableInstance mapOwnerInstance = mapOwnerType.createInstance();
-        ITypedReferenceableInstance mapValueInstance = mapValueType.createInstance();
-        mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance));
-        mapOwnerInstance.set("biMap", Collections.singletonMap("value1", mapValueInstance));
-        // Set biMapOwner reverse reference on MapValue.
-        mapValueInstance.set("biMapOwner", mapOwnerInstance);
-        List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance);
-        Assert.assertEquals(createEntitiesResult.size(), 2);
-        List<String> guids = repositoryService.getEntityList("MapOwner");
-        Assert.assertEquals(guids.size(), 1);
-        String mapOwnerGuid = guids.get(0);
-        
-        String edgeLabel = GraphHelper.getEdgeLabel(mapOwnerType, mapOwnerType.fieldMapping.fields.get("map"));
-        String mapEntryLabel = edgeLabel + "." + "value1";
-        AtlasEdgeLabel atlasEdgeLabel = new AtlasEdgeLabel(mapEntryLabel);
-        edgeLabel = GraphHelper.getEdgeLabel(mapOwnerType, mapOwnerType.fieldMapping.fields.get("biMap"));
-        mapEntryLabel = edgeLabel + "." + "value1";
-        AtlasEdgeLabel biMapAtlasEdgeLabel = new AtlasEdgeLabel(mapEntryLabel);
-        
-        // Verify MapOwner.map attribute has expected value.
-        String mapValueGuid = null;
-        Vertex mapOwnerVertex = null;
-        mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
-        for (String mapAttrName : Arrays.asList("map", "biMap")) {
-            Object object = mapOwnerInstance.get(mapAttrName);
-            Assert.assertNotNull(object);
-            Assert.assertTrue(object instanceof Map);
-            Map<String, ITypedReferenceableInstance> map = (Map<String, ITypedReferenceableInstance>)object;
-            Assert.assertEquals(map.size(), 1);
-            mapValueInstance = map.get("value1");
-            Assert.assertNotNull(mapValueInstance);
-            mapValueGuid = mapValueInstance.getId()._getId();
-            mapOwnerVertex = GraphHelper.getInstance().getVertexForGUID(mapOwnerGuid);
-            object = mapOwnerVertex.getProperty(atlasEdgeLabel.getQualifiedMapKey());
-            Assert.assertNotNull(object);
-        }
-        
-        // Delete the map value instance.
-        // This should disconnect the references from the map owner instance. 
-        Pair<List<String>, List<ITypedReferenceableInstance>> deleteEntitiesResult = 
-            repositoryService.deleteEntities(Arrays.asList(mapValueGuid));
-        verifyEntityDoesNotExist(mapValueGuid);
-        
-        // Verify map references from mapOwner were disconnected.
-        mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
-        Assert.assertNull(mapOwnerInstance.get("map"));
-        Assert.assertNull(mapOwnerInstance.get("biMap"));
-        mapOwnerVertex = GraphHelper.getInstance().getVertexForGUID(mapOwnerGuid);
-        Object object = mapOwnerVertex.getProperty(atlasEdgeLabel.getQualifiedMapKey());
-        Assert.assertNull(object);
-        object = mapOwnerVertex.getProperty(biMapAtlasEdgeLabel.getQualifiedMapKey());
-        Assert.assertNull(object);
-    }
-    
-    private String createHrDeptGraph() throws Exception {
-        Referenceable deptEg1 = TestUtils.createDeptEg1(typeSystem);
-        ClassType deptType = typeSystem.getDataType(ClassType.class, "Department");
-        ITypedReferenceableInstance hrDept2 = deptType.convert(deptEg1, Multiplicity.REQUIRED);
-
-        List<String> guids = repositoryService.createEntities(hrDept2);
-        Assert.assertNotNull(guids);
-        Assert.assertEquals(guids.size(), 5);
-
-        List<String> entityList = repositoryService.getEntityList("Department");
-        Assert.assertNotNull(entityList);
-        Assert.assertEquals(entityList.size(), 1);
-        return entityList.get(0);
-    }
-    
-    private void createDbTableGraph() throws Exception {
-        Referenceable databaseInstance = new Referenceable(TestUtils.DATABASE_TYPE);
-        databaseInstance.set("name", TestUtils.DATABASE_NAME);
-        databaseInstance.set("description", "foo database");
- 
-        ClassType dbType = typeSystem.getDataType(ClassType.class, TestUtils.DATABASE_TYPE);
-        ITypedReferenceableInstance db = dbType.convert(databaseInstance, Multiplicity.REQUIRED);
-        Referenceable tableInstance = new Referenceable(TestUtils.TABLE_TYPE, TestUtils.CLASSIFICATION);
-        tableInstance.set("name", TestUtils.TABLE_NAME);
-        tableInstance.set("description", "bar table");
-        tableInstance.set("type", "managed");
-        Struct traitInstance = (Struct) tableInstance.getTrait(TestUtils.CLASSIFICATION);
-        traitInstance.set("tag", "foundation_etl");
-        tableInstance.set("tableType", 1); // enum
-
-        tableInstance.set("database", databaseInstance);
-        ArrayList<Referenceable> columns = new ArrayList<>();
-        for (int index = 0; index < 5; index++) {
-            Referenceable columnInstance = new Referenceable("column_type");
-            final String name = "column_" + index;
-            columnInstance.set("name", name);
-            columnInstance.set("type", "string");
-            columns.add(columnInstance);
-        }
-        tableInstance.set("columns", columns);
-        ClassType tableType = typeSystem.getDataType(ClassType.class, TestUtils.TABLE_TYPE);
-        ITypedReferenceableInstance table = tableType.convert(tableInstance, Multiplicity.REQUIRED);
-        repositoryService.createEntities(db, table);
-    }
-    
-    private int countVertices(String propertyName, Object value) {
-        Iterable<Vertex> vertices = graphProvider.get().getVertices(propertyName, value);
-        int vertexCount = 0;
-        for (Vertex vertex : vertices) {
-            vertexCount++;
-        }
-        return vertexCount;
-    }
-    
-    private void verifyEntityDoesNotExist(String guid) throws RepositoryException {
-        try {
-            repositoryService.getEntityDefinition(guid);
-            Assert.fail("EntityNotFoundException was expected but none thrown");
-        } catch(EntityNotFoundException e) {
-            // good
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/40ee9492/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteTestBase.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
new file mode 100644
index 0000000..ae215f9
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryDeleteTestBase.java
@@ -0,0 +1,772 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+package org.apache.atlas.repository.graph;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.thinkaurelius.titan.core.TitanGraph;
+import com.thinkaurelius.titan.core.util.TitanCleanup;
+import com.tinkerpop.blueprints.Vertex;
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.RepositoryMetadataModule;
+import org.apache.atlas.RequestContext;
+import org.apache.atlas.TestUtils;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.repository.RepositoryException;
+import org.apache.atlas.typesystem.IReferenceableInstance;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+import org.apache.atlas.typesystem.ITypedStruct;
+import org.apache.atlas.typesystem.Referenceable;
+import org.apache.atlas.typesystem.Struct;
+import org.apache.atlas.typesystem.TypesDef;
+import org.apache.atlas.typesystem.exception.EntityNotFoundException;
+import org.apache.atlas.typesystem.persistence.Id;
+import org.apache.atlas.typesystem.types.AttributeDefinition;
+import org.apache.atlas.typesystem.types.ClassType;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.atlas.typesystem.types.EnumTypeDefinition;
+import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition;
+import org.apache.atlas.typesystem.types.Multiplicity;
+import org.apache.atlas.typesystem.types.StructTypeDefinition;
+import org.apache.atlas.typesystem.types.TraitType;
+import org.apache.atlas.typesystem.types.TypeSystem;
+import org.apache.atlas.typesystem.types.TypeUtils;
+import org.apache.atlas.typesystem.types.utils.TypesUtil;
+import org.testng.Assert;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.atlas.TestUtils.COLUMNS_ATTR_NAME;
+import static org.apache.atlas.TestUtils.COLUMN_TYPE;
+import static org.apache.atlas.TestUtils.NAME;
+import static org.apache.atlas.TestUtils.PROCESS_TYPE;
+import static org.apache.atlas.TestUtils.TABLE_TYPE;
+import static org.apache.atlas.TestUtils.createColumnEntity;
+import static org.apache.atlas.TestUtils.createDBEntity;
+import static org.apache.atlas.TestUtils.createTableEntity;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * Test for GraphBackedMetadataRepository.deleteEntities
+ *
+ * Guice loads the dependencies and injects the necessary objects
+ *
+ */
+@Guice(modules = RepositoryMetadataModule.class)
+public abstract class GraphBackedMetadataRepositoryDeleteTestBase {
+
+    @Inject
+    private GraphProvider<TitanGraph> graphProvider;
+
+    protected GraphBackedMetadataRepository repositoryService;
+
+    private TypeSystem typeSystem;
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        typeSystem = TypeSystem.getInstance();
+        typeSystem.reset();
+
+        new GraphBackedSearchIndexer(graphProvider);
+
+        repositoryService = new GraphBackedMetadataRepository(graphProvider, getDeleteHandler(typeSystem));
+
+        TestUtils.defineDeptEmployeeTypes(typeSystem);
+        TestUtils.createHiveTypes(typeSystem);
+    }
+
+    abstract DeleteHandler getDeleteHandler(TypeSystem typeSystem);
+
+    @BeforeMethod
+    public void setupContext() {
+        RequestContext.createContext();
+    }
+
+    @AfterClass
+    public void tearDown() throws Exception {
+        TypeSystem.getInstance().reset();
+        try {
+            graphProvider.get().shutdown();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            TitanCleanup.clear(graphProvider.get());
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Test
+    public void testDeleteAndCreate() throws Exception {
+        Referenceable entity = createDBEntity();
+        String id = createInstance(entity);
+
+        //get entity by unique attribute should return the created entity
+        ITypedReferenceableInstance instance =
+                repositoryService.getEntityDefinition(TestUtils.DATABASE_TYPE, "name", entity.get("name"));
+        assertEquals(instance.getId()._getId(), id);
+
+        //delete entity should mark it as deleted
+        List<String> results = deleteEntities(id);
+        assertEquals(results.get(0), id);
+        assertEntityDeleted(id);
+
+        //get entity by unique attribute should throw EntityNotFoundException
+        try {
+            repositoryService.getEntityDefinition(TestUtils.DATABASE_TYPE, "name", entity.get("name"));
+            fail("Expected EntityNotFoundException");
+        } catch(EntityNotFoundException e) {
+            //expected
+        }
+
+        //Create the same entity again, should create new entity
+        String newId = createInstance(entity);
+        assertNotEquals(id, newId);
+
+        //get by unique attribute should return the new entity
+        instance = repositoryService.getEntityDefinition(TestUtils.DATABASE_TYPE, "name", entity.get("name"));
+        assertEquals(instance.getId()._getId(), newId);
+    }
+
+    @Test
+    public void testDeleteReference() throws Exception {
+        //Deleting column should update table
+        Referenceable db = createDBEntity();
+        String dbId = createInstance(db);
+
+        Referenceable column = createColumnEntity();
+        String colId = createInstance(column);
+
+        Referenceable table = createTableEntity(dbId);
+        table.set(COLUMNS_ATTR_NAME, Arrays.asList(new Id(colId, 0, COLUMN_TYPE)));
+        String tableId = createInstance(table);
+
+        deleteEntities(colId);
+        assertEntityDeleted(colId);
+
+        ITypedReferenceableInstance tableInstance = repositoryService.getEntityDefinition(tableId);
+        List<ITypedReferenceableInstance> columns =
+                (List<ITypedReferenceableInstance>) tableInstance.get(COLUMNS_ATTR_NAME);
+        assertNull(columns);
+
+        //Deleting table should update process
+        Referenceable process = new Referenceable(PROCESS_TYPE);
+        process.set(AtlasClient.PROCESS_ATTRIBUTE_OUTPUTS, Arrays.asList(new Id(tableId, 0, TABLE_TYPE)));
+        String processId = createInstance(process);
+        ITypedReferenceableInstance processInstance = repositoryService.getEntityDefinition(processId);
+
+        deleteEntities(tableId);
+        assertEntityDeleted(tableId);
+        assertTestDeleteReference(processInstance);
+    }
+
+    protected abstract void assertTestDeleteReference(ITypedReferenceableInstance processInstance) throws Exception;
+
+    protected abstract void assertEntityDeleted(String id) throws Exception;
+
+    private List<String> deleteEntities(String... id) throws Exception {
+        RequestContext.createContext();
+        List<String> response = repositoryService.deleteEntities(Arrays.asList(id)).left;
+        assertNotNull(response);
+        return response;
+    }
+
+    private String createInstance(Referenceable entity) throws Exception {
+        ClassType dataType = typeSystem.getDataType(ClassType.class, entity.getTypeName());
+        ITypedReferenceableInstance instance = dataType.convert(entity, Multiplicity.REQUIRED);
+        List<String> results = repositoryService.createEntities(instance);
+        return results.get(results.size() - 1);
+    }
+
+    @Test
+    public void testDeleteEntities() throws Exception {
+        // Create a table entity, with 3 composite column entities
+        Referenceable dbEntity = createDBEntity();
+        String dbGuid = createInstance(dbEntity);
+        Referenceable table1Entity = createTableEntity(dbGuid);
+        Referenceable col1 = createColumnEntity();
+        Referenceable col2 = createColumnEntity();
+        Referenceable col3 = createColumnEntity();
+        table1Entity.set(COLUMNS_ATTR_NAME, ImmutableList.of(col1, col2, col3));
+        createInstance(table1Entity);
+
+        // Retrieve the table entities from the auditRepository,
+        // to get their guids and the composite column guids.
+        ITypedReferenceableInstance tableInstance = repositoryService.getEntityDefinition(TestUtils.TABLE_TYPE,
+                NAME, table1Entity.get(NAME));
+        List<IReferenceableInstance> table1Columns = (List<IReferenceableInstance>) tableInstance.get(COLUMNS_ATTR_NAME);
+
+        // Delete the table entities.  The deletion should cascade
+        // to their composite columns.
+        List<String> deletedGuids = deleteEntities(tableInstance.getId()._getId());
+
+        // Verify that deleteEntities() response has guids for tables and their composite columns.
+        Assert.assertTrue(deletedGuids.contains(tableInstance.getId()._getId()));
+        for (IReferenceableInstance column : table1Columns) {
+            Assert.assertTrue(deletedGuids.contains(column.getId()._getId()));
+        }
+
+        // Verify that tables and their composite columns have been deleted from the graph Repository.
+        for (String guid : deletedGuids) {
+            assertEntityDeleted(guid);
+        }
+        assertTestDeleteEntities(tableInstance);
+    }
+
+    protected abstract void assertTestDeleteEntities(ITypedReferenceableInstance tableInstance) throws Exception;
+
+    /**
+     * Verify deleting entities with composite references to other entities.
+     * The composite entities should also be deleted.
+     */
+    @Test
+    public void testDeleteEntitiesWithCompositeArrayReference() throws Exception {
+        String hrDeptGuid = createHrDeptGraph();
+
+        ITypedReferenceableInstance hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
+        List<ITypedReferenceableInstance> employees = (List<ITypedReferenceableInstance>) hrDept.get("employees");
+        Assert.assertEquals(employees.size(), 4);
+
+        List<String> employeeGuids = new ArrayList(4);
+        for (ITypedReferenceableInstance employee : employees) {
+            employeeGuids.add(employee.getId()._getId());
+        }
+        
+        // There should be 4 vertices for Address structs (one for each Person.address attribute value).
+        int vertexCount = getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "Address").size();
+        Assert.assertEquals(vertexCount, 4);
+        vertexCount = getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "SecurityClearance").size();
+        Assert.assertEquals(vertexCount, 1);
+
+        List<String> deletedEntities = deleteEntities(hrDeptGuid);
+        assertTrue(deletedEntities.contains(hrDeptGuid));
+
+        // Verify Department entity and its contained Person entities were deleted.
+        assertEntityDeleted(hrDeptGuid);
+        for (String employeeGuid : employeeGuids) {
+            assertEntityDeleted(employeeGuid);
+        }
+
+        // Verify all Person.address struct vertices were removed.
+        assertVerticesDeleted(getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "Address"));
+
+        // Verify all SecurityClearance trait vertices were removed.
+        assertVerticesDeleted(getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "SecurityClearance"));
+    }
+
+    protected abstract void assertVerticesDeleted(List<Vertex> vertices);
+
+    @Test
+    public void testDeleteEntitiesWithCompositeMapReference() throws Exception {
+        // Define type for map value.
+        HierarchicalTypeDefinition<ClassType> mapValueDef = TypesUtil.createClassTypeDef("CompositeMapValue", 
+            ImmutableSet.<String>of(),
+            TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
+        
+        // Define type with map where the value is a composite class reference to MapValue.
+        HierarchicalTypeDefinition<ClassType> mapOwnerDef = TypesUtil.createClassTypeDef("CompositeMapOwner", 
+            ImmutableSet.<String>of(),
+            new AttributeDefinition("map", DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(),
+                        "CompositeMapValue"), Multiplicity.OPTIONAL, true, null));
+        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(),
+            ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(),
+            ImmutableList.of(mapOwnerDef, mapValueDef));
+        typeSystem.defineTypes(typesDef);
+        ClassType mapOwnerType = typeSystem.getDataType(ClassType.class, "CompositeMapOwner");
+        ClassType mapValueType = typeSystem.getDataType(ClassType.class, "CompositeMapValue");
+        
+        // Create instances of MapOwner and MapValue.
+        // Set MapOwner.map with one entry that references MapValue instance.
+        ITypedReferenceableInstance mapOwnerInstance = mapOwnerType.createInstance();
+        ITypedReferenceableInstance mapValueInstance = mapValueType.createInstance();
+        mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance));
+        List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance);
+        Assert.assertEquals(createEntitiesResult.size(), 2);
+        List<String> guids = repositoryService.getEntityList("CompositeMapOwner");
+        Assert.assertEquals(guids.size(), 1);
+        String mapOwnerGuid = guids.get(0);
+        
+        // Verify MapOwner.map attribute has expected value.
+        mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
+        Object object = mapOwnerInstance.get("map");
+        Assert.assertNotNull(object);
+        Assert.assertTrue(object instanceof Map);
+        Map<String, ITypedReferenceableInstance> map = (Map<String, ITypedReferenceableInstance>)object;
+        Assert.assertEquals(map.size(), 1);
+        mapValueInstance = map.get("value1");
+        Assert.assertNotNull(mapValueInstance);
+        String mapValueGuid = mapValueInstance.getId()._getId();
+        String edgeLabel = GraphHelper.getEdgeLabel(mapOwnerType, mapOwnerType.fieldMapping.fields.get("map"));
+        String mapEntryLabel = edgeLabel + "." + "value1";
+        AtlasEdgeLabel atlasEdgeLabel = new AtlasEdgeLabel(mapEntryLabel);
+        Vertex mapOwnerVertex = GraphHelper.getInstance().getVertexForGUID(mapOwnerGuid);
+        object = mapOwnerVertex.getProperty(atlasEdgeLabel.getQualifiedMapKey());
+        Assert.assertNotNull(object);
+
+        List<String> deletedEntities = deleteEntities(mapOwnerGuid);
+        Assert.assertEquals(deletedEntities.size(), 2);
+        Assert.assertTrue(deletedEntities.containsAll(guids));
+
+        assertEntityDeleted(mapOwnerGuid);
+        assertEntityDeleted(mapValueGuid);
+    }
+
+    private TypeUtils.Pair<List<String>, List<String>> updatePartial(ITypedReferenceableInstance entity) throws RepositoryException {
+        RequestContext.createContext();
+        return repositoryService.updatePartial(entity);
+    }
+
+    @Test
+    public void testUpdateEntity_MultiplicityOneNonCompositeReference() throws Exception {
+        ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
+        repositoryService.createEntities(hrDept);
+
+        ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Person", "name", "John");
+        Id johnGuid = john.getId();
+
+        ITypedReferenceableInstance max = repositoryService.getEntityDefinition("Person", "name", "Max");
+        String maxGuid = max.getId()._getId();
+        Vertex vertex = GraphHelper.getInstance().getVertexForGUID(maxGuid);
+        Long creationTimestamp = vertex.getProperty(Constants.TIMESTAMP_PROPERTY_KEY);
+        Assert.assertNotNull(creationTimestamp);
+
+        Long modificationTimestampPreUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
+        Assert.assertNotNull(modificationTimestampPreUpdate);
+
+        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Person", "name", "Jane");
+        Id janeGuid = jane.getId();
+
+        // Update max's mentor reference to john.
+        ClassType personType = typeSystem.getDataType(ClassType.class, "Person");
+        ITypedReferenceableInstance maxEntity = personType.createInstance(max.getId());
+        maxEntity.set("mentor", johnGuid);
+        updatePartial(maxEntity);
+
+        // Verify the update was applied correctly - john should now be max's mentor.
+        max = repositoryService.getEntityDefinition(maxGuid);
+        ITypedReferenceableInstance refTarget = (ITypedReferenceableInstance) max.get("mentor");
+        Assert.assertEquals(refTarget.getId()._getId(), johnGuid._getId());
+
+        // Verify modification timestamp was updated.
+        vertex = GraphHelper.getInstance().getVertexForGUID(maxGuid);
+        Long modificationTimestampPostUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
+        Assert.assertNotNull(modificationTimestampPostUpdate);
+        Assert.assertTrue(creationTimestamp < modificationTimestampPostUpdate);
+
+        // Update max's mentor reference to jane.
+        maxEntity.set("mentor", janeGuid);
+        updatePartial(maxEntity);
+
+        // Verify the update was applied correctly - jane should now be max's mentor.
+        max = repositoryService.getEntityDefinition(maxGuid);
+        refTarget = (ITypedReferenceableInstance) max.get("mentor");
+        Assert.assertEquals(refTarget.getId()._getId(), janeGuid._getId());
+
+        // Verify modification timestamp was updated.
+        vertex = GraphHelper.getInstance().getVertexForGUID(maxGuid);
+        Long modificationTimestampPost2ndUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
+        Assert.assertNotNull(modificationTimestampPost2ndUpdate);
+        Assert.assertTrue(modificationTimestampPostUpdate < modificationTimestampPost2ndUpdate);
+
+        ITypedReferenceableInstance julius = repositoryService.getEntityDefinition("Person", "name", "Julius");
+        Id juliusGuid = julius.getId();
+        maxEntity = personType.createInstance(max.getId());
+        maxEntity.set("manager", juliusGuid);
+        updatePartial(maxEntity);
+
+        // Verify the update was applied correctly - julius should now be max's manager.
+        max = repositoryService.getEntityDefinition(maxGuid);
+        refTarget = (ITypedReferenceableInstance) max.get("manager");
+        Assert.assertEquals(refTarget.getId()._getId(), juliusGuid._getId());
+
+        assertTestUpdateEntity_MultiplicityOneNonCompositeReference();
+    }
+
+    protected abstract void assertTestUpdateEntity_MultiplicityOneNonCompositeReference() throws Exception;
+
+    /**
+     * Verify deleting an entity which is contained by another
+     * entity through a bi-directional composite reference.
+     * 
+     * @throws Exception
+     */
+    @Test
+    public void testDisconnectBidirectionalReferences() throws Exception {
+        String hrDeptGuid = createHrDeptGraph();
+        ITypedReferenceableInstance hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
+        Object refValue = hrDept.get("employees");
+        Assert.assertTrue(refValue instanceof List);
+        List<Object> employees = (List<Object>)refValue;
+        Assert.assertEquals(employees.size(), 4);
+        String maxGuid = null;
+        for (Object listValue : employees) {
+            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
+            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
+            if (employee.get("name").equals("Max")) {
+                maxGuid = employee.getId()._getId();
+            }
+        }
+        Assert.assertNotNull(maxGuid);
+        
+        // Verify that Max is one of Jane's subordinates.
+        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Manager", "name", "Jane");
+        refValue = jane.get("subordinates");
+        Assert.assertTrue(refValue instanceof List);
+        List<Object> subordinates = (List<Object>)refValue;
+        Assert.assertEquals(subordinates.size(), 2);
+        List<String> subordinateIds = new ArrayList<>(2);
+        for (Object listValue : employees) {
+            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
+            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
+            subordinateIds.add(employee.getId()._getId());
+        }
+        Assert.assertTrue(subordinateIds.contains(maxGuid));
+
+        List<String> deletedEntities = deleteEntities(maxGuid);
+        Assert.assertTrue(deletedEntities.contains(maxGuid));
+        assertEntityDeleted(maxGuid);
+        
+        // Verify that the Department.employees reference to the deleted employee
+        // was disconnected.
+        hrDept = repositoryService.getEntityDefinition(hrDeptGuid);
+        refValue = hrDept.get("employees");
+        Assert.assertTrue(refValue instanceof List);
+        employees = (List<Object>)refValue;
+        Assert.assertEquals(employees.size(), 3);
+        for (Object listValue : employees) {
+            Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
+            ITypedReferenceableInstance employee = (ITypedReferenceableInstance) listValue;
+            Assert.assertNotEquals(employee.getId()._getId(), maxGuid);
+        }
+
+        // Verify that max's Person.mentor unidirectional reference to john was disconnected.
+        ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Manager", "name", "John");
+        refValue = john.get("mentor");
+        Assert.assertNull(refValue);
+
+        assertTestDisconnectBidirectionalReferences();
+
+        // Now delete jane - this should disconnect the manager reference from her
+        // subordinate.
+        String janeGuid = jane.getId()._getId();
+        deletedEntities = deleteEntities(janeGuid);
+        Assert.assertTrue(deletedEntities.contains(janeGuid));
+        assertEntityDeleted(janeGuid);
+
+        john = repositoryService.getEntityDefinition("Person", "name", "John");
+        Assert.assertNull(john.get("manager"));
+    }
+
+    protected abstract void assertTestDisconnectBidirectionalReferences() throws Exception;
+
+    /**
+     * Verify deleting entity that is the target of a unidirectional class array reference
+     * from a class instance.
+     */
+    @Test
+    public void testDisconnectUnidirectionalArrayReferenceFromClassType() throws Exception {
+        createDbTableGraph();
+        
+        // Get the guid for one of the table's columns.
+        ITypedReferenceableInstance table = repositoryService.getEntityDefinition(TestUtils.TABLE_TYPE, "name", TestUtils.TABLE_NAME);
+        String tableGuid = table.getId()._getId();
+        Object refValues = table.get("columns");
+        Assert.assertTrue(refValues instanceof List);
+        List<Object> refList = (List<Object>) refValues;
+        Assert.assertEquals(refList.size(), 5);
+        Assert.assertTrue(refList.get(0) instanceof ITypedReferenceableInstance);
+        ITypedReferenceableInstance column = (ITypedReferenceableInstance) refList.get(0);
+        String columnGuid = column.getId()._getId();
+        
+        // Delete the column.
+        List<String> deletedEntities = deleteEntities(columnGuid);
+        Assert.assertTrue(deletedEntities.contains(columnGuid));
+        assertEntityDeleted(columnGuid);
+        
+        // Verify table.columns reference to the deleted column has been disconnected.
+        table = repositoryService.getEntityDefinition(tableGuid);
+        refList = (List<Object>) table.get("columns");
+        Assert.assertEquals(refList.size(), 4);
+        for (Object refValue : refList) {
+            Assert.assertTrue(refValue instanceof ITypedReferenceableInstance);
+            column = (ITypedReferenceableInstance)refValue;
+            Assert.assertFalse(column.getId()._getId().equals(columnGuid));
+        }
+    }
+    
+    /**
+     * Verify deleting entities that are the target of a unidirectional class array reference
+     * from a struct or trait instance.
+     */
+    @Test
+    public void testDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes() throws Exception {
+        // Define class types.
+        HierarchicalTypeDefinition<ClassType> structTargetDef = TypesUtil.createClassTypeDef("StructTarget", 
+            ImmutableSet.<String>of(), TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
+        HierarchicalTypeDefinition<ClassType> traitTargetDef = TypesUtil.createClassTypeDef("TraitTarget", 
+            ImmutableSet.<String>of(), TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
+        HierarchicalTypeDefinition<ClassType> structContainerDef = TypesUtil.createClassTypeDef("StructContainer", 
+            ImmutableSet.<String>of(), TypesUtil.createOptionalAttrDef("struct", "TestStruct"));
+        
+        // Define struct and trait types which have a unidirectional array reference
+        // to a class type.
+        StructTypeDefinition structDef = TypesUtil.createStructTypeDef("TestStruct", 
+            new AttributeDefinition("target", DataTypes.arrayTypeName("StructTarget"), Multiplicity.OPTIONAL, false, null),
+            new AttributeDefinition("nestedStructs", DataTypes.arrayTypeName("NestedStruct"), Multiplicity.OPTIONAL, false, null));
+        StructTypeDefinition nestedStructDef = TypesUtil.createStructTypeDef("NestedStruct", 
+            TypesUtil.createOptionalAttrDef("attr1", DataTypes.STRING_TYPE));
+        HierarchicalTypeDefinition<TraitType> traitDef = TypesUtil.createTraitTypeDef("TestTrait", ImmutableSet.<String>of(), 
+            new AttributeDefinition("target", DataTypes.arrayTypeName("TraitTarget"), Multiplicity.OPTIONAL, false, null));
+        
+        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(), ImmutableList.of(structDef, nestedStructDef),
+            ImmutableList.of(traitDef), ImmutableList.of(structTargetDef, traitTargetDef, structContainerDef));
+        typeSystem.defineTypes(typesDef);
+        
+        // Create instances of class, struct, and trait types.
+        Referenceable structTargetEntity = new Referenceable("StructTarget");
+        Referenceable traitTargetEntity = new Referenceable("TraitTarget");
+        Referenceable structContainerEntity = new Referenceable("StructContainer");
+        Referenceable structInstance = new Referenceable("TestStruct");
+        Referenceable nestedStructInstance = new Referenceable("NestedStruct");
+        Referenceable traitInstance = new Referenceable("TestTrait");
+        structContainerEntity.set("struct", structInstance);
+        structInstance.set("target", ImmutableList.of(structTargetEntity));
+        structInstance.set("nestedStructs", ImmutableList.of(nestedStructInstance));
+        
+        ClassType structTargetType = typeSystem.getDataType(ClassType.class, "StructTarget");
+        ClassType traitTargetType = typeSystem.getDataType(ClassType.class, "TraitTarget");
+        ClassType structContainerType = typeSystem.getDataType(ClassType.class, "StructContainer");
+        
+        ITypedReferenceableInstance structTargetConvertedEntity = 
+            structTargetType.convert(structTargetEntity, Multiplicity.REQUIRED);
+        ITypedReferenceableInstance traitTargetConvertedEntity = 
+            traitTargetType.convert(traitTargetEntity, Multiplicity.REQUIRED);
+        ITypedReferenceableInstance structContainerConvertedEntity =
+            structContainerType.convert(structContainerEntity, Multiplicity.REQUIRED);
+        
+        List<String> guids = repositoryService.createEntities(
+            structTargetConvertedEntity, traitTargetConvertedEntity, structContainerConvertedEntity);
+        Assert.assertEquals(guids.size(), 3);
+        
+        guids = repositoryService.getEntityList("StructTarget");
+        Assert.assertEquals(guids.size(), 1);
+        String structTargetGuid = guids.get(0);
+        
+        guids = repositoryService.getEntityList("TraitTarget");
+        Assert.assertEquals(guids.size(), 1);
+        String traitTargetGuid = guids.get(0);
+
+        guids = repositoryService.getEntityList("StructContainer");
+        Assert.assertEquals(guids.size(), 1);
+        String structContainerGuid = guids.get(0);
+        
+        // Add TestTrait to StructContainer instance
+        traitInstance.set("target", ImmutableList.of(new Id(traitTargetGuid, 0, "TraitTarget")));
+        TraitType traitType = typeSystem.getDataType(TraitType.class, "TestTrait");
+        ITypedStruct convertedTrait = traitType.convert(traitInstance, Multiplicity.REQUIRED);
+        repositoryService.addTrait(structContainerGuid, convertedTrait);
+        
+        // Verify that the unidirectional references from the struct and trait instances
+        // are pointing at the target entities.
+        structContainerConvertedEntity = repositoryService.getEntityDefinition(structContainerGuid);
+        Object object = structContainerConvertedEntity.get("struct");
+        Assert.assertNotNull(object);
+        Assert.assertTrue(object instanceof ITypedStruct);
+        ITypedStruct struct = (ITypedStruct) object;
+        object = struct.get("target");
+        Assert.assertNotNull(object);
+        Assert.assertTrue(object instanceof List);
+        List<ITypedReferenceableInstance> refList = (List<ITypedReferenceableInstance>)object;
+        Assert.assertEquals(refList.size(), 1);
+        Assert.assertEquals(refList.get(0).getId()._getId(), structTargetGuid);
+        
+        IStruct trait = structContainerConvertedEntity.getTrait("TestTrait");
+        Assert.assertNotNull(trait);
+        object = trait.get("target");
+        Assert.assertNotNull(object);
+        Assert.assertTrue(object instanceof List);
+        refList = (List<ITypedReferenceableInstance>)object;
+        Assert.assertEquals(refList.size(), 1);
+        Assert.assertEquals(refList.get(0).getId()._getId(), traitTargetGuid);
+        
+        // Delete the entities that are targets of the struct and trait instances.
+        List<String> deletedEntities = deleteEntities(structTargetGuid, traitTargetGuid);
+        assertEntityDeleted(structTargetGuid);
+        assertEntityDeleted(traitTargetGuid);
+        Assert.assertEquals(deletedEntities.size(), 2);
+        Assert.assertTrue(deletedEntities.containsAll(Arrays.asList(structTargetGuid, traitTargetGuid)));
+
+        assertTestDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes(structContainerGuid);
+
+        // Delete the entity which contains nested structs and has the TestTrait trait.
+        deletedEntities = deleteEntities(structContainerGuid);
+        assertEntityDeleted(structContainerGuid);
+        Assert.assertEquals(deletedEntities.size(), 1);
+        Assert.assertTrue(deletedEntities.contains(structContainerGuid));
+        
+        // Verify all TestStruct struct vertices were removed.
+        assertVerticesDeleted(getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "TestStruct"));
+
+        // Verify all NestedStruct struct vertices were removed.
+        assertVerticesDeleted(getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "NestedStruct"));
+
+        // Verify all TestTrait trait vertices were removed.
+        assertVerticesDeleted(getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, "TestTrait"));
+    }
+
+    protected abstract void assertTestDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes(
+            String structContainerGuid) throws Exception;
+
+    /**
+     * Verify deleting entities that are the target of class map references.
+     */
+    @Test
+    public void testDisconnectMapReferenceFromClassType() throws Exception {
+        // Define type for map value.
+        HierarchicalTypeDefinition<ClassType> mapValueDef = TypesUtil.createClassTypeDef("MapValue", 
+            ImmutableSet.<String>of(),
+            new AttributeDefinition("biMapOwner", "MapOwner", Multiplicity.OPTIONAL, false, "biMap"));
+        
+        // Define type with unidirectional and bidirectional map references,
+        // where the map value is a class reference to MapValue.
+        HierarchicalTypeDefinition<ClassType> mapOwnerDef = TypesUtil.createClassTypeDef("MapOwner", 
+            ImmutableSet.<String>of(),
+            new AttributeDefinition("map", DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(),
+                        "MapValue"), Multiplicity.OPTIONAL, false, null),
+            new AttributeDefinition("biMap", DataTypes.mapTypeName(DataTypes.STRING_TYPE.getName(),
+                "MapValue"), Multiplicity.OPTIONAL, false, "biMapOwner"));
+        TypesDef typesDef = TypesUtil.getTypesDef(ImmutableList.<EnumTypeDefinition>of(),
+            ImmutableList.<StructTypeDefinition>of(), ImmutableList.<HierarchicalTypeDefinition<TraitType>>of(),
+            ImmutableList.of(mapOwnerDef, mapValueDef));
+        typeSystem.defineTypes(typesDef);
+        ClassType mapOwnerType = typeSystem.getDataType(ClassType.class, "MapOwner");
+        ClassType mapValueType = typeSystem.getDataType(ClassType.class, "MapValue");
+        
+        // Create instances of MapOwner and MapValue.
+        // Set MapOwner.map and MapOwner.biMap with one entry that references MapValue instance.
+        ITypedReferenceableInstance mapOwnerInstance = mapOwnerType.createInstance();
+        ITypedReferenceableInstance mapValueInstance = mapValueType.createInstance();
+        mapOwnerInstance.set("map", Collections.singletonMap("value1", mapValueInstance));
+        mapOwnerInstance.set("biMap", Collections.singletonMap("value1", mapValueInstance));
+        // Set biMapOwner reverse reference on MapValue.
+        mapValueInstance.set("biMapOwner", mapOwnerInstance);
+        List<String> createEntitiesResult = repositoryService.createEntities(mapOwnerInstance, mapValueInstance);
+        Assert.assertEquals(createEntitiesResult.size(), 2);
+        List<String> guids = repositoryService.getEntityList("MapOwner");
+        Assert.assertEquals(guids.size(), 1);
+        String mapOwnerGuid = guids.get(0);
+
+        String edgeLabel = GraphHelper.getEdgeLabel(mapOwnerType, mapOwnerType.fieldMapping.fields.get("map"));
+        String mapEntryLabel = edgeLabel + "." + "value1";
+        AtlasEdgeLabel atlasEdgeLabel = new AtlasEdgeLabel(mapEntryLabel);
+
+        // Verify MapOwner.map attribute has expected value.
+        String mapValueGuid = null;
+        Vertex mapOwnerVertex = null;
+        mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
+        for (String mapAttrName : Arrays.asList("map", "biMap")) {
+            Object object = mapOwnerInstance.get(mapAttrName);
+            Assert.assertNotNull(object);
+            Assert.assertTrue(object instanceof Map);
+            Map<String, ITypedReferenceableInstance> map = (Map<String, ITypedReferenceableInstance>)object;
+            Assert.assertEquals(map.size(), 1);
+            mapValueInstance = map.get("value1");
+            Assert.assertNotNull(mapValueInstance);
+            mapValueGuid = mapValueInstance.getId()._getId();
+            mapOwnerVertex = GraphHelper.getInstance().getVertexForGUID(mapOwnerGuid);
+            object = mapOwnerVertex.getProperty(atlasEdgeLabel.getQualifiedMapKey());
+            Assert.assertNotNull(object);
+        }
+        
+        // Delete the map value instance.
+        // This should disconnect the references from the map owner instance. 
+        deleteEntities(mapValueGuid);
+        assertEntityDeleted(mapValueGuid);
+        assertTestDisconnectMapReferenceFromClassType(mapOwnerGuid);
+    }
+
+    protected abstract void assertTestDisconnectMapReferenceFromClassType(String mapOwnerGuid) throws Exception;
+
+    private String createHrDeptGraph() throws Exception {
+        ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
+
+        List<String> guids = repositoryService.createEntities(hrDept);
+        Assert.assertNotNull(guids);
+        Assert.assertEquals(guids.size(), 5);
+
+        hrDept = repositoryService.getEntityDefinition("Department", "name", "hr");
+        return hrDept.getId()._getId();
+    }
+    
+    private void createDbTableGraph() throws Exception {
+        Referenceable databaseInstance = new Referenceable(TestUtils.DATABASE_TYPE);
+        databaseInstance.set("name", TestUtils.DATABASE_NAME);
+        databaseInstance.set("description", "foo database");
+ 
+        ClassType dbType = typeSystem.getDataType(ClassType.class, TestUtils.DATABASE_TYPE);
+        ITypedReferenceableInstance db = dbType.convert(databaseInstance, Multiplicity.REQUIRED);
+        Referenceable tableInstance = new Referenceable(TestUtils.TABLE_TYPE, TestUtils.CLASSIFICATION);
+        tableInstance.set("name", TestUtils.TABLE_NAME);
+        tableInstance.set("description", "bar table");
+        tableInstance.set("type", "managed");
+        Struct traitInstance = (Struct) tableInstance.getTrait(TestUtils.CLASSIFICATION);
+        traitInstance.set("tag", "foundation_etl");
+        tableInstance.set("tableType", 1); // enum
+
+        tableInstance.set("database", databaseInstance);
+        ArrayList<Referenceable> columns = new ArrayList<>();
+        for (int index = 0; index < 5; index++) {
+            Referenceable columnInstance = new Referenceable("column_type");
+            final String name = "column_" + index;
+            columnInstance.set("name", name);
+            columnInstance.set("type", "string");
+            columns.add(columnInstance);
+        }
+        tableInstance.set("columns", columns);
+        ClassType tableType = typeSystem.getDataType(ClassType.class, TestUtils.TABLE_TYPE);
+        ITypedReferenceableInstance table = tableType.convert(tableInstance, Multiplicity.REQUIRED);
+        repositoryService.createEntities(db, table);
+    }
+    
+    protected List<Vertex> getVertices(String propertyName, Object value) {
+        Iterable<Vertex> vertices = graphProvider.get().getVertices(propertyName, value);
+        List<Vertex> list = new ArrayList<>();
+        for (Vertex vertex : vertices) {
+            list.add(vertex);
+        }
+        return list;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/40ee9492/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
index b5440c2..2d1c33a 100755
--- a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
+++ b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedMetadataRepositoryTest.java
@@ -28,6 +28,7 @@ import com.tinkerpop.blueprints.Vertex;
 
 import org.apache.atlas.GraphTransaction;
 import org.apache.atlas.RepositoryMetadataModule;
+import org.apache.atlas.RequestContext;
 import org.apache.atlas.TestUtils;
 import org.apache.atlas.discovery.graph.GraphBackedDiscoveryService;
 import org.apache.atlas.repository.Constants;
@@ -53,6 +54,7 @@ import org.codehaus.jettison.json.JSONObject;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
@@ -99,6 +101,10 @@ public class GraphBackedMetadataRepositoryTest {
         TestUtils.createHiveTypes(typeSystem);
     }
 
+    @BeforeMethod
+    public void setupContext() {
+        RequestContext.createContext();
+    }
 
     @AfterClass
     public void tearDown() throws Exception {
@@ -116,14 +122,11 @@ public class GraphBackedMetadataRepositoryTest {
         }
     }
 
-
     @Test
     public void testSubmitEntity() throws Exception {
-        Referenceable hrDept = TestUtils.createDeptEg1(typeSystem);
-        ClassType deptType = typeSystem.getDataType(ClassType.class, "Department");
-        ITypedReferenceableInstance hrDept2 = deptType.convert(hrDept, Multiplicity.REQUIRED);
+        ITypedReferenceableInstance hrDept = TestUtils.createDeptEg1(typeSystem);
 
-        List<String> guids = repositoryService.createEntities(hrDept2);
+        List<String> guids = repositoryService.createEntities(hrDept);
         Assert.assertNotNull(guids);
         Assert.assertEquals(guids.size(), 5);
         guid = guids.get(4);
@@ -147,7 +150,7 @@ public class GraphBackedMetadataRepositoryTest {
 
     @Test(dependsOnMethods = "testSubmitEntity")
     public void testGetEntityList() throws Exception {
-        List<String> entityList = repositoryService.getEntityList(TestUtils.ENTITY_TYPE);
+        List<String> entityList = repositoryService.getEntityList(TestUtils.DEPARTMENT_TYPE);
         System.out.println("entityList = " + entityList);
         Assert.assertNotNull(entityList);
         Assert.assertTrue(entityList.contains(guid));
@@ -247,7 +250,7 @@ public class GraphBackedMetadataRepositoryTest {
         final String aGUID = getGUID();
         Vertex vertex = GraphHelper.getInstance().getVertexForGUID(aGUID);
         Long modificationTimestampPreUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
-        Assert.assertNull(modificationTimestampPreUpdate);
+        Assert.assertNotNull(modificationTimestampPreUpdate);
 
         List<String> traitNames = repositoryService.getTraitNames(aGUID);
         System.out.println("traitNames = " + traitNames);
@@ -499,85 +502,6 @@ public class GraphBackedMetadataRepositoryTest {
         row = (JSONObject) results.get(0);
         Assert.assertEquals(row.get("typeName"), "Person");
     }
-    
-    @Test(dependsOnMethods = "testSubmitEntity")
-    public void testUpdateEntity_MultiplicityOneNonCompositeReference() throws Exception {
-        ITypedReferenceableInstance john = repositoryService.getEntityDefinition("Person", "name", "John");
-        Id johnGuid = john.getId();
-
-        ITypedReferenceableInstance max = repositoryService.getEntityDefinition("Person", "name", "Max");
-        String maxGuid = max.getId()._getId();
-        Vertex vertex = GraphHelper.getInstance().getVertexForGUID(maxGuid);
-        Long creationTimestamp = vertex.getProperty(Constants.TIMESTAMP_PROPERTY_KEY);
-        Assert.assertNotNull(creationTimestamp);
-
-        Long modificationTimestampPreUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
-        Assert.assertNull(modificationTimestampPreUpdate);
-
-        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Person", "name", "Jane");
-        Id janeGuid = jane.getId();
-        
-        // Update max's mentor reference to john.
-        ClassType personType = typeSystem.getDataType(ClassType.class, "Person");
-        ITypedReferenceableInstance instance = personType.createInstance(max.getId());
-        instance.set("mentor", johnGuid);
-        repositoryService.updatePartial(instance);
-        
-        // Verify the update was applied correctly - john should now be max's mentor.
-        max = repositoryService.getEntityDefinition(maxGuid);
-        Object object = max.get("mentor");
-        Assert.assertTrue(object instanceof ITypedReferenceableInstance);
-        ITypedReferenceableInstance refTarget = (ITypedReferenceableInstance) object;
-        Assert.assertEquals(refTarget.getId()._getId(), johnGuid._getId());
-
-
-        // Verify modification timestamp was updated.
-        vertex = GraphHelper.getInstance().getVertexForGUID(maxGuid);
-        Long modificationTimestampPostUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
-        Assert.assertNotNull(modificationTimestampPostUpdate);
-        Assert.assertTrue(creationTimestamp < modificationTimestampPostUpdate);
-
-        // Update max's mentor reference to jane.
-        instance.set("mentor", janeGuid);
-        repositoryService.updatePartial(instance);
-
-        // Verify the update was applied correctly - jane should now be max's mentor.
-        max = repositoryService.getEntityDefinition(maxGuid);
-        object = max.get("mentor");
-        Assert.assertTrue(object instanceof ITypedReferenceableInstance);
-        refTarget = (ITypedReferenceableInstance) object;
-        Assert.assertEquals(refTarget.getId()._getId(), janeGuid._getId());
-        
-        // Verify modification timestamp was updated.
-        vertex = GraphHelper.getInstance().getVertexForGUID(maxGuid);
-        Long modificationTimestampPost2ndUpdate = vertex.getProperty(Constants.MODIFICATION_TIMESTAMP_PROPERTY_KEY);
-        Assert.assertNotNull(modificationTimestampPost2ndUpdate);
-        Assert.assertTrue(modificationTimestampPostUpdate < modificationTimestampPost2ndUpdate);
-        
-        ITypedReferenceableInstance julius = repositoryService.getEntityDefinition("Person", "name", "Julius");
-        Id juliusGuid = julius.getId();
-        instance = personType.createInstance(max.getId());
-        instance.set("manager", juliusGuid);
-        repositoryService.updatePartial(instance);
-
-        // Verify the update was applied correctly - julius should now be max's manager.
-        max = repositoryService.getEntityDefinition(maxGuid);
-        object = max.get("manager");
-        Assert.assertTrue(object instanceof ITypedReferenceableInstance);
-        refTarget = (ITypedReferenceableInstance) object;
-        Assert.assertEquals(refTarget.getId()._getId(), juliusGuid._getId());
-        
-        // Verify that max is no longer a subordinate of jane.
-        jane = repositoryService.getEntityDefinition(janeGuid._getId());
-        Object refValue = jane.get("subordinates");
-        Assert.assertTrue(refValue instanceof List);
-        List<Object> subordinates = (List<Object>)refValue;
-        Assert.assertEquals(subordinates.size(), 1);
-        Object listValue = subordinates.get(0);
-        Assert.assertTrue(listValue instanceof ITypedReferenceableInstance);
-        ITypedReferenceableInstance subordinate = (ITypedReferenceableInstance) listValue;
-        Assert.assertNotEquals(subordinate.getId()._getId(), maxGuid);
-    }
 
     private ITypedReferenceableInstance createHiveTableInstance(Referenceable databaseInstance) throws Exception {
         Referenceable tableInstance = new Referenceable(TestUtils.TABLE_TYPE, TestUtils.CLASSIFICATION);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/40ee9492/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedRepositoryHardDeleteTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedRepositoryHardDeleteTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedRepositoryHardDeleteTest.java
new file mode 100644
index 0000000..8d2961e
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/graph/GraphBackedRepositoryHardDeleteTest.java
@@ -0,0 +1,121 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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.
+ */
+
+package org.apache.atlas.repository.graph;
+
+import com.tinkerpop.blueprints.Vertex;
+import org.apache.atlas.AtlasClient;
+import org.apache.atlas.TestUtils;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.typesystem.IStruct;
+import org.apache.atlas.typesystem.ITypedReferenceableInstance;
+import org.apache.atlas.typesystem.ITypedStruct;
+import org.apache.atlas.typesystem.exception.EntityNotFoundException;
+import org.apache.atlas.typesystem.types.TypeSystem;
+import org.testng.Assert;
+
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.fail;
+import static org.testng.AssertJUnit.assertNotNull;
+
+public class GraphBackedRepositoryHardDeleteTest extends GraphBackedMetadataRepositoryDeleteTestBase {
+    @Override
+    DeleteHandler getDeleteHandler(TypeSystem typeSystem) {
+        return new HardDeleteHandler(typeSystem);
+    }
+
+    @Override
+    protected void assertTestDeleteReference(ITypedReferenceableInstance processInstance) throws Exception {
+        //assert that outputs is empty
+        ITypedReferenceableInstance newProcess =
+                repositoryService.getEntityDefinition(processInstance.getId()._getId());
+        assertNull(newProcess.get(AtlasClient.PROCESS_ATTRIBUTE_OUTPUTS));
+    }
+
+    @Override
+    protected void assertEntityDeleted(String id) throws Exception {
+        try {
+            repositoryService.getEntityDefinition(id);
+            fail("Expected EntityNotFoundException");
+        } catch(EntityNotFoundException e) {
+            //expected
+        }
+    }
+
+    @Override
+    protected void assertTestDeleteEntities(ITypedReferenceableInstance tableInstance) {
+        int vertexCount = getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, TestUtils.TABLE_TYPE).size();
+        assertEquals(vertexCount, 0);
+
+        vertexCount = getVertices(Constants.ENTITY_TYPE_PROPERTY_KEY, TestUtils.COLUMN_TYPE).size();
+        assertEquals(vertexCount, 0);
+    }
+
+    @Override
+    protected void assertVerticesDeleted(List<Vertex> vertices) {
+        assertEquals(vertices.size(), 0);
+    }
+
+    @Override
+    protected void assertTestUpdateEntity_MultiplicityOneNonCompositeReference() throws Exception {
+        // Verify that max is no longer a subordinate of jane.
+        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Manager", "name", "Jane");
+        List<ITypedReferenceableInstance> subordinates = (List<ITypedReferenceableInstance>) jane.get("subordinates");
+        Assert.assertEquals(subordinates.size(), 1);
+    }
+
+    @Override
+    protected void assertTestDisconnectBidirectionalReferences() throws Exception {
+        // Verify that the Manager.subordinates reference to the deleted employee
+        // Max was disconnected.
+        ITypedReferenceableInstance jane = repositoryService.getEntityDefinition("Manager", "name", "Jane");
+        List<ITypedReferenceableInstance> subordinates = (List<ITypedReferenceableInstance>) jane.get("subordinates");
+        assertEquals(subordinates.size(), 1);
+    }
+
+    @Override
+    protected void assertTestDisconnectUnidirectionalArrayReferenceFromStructAndTraitTypes(String structContainerGuid)
+            throws Exception {
+        // Verify that the unidirectional references from the struct and trait instances
+        // to the deleted entities were disconnected.
+        ITypedReferenceableInstance structContainerConvertedEntity =
+                repositoryService.getEntityDefinition(structContainerGuid);
+        ITypedStruct struct = (ITypedStruct) structContainerConvertedEntity.get("struct");
+        assertNull(struct.get("target"));
+        IStruct trait = structContainerConvertedEntity.getTrait("TestTrait");
+        assertNotNull(trait);
+        assertNull(trait.get("target"));
+    }
+
+    @Override
+    protected void assertTestDisconnectMapReferenceFromClassType(String mapOwnerGuid) throws Exception {
+        // Verify map references from mapOwner were disconnected.
+        ITypedReferenceableInstance mapOwnerInstance = repositoryService.getEntityDefinition(mapOwnerGuid);
+        assertNull(mapOwnerInstance.get("map"));
+        assertNull(mapOwnerInstance.get("biMap"));
+
+        Vertex mapOwnerVertex = GraphHelper.getInstance().getVertexForGUID(mapOwnerGuid);
+        Object object = mapOwnerVertex.getProperty("MapOwner.map.value1");
+        assertNull(object);
+        object = mapOwnerVertex.getProperty("MapOwner.biMap.value1");
+        assertNull(object);
+    }
+}


Mime
View raw message