Repository: atlas
Updated Branches:
  refs/heads/branch-1.0 2bebba809 -> 7869c9a5f


ATLAS-2774: enhancement to support parameterized delete-type (hard or soft) per 
API call

(cherry picked from commit d003ddb33b16a0a67e6b7f7eae29c1638a4d0971)


Project: http://git-wip-us.apache.org/repos/asf/atlas/repo
Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/7869c9a5
Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/7869c9a5
Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/7869c9a5

Branch: refs/heads/branch-1.0
Commit: 7869c9a5fe884397b883f30236ae01aa710d8c31
Parents: 2bebba8
Author: Madhan Neethiraj <mad...@apache.org>
Authored: Tue Nov 13 17:11:48 2018 -0800
Committer: Madhan Neethiraj <mad...@apache.org>
Committed: Wed Nov 14 18:07:39 2018 -0800

----------------------------------------------------------------------
 .../org/apache/atlas/AtlasConfiguration.java    |   2 +
 .../java/org/apache/atlas/store/DeleteType.java |  44 ++++
 .../store/graph/v1/DeleteHandlerDelegate.java   |  86 ++++++++
 .../store/graph/v1/SoftDeleteHandlerV1.java     |   4 -
 .../store/graph/v2/AtlasEntityStoreV2.java      |  10 +-
 .../graph/v2/AtlasRelationshipStoreV2.java      |  20 +-
 .../store/graph/v2/BulkImporterImpl.java        |   2 +-
 .../store/graph/v2/EntityGraphMapper.java       |  31 ++-
 .../test/java/org/apache/atlas/TestModules.java |  25 ---
 .../repository/impexp/ExportImportTestBase.java |  12 --
 .../repository/impexp/ExportServiceTest.java    |  12 --
 .../impexp/ExportSkipLineageTest.java           |   7 +-
 .../store/graph/v1/SoftReferenceTest.java       |  12 +-
 .../store/graph/v2/AtlasEntityStoreV2Test.java  |   2 +-
 .../store/graph/v2/AtlasEntityTestBase.java     |   6 +-
 .../AtlasRelationshipStoreHardDeleteV2Test.java |  13 +-
 .../AtlasRelationshipStoreSoftDeleteV2Test.java |  11 +-
 .../graph/v2/AtlasRelationshipStoreV2Test.java  |  15 +-
 .../InverseReferenceUpdateHardDeleteV2Test.java |  11 +-
 .../InverseReferenceUpdateSoftDeleteV2Test.java |  11 +-
 .../graph/v2/InverseReferenceUpdateV2Test.java  |  10 +
 .../java/org/apache/atlas/RequestContext.java   |  44 ++--
 .../apache/atlas/web/filters/AuditFilter.java   |  20 ++
 .../web/adapters/TestEntityRESTDelete.java      | 207 +++++++++++++++++++
 24 files changed, 479 insertions(+), 138 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java 
b/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java
index 1b3ce1e..c5357f5 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasConfiguration.java
@@ -33,6 +33,8 @@ public enum AtlasConfiguration {
 
     QUERY_PARAM_MAX_LENGTH("atlas.query.param.max.length", 4*1024),
 
+    
REST_API_ENABLE_DELETE_TYPE_OVERRIDE("atlas.rest.enable.delete.type.override", 
false),
+
     NOTIFICATION_HOOK_TOPIC_NAME("atlas.notification.hook.topic.name", 
"ATLAS_HOOK"),
     NOTIFICATION_ENTITIES_TOPIC_NAME("atlas.notification.entities.topic.name", 
"ATLAS_ENTITIES"),
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/intg/src/main/java/org/apache/atlas/store/DeleteType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/store/DeleteType.java 
b/intg/src/main/java/org/apache/atlas/store/DeleteType.java
new file mode 100644
index 0000000..de5e5e4
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/store/DeleteType.java
@@ -0,0 +1,44 @@
+/**
+ * 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.store;
+
+import org.apache.commons.lang.StringUtils;
+
+public enum DeleteType {
+    DEFAULT,
+    SOFT,
+    HARD;
+
+    public static DeleteType from(String s) {
+        if(StringUtils.isEmpty(s)) {
+            return DEFAULT;
+        }
+
+        switch (s.toLowerCase()) {
+            case "soft":
+                return SOFT;
+
+            case "hard":
+                return HARD;
+
+            default:
+                return DEFAULT;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerDelegate.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerDelegate.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerDelegate.java
new file mode 100644
index 0000000..512eb46
--- /dev/null
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerDelegate.java
@@ -0,0 +1,86 @@
+/**
+ * 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.store.graph.v1;
+
+import org.apache.atlas.RequestContext;
+import org.apache.atlas.store.DeleteType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.util.AtlasRepositoryConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
+@Component
+public class DeleteHandlerDelegate {
+    private static final Logger LOG = 
LoggerFactory.getLogger(DeleteHandlerDelegate.class);
+
+    private final SoftDeleteHandlerV1 softDeleteHandler;
+    private final HardDeleteHandlerV1 hardDeleteHandler;
+    private final DeleteHandlerV1     defaultHandler;
+
+    @Inject
+    public DeleteHandlerDelegate(AtlasTypeRegistry typeRegistry) {
+        this.softDeleteHandler = new SoftDeleteHandlerV1(typeRegistry);
+        this.hardDeleteHandler = new HardDeleteHandlerV1(typeRegistry);
+        this.defaultHandler    = getDefaultConfiguredHandler(typeRegistry);
+    }
+
+    public DeleteHandlerV1 getHandler() {
+        return getHandler(RequestContext.get().getDeleteType());
+    }
+
+    public DeleteHandlerV1 getHandler(DeleteType deleteType) {
+        if (deleteType == null) {
+            deleteType = DeleteType.DEFAULT;
+        }
+
+        switch (deleteType) {
+            case SOFT:
+                return softDeleteHandler;
+
+            case HARD:
+                return hardDeleteHandler;
+
+            default:
+                return defaultHandler;
+        }
+    }
+
+    private DeleteHandlerV1 getDefaultConfiguredHandler(AtlasTypeRegistry 
typeRegistry) {
+        DeleteHandlerV1 ret = null;
+
+        try {
+            Class handlerFromProperties = 
AtlasRepositoryConfiguration.getDeleteHandlerV1Impl();
+
+            LOG.info("Default delete handler set to: {}", 
handlerFromProperties.getName());
+
+            ret = (DeleteHandlerV1) 
handlerFromProperties.getConstructor(AtlasTypeRegistry.class).newInstance(typeRegistry);
+        } catch (Exception ex) {
+            LOG.error("Error instantiating default delete handler. Defaulting 
to: {}", softDeleteHandler.getClass().getName(), ex);
+
+            ret = softDeleteHandler;
+        }
+
+        return ret;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/SoftDeleteHandlerV1.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/SoftDeleteHandlerV1.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/SoftDeleteHandlerV1.java
index 0bcf0d6..e614a4e 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/SoftDeleteHandlerV1.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/SoftDeleteHandlerV1.java
@@ -19,14 +19,12 @@
 package org.apache.atlas.repository.store.graph.v1;
 
 import org.apache.atlas.RequestContext;
-import org.apache.atlas.annotation.ConditionalOnAtlasProperty;
 import org.apache.atlas.model.instance.AtlasEntity.Status;
 import org.apache.atlas.repository.graph.GraphHelper;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
 import org.apache.atlas.type.AtlasTypeRegistry;
-import org.springframework.stereotype.Component;
 
 import javax.inject.Inject;
 
@@ -35,8 +33,6 @@ import static 
org.apache.atlas.repository.Constants.MODIFICATION_TIMESTAMP_PROPE
 import static org.apache.atlas.repository.Constants.MODIFIED_BY_KEY;
 import static org.apache.atlas.repository.Constants.STATE_PROPERTY_KEY;
 
-@Component
-@ConditionalOnAtlasProperty(property = "atlas.DeleteHandlerV1.impl", isDefault 
= true)
 public class SoftDeleteHandlerV1 extends DeleteHandlerV1 {
 
     @Inject

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
index 7333696..ee8de1f 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
@@ -33,7 +33,7 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscovery;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscoveryContext;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
@@ -62,16 +62,16 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore 
{
     private static final Logger PERF_LOG = 
AtlasPerfTracer.getPerfLogger("store.EntityStore");
 
 
-    private final DeleteHandlerV1 deleteHandler;
+    private final DeleteHandlerDelegate     deleteDelegate;
     private final AtlasTypeRegistry         typeRegistry;
     private final AtlasEntityChangeNotifier entityChangeNotifier;
     private final EntityGraphMapper         entityGraphMapper;
     private final EntityGraphRetriever      entityRetriever;
 
     @Inject
-    public AtlasEntityStoreV2(DeleteHandlerV1 deleteHandler, AtlasTypeRegistry 
typeRegistry,
+    public AtlasEntityStoreV2(DeleteHandlerDelegate deleteDelegate, 
AtlasTypeRegistry typeRegistry,
                               AtlasEntityChangeNotifier entityChangeNotifier, 
EntityGraphMapper entityGraphMapper) {
-        this.deleteHandler        = deleteHandler;
+        this.deleteDelegate       = deleteDelegate;
         this.typeRegistry         = typeRegistry;
         this.entityChangeNotifier = entityChangeNotifier;
         this.entityGraphMapper    = entityGraphMapper;
@@ -802,7 +802,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore 
{
         EntityMutationResponse response = new EntityMutationResponse();
         RequestContext         req      = RequestContext.get();
 
-        deleteHandler.deleteEntities(deletionCandidates); // this will update 
req with list of deleted/updated entities
+        deleteDelegate.getHandler().deleteEntities(deletionCandidates); // 
this will update req with list of deleted/updated entities
 
         for (AtlasObjectId entity : req.getDeletedEntities()) {
             response.addEntity(DELETE, entity);

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
index 21617dc..6bc36b3 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2.java
@@ -41,7 +41,7 @@ import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasRelationshipType;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
@@ -95,15 +95,15 @@ public class AtlasRelationshipStoreV2 implements 
AtlasRelationshipStore {
 
     private final AtlasTypeRegistry         typeRegistry;
     private final EntityGraphRetriever      entityRetriever;
-    private final DeleteHandlerV1 deleteHandler;
+    private final DeleteHandlerDelegate     deleteDelegate;
     private final GraphHelper               graphHelper = 
GraphHelper.getInstance();
     private final AtlasEntityChangeNotifier entityChangeNotifier;
 
     @Inject
-    public AtlasRelationshipStoreV2(AtlasTypeRegistry typeRegistry, 
DeleteHandlerV1 deleteHandler, AtlasEntityChangeNotifier entityChangeNotifier) {
+    public AtlasRelationshipStoreV2(AtlasTypeRegistry typeRegistry, 
DeleteHandlerDelegate deleteDelegate, AtlasEntityChangeNotifier 
entityChangeNotifier) {
         this.typeRegistry         = typeRegistry;
         this.entityRetriever      = new EntityGraphRetriever(typeRegistry);
-        this.deleteHandler        = deleteHandler;
+        this.deleteDelegate       = deleteDelegate;
         this.entityChangeNotifier = entityChangeNotifier;
     }
 
@@ -277,7 +277,7 @@ public class AtlasRelationshipStoreV2 implements 
AtlasRelationshipStore {
         AtlasAuthorizationUtils.verifyAccess(new 
AtlasRelationshipAccessRequest(typeRegistry,AtlasPrivilege.RELATIONSHIP_REMOVE, 
relationShipType, end1Entity, end2Entity ));
 
 
-        deleteHandler.deleteRelationships(Collections.singleton(edge), 
forceDelete);
+        
deleteDelegate.getHandler().deleteRelationships(Collections.singleton(edge), 
forceDelete);
 
         // notify entities for added/removed classification propagation
         entityChangeNotifier.notifyPropagatedEntities();
@@ -426,7 +426,7 @@ public class AtlasRelationshipStoreV2 implements 
AtlasRelationshipStore {
             for (AtlasVertex classificationVertex : 
addedBlockedClassifications) {
                 List<AtlasVertex> removePropagationFromVertices = 
graphHelper.getPropagatedEntityVertices(classificationVertex);
 
-                deleteHandler.removeTagPropagation(classificationVertex, 
removePropagationFromVertices);
+                
deleteDelegate.getHandler().removeTagPropagation(classificationVertex, 
removePropagationFromVertices);
             }
 
             // add propagated tag for removed entry
@@ -435,7 +435,7 @@ public class AtlasRelationshipStoreV2 implements 
AtlasRelationshipStore {
             for (AtlasVertex classificationVertex : 
removedBlockedClassifications) {
                 List<AtlasVertex> addPropagationToVertices = 
graphHelper.getPropagatedEntityVertices(classificationVertex);
 
-                deleteHandler.addTagPropagation(classificationVertex, 
addPropagationToVertices);
+                
deleteDelegate.getHandler().addTagPropagation(classificationVertex, 
addPropagationToVertices);
             }
         }
     }
@@ -527,11 +527,11 @@ public class AtlasRelationshipStoreV2 implements 
AtlasRelationshipStore {
             }
 
             for (AtlasVertex classificationVertex : 
addPropagationsMap.keySet()) {
-                deleteHandler.addTagPropagation(classificationVertex, 
addPropagationsMap.get(classificationVertex));
+                
deleteDelegate.getHandler().addTagPropagation(classificationVertex, 
addPropagationsMap.get(classificationVertex));
             }
 
             for (AtlasVertex classificationVertex : 
removePropagationsMap.keySet()) {
-                deleteHandler.removeTagPropagation(classificationVertex, 
removePropagationsMap.get(classificationVertex));
+                
deleteDelegate.getHandler().removeTagPropagation(classificationVertex, 
removePropagationsMap.get(classificationVertex));
             }
         } else {
             // update blocked propagated classifications only if there is no 
change is tag propagation (don't update both)
@@ -758,7 +758,7 @@ public class AtlasRelationshipStoreV2 implements 
AtlasRelationshipStore {
             handleBlockedClassifications(ret, 
relationship.getBlockedPropagatedClassifications());
 
             // propagate tags
-            deleteHandler.addTagPropagation(ret, tagPropagation);
+            deleteDelegate.getHandler().addTagPropagation(ret, tagPropagation);
         }
 
         return ret;

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
index a3d31b6..dc8bd19 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/BulkImporterImpl.java
@@ -100,7 +100,7 @@ public class BulkImporterImpl implements BulkImporter {
                     throw abe;
                 }
             } finally {
-                RequestContext.clear();
+                RequestContext.get().clearCache();
             }
         }
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
index e8c8c0c..f5a5982 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
@@ -26,7 +26,6 @@ import org.apache.atlas.model.TimeBoundary;
 import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
-import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.AtlasRelatedObjectId;
@@ -43,7 +42,7 @@ import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.type.AtlasArrayType;
 import org.apache.atlas.type.AtlasBuiltInTypes;
 import org.apache.atlas.type.AtlasClassificationType;
@@ -93,7 +92,7 @@ public class EntityGraphMapper {
 
     private final GraphHelper               graphHelper = 
GraphHelper.getInstance();
     private final AtlasGraph                graph;
-    private final DeleteHandlerV1           deleteHandler;
+    private final DeleteHandlerDelegate     deleteDelegate;
     private final AtlasTypeRegistry         typeRegistry;
     private final AtlasRelationshipStore    relationshipStore;
     private final AtlasEntityChangeNotifier entityChangeNotifier;
@@ -101,10 +100,10 @@ public class EntityGraphMapper {
     private final EntityGraphRetriever      entityRetriever;
 
     @Inject
-    public EntityGraphMapper(DeleteHandlerV1 deleteHandler, AtlasTypeRegistry 
typeRegistry, AtlasGraph atlasGraph,
+    public EntityGraphMapper(DeleteHandlerDelegate deleteDelegate, 
AtlasTypeRegistry typeRegistry, AtlasGraph atlasGraph,
                              AtlasRelationshipStore relationshipStore, 
AtlasEntityChangeNotifier entityChangeNotifier,
                              AtlasInstanceConverter instanceConverter) {
-        this.deleteHandler        = deleteHandler;
+        this.deleteDelegate       = deleteDelegate;
         this.typeRegistry         = typeRegistry;
         this.graph                = atlasGraph;
         this.relationshipStore    = relationshipStore;
@@ -394,7 +393,7 @@ public class EntityGraphMapper {
                 AtlasEdge newEdge = mapStructValue(ctx, context);
 
                 if (currentEdge != null && !currentEdge.equals(newEdge)) {
-                    deleteHandler.deleteEdgeReference(currentEdge, 
ctx.getAttrType().getTypeCategory(), false, true, ctx.getReferringVertex());
+                    
deleteDelegate.getHandler().deleteEdgeReference(currentEdge, 
ctx.getAttrType().getTypeCategory(), false, true, ctx.getReferringVertex());
                 }
 
                 return newEdge;
@@ -466,7 +465,7 @@ public class EntityGraphMapper {
                     }
 
                     //delete old reference
-                    deleteHandler.deleteEdgeReference(currentEdge, 
ctx.getAttrType().getTypeCategory(), ctx.getAttribute().isOwnedRef(),
+                    
deleteDelegate.getHandler().deleteEdgeReference(currentEdge, 
ctx.getAttrType().getTypeCategory(), ctx.getAttribute().isOwnedRef(),
                                                       true, 
ctx.getAttribute().getRelationshipEdgeDirection(), ctx.getReferringVertex());
                 }
 
@@ -527,7 +526,7 @@ public class EntityGraphMapper {
             if (inverseEdge != null) {
                 if (!inverseEdge.equals(newEdge)) {
                     // Disconnect old reference
-                    deleteHandler.deleteEdgeReference(inverseEdge, 
inverseAttribute.getAttributeType().getTypeCategory(),
+                    
deleteDelegate.getHandler().deleteEdgeReference(inverseEdge, 
inverseAttribute.getAttributeType().getTypeCategory(),
                                                       
inverseAttribute.isOwnedRef(), true, inverseVertex);
                 }
                 else {
@@ -1178,7 +1177,7 @@ public class EntityGraphMapper {
             AtlasEdge currentEdge = (AtlasEdge) currentMap.get(currentKey);
 
             if (!newMap.values().contains(currentEdge)) {
-                boolean deleted = 
deleteHandler.deleteEdgeReference(currentEdge, 
mapType.getValueType().getTypeCategory(), attribute.isOwnedRef(), true, vertex);
+                boolean deleted = 
deleteDelegate.getHandler().deleteEdgeReference(currentEdge, 
mapType.getValueType().getTypeCategory(), attribute.isOwnedRef(), true, vertex);
 
                 if (!deleted) {
                     additionalMap.put(currentKey, currentEdge);
@@ -1308,7 +1307,7 @@ public class EntityGraphMapper {
                     List<AtlasEdge> additionalElements = new ArrayList<>();
 
                     for (AtlasEdge edge : edgesToRemove) {
-                        boolean deleted = 
deleteHandler.deleteEdgeReference(edge, entryType.getTypeCategory(), 
attribute.isOwnedRef(),
+                        boolean deleted = 
deleteDelegate.getHandler().deleteEdgeReference(edge, 
entryType.getTypeCategory(), attribute.isOwnedRef(),
                                                                              
true, attribute.getRelationshipEdgeDirection(), entityVertex);
 
                         if (!deleted) {
@@ -1447,7 +1446,7 @@ public class EntityGraphMapper {
                             LOG.debug("Propagating tag: [{}][{}] to {}", 
classificationName, entityTypeName, getTypeNames(entitiesToPropagateTo));
                         }
 
-                        List<AtlasVertex> entitiesPropagatedTo = 
deleteHandler.addTagPropagation(classificationVertex, entitiesToPropagateTo);
+                        List<AtlasVertex> entitiesPropagatedTo = 
deleteDelegate.getHandler().addTagPropagation(classificationVertex, 
entitiesToPropagateTo);
 
                         if (entitiesPropagatedTo != null) {
                             for (AtlasVertex entityPropagatedTo : 
entitiesPropagatedTo) {
@@ -1506,7 +1505,7 @@ public class EntityGraphMapper {
             throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, entityGuid);
         }
 
-        deleteHandler.deletePropagatedClassification(entityVertex, 
classificationName, associatedEntityGuid);
+        
deleteDelegate.getHandler().deletePropagatedClassification(entityVertex, 
classificationName, associatedEntityGuid);
     }
 
     public void deleteClassification(String entityGuid, String 
classificationName) throws AtlasBaseException {
@@ -1535,7 +1534,7 @@ public class EntityGraphMapper {
 
         // remove classification from propagated entities if propagation is 
turned on
         if (isPropagationEnabled(classificationVertex)) {
-            List<AtlasVertex> propagatedEntityVertices = 
deleteHandler.removeTagPropagation(classificationVertex);
+            List<AtlasVertex> propagatedEntityVertices = 
deleteDelegate.getHandler().removeTagPropagation(classificationVertex);
 
             // add propagated entities and deleted classification details to 
removeClassifications map
             if (CollectionUtils.isNotEmpty(propagatedEntityVertices)) {
@@ -1572,7 +1571,7 @@ public class EntityGraphMapper {
 
         AtlasEdge edge = getClassificationEdge(entityVertex, 
classificationVertex);
 
-        deleteHandler.deleteEdgeReference(edge, CLASSIFICATION, false, true, 
entityVertex);
+        deleteDelegate.getHandler().deleteEdgeReference(edge, CLASSIFICATION, 
false, true, entityVertex);
 
         traitNames.remove(classificationName);
 
@@ -1701,7 +1700,7 @@ public class EntityGraphMapper {
                             }
                         }
 
-                        List<AtlasVertex> entitiesPropagatedTo = 
deleteHandler.addTagPropagation(classificationVertex, entitiesToPropagateTo);
+                        List<AtlasVertex> entitiesPropagatedTo = 
deleteDelegate.getHandler().addTagPropagation(classificationVertex, 
entitiesToPropagateTo);
 
                         if (entitiesPropagatedTo != null) {
                             for (AtlasVertex entityPropagatedTo : 
entitiesPropagatedTo) {
@@ -1710,7 +1709,7 @@ public class EntityGraphMapper {
                         }
                     }
                 } else {
-                    List<AtlasVertex> impactedVertices = 
deleteHandler.removeTagPropagation(classificationVertex);
+                    List<AtlasVertex> impactedVertices = 
deleteDelegate.getHandler().removeTagPropagation(classificationVertex);
 
                     if (CollectionUtils.isNotEmpty(impactedVertices)) {
                         if (removedPropagations == null) {

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/TestModules.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/TestModules.java 
b/repository/src/test/java/org/apache/atlas/TestModules.java
index d3d30d5..94b08a1 100644
--- a/repository/src/test/java/org/apache/atlas/TestModules.java
+++ b/repository/src/test/java/org/apache/atlas/TestModules.java
@@ -59,10 +59,7 @@ import 
org.apache.atlas.repository.store.graph.v2.AtlasEntityStoreV2;
 import org.apache.atlas.repository.store.graph.v2.AtlasRelationshipStoreV2;
 import org.apache.atlas.repository.store.graph.v2.AtlasTypeDefGraphStoreV2;
 import org.apache.atlas.repository.store.graph.v2.BulkImporterImpl;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
 import org.apache.atlas.repository.store.graph.v2.EntityGraphMapper;
-import org.apache.atlas.repository.store.graph.v1.HardDeleteHandlerV1;
-import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
 import org.apache.atlas.runner.LocalSolrRunner;
 import org.apache.atlas.service.Service;
 import org.apache.atlas.store.AtlasTypeDefStore;
@@ -125,8 +122,6 @@ public class TestModules {
 
             bindAuditRepository(binder());
 
-            bindDeleteHandler(binder());
-
             bind(AtlasGraph.class).toProvider(AtlasGraphProvider.class);
 
             // allow for dynamic binding of graph service
@@ -186,10 +181,6 @@ public class TestModules {
             bindInterceptor(Matchers.any(), 
Matchers.annotatedWith(GraphTransaction.class), graphTransactionInterceptor);
         }
 
-        protected void bindDeleteHandler(Binder binder) {
-            
binder.bind(DeleteHandlerV1.class).to(AtlasRepositoryConfiguration.getDeleteHandlerV1Impl()).asEagerSingleton();
-        }
-
         protected void bindAuditRepository(Binder binder) {
 
             Class<? extends EntityAuditRepository> auditRepoImpl = 
AtlasRepositoryConfiguration.getAuditRepositoryImpl();
@@ -205,20 +196,4 @@ public class TestModules {
             }
         }
     }
-
-    public static class SoftDeleteModule extends TestOnlyModule {
-        @Override
-        protected void bindDeleteHandler(Binder binder) {
-            
bind(DeleteHandlerV1.class).to(SoftDeleteHandlerV1.class).asEagerSingleton();
-            
bind(AtlasEntityChangeNotifier.class).toProvider(MockNotifier.class);
-        }
-    }
-
-    public static class HardDeleteModule extends TestOnlyModule {
-        @Override
-        protected void bindDeleteHandler(Binder binder) {
-            
bind(DeleteHandlerV1.class).to(HardDeleteHandlerV1.class).asEagerSingleton();
-            
bind(AtlasEntityChangeNotifier.class).toProvider(MockNotifier.class);
-        }
-    }
 }

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/impexp/ExportImportTestBase.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportImportTestBase.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportImportTestBase.java
index 4b253ff..925b2a0 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportImportTestBase.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportImportTestBase.java
@@ -18,14 +18,9 @@
 
 package org.apache.atlas.repository.impexp;
 
-import org.apache.atlas.ApplicationProperties;
-import org.apache.atlas.AtlasConstants;
-import org.apache.atlas.AtlasException;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.impexp.ExportImportAuditEntry;
 import org.apache.atlas.model.instance.AtlasEntity;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
-import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityStoreV2;
 import org.apache.atlas.store.AtlasTypeDefStore;
 import org.apache.atlas.type.AtlasTypeRegistry;
@@ -39,11 +34,9 @@ import static 
org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.create
 import static 
org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.loadBaseModel;
 import static 
org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.loadEntity;
 import static 
org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.loadHiveModel;
-import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
 
 public class ExportImportTestBase {
     protected static final String ENTITIES_SUB_DIR = "stocksDB-Entities";
@@ -53,7 +46,6 @@ public class ExportImportTestBase {
     protected static final String TABLE_VIEW_GUID = 
"56415119-7cb0-40dd-ace8-1e50efd54991";
     protected static final String COLUMN_GUID_HIGH = 
"f87a5320-1529-4369-8d63-b637ebdf2c1c";
 
-    protected DeleteHandlerV1 deleteHandler = mock(SoftDeleteHandlerV1.class);
 
     protected void basicSetup(AtlasTypeDefStore typeDefStore, 
AtlasTypeRegistry typeRegistry) throws IOException, AtlasBaseException {
         loadBaseModel(typeDefStore, typeRegistry);
@@ -90,10 +82,6 @@ public class ExportImportTestBase {
         assertTrue(result.size() > 0);
     }
 
-    private String getCurrentCluster() throws AtlasException {
-        return 
ApplicationProperties.get().getString(AtlasConstants.CLUSTER_NAME_KEY, 
"default");
-    }
-
     protected void pauseForIndexCreation() {
         try {
             Thread.sleep(5000);

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
index 936586b..db8c6c8 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportServiceTest.java
@@ -30,12 +30,8 @@ import 
org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
 import org.apache.atlas.repository.graph.AtlasGraphProvider;
 import 
org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
-import org.apache.atlas.repository.store.graph.v2.AtlasEntityChangeNotifier;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityStoreV2;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
-import org.apache.atlas.repository.store.graph.v2.EntityGraphMapper;
-import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
 import org.apache.atlas.runner.LocalSolrRunner;
 import org.apache.atlas.store.AtlasTypeDefStore;
 import org.apache.atlas.type.AtlasType;
@@ -60,11 +56,9 @@ import java.util.List;
 import java.util.Map;
 
 import static org.apache.atlas.graph.GraphSandboxUtil.useLocalSolr;
-import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
 
 @Guice(modules = TestModules.TestOnlyModule.class)
 public class ExportServiceTest extends ExportImportTestBase {
@@ -77,9 +71,6 @@ public class ExportServiceTest extends ExportImportTestBase {
     private AtlasTypeDefStore typeDefStore;
 
     @Inject
-    private EntityGraphMapper graphMapper;
-
-    @Inject
     ExportService exportService;
 
     @Inject
@@ -88,9 +79,6 @@ public class ExportServiceTest extends ExportImportTestBase {
     @Inject
     private AtlasEntityStoreV2 entityStore;
 
-    private DeleteHandlerV1 deleteHandler = mock(SoftDeleteHandlerV1.class);;
-    private AtlasEntityChangeNotifier mockChangeNotifier = 
mock(AtlasEntityChangeNotifier.class);
-
     @BeforeTest
     public void setupTest() throws IOException, AtlasBaseException {
         RequestContext.clear();

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/impexp/ExportSkipLineageTest.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportSkipLineageTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportSkipLineageTest.java
index 3393b82..28773d5 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/impexp/ExportSkipLineageTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/impexp/ExportSkipLineageTest.java
@@ -25,8 +25,7 @@ import org.apache.atlas.TestUtilsV2;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.impexp.AtlasExportRequest;
 import org.apache.atlas.model.instance.AtlasEntity;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
-import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityChangeNotifier;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityStoreV2;
 import org.apache.atlas.repository.store.graph.v2.EntityGraphMapper;
@@ -65,7 +64,7 @@ public class ExportSkipLineageTest extends 
ExportImportTestBase {
     @Inject
     ExportService exportService;
 
-    private DeleteHandlerV1 deleteHandler = mock(SoftDeleteHandlerV1.class);
+    private DeleteHandlerDelegate deleteDelegate = 
mock(DeleteHandlerDelegate.class);
     private AtlasEntityChangeNotifier mockChangeNotifier = 
mock(AtlasEntityChangeNotifier.class);
     private AtlasEntityStoreV2 entityStore;
 
@@ -74,7 +73,7 @@ public class ExportSkipLineageTest extends 
ExportImportTestBase {
         loadBaseModel(typeDefStore, typeRegistry);
         loadHiveModel(typeDefStore, typeRegistry);
 
-        entityStore = new AtlasEntityStoreV2(deleteHandler, typeRegistry, 
mockChangeNotifier, graphMapper);
+        entityStore = new AtlasEntityStoreV2(deleteDelegate, typeRegistry, 
mockChangeNotifier, graphMapper);
         createEntities(entityStore, ENTITIES_SUB_DIR, new String[]{"db", 
"table-columns", "table-view", "table-table-lineage"});
         final String[] entityGuids = {DB_GUID, TABLE_GUID, TABLE_TABLE_GUID, 
TABLE_VIEW_GUID};
         verifyCreatedEntities(entityStore, entityGuids, 4);

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/SoftReferenceTest.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/SoftReferenceTest.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/SoftReferenceTest.java
index a860764..2ffc972 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/SoftReferenceTest.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/SoftReferenceTest.java
@@ -18,7 +18,9 @@
 
 package org.apache.atlas.repository.store.graph.v1;
 
+import org.apache.atlas.RequestContext;
 import org.apache.atlas.TestModules;
+import org.apache.atlas.TestUtilsV2;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
@@ -32,10 +34,12 @@ import 
org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.repository.store.graph.v2.AtlasEntityStream;
 import org.apache.atlas.repository.store.graph.v2.AtlasGraphUtilsV2;
 import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.utils.TestResourceFileUtils;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Guice;
 import org.testng.annotations.Test;
 
@@ -50,7 +54,7 @@ import static org.testng.Assert.assertFalse;
 import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertTrue;
 
-@Guice(modules = TestModules.SoftDeleteModule.class)
+@Guice(modules = TestModules.TestOnlyModule.class)
 public class SoftReferenceTest {
     private static final String TYPE_RDBMS_DB = "rdbms_db";
     private static final String RDBMS_DB_FILE = "rdbms-db";
@@ -75,6 +79,12 @@ public class SoftReferenceTest {
     private String dbGuid;
     private String storageGuid;
 
+    @BeforeMethod
+    public void init() throws Exception {
+        RequestContext.get().setUser(TestUtilsV2.TEST_USER, null);
+        RequestContext.get().setDeleteType(DeleteType.SOFT);
+    }
+
     @Test
     public void typeCreationFromFile() throws IOException, AtlasBaseException {
         String typesDefJson = 
TestResourceFileUtils.getJson(TYPESDEF_FILE_NAME);

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
index 4fd2820..ca46ffd 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2Test.java
@@ -109,7 +109,7 @@ public class AtlasEntityStoreV2Test extends 
AtlasEntityTestBase {
     }
     @BeforeTest
     public void init() throws Exception {
-        entityStore = new AtlasEntityStoreV2(deleteHandler, typeRegistry, 
mockChangeNotifier, graphMapper);
+        entityStore = new AtlasEntityStoreV2(deleteDelegate, typeRegistry, 
mockChangeNotifier, graphMapper);
         RequestContext.clear();
         RequestContext.get().setUser(TestUtilsV2.TEST_USER, null);
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityTestBase.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityTestBase.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityTestBase.java
index ba05510..368951d 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityTestBase.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityTestBase.java
@@ -38,7 +38,7 @@ import 
org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
 import org.apache.atlas.repository.graphdb.AtlasGraph;
 import 
org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.runner.LocalSolrRunner;
 import org.apache.atlas.store.AtlasTypeDefStore;
 import org.apache.atlas.type.AtlasArrayType;
@@ -78,7 +78,7 @@ public class AtlasEntityTestBase {
     AtlasEntityStore entityStore;
 
     @Inject
-    DeleteHandlerV1 deleteHandler;
+    DeleteHandlerDelegate deleteDelegate;
 
     @Inject
     private EntityGraphMapper graphMapper;
@@ -107,7 +107,7 @@ public class AtlasEntityTestBase {
 
     @BeforeTest
     public void init() throws Exception {
-        entityStore = new AtlasEntityStoreV2(deleteHandler, typeRegistry, 
mockChangeNotifier, graphMapper);
+        entityStore = new AtlasEntityStoreV2(deleteDelegate, typeRegistry, 
mockChangeNotifier, graphMapper);
 
         RequestContext.clear();
         RequestContext.get().setUser(TestUtilsV2.TEST_USER, null);

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreHardDeleteV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreHardDeleteV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreHardDeleteV2Test.java
index 8955be7..623235f 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreHardDeleteV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreHardDeleteV2Test.java
@@ -18,11 +18,11 @@
 package org.apache.atlas.repository.store.graph.v2;
 
 import com.google.common.collect.ImmutableList;
-import org.apache.atlas.TestModules;
+import org.apache.atlas.RequestContext;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.repository.store.graph.v1.HardDeleteHandlerV1;
-import org.testng.annotations.Guice;
+import org.apache.atlas.store.DeleteType;
+import org.testng.annotations.BeforeTest;
 
 import java.util.List;
 
@@ -32,11 +32,14 @@ import static org.testng.Assert.assertNotNull;
 import static org.testng.Assert.assertNull;
 
 /**
- * Inverse reference update test with {@link HardDeleteHandlerV1}
+ * Inverse reference update test with HardDeleteHandlerV1
  */
-@Guice(modules = TestModules.HardDeleteModule.class)
 public class AtlasRelationshipStoreHardDeleteV2Test extends 
AtlasRelationshipStoreV2Test {
 
+    public AtlasRelationshipStoreHardDeleteV2Test() {
+        super(DeleteType.HARD);
+    }
+
     @Override
     protected void 
verifyRelationshipAttributeUpdate_NonComposite_OneToMany(AtlasEntity jane) 
throws Exception {
         // Max should have been removed from the subordinates list, leaving 
only John.

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreSoftDeleteV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreSoftDeleteV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreSoftDeleteV2Test.java
index 82b75da..b169988 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreSoftDeleteV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreSoftDeleteV2Test.java
@@ -18,11 +18,9 @@
 package org.apache.atlas.repository.store.graph.v2;
 
 import com.google.common.collect.ImmutableList;
-import org.apache.atlas.TestModules;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
-import org.testng.annotations.Guice;
+import org.apache.atlas.store.DeleteType;
 
 import java.util.List;
 
@@ -32,11 +30,14 @@ import static org.testng.Assert.assertNotNull;
 
 
 /**
- * Inverse reference update test with {@link SoftDeleteHandlerV1}
+ * Inverse reference update test with SoftDeleteHandlerV1
  */
-@Guice(modules = TestModules.SoftDeleteModule.class)
 public class AtlasRelationshipStoreSoftDeleteV2Test extends 
AtlasRelationshipStoreV2Test {
 
+    public AtlasRelationshipStoreSoftDeleteV2Test() {
+        super(DeleteType.SOFT);
+    }
+
     @Override
     protected void 
verifyRelationshipAttributeUpdate_NonComposite_OneToMany(AtlasEntity jane) 
throws Exception {
         // Max is still in the subordinates list, as the edge still exists 
with state DELETED

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2Test.java
index cd1d727..a40cf85 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasRelationshipStoreV2Test.java
@@ -35,9 +35,10 @@ import 
org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
 import 
org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
-import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
+import org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.runner.LocalSolrRunner;
 import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.commons.collections.CollectionUtils;
@@ -77,7 +78,7 @@ public abstract class AtlasRelationshipStoreV2Test {
     AtlasTypeDefStore typeDefStore;
 
     @Inject
-    DeleteHandlerV1 deleteHandler;
+    DeleteHandlerDelegate deleteDelegate;
 
     @Inject
     EntityGraphMapper graphMapper;
@@ -88,9 +89,14 @@ public abstract class AtlasRelationshipStoreV2Test {
     AtlasEntityStore          entityStore;
     AtlasRelationshipStore    relationshipStore;
     AtlasEntityChangeNotifier mockChangeNotifier = 
mock(AtlasEntityChangeNotifier.class);
+    private final DeleteType  deleteType;
 
     protected Map<String, AtlasObjectId> employeeNameIdMap = new HashMap<>();
 
+    protected AtlasRelationshipStoreV2Test(DeleteType delteType) {
+        this.deleteType = delteType;
+    }
+
     @BeforeClass
     public void setUp() throws Exception {
         new GraphBackedSearchIndexer(typeRegistry);
@@ -118,11 +124,12 @@ public abstract class AtlasRelationshipStoreV2Test {
 
     @BeforeTest
     public void init() throws Exception {
-        entityStore       = new AtlasEntityStoreV2(deleteHandler, 
typeRegistry, mockChangeNotifier, graphMapper);
-        relationshipStore = new AtlasRelationshipStoreV2(typeRegistry, 
deleteHandler, entityNotifier);
+        entityStore       = new AtlasEntityStoreV2(deleteDelegate, 
typeRegistry, mockChangeNotifier, graphMapper);
+        relationshipStore = new AtlasRelationshipStoreV2(typeRegistry, 
deleteDelegate, entityNotifier);
 
         RequestContext.clear();
         RequestContext.get().setUser(TestUtilsV2.TEST_USER, null);
+        RequestContext.get().setDeleteType(deleteType);
     }
 
     @AfterClass

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateHardDeleteV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateHardDeleteV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateHardDeleteV2Test.java
index 5d45908..ed72d5f 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateHardDeleteV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateHardDeleteV2Test.java
@@ -18,12 +18,10 @@
 package org.apache.atlas.repository.store.graph.v2;
 
 import com.google.common.collect.ImmutableList;
-import org.apache.atlas.TestModules;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.repository.store.graph.v1.HardDeleteHandlerV1;
+import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.type.AtlasTypeUtil;
-import org.testng.annotations.Guice;
 
 import java.util.Map;
 
@@ -31,11 +29,14 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertTrue;
 
 /**
- * Inverse reference update test with {@link HardDeleteHandlerV1}
+ * Inverse reference update test with HardDeleteHandlerV1
  */
-@Guice(modules = TestModules.HardDeleteModule.class)
 public class InverseReferenceUpdateHardDeleteV2Test extends 
InverseReferenceUpdateV2Test {
 
+    public InverseReferenceUpdateHardDeleteV2Test() {
+        super(DeleteType.HARD);
+    }
+
     @Override
     protected void 
verify_testInverseReferenceAutoUpdate_NonComposite_OneToMany(AtlasEntity jane) 
throws Exception {
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateSoftDeleteV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateSoftDeleteV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateSoftDeleteV2Test.java
index 76d6b7d..92d1ddc 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateSoftDeleteV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateSoftDeleteV2Test.java
@@ -18,12 +18,10 @@
 package org.apache.atlas.repository.store.graph.v2;
 
 import com.google.common.collect.ImmutableList;
-import org.apache.atlas.TestModules;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.repository.store.graph.v1.SoftDeleteHandlerV1;
+import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.type.AtlasTypeUtil;
-import org.testng.annotations.Guice;
 
 import java.util.Map;
 
@@ -32,11 +30,14 @@ import static org.testng.Assert.assertTrue;
 
 
 /**
- * Inverse reference update test with {@link SoftDeleteHandlerV1}
+ * Inverse reference update test with SoftDeleteHandlerV1
  */
-@Guice(modules = TestModules.SoftDeleteModule.class)
 public class InverseReferenceUpdateSoftDeleteV2Test extends 
InverseReferenceUpdateV2Test {
 
+    public InverseReferenceUpdateSoftDeleteV2Test() {
+        super(DeleteType.SOFT);
+    }
+
     @Override
     protected void 
verify_testInverseReferenceAutoUpdate_NonComposite_OneToMany(AtlasEntity jane)
         throws Exception {

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateV2Test.java
----------------------------------------------------------------------
diff --git 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateV2Test.java
 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateV2Test.java
index ea647ec..6364fd4 100644
--- 
a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateV2Test.java
+++ 
b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/InverseReferenceUpdateV2Test.java
@@ -20,6 +20,7 @@ package org.apache.atlas.repository.store.graph.v2;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import org.apache.atlas.RequestContext;
+import org.apache.atlas.TestModules;
 import org.apache.atlas.TestUtilsV2;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo;
@@ -33,12 +34,14 @@ import 
org.apache.atlas.repository.store.bootstrap.AtlasTypeDefStoreInitializer;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
 import org.apache.atlas.runner.LocalSolrRunner;
 import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.type.AtlasTypeUtil;
 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;
@@ -58,6 +61,7 @@ import static org.apache.atlas.TestUtilsV2.NAME;
  * Test automatic inverse reference updating in V1 (V2?) code path.
  *
  */
+@Guice(modules = TestModules.TestOnlyModule.class)
 public abstract class InverseReferenceUpdateV2Test {
     @Inject
     AtlasTypeRegistry typeRegistry;
@@ -69,9 +73,14 @@ public abstract class InverseReferenceUpdateV2Test {
     AtlasEntityStore entityStore;
 
     private AtlasEntitiesWithExtInfo deptEntity;
+    private final DeleteType         deleteType;
 
     protected Map<String, AtlasObjectId> nameIdMap = new HashMap<>();
 
+    protected InverseReferenceUpdateV2Test(DeleteType deleteType) {
+        this.deleteType = deleteType;
+    }
+
     @BeforeClass
     public void setUp() throws Exception {
         RequestContext.clear();
@@ -110,6 +119,7 @@ public abstract class InverseReferenceUpdateV2Test {
     public void init() throws Exception {
         RequestContext.clear();
         RequestContext.get().setUser(TestUtilsV2.TEST_USER, null);
+        RequestContext.get().setDeleteType(deleteType);
     }
 
     @Test

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/server-api/src/main/java/org/apache/atlas/RequestContext.java
----------------------------------------------------------------------
diff --git a/server-api/src/main/java/org/apache/atlas/RequestContext.java 
b/server-api/src/main/java/org/apache/atlas/RequestContext.java
index 9a9bba6..b49591d 100644
--- a/server-api/src/main/java/org/apache/atlas/RequestContext.java
+++ b/server-api/src/main/java/org/apache/atlas/RequestContext.java
@@ -22,6 +22,7 @@ import org.apache.atlas.model.instance.AtlasClassification;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo;
 import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.store.DeleteType;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,20 +35,21 @@ public class RequestContext {
     private static final ThreadLocal<RequestContext> CURRENT_CONTEXT = new 
ThreadLocal<>();
     private static final Set<RequestContext>         ACTIVE_REQUESTS = new 
HashSet<>();
 
+    private final long                                   requestTime         = 
System.currentTimeMillis();
     private final Map<String, AtlasObjectId>             updatedEntities     = 
new HashMap<>();
     private final Map<String, AtlasObjectId>             deletedEntities     = 
new HashMap<>();
     private final Map<String, AtlasEntity>               entityCache         = 
new HashMap<>();
     private final Map<String, AtlasEntityWithExtInfo>    entityExtInfoCache  = 
new HashMap<>();
     private final Map<String, List<AtlasClassification>> addedPropagations   = 
new HashMap<>();
     private final Map<String, List<AtlasClassification>> removedPropagations = 
new HashMap<>();
-    private final long                                   requestTime         = 
System.currentTimeMillis();
     private       List<EntityGuidPair>                   entityGuidInRequest = 
null;
 
     private String      user;
     private Set<String> userGroups;
-    private String clientIPAddress;
-    private int    maxAttempts  = 1;
-    private int    attemptCount = 1;
+    private String      clientIPAddress;
+    private DeleteType  deleteType   = DeleteType.DEFAULT;
+    private int         maxAttempts  = 1;
+    private int         attemptCount = 1;
 
 
     private RequestContext() {
@@ -74,16 +76,7 @@ public class RequestContext {
         RequestContext instance = CURRENT_CONTEXT.get();
 
         if (instance != null) {
-            instance.updatedEntities.clear();
-            instance.deletedEntities.clear();
-            instance.entityCache.clear();
-            instance.entityExtInfoCache.clear();
-            instance.addedPropagations.clear();
-            instance.removedPropagations.clear();
-
-            if (instance.entityGuidInRequest != null) {
-                instance.entityGuidInRequest.clear();
-            }
+            instance.clearCache();
 
             synchronized (ACTIVE_REQUESTS) {
                 ACTIVE_REQUESTS.remove(instance);
@@ -93,6 +86,19 @@ public class RequestContext {
         CURRENT_CONTEXT.remove();
     }
 
+    public void clearCache() {
+        this.updatedEntities.clear();
+        this.deletedEntities.clear();
+        this.entityCache.clear();
+        this.entityExtInfoCache.clear();
+        this.addedPropagations.clear();
+        this.removedPropagations.clear();
+
+        if (this.entityGuidInRequest != null) {
+            this.entityGuidInRequest.clear();
+        }
+    }
+
     public static String getCurrentUser() {
         RequestContext context = CURRENT_CONTEXT.get();
         return context != null ? context.getUser() : null;
@@ -111,6 +117,10 @@ public class RequestContext {
         this.userGroups = userGroups;
     }
 
+    public DeleteType getDeleteType() { return deleteType; }
+
+    public void setDeleteType(DeleteType deleteType) { this.deleteType = 
(deleteType == null) ? DeleteType.DEFAULT : deleteType; }
+
     public String getClientIPAddress() {
         return clientIPAddress;
     }
@@ -162,12 +172,6 @@ public class RequestContext {
         }
     }
 
-    public static RequestContext createContext() {
-        clear();
-
-        return get();
-    }
-
     public static int getActiveRequestsCount() {
         return ACTIVE_REQUESTS.size();
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java 
b/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
index adf3cf2..54f7330 100755
--- a/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
+++ b/webapp/src/main/java/org/apache/atlas/web/filters/AuditFilter.java
@@ -22,10 +22,12 @@ import org.apache.atlas.AtlasClient;
 import org.apache.atlas.AtlasException;
 import org.apache.atlas.RequestContext;
 import org.apache.atlas.authorize.AtlasAuthorizationUtils;
+import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.util.AtlasRepositoryConfiguration;
 import org.apache.atlas.web.util.DateTimeHelper;
 import org.apache.atlas.web.util.Servlets;
 import org.apache.commons.configuration.Configuration;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -43,6 +45,8 @@ import java.util.Date;
 import java.util.Set;
 import java.util.UUID;
 
+import static 
org.apache.atlas.AtlasConfiguration.REST_API_ENABLE_DELETE_TYPE_OVERRIDE;
+
 /**
  * This records audit information as part of the filter after processing the 
request
  * and also introduces a UUID into request and response for tracing requests 
in logs.
@@ -52,9 +56,15 @@ public class AuditFilter implements Filter {
     private static final Logger LOG       = 
LoggerFactory.getLogger(AuditFilter.class);
     private static final Logger AUDIT_LOG = LoggerFactory.getLogger("AUDIT");
 
+    private boolean deleteTypeOverrideEnabled = false;
+
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         LOG.info("AuditFilter initialization started");
+
+        deleteTypeOverrideEnabled = 
REST_API_ENABLE_DELETE_TYPE_OVERRIDE.getBoolean();
+
+        LOG.info("REST_API_ENABLE_DELETE_TYPE_OVERRIDE={}", 
deleteTypeOverrideEnabled);
     }
 
     @Override
@@ -69,6 +79,7 @@ public class AuditFilter implements Filter {
         final String              oldName            = currentThread.getName();
         final String              user               = 
AtlasAuthorizationUtils.getCurrentUserName();
         final Set<String>         userGroups         = 
AtlasAuthorizationUtils.getCurrentUserGroups();
+        final String              deleteType         = 
httpRequest.getParameter("deleteType");
 
         try {
             currentThread.setName(formatName(oldName, requestId));
@@ -77,6 +88,15 @@ public class AuditFilter implements Filter {
             RequestContext requestContext = RequestContext.get();
             requestContext.setUser(user, userGroups);
             
requestContext.setClientIPAddress(AtlasAuthorizationUtils.getRequestIpAddress(httpRequest));
+
+            if (StringUtils.isNotEmpty(deleteType)) {
+                if (deleteTypeOverrideEnabled) {
+                    requestContext.setDeleteType(DeleteType.from(deleteType));
+                } else {
+                    LOG.warn("Override of deleteType is not enabled. Ignoring 
parameter deleteType={}, in request from user={}", deleteType, user);
+                }
+            }
+
             filterChain.doFilter(request, response);
         } finally {
             long timeTaken = System.currentTimeMillis() - startTime;

http://git-wip-us.apache.org/repos/asf/atlas/blob/7869c9a5/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityRESTDelete.java
----------------------------------------------------------------------
diff --git 
a/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityRESTDelete.java 
b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityRESTDelete.java
new file mode 100644
index 0000000..02e78f4
--- /dev/null
+++ 
b/webapp/src/test/java/org/apache/atlas/web/adapters/TestEntityRESTDelete.java
@@ -0,0 +1,207 @@
+/**
+ * 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.web.adapters;
+
+import org.apache.atlas.RequestContext;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.TestUtilsV2;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasEntityHeader;
+import org.apache.atlas.model.instance.EntityMutationResponse;
+import org.apache.atlas.model.instance.EntityMutations;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.store.AtlasTypeDefStore;
+import org.apache.atlas.store.DeleteType;
+import org.apache.atlas.web.rest.EntityREST;
+import org.mockito.Mockito;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import javax.inject.Inject;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.testng.Assert.assertNotNull;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.FileAssert.fail;
+
+@Guice(modules = {TestModules.TestOnlyModule.class})
+public class TestEntityRESTDelete {
+
+    @Inject
+    private AtlasTypeDefStore typeStore;
+
+    @Inject
+    private EntityREST entityREST;
+
+    private List<AtlasEntity> dbEntities = new ArrayList<>();
+
+    @BeforeClass
+    public void setUp() throws Exception {
+        AtlasTypesDef typesDef = TestUtilsV2.defineHiveTypes();
+        typeStore.createTypesDef(typesDef);
+    }
+
+    @AfterMethod
+    public void cleanup() {
+        RequestContext.clear();
+    }
+
+    private void assertSoftDelete(String guid) throws AtlasBaseException {
+        AtlasEntity.AtlasEntityWithExtInfo entity = entityREST.getById(guid, 
false);
+        assertTrue(entity != null && entity.getEntity().getStatus() == 
AtlasEntity.Status.DELETED);
+    }
+
+    private void assertHardDelete(String guid) {
+        try {
+            entityREST.getById(guid, false);
+            fail("Entity should have been deleted. Exception should have been 
thrown.");
+        } catch (AtlasBaseException e) {
+            assertTrue(true);
+        }
+    }
+
+    private void createEntities() throws Exception {
+        dbEntities.clear();
+
+        for (int i = 1; i <= 2; i++) {
+            AtlasEntity dbEntity = TestUtilsV2.createDBEntity();
+
+            final EntityMutationResponse response = 
entityREST.createOrUpdate(new AtlasEntity.AtlasEntitiesWithExtInfo(dbEntity));
+
+            assertNotNull(response);
+            List<AtlasEntityHeader> entitiesMutated = 
response.getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
+
+            assertNotNull(entitiesMutated);
+            Assert.assertEquals(entitiesMutated.size(), 1);
+            assertNotNull(entitiesMutated.get(0));
+            dbEntity.setGuid(entitiesMutated.get(0).getGuid());
+
+            dbEntities.add(dbEntity);
+        }
+    }
+
+    @Test
+    public void deleteByGuidTestSoft() throws Exception {
+        RequestContext.get().setDeleteType(DeleteType.SOFT);
+
+        createEntities();
+
+        EntityMutationResponse response = 
entityREST.deleteByGuid(dbEntities.get(0).getGuid());
+
+        assertNotNull(response);
+        assertNotNull(response.getDeletedEntities());
+        assertSoftDelete(dbEntities.get(0).getGuid());
+    }
+
+    @Test
+    public void deleteByGuidTestHard() throws Exception {
+        RequestContext.get().setDeleteType(DeleteType.HARD);
+
+        createEntities();
+        EntityMutationResponse response = 
entityREST.deleteByGuid(dbEntities.get(0).getGuid());
+
+        assertNotNull(response);
+        assertNotNull(response.getDeletedEntities());
+        assertHardDelete(dbEntities.get(0).getGuid());
+    }
+
+
+    @Test
+    public void deleteByGuidsSoft() throws Exception {
+        RequestContext.get().setDeleteType(DeleteType.SOFT);
+
+        createEntities();
+        List<String> guids = new ArrayList<>();
+        guids.add(dbEntities.get(0).getGuid());
+        guids.add(dbEntities.get(1).getGuid());
+
+        EntityMutationResponse response = entityREST.deleteByGuids(guids);
+
+        assertNotNull(response);
+        assertNotNull(response.getDeletedEntities());
+
+        for (String guid : guids) {
+            assertSoftDelete(guid);
+        }
+    }
+
+    @Test
+    public void deleteByGuidsHard() throws Exception {
+        RequestContext.get().setDeleteType(DeleteType.HARD);
+
+        createEntities();
+        List<String> guids = new ArrayList<>();
+        guids.add(dbEntities.get(0).getGuid());
+        guids.add(dbEntities.get(1).getGuid());
+        EntityMutationResponse response = entityREST.deleteByGuids(guids);
+
+        assertNotNull(response);
+        assertNotNull(response.getDeletedEntities());
+
+        for (String guid : guids) {
+            assertHardDelete(guid);
+        }
+    }
+
+    @Test
+    public void testUpdateGetDeleteEntityByUniqueAttributeSoft() throws 
Exception {
+        RequestContext.get().setDeleteType(DeleteType.SOFT);
+
+        createEntities();
+        entityREST.deleteByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, 
toHttpServletRequest(TestUtilsV2.NAME,
+                (String) dbEntities.get(0).getAttribute(TestUtilsV2.NAME)));
+
+        assertSoftDelete(dbEntities.get(0).getGuid());
+    }
+
+    @Test
+    public void testUpdateGetDeleteEntityByUniqueAttributeHard() throws 
Exception {
+        RequestContext.get().setDeleteType(DeleteType.HARD);
+
+        createEntities();
+
+        entityREST.deleteByUniqueAttribute(TestUtilsV2.DATABASE_TYPE, 
toHttpServletRequest(TestUtilsV2.NAME,
+                (String) dbEntities.get(0).getAttribute(TestUtilsV2.NAME)));
+
+        assertHardDelete(dbEntities.get(0).getGuid());
+    }
+
+    private HttpServletRequest toHttpServletRequest(String attrName, String 
attrValue) {
+        HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
+        Map<String, String[]> paramsMap = 
toParametersMap(EntityREST.PREFIX_ATTR + attrName, attrValue);
+
+        Mockito.when(request.getParameterMap()).thenReturn(paramsMap);
+
+        return request;
+    }
+
+    private Map<String, String[]> toParametersMap(final String name, final 
String value) {
+        return new HashMap<String, String[]>() {{
+            put(name, new String[]{value});
+        }};
+    }
+}
\ No newline at end of file

Reply via email to