You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by ma...@apache.org on 2017/02/04 00:33:07 UTC

[3/3] incubator-atlas git commit: ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references

ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references

Signed-off-by: Madhan Neethiraj <ma...@apache.org>


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

Branch: refs/heads/master
Commit: d8c2a10e080eb79ba23f646270313089b2afdfda
Parents: 02cf8c4
Author: Suma Shivaprasad <su...@gmail.com>
Authored: Fri Feb 3 04:15:41 2017 -0800
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri Feb 3 15:18:05 2017 -0800

----------------------------------------------------------------------
 .../org/apache/atlas/AtlasEntitiesClientV2.java |  25 +-
 .../java/org/apache/atlas/AtlasErrorCode.java   |   2 +
 .../atlas/model/instance/AtlasEntity.java       |  75 ++--
 .../instance/AtlasEntityWithAssociations.java   |   4 +
 .../atlas/model/instance/AtlasObjectId.java     |  38 ++
 .../model/instance/EntityMutationResponse.java  |  28 ++
 .../org/apache/atlas/type/AtlasEntityType.java  |  18 +-
 .../org/apache/atlas/type/AtlasStructType.java  |  17 +-
 .../test/java/org/apache/atlas/TestUtilsV2.java |  34 +-
 .../store/graph/AtlasEntityStore.java           |  52 +--
 .../graph/EntityGraphDiscoveryContext.java      | 165 +++++---
 .../graph/v1/AtlasEntityGraphDiscoveryV1.java   | 110 +++---
 .../store/graph/v1/AtlasEntityStoreV1.java      |  93 ++---
 .../store/graph/v1/DeleteHandlerV1.java         |   1 +
 .../store/graph/v1/EntityGraphMapper.java       |  20 +-
 .../store/graph/v1/EntityMutationContext.java   |  73 ++--
 .../repository/store/graph/v1/EntityStream.java |  32 ++
 .../store/graph/v1/IDBasedEntityResolver.java   |  53 +--
 .../store/graph/v1/InMemoryMapEntityStream.java |  60 +++
 .../graph/v1/UniqAttrBasedEntityResolver.java   | 150 +++++--
 .../store/graph/v1/AtlasEntityStoreV1Test.java  | 390 +++++++++++--------
 .../web/adapters/AtlasArrayFormatConverter.java |   8 +-
 .../AtlasClassificationFormatConverter.java     |   6 +-
 .../adapters/AtlasEntityFormatConverter.java    |  27 +-
 .../web/adapters/AtlasEnumFormatConverter.java  |   4 +-
 .../web/adapters/AtlasFormatConverter.java      |  54 ++-
 .../web/adapters/AtlasInstanceRestAdapters.java |  36 +-
 .../web/adapters/AtlasMapFormatConverter.java   |  12 +-
 .../web/adapters/AtlasObjectIdConverter.java    |  90 +++++
 .../adapters/AtlasPrimitiveFormatConverter.java |   4 +-
 .../adapters/AtlasStructFormatConverter.java    |  44 ++-
 .../org/apache/atlas/web/rest/EntitiesREST.java |  56 +--
 .../org/apache/atlas/web/rest/EntityREST.java   |  69 ++--
 .../atlas/web/adapters/TestEntitiesREST.java    |  33 +-
 .../atlas/web/adapters/TestEntityREST.java      |  44 ++-
 .../web/resources/EntityV2JerseyResourceIT.java |   2 +-
 36 files changed, 1189 insertions(+), 740 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java b/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
index 8d1bfa7..2b3669d 100644
--- a/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
+++ b/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java
@@ -32,7 +32,9 @@ import org.apache.hadoop.security.UserGroupInformation;
 import javax.ws.rs.HttpMethod;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import static org.apache.atlas.model.instance.AtlasEntity.AtlasEntities;
 
@@ -43,12 +45,11 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
 
     private static final APIInfo GET_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.GET, Response.Status.OK);
     private static final APIInfo GET_ENTITY_WITH_ASSOCIATION_BY_GUID = new APIInfo(ENTITY_API + "guid/%s/associations", HttpMethod.GET, Response.Status.OK);
-    private static final APIInfo CREATE_ENTITY = new APIInfo(ENTITY_API, HttpMethod.POST, Response.Status.OK);
+    private static final APIInfo CREATE_ENTITY = new APIInfo(ENTITIES_API, HttpMethod.POST, Response.Status.OK);
     private static final APIInfo UPDATE_ENTITY = CREATE_ENTITY;
     private static final APIInfo GET_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%s/attribute/%s", HttpMethod.GET, Response.Status.OK);
     private static final APIInfo UPDATE_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%s/attribute/%s", HttpMethod.PUT, Response.Status.OK);
     private static final APIInfo DELETE_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%s/attribute/%s", HttpMethod.DELETE, Response.Status.OK);
-    private static final APIInfo UPDATE_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.PUT, Response.Status.OK);
     private static final APIInfo DELETE_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.DELETE, Response.Status.OK);
     private static final APIInfo DELETE_ENTITY_BY_GUIDS = new APIInfo(ENTITIES_API + "guids/", HttpMethod.DELETE, Response.Status.OK);
     private static final APIInfo GET_CLASSIFICATIONS = new APIInfo(ENTITY_API + "guid/%s/classifications", HttpMethod.GET, Response.Status.OK);
@@ -113,16 +114,12 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
         return callAPI(formatPathForPathParams(DELETE_ENTITY_BY_ATTRIBUTE, type, attribute), null, EntityMutationResponse.class, queryParams);
     }
 
-    public EntityMutationResponse createEntity(AtlasEntity atlasEntity) throws AtlasServiceException {
-        return callAPI(CREATE_ENTITY, atlasEntity, EntityMutationResponse.class);
+    public EntityMutationResponse createEntity(final AtlasEntity atlasEntity) throws AtlasServiceException {
+        return callAPI(CREATE_ENTITY, new HashMap<String, AtlasEntity>() {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class);
     }
 
-    public EntityMutationResponse updateEntity(AtlasEntity atlasEntity) throws AtlasServiceException {
-        return callAPI(UPDATE_ENTITY, atlasEntity, EntityMutationResponse.class);
-    }
-
-    public EntityMutationResponse updateEntity(String guid, AtlasEntity atlasEntity) throws AtlasServiceException {
-        return callAPI(UPDATE_ENTITY_BY_GUID, atlasEntity, EntityMutationResponse.class, guid);
+    public EntityMutationResponse updateEntity(final AtlasEntity atlasEntity) throws AtlasServiceException {
+        return callAPI(UPDATE_ENTITY, new HashMap<String, AtlasEntity>() {{ put(atlasEntity.getGuid(), atlasEntity); }}, EntityMutationResponse.class);
     }
 
     public AtlasEntity deleteEntityByGuid(String guid) throws AtlasServiceException {
@@ -159,15 +156,11 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient {
         return null;
     }
 
-    public List<AtlasEntity> createEntities(List<AtlasEntity> atlasEntities) throws AtlasServiceException {
+    public List<AtlasEntity> createEntities(Map<String, AtlasEntity> atlasEntities) throws AtlasServiceException {
         return (List<AtlasEntity>)callAPI(CREATE_ENTITIES, atlasEntities, List.class);
     }
 
-    public List<AtlasEntity> updateEntities(List<AtlasEntity> atlasEntities) throws AtlasServiceException {
+    public List<AtlasEntity> updateEntities(Map<String, AtlasEntity> atlasEntities) throws AtlasServiceException {
         return (List<AtlasEntity>)callAPI(UPDATE_ENTITIES, atlasEntities, List.class);
     }
-
-    public AtlasEntity.AtlasEntities searchEntities(SearchFilter searchFilter) throws AtlasServiceException {
-        return callAPI(GET_ENTITIES, AtlasEntity.AtlasEntities.class, searchFilter.getParams());
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 0fb16c6..49289d8 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -80,6 +80,8 @@ public enum AtlasErrorCode {
 
     INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND(400, "ATLAS40018E", "Instance {0} with unique attribute {1} does not exist"),
 
+    UNRESOLVED_REFERENCES_FOUND(400, "ATLAS40010E", "Unresolved references: byId={0}; byUniqueAttributes={1}"),
+
     UNKNOWN_ATTRIBUTE(400, "ATLAS40019E", "Attribute {0} not found for type {1}");
 
     private String errorCode;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
index 9494fe4..de57145 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
@@ -161,6 +161,41 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
         this.version = version;
     }
 
+    @JsonIgnore
+    public boolean isUnassigned() {
+        return isUnAssigned(guid);
+    }
+
+    @JsonIgnore
+    public boolean isAssigned() {
+        return isAssigned(guid);
+    }
+
+    @JsonIgnore
+    public static boolean isAssigned(String guid) {
+        try {
+            UUID.fromString(guid);
+        } catch (IllegalArgumentException e) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @JsonIgnore
+    public static boolean isUnAssigned(String guid) {
+        return guid != null && guid.length() > 0 && guid.charAt(0) == '-';
+    }
+
+    private static String nextInternalId() {
+        return "-" + Long.toString(s_nextId.getAndIncrement());
+    }
+
+    @JsonIgnore
+    public AtlasObjectId getAtlasObjectId() {
+        return new AtlasObjectId(getTypeName(), getGuid());
+    }
+
     @Override
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
@@ -233,44 +268,4 @@ public class AtlasEntity extends AtlasStruct implements Serializable {
             super(list, startIndex, pageSize, totalCount, sortType, sortBy);
         }
     }
-
-    @JsonIgnore
-    public boolean validate(String id) {
-        try {
-            long l = Long.parseLong(id);
-            return l < 0;
-        } catch (NumberFormatException ne) {
-            return false;
-        }
-    }
-
-    @JsonIgnore
-    public boolean isUnassigned() {
-        return isUnAssigned(guid);
-    }
-
-    @JsonIgnore
-    public boolean isAssigned() {
-        return isAssigned(guid);
-    }
-
-    @JsonIgnore
-    public static boolean isAssigned(String guid) {
-        try {
-            UUID.fromString(guid);
-        } catch (IllegalArgumentException e) {
-            return false;
-        }
-
-        return true;
-    }
-
-    @JsonIgnore
-    public static boolean isUnAssigned(String guid) {
-        return guid != null && guid.length() > 0 && guid.charAt(0) == '-';
-    }
-
-    private String nextInternalId() {
-        return "-" + Long.toString(s_nextId.getAndIncrement());
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
index 932a40d..abcf276 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java
@@ -73,6 +73,10 @@ public class AtlasEntityWithAssociations extends AtlasEntity implements Serializ
         setClassifications(other != null ? other.getClassifications() : null);
     }
 
+    public AtlasEntityWithAssociations(AtlasEntity other) {
+        super(other);
+    }
+
     @Override
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
index 738f22f..e4abda7 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasObjectId.java
@@ -30,10 +30,13 @@ import javax.xml.bind.annotation.XmlSeeAlso;
 import org.apache.atlas.model.PList;
 import org.apache.atlas.model.SearchFilter.SortType;
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
 import org.codehaus.jackson.annotate.JsonAutoDetect;
 import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
 import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
 
+import org.codehaus.jackson.annotate.JsonIgnore;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
 
@@ -56,6 +59,12 @@ public class AtlasObjectId  implements Serializable {
     private String              guid;
     private Map<String, Object> uniqueAttributes;
 
+    @JsonIgnore
+    private boolean isAssignedGuid = false;
+
+    @JsonIgnore
+    private boolean isUnAssignedGuid = false;
+
     public AtlasObjectId() {
         this(null, null, null);
     }
@@ -120,6 +129,10 @@ public class AtlasObjectId  implements Serializable {
 
     public void setGuid(String guid) {
         this.guid = guid;
+        if ( guid != null) {
+            this.isAssignedGuid = AtlasEntity.isAssigned(guid);
+            this.isUnAssignedGuid = AtlasEntity.isUnAssigned(guid);
+        }
     }
 
     public Map<String, Object> getUniqueAttributes() {
@@ -130,6 +143,31 @@ public class AtlasObjectId  implements Serializable {
         this.uniqueAttributes = uniqueAttributes;
     }
 
+    @JsonIgnore
+    public boolean isAssignedGuid() {
+        return isAssignedGuid;
+    }
+
+    @JsonIgnore
+    public boolean isUnAssignedGuid() {
+        return isUnAssignedGuid;
+    }
+
+    @JsonIgnore
+    public boolean isValid() {
+        if (StringUtils.isEmpty(typeName)) {
+            return false;
+        } else if (StringUtils.isNotEmpty(guid)) {
+            if (!isAssignedGuid && !isUnAssignedGuid) {
+                return false;
+            }
+        } else if (MapUtils.isEmpty(uniqueAttributes)) {
+            return false;
+        }
+
+        return true;
+    }
+
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
             sb = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java b/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
index c9b6e97..874a43a 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/EntityMutationResponse.java
@@ -89,6 +89,34 @@ public class EntityMutationResponse {
         return null;
     }
 
+    @JsonIgnore
+    public AtlasEntityHeader getFirstCreatedEntityByTypeName(String typeName) {
+        final List<AtlasEntityHeader> entitiesByOperation = getEntitiesByOperation(EntityMutations.EntityOperation.CREATE);
+        if ( entitiesByOperation != null && entitiesByOperation.size() > 0) {
+            for (AtlasEntityHeader header : entitiesByOperation) {
+                if ( header.getTypeName().equals(typeName)) {
+                    return header;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    @JsonIgnore
+    public AtlasEntityHeader getFirstUpdatedEntityByTypeName(String typeName) {
+        final List<AtlasEntityHeader> entitiesByOperation = getEntitiesByOperation(EntityMutations.EntityOperation.UPDATE);
+        if ( entitiesByOperation != null && entitiesByOperation.size() > 0) {
+            for (AtlasEntityHeader header : entitiesByOperation) {
+                if ( header.getTypeName().equals(typeName)) {
+                    return header;
+                }
+            }
+        }
+
+        return null;
+    }
+
     public void addEntity(EntityMutations.EntityOperation op, AtlasEntityHeader header) {
         if (entitiesMutated == null) {
             entitiesMutated = new HashMap<>();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
index fcd483c..0099307 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -193,7 +193,7 @@ public class AtlasEntityType extends AtlasStructType {
         if (obj != null) {
             if (obj instanceof AtlasObjectId) {
                 AtlasObjectId objId = (AtlasObjectId ) obj;
-                return validateAtlasObjectId(objId);
+                return isAssignableFrom(objId);
             } else {
                 for (AtlasEntityType superType : superTypes) {
                     if (!superType.isValidValue(obj)) {
@@ -240,7 +240,7 @@ public class AtlasEntityType extends AtlasStructType {
         if (obj != null) {
             if (obj instanceof AtlasObjectId) {
                 AtlasObjectId objId = (AtlasObjectId ) obj;
-                return validateAtlasObjectId(objId);
+                return isAssignableFrom(objId);
             }
 
             for (AtlasEntityType superType : superTypes) {
@@ -406,16 +406,10 @@ public class AtlasEntityType extends AtlasStructType {
         return ret == null ? Collections.<String, AtlasAttribute>emptyMap() : ret;
     }
 
-    private boolean validateAtlasObjectId(AtlasObjectId objId) {
-        if (StringUtils.isEmpty(objId.getTypeName()) || StringUtils.isEmpty(objId.getGuid())) {
-            return false;
-        } else {
-            String typeName = objId.getTypeName();
-            if (!typeName.equals(getTypeName()) && !isSuperTypeOf(typeName)) {
-                return false;
-            }
-        }
-        return AtlasEntity.isAssigned(objId.getGuid()) || AtlasEntity.isUnAssigned((objId.getGuid()));
+    boolean isAssignableFrom(AtlasObjectId objId) {
+        boolean ret = objId.isValid() && (StringUtils.equals(objId.getTypeName(), getTypeName()) || isSuperTypeOf(objId.getTypeName()));
+
+        return ret;
     }
 
     public static class ForeignKeyReference {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index 8bdbe93..3a815b7 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -34,7 +34,6 @@ import org.slf4j.LoggerFactory;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -481,6 +480,22 @@ public class AtlasStructType extends AtlasType {
             return qualifiedName;
         }
 
+        /*
+         * "isContainedAttribute" can not be computed and cached in the constructor - as structType is not fully
+         * populated at the time AtlasAttribute object is constructed.
+         */
+        public boolean isContainedAttribute() {
+            if ( structType.isForeignKeyOnDeleteActionUpdate(attributeDef.getName()) ) {
+                return true;
+            }
+
+            if ( structType instanceof AtlasEntityType) {
+                return ((AtlasEntityType) structType).isMappedFromRefAttribute(attributeDef.getName());
+            }
+
+            return false;
+        }
+
         public static String getQualifiedAttributeName(AtlasStructDef structDef, String attrName) {
             final String typeName = structDef.getName();
             return attrName.contains(".") ? attrName : String.format("%s.%s", typeName, attrName);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
index 0756937..b4aa8aa 100755
--- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
@@ -284,7 +284,9 @@ public final class TestUtilsV2 {
     public static final String PERSON_TYPE = "Person";
     public static final String EMPLOYEE_TYPE = "Employee";
 
-    public static AtlasEntity createDeptEg1() {
+    public static Map<String, AtlasEntity> createDeptEg1() {
+        Map<String, AtlasEntity> deptEmpEntities = new HashMap<>();
+
         AtlasEntity hrDept = new AtlasEntity(DEPARTMENT_TYPE);
         AtlasEntity john = new AtlasEntity(EMPLOYEE_TYPE);
 
@@ -329,7 +331,8 @@ public final class TestUtilsV2 {
         julius.setAttribute("address", juliusAddr);
         julius.setAttribute("subordinates", ImmutableList.of());
 
-        AtlasObjectId janeId = new AtlasObjectId(jane.getTypeName(), jane.getGuid());
+        AtlasObjectId janeId = jane.getAtlasObjectId();
+        AtlasObjectId johnId = john.getAtlasObjectId();
 
         //TODO - Change to MANAGER_TYPE for JULIUS
         AtlasObjectId maxId = new AtlasObjectId(EMPLOYEE_TYPE, max.getGuid());
@@ -355,15 +358,20 @@ public final class TestUtilsV2 {
 
         john.setAttribute("manager", janeId);
         john.setAttribute("mentor", maxId);
-        hrDept.setAttribute("employees", ImmutableList.of(john, jane, julius, max));
+        hrDept.setAttribute("employees", ImmutableList.of(johnId, janeId, juliusId, maxId));
 
-        jane.setAttribute("subordinates", ImmutableList.of(john, max));
+        jane.setAttribute("subordinates", ImmutableList.of(johnId, maxId));
 
 //        Map<String, Integer> secClearanceLevelMap = new HashMap<>();
 //        secClearanceLevelMap.put("level", 1);
 //        jane.setAttribute("SecurityClearance", secClearanceLevelMap);
 
-        return hrDept;
+        deptEmpEntities.put(jane.getGuid(), jane);
+        deptEmpEntities.put(john.getGuid(), john);
+        deptEmpEntities.put(julius.getGuid(), julius);
+        deptEmpEntities.put(max.getGuid(), max);
+        deptEmpEntities.put(deptId.getGuid(), hrDept);
+        return deptEmpEntities;
     }
 
     public static final String DATABASE_TYPE = "hive_database";
@@ -661,15 +669,20 @@ public final class TestUtilsV2 {
         return RandomStringUtils.randomAlphanumeric(10);
     }
 
-    public static AtlasEntity createDBEntity() {
+    public static Map<String, AtlasEntity> createDBEntity() {
+        Map<String, AtlasEntity> ret = new HashMap<>();
         AtlasEntity entity = new AtlasEntity(DATABASE_TYPE);
         String dbName = RandomStringUtils.randomAlphanumeric(10);
         entity.setAttribute(NAME, dbName);
         entity.setAttribute("description", "us db");
-        return entity;
+
+        ret.put(entity.getGuid(), entity);
+        return ret;
     }
 
-    public static AtlasEntity createTableEntity(String dbId) {
+    public static Map<String, AtlasEntity> createTableEntity(String dbId) {
+        Map<String, AtlasEntity> ret = new HashMap<>();
+
         AtlasEntity entity = new AtlasEntity(TABLE_TYPE);
         String tableName = RandomStringUtils.randomAlphanumeric(10);
         entity.setAttribute(NAME, tableName);
@@ -688,10 +701,13 @@ public final class TestUtilsV2 {
         entity.setAttribute("parametersMap", new java.util.HashMap<String, String>() {{
             put("key1", "value1");
         }});
-        return entity;
+
+        ret.put(entity.getGuid(), entity);
+        return ret;
     }
 
     public static AtlasEntity createColumnEntity(String tableId) {
+
         AtlasEntity entity = new AtlasEntity(COLUMN_TYPE);
         entity.setAttribute(NAME, RandomStringUtils.randomAlphanumeric(10));
         entity.setAttribute("type", "VARCHAR(32)");

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
index c42f95f..ed0fabb 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
@@ -28,6 +28,7 @@ import org.apache.atlas.model.instance.EntityMutationResponse;
 import org.apache.atlas.type.AtlasTypeRegistry;
 
 import java.util.List;
+import java.util.Map;
 
 /**
  * Persistence/Retrieval API for AtlasEntity
@@ -37,23 +38,8 @@ public interface AtlasEntityStore {
     /**
      * Initialization
      */
-    void init(AtlasTypeRegistry typeRegistry, EntityGraphDiscovery graphDiscovery) throws AtlasBaseException;
+    void init(AtlasTypeRegistry typeRegistry) throws AtlasBaseException;
 
-    /**
-     * Create or update an entity if it already exists.
-     * @param entity
-     * @return
-     */
-    EntityMutationResponse createOrUpdate(AtlasEntity entity) throws AtlasBaseException;
-
-
-    /**
-     * Update entity identified by its guid
-     * @param guid
-     * @param entity
-     * @return
-     */
-    EntityMutationResponse updateById(String guid, AtlasEntity entity);
 
     /**
      *
@@ -70,25 +56,14 @@ public interface AtlasEntityStore {
      */
     EntityMutationResponse deleteById(String guid);
 
-
     /**
-     * Create or update a list of entities
-     * @param entities List of AtlasEntity objects that need to be created
+     * Create or update  entities
+     * @param entities Map of the entity Id(guid or transient Id) to AtlasEntity objects that need to be created
      * @return EntityMutationResponse Entity mutations operations with the correspomding set of entities on which these operations were performed
      * @throws AtlasBaseException
      */
 
-    EntityMutationResponse createOrUpdate(List<AtlasEntity> entities) throws AtlasBaseException;
-
-    /**
-     *
-     * Provides list of updated entity guids including any child entities
-     * @param guid
-     * @param entity
-     * @return
-     * @throws AtlasBaseException
-     */
-    EntityMutationResponse updateByIds(String guid, AtlasEntity entity) throws AtlasBaseException;
+    EntityMutationResponse createOrUpdate(Map<String, AtlasEntity> entities) throws AtlasBaseException;
 
     /**
      * Batch GET to retrieve entities by their ID
@@ -145,14 +120,6 @@ public interface AtlasEntityStore {
     EntityMutationResponse deleteByUniqueAttribute(String typeName, String attributeName, String attributeValue) throws AtlasBaseException;
 
     /**
-     * Compose any type of mutation op - EntityMutation.EntityOperation - CREATE_OR_UPDATE, PARTIAL_UPDATE, DELETE etc in a single transaction
-     * @param mutations
-     * @return
-     * @throws AtlasBaseException
-     */
-    EntityMutationResponse batchMutate(EntityMutations mutations) throws AtlasBaseException;
-
-    /**
      * Add classification(s)
      */
     void addClassifications(String guid, List<AtlasClassification> classification) throws AtlasBaseException;
@@ -168,13 +135,4 @@ public interface AtlasEntityStore {
      */
     void deleteClassifications(String guid, List<String> classificationNames) throws AtlasBaseException;
 
-    /**
-     *
-     * Search by AND filters like typename, pre-defined attribute(s) eg: name, qualifiedName
-     * @param searchFilter
-     * @return
-     * @throws AtlasBaseException
-     */
-    AtlasEntity.AtlasEntities searchEntities(SearchFilter searchFilter) throws AtlasBaseException;
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
index 2d748da..cd92a11 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/EntityGraphDiscoveryContext.java
@@ -17,106 +17,145 @@
  */
 package org.apache.atlas.repository.store.graph;
 
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.LinkedHashMap;
-import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
 public final class EntityGraphDiscoveryContext {
+    private static final Logger LOG = LoggerFactory.getLogger(EntityGraphDiscoveryContext.class);
 
-    /**
-     *  Keeps track of all the entities that need to be created/updated including its child entities *
-     */
-    private Set<AtlasEntity> rootEntities = new LinkedHashSet<>();
+    private final AtlasTypeRegistry         typeRegistry;
+    private List<AtlasEntity>               rootEntities               = new ArrayList<>();
+    private Map<AtlasObjectId, AtlasVertex> resolvedIds                = new LinkedHashMap<>();
+    private Set<AtlasObjectId>              unresolvedIds              = new HashSet<>();
+    private List<AtlasObjectId>             unresolvedIdsByUniqAttribs = new ArrayList<>();
 
-    //Key is a transient id/guid
-    /**
-     * These references have been resolved using a unique identifier like guid or a qualified name etc in Atlas repository
-     */
-    private Map<String, AtlasVertex> repositoryResolvedReferences = new LinkedHashMap<>();
-
-    /**
-     * Unresolved entity references
-     */
-    private List<AtlasEntity> unresolvedEntityReferences = new ArrayList<>();
+    public EntityGraphDiscoveryContext(AtlasTypeRegistry typeRegistry) {
+        this.typeRegistry = typeRegistry;
+    }
 
-    /**
-     * Unresolved entity id references
-     */
-    private Set<AtlasObjectId> unresolvedIdReferences = new HashSet<>();
 
-    public void addRepositoryResolvedReference(AtlasObjectId id, AtlasVertex vertex) {
-        repositoryResolvedReferences.put(id.getGuid(), vertex);
+    public Collection<AtlasEntity> getRootEntities() {
+        return rootEntities;
     }
 
-    public void addUnResolvedEntityReference(AtlasEntity entity) {
-        this.unresolvedEntityReferences.add(entity);
+    public Map<AtlasObjectId, AtlasVertex> getResolvedIds() {
+        return resolvedIds;
     }
 
-    public void addUnResolvedIdReference(AtlasEntityType entityType, String id) {
-        this.unresolvedIdReferences.add(new AtlasObjectId(entityType.getTypeName(), id));
+    public Set<AtlasObjectId> getUnresolvedIds() {
+        return unresolvedIds;
     }
 
-    public Set<AtlasObjectId> getUnresolvedIdReferences() {
-        return unresolvedIdReferences;
+    public List<AtlasObjectId> getUnresolvedIdsByUniqAttribs() {
+        return unresolvedIdsByUniqAttribs;
     }
 
-    public boolean isResolved(String guid) {
-        return repositoryResolvedReferences.containsKey(guid);
-    }
 
-    public AtlasVertex getResolvedReference(AtlasObjectId ref) {
-        return repositoryResolvedReferences.get(ref.getGuid());
+    public void addRootEntity(AtlasEntity rootEntity) {
+        this.rootEntities.add(rootEntity);
     }
 
-    public Map<String, AtlasVertex> getRepositoryResolvedReferences() {
-        return repositoryResolvedReferences;
-    }
 
-    public AtlasVertex getResolvedReference(String id) {
-        return repositoryResolvedReferences.get(id);
+    public void addResolvedId(AtlasObjectId objId, AtlasVertex vertex) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("addResolvedId({})", objId);
+        }
+
+        resolvedIds.put(objId, vertex);
     }
 
-    public List<AtlasEntity> getUnResolvedEntityReferences() {
-        return unresolvedEntityReferences;
+    public boolean removeUnResolvedId(AtlasObjectId objId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removeUnResolvedId({})", objId);
+        }
+
+        return unresolvedIds.remove(objId);
     }
 
-    public void addRootEntity(AtlasEntity rootEntity) {
-        this.rootEntities.add(rootEntity);
+
+    public void addUnResolvedId(AtlasObjectId objId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("addUnResolvedId({})", objId);
+        }
+
+        this.unresolvedIds.add(objId);
     }
 
-    public Collection<AtlasEntity> getRootEntities() {
-        return rootEntities;
+    public boolean removeUnResolvedIds(List<AtlasObjectId> objIds) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removeUnResolvedIds({})", objIds);
+        }
+
+        return unresolvedIds.removeAll(objIds);
     }
 
-    public boolean removeUnResolvedEntityReference(final AtlasEntity entity) {
-        return unresolvedEntityReferences.remove(entity);
+
+    public void addUnresolvedIdByUniqAttribs(AtlasObjectId objId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("addUnresolvedIdByUniqAttribs({})", objId);
+        }
+
+        this.unresolvedIdsByUniqAttribs.add(objId);
     }
 
-    public boolean removeUnResolvedEntityReferences(final List<AtlasEntity> entities) {
-        return unresolvedEntityReferences.removeAll(entities);
+    public boolean removeUnresolvedIdsByUniqAttribs(List<AtlasObjectId> objIds) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("removeUnresolvedIdsByUniqAttribs({})", objIds);
+        }
+
+        return unresolvedIdsByUniqAttribs.removeAll(objIds);
     }
 
-    public boolean removeUnResolvedIdReferences(final List<AtlasObjectId> entities) {
-        return unresolvedIdReferences.removeAll(entities);
+    public boolean hasUnresolvedReferences() {
+        return unresolvedIdsByUniqAttribs.size() > 0 || unresolvedIds.size() > 0;
     }
 
-    public boolean removeUnResolvedIdReference(final AtlasObjectId entity) {
-        return unresolvedIdReferences.remove(entity);
+    public boolean isResolvedId(AtlasObjectId id) {
+        return resolvedIds.containsKey(id);
     }
 
-    public boolean hasUnresolvedReferences() {
-        return unresolvedEntityReferences.size() > 0 || unresolvedIdReferences.size() > 0;
+    public AtlasVertex getResolvedEntityVertex(AtlasObjectId ref) throws AtlasBaseException {
+        AtlasVertex vertex = resolvedIds.get(ref);
+
+        // check also for sub-types; ref={typeName=Asset; guid=abcd} should match {typeName=hive_table; guid=abcd}
+        if (vertex == null) {
+            final AtlasEntityType entityType  = typeRegistry.getEntityTypeByName(ref.getTypeName());
+            final Set<String>     allSubTypes = entityType.getAllSubTypes();
+
+            for (String subType : allSubTypes) {
+                AtlasObjectId subTypeObjId = new AtlasObjectId(subType, ref.getGuid(), ref.getUniqueAttributes());
+
+                vertex = resolvedIds.get(subTypeObjId);
+
+                if (vertex != null) {
+                    resolvedIds.put(ref, vertex);
+                    break;
+                }
+            }
+        }
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS,
+                                         " : Could not find an entity with " + ref.toString());
+        }
+
+        return vertex;
     }
 
     @Override
@@ -130,15 +169,15 @@ public final class EntityGraphDiscoveryContext {
         } else {
             EntityGraphDiscoveryContext ctx = (EntityGraphDiscoveryContext) obj;
             return Objects.equals(rootEntities, ctx.getRootEntities()) &&
-                Objects.equals(repositoryResolvedReferences, ctx.getRepositoryResolvedReferences()) &&
-                Objects.equals(unresolvedEntityReferences, ctx.getUnResolvedEntityReferences()) &&
-                Objects.equals(unresolvedIdReferences, ctx.getUnresolvedIdReferences());
+                Objects.equals(resolvedIds, ctx.getResolvedIds()) &&
+                Objects.equals(unresolvedIdsByUniqAttribs, ctx.getUnresolvedIdsByUniqAttribs()) &&
+                Objects.equals(unresolvedIds, ctx.getUnresolvedIds());
         }
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(rootEntities, repositoryResolvedReferences, unresolvedEntityReferences, unresolvedIdReferences);
+        return Objects.hash(rootEntities, resolvedIds, unresolvedIdsByUniqAttribs, unresolvedIds);
     }
 
     public StringBuilder toString(StringBuilder sb) {
@@ -148,9 +187,9 @@ public final class EntityGraphDiscoveryContext {
 
         sb.append("EntityGraphDiscoveryCtx{");
         sb.append("rootEntities='").append(rootEntities).append('\'');
-        sb.append(", repositoryResolvedReferences=").append(repositoryResolvedReferences);
-        sb.append(", unresolvedEntityReferences='").append(unresolvedEntityReferences).append('\'');
-        sb.append(", unresolvedIdReferences='").append(unresolvedIdReferences).append('\'');
+        sb.append(", resolvedIds=").append(resolvedIds);
+        sb.append(", unresolvedIdsByUniqAttribs='").append(unresolvedIdsByUniqAttribs).append('\'');
+        sb.append(", unresolvedIds='").append(unresolvedIds).append('\'');
         sb.append('}');
 
         return sb;
@@ -163,8 +202,8 @@ public final class EntityGraphDiscoveryContext {
 
     public void cleanUp() {
         rootEntities.clear();
-        unresolvedEntityReferences.clear();
-        repositoryResolvedReferences.clear();
-        unresolvedIdReferences.clear();
+        unresolvedIdsByUniqAttribs.clear();
+        resolvedIds.clear();
+        unresolvedIds.clear();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
index 0e1d9e6..2b0804f 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityGraphDiscoveryV1.java
@@ -41,6 +41,7 @@ import org.apache.atlas.type.AtlasMapType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.commons.lang3.StringUtils;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.inject.Inject;
@@ -49,17 +50,15 @@ import com.google.inject.Provider;
 
 public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
 
-    private AtlasTypeRegistry typeRegistry;
-
-    private Set<String> processedIds = new HashSet<>();
-
-    private EntityGraphDiscoveryContext discoveredEntities = new EntityGraphDiscoveryContext();
-
-    private final Collection<EntityResolver> entityResolvers = new LinkedHashSet<>();
+    private final AtlasTypeRegistry           typeRegistry;
+    private final EntityGraphDiscoveryContext discoveredEntities;
+    private final Set<String>                 processedIds    = new HashSet<>();
+    private final Collection<EntityResolver>  entityResolvers = new LinkedHashSet<>();
 
     @Inject
-    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, final Collection<Provider<EntityResolver>> entityResolverProviders) {
-        this.typeRegistry = typeRegistry;
+    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, Collection<Provider<EntityResolver>> entityResolverProviders) {
+        this.typeRegistry       = typeRegistry;
+        this.discoveredEntities = new EntityGraphDiscoveryContext(typeRegistry);
 
         for (Provider<EntityResolver> entityResolverProvider : entityResolverProviders) {
              entityResolvers.add(entityResolverProvider.get());
@@ -67,8 +66,9 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
     }
 
     @VisibleForTesting
-    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, final List<EntityResolver> entityResolvers) {
-        this.typeRegistry = typeRegistry;
+    public AtlasEntityGraphDiscoveryV1(AtlasTypeRegistry typeRegistry, List<EntityResolver> entityResolvers) {
+        this.typeRegistry       = typeRegistry;
+        this.discoveredEntities = new EntityGraphDiscoveryContext(typeRegistry);
 
         for (EntityResolver entityResolver : entityResolvers) {
             this.entityResolvers.add(entityResolver);
@@ -96,22 +96,14 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
     public void cleanUp() throws AtlasBaseException {
         processedIds.clear();
         discoveredEntities.cleanUp();
-        final Collection<EntityResolver> entityResolvers = this.entityResolvers;
+
         for (EntityResolver resolver : entityResolvers) {
             resolver.cleanUp();
         }
     }
 
 
-    protected void resolveReferences() throws AtlasBaseException {
-        for (EntityResolver resolver : entityResolvers ) {
-            resolver.init(discoveredEntities);
-            resolver.resolveEntityReferences();
-        }
-    }
-
-
-    protected void discover(final List<AtlasEntity> entities) throws AtlasBaseException {
+    protected void discover(List<AtlasEntity> entities) throws AtlasBaseException {
         for (AtlasEntity entity : entities) {
             AtlasEntityType type = typeRegistry.getEntityTypeByName(entity.getTypeName());
 
@@ -120,27 +112,41 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
             }
 
             discoveredEntities.addRootEntity(entity);
+
             walkEntityGraph(type, entity);
         }
     }
 
-    private void visitReference(AtlasEntityType type, Object entity, boolean isManagedEntity) throws AtlasBaseException {
+    protected void resolveReferences() throws AtlasBaseException {
+        for (EntityResolver resolver : entityResolvers) {
+            resolver.init(discoveredEntities);
+
+            resolver.resolveEntityReferences();
+        }
+
+        if (discoveredEntities.hasUnresolvedReferences()) {
+            throw new AtlasBaseException(AtlasErrorCode.UNRESOLVED_REFERENCES_FOUND,
+                                                         discoveredEntities.getUnresolvedIds().toString(),
+                                                         discoveredEntities.getUnresolvedIdsByUniqAttribs().toString());
+        }
+    }
+
+    private void visitReference(AtlasEntityType type, Object entity) throws AtlasBaseException {
         if (entity != null) {
             if (entity instanceof AtlasObjectId) {
-                final String guid = ((AtlasObjectId) entity).getGuid();
-                discoveredEntities.addUnResolvedIdReference(type, guid);
-            } else if (entity instanceof AtlasEntity) {
-                AtlasEntity entityObj = (AtlasEntity) entity;
-                if (isManagedEntity) {
-                    if (!processedIds.contains(entityObj.getGuid())) {
-                        processedIds.add(entityObj.getGuid());
-
-                        discoveredEntities.addRootEntity(entityObj);
-                        visitStruct(type, entityObj);
-                    }
+                AtlasObjectId objId = (AtlasObjectId)entity;
+
+                if (!objId.isValid()) {
+                    throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Invalid object id " + objId);
+                }
+
+                if (!StringUtils.isEmpty(objId.getGuid()) && (objId.isAssignedGuid() || objId.isUnAssignedGuid())) {
+                    discoveredEntities.addUnResolvedId(objId);
                 } else {
-                    discoveredEntities.addUnResolvedEntityReference(entityObj);
+                    discoveredEntities.addUnresolvedIdByUniqAttribs(objId);
                 }
+            } else if (entity instanceof AtlasEntity) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Use AtlasObjectId to refer to another instance instead of AtlasEntity " + type.getTypeName());
             } else {
                 throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Invalid object type " + entity.getClass());
             }
@@ -154,26 +160,18 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
             }
             if (attrType.getTypeCategory() == TypeCategory.ARRAY) {
                 AtlasArrayType arrayType = (AtlasArrayType) attrType;
-                AtlasType elemType = arrayType.getElementType();
+                AtlasType      elemType  = arrayType.getElementType();
+
                 visitCollectionReferences(parentType, attrType, attrDef, elemType, val);
             } else if (attrType.getTypeCategory() == TypeCategory.MAP) {
-                AtlasType keyType = ((AtlasMapType) attrType).getKeyType();
+                AtlasType keyType   = ((AtlasMapType) attrType).getKeyType();
                 AtlasType valueType = ((AtlasMapType) attrType).getValueType();
+
                 visitMapReferences(parentType, attrType, attrDef, keyType, valueType, val);
             } else if (attrType.getTypeCategory() == TypeCategory.STRUCT) {
-                visitStruct(attrType, val);
+                visitStruct((AtlasStructType)attrType, val);
             } else if (attrType.getTypeCategory() == TypeCategory.ENTITY) {
-                if ( val instanceof AtlasObjectId) {
-                    visitReference((AtlasEntityType) attrType,  val, false);
-                } else if ( val instanceof AtlasEntity ) {
-                    //TODO - Change this to foreign key checks after changes in the model
-                   if ((parentType instanceof AtlasEntityType) &&
-                       ((AtlasEntityType)parentType).isMappedFromRefAttribute(attrDef.getName())) {
-                       visitReference((AtlasEntityType) attrType,  val, true);
-                   } else {
-                       visitReference((AtlasEntityType) attrType,  val, false);
-                   }
-                }
+                visitReference((AtlasEntityType) attrType,  val);
             }
         }
     }
@@ -184,7 +182,6 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
         }
 
         if (val != null) {
-
             if (Map.class.isAssignableFrom(val.getClass())) {
                 Iterator<Map.Entry> it = ((Map) val).entrySet().iterator();
                 while (it.hasNext()) {
@@ -197,7 +194,6 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
     }
 
     void visitCollectionReferences(final AtlasStructType parentType, final AtlasType attrType, final AtlasAttributeDef attrDef, AtlasType elemType, Object val) throws AtlasBaseException {
-
         if (isPrimitive(elemType.getTypeCategory())) {
             return;
         }
@@ -220,24 +216,22 @@ public class AtlasEntityGraphDiscoveryV1 implements EntityGraphDiscovery {
         }
     }
 
-    void visitStruct(AtlasType type, Object val) throws AtlasBaseException {
-
-        if (val == null || !(val instanceof AtlasStruct)) {
+    void visitStruct(AtlasStructType structType, Object val) throws AtlasBaseException {
+        if (structType == null) {
             return;
         }
 
-        AtlasStructType structType = (AtlasStructType) type;
-
         for (AtlasStructType.AtlasAttribute attribute : structType.getAllAttributes().values()) {
             AtlasType attrType = attribute.getAttributeType();
-            Object attrVal = ((AtlasStruct) val).getAttribute(attribute.getName());
+            Object    attrVal  = ((AtlasStruct) val).getAttribute(attribute.getName());
+
             visitAttribute(structType, attrType, attribute.getAttributeDef(), attrVal);
         }
     }
 
 
-    void walkEntityGraph(AtlasType type, AtlasEntity entity) throws AtlasBaseException {
-        visitStruct(type, entity);
+    void walkEntityGraph(AtlasEntityType entityType, AtlasEntity entity) throws AtlasBaseException {
+        visitStruct(entityType, entity);
     }
 
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
index 4c79cef..9e08282 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1.java
@@ -25,31 +25,29 @@ import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.GraphTransaction;
 import org.apache.atlas.RequestContextV1;
 import org.apache.atlas.exception.AtlasBaseException;
-import org.apache.atlas.model.SearchFilter;
 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.AtlasEntityWithAssociations;
 import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.model.instance.EntityMutationResponse;
-import org.apache.atlas.model.instance.EntityMutations;
 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.EntityResolver;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.inject.Inject;
+import java.util.Map;
 
+import com.google.inject.Inject;
 
 
 public class AtlasEntityStoreV1 implements AtlasEntityStore {
 
-    protected EntityGraphDiscovery graphDiscoverer;
     protected AtlasTypeRegistry typeRegistry;
 
     private EntityGraphMapper graphMapper;
@@ -62,22 +60,11 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     @Inject
-    public void init(AtlasTypeRegistry typeRegistry, EntityGraphDiscovery graphDiscoverer) throws AtlasBaseException {
-        this.graphDiscoverer = graphDiscoverer;
+    public void init(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
         this.typeRegistry = typeRegistry;
     }
 
     @Override
-    public EntityMutationResponse createOrUpdate(final AtlasEntity entity) throws AtlasBaseException {
-        return createOrUpdate(new ArrayList<AtlasEntity>() {{ add(entity); }});
-    }
-
-    @Override
-    public EntityMutationResponse updateById(final String guid, final AtlasEntity entity) {
-        return null;
-    }
-
-    @Override
     public AtlasEntity getById(final String guid) {
         return null;
     }
@@ -89,7 +76,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
 
     @Override
     @GraphTransaction
-    public EntityMutationResponse createOrUpdate(final List<AtlasEntity> entities) throws AtlasBaseException {
+    public EntityMutationResponse createOrUpdate(final Map<String, AtlasEntity> entities) throws AtlasBaseException {
 
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> AtlasEntityStoreV1.createOrUpdate({}, {})", entities);
@@ -109,11 +96,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     @Override
-    public EntityMutationResponse updateByIds(final String guid, final AtlasEntity entity) throws AtlasBaseException {
-        return null;
-    }
-
-    @Override
     public AtlasEntity.AtlasEntities getByIds(final List<String> guid) throws AtlasBaseException {
         return null;
     }
@@ -144,12 +126,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     @Override
-    public EntityMutationResponse batchMutate(final EntityMutations mutations) throws AtlasBaseException {
-        return null;
-    }
-
-
-    @Override
     public void addClassifications(final String guid, final List<AtlasClassification> classification) throws AtlasBaseException {
 
     }
@@ -164,42 +140,49 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
 
     }
 
-    @Override
-    public AtlasEntity.AtlasEntities searchEntities(final SearchFilter searchFilter) throws AtlasBaseException {
-        // TODO: Add checks here to ensure that typename and supertype are mandatory in the request
-        return null;
-    }
-
     private EntityMutationContext preCreateOrUpdate(final List<AtlasEntity> atlasEntities) throws AtlasBaseException {
+        List<EntityResolver> entityResolvers = new ArrayList<>();
+
+        entityResolvers.add(new IDBasedEntityResolver());
+        entityResolvers.add(new UniqAttrBasedEntityResolver(typeRegistry));
 
+        EntityGraphDiscovery        graphDiscoverer    = new AtlasEntityGraphDiscoveryV1(typeRegistry, entityResolvers);
         EntityGraphDiscoveryContext discoveredEntities = graphDiscoverer.discoverEntities(atlasEntities);
-        EntityMutationContext context = new EntityMutationContext(discoveredEntities);
-        for (AtlasEntity entity : discoveredEntities.getRootEntities()) {
+        EntityMutationContext       context            = new EntityMutationContext(discoveredEntities);
 
-            AtlasVertex vertex = null;
+        for (AtlasEntity entity : discoveredEntities.getRootEntities()) {
             if (LOG.isDebugEnabled()) {
-                LOG.debug("<== AtlasEntityStoreV1.preCreateOrUpdate({}): {}", entity);
+                LOG.debug("==> AtlasEntityStoreV1.preCreateOrUpdate({}): {}", entity);
             }
 
             AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entity.getTypeName());
 
-            if ( entityType == null) {
+            if (entityType == null) {
                 throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), entity.getTypeName());
             }
 
-            if ( discoveredEntities.isResolved(entity.getGuid()) ) {
-                vertex = discoveredEntities.getResolvedReference(entity.getGuid());
+            final AtlasVertex vertex;
+            AtlasObjectId     objId = entity.getAtlasObjectId();
+
+            if (discoveredEntities.isResolvedId(objId) ) {
+                vertex = discoveredEntities.getResolvedEntityVertex(objId);
+
                 context.addUpdated(entity, entityType, vertex);
 
                 String guid = AtlasGraphUtilsV1.getIdFromVertex(vertex);
+
                 RequestContextV1.get().recordEntityUpdate(new AtlasObjectId(entityType.getTypeName(), guid));
             } else {
                 //Create vertices which do not exist in the repository
                 vertex = graphMapper.createVertexTemplate(entity, entityType);
+
                 context.addCreated(entity, entityType, vertex);
-                discoveredEntities.addRepositoryResolvedReference(new AtlasObjectId(entityType.getTypeName(), entity.getGuid()), vertex);
+
+                discoveredEntities.addResolvedId(objId, vertex);
+                discoveredEntities.removeUnResolvedId(objId);
 
                 String guid = AtlasGraphUtilsV1.getIdFromVertex(vertex);
+
                 RequestContextV1.get().recordEntityCreate(new AtlasObjectId(entityType.getTypeName(), guid));
             }
 
@@ -211,12 +194,21 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
         return context;
     }
 
-    private List<AtlasEntity> validateAndNormalize(final List<AtlasEntity> entities) throws AtlasBaseException {
-
+    private List<AtlasEntity> validateAndNormalize(final Map<String, AtlasEntity> entities) throws AtlasBaseException {
         List<AtlasEntity> normalizedEntities = new ArrayList<>();
-        List<String> messages = new ArrayList<>();
+        List<String>      messages           = new ArrayList<>();
+
+        for (String entityId : entities.keySet()) {
+            if ( !AtlasEntity.isAssigned(entityId) && !AtlasEntity.isUnAssigned(entityId)) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, ": Guid in map key is invalid " + entityId);
+            }
+
+            AtlasEntity entity = entities.get(entityId);
+
+            if ( entity == null) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, ": Entity is null for guid " + entityId);
+            }
 
-        for (AtlasEntity entity : entities) {
             AtlasEntityType type = typeRegistry.getEntityTypeByName(entity.getTypeName());
             if (type == null) {
                 throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, TypeCategory.ENTITY.name(), entity.getTypeName());
@@ -227,11 +219,9 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
             if ( !messages.isEmpty()) {
                 throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, messages);
             }
+
             AtlasEntity normalizedEntity = (AtlasEntity) type.getNormalizedValue(entity);
-            if ( normalizedEntity == null) {
-                //TODO - Fix this. Should not come here. Should ideally fail above
-                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, "Failed to validate entity");
-            }
+
             normalizedEntities.add(normalizedEntity);
         }
 
@@ -239,6 +229,5 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore {
     }
 
     public void cleanUp() throws AtlasBaseException {
-        this.graphDiscoverer.cleanUp();
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
index a989f76..f507ae0 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/DeleteHandlerV1.java
@@ -25,6 +25,7 @@ import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.graph.AtlasEdgeLabel;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
index e534d4f..a0096c1 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
@@ -88,8 +88,8 @@ public class EntityGraphMapper implements InstanceGraphMapper<AtlasEdge> {
     public AtlasEdge toGraph(GraphMutationContext ctx) throws AtlasBaseException {
         AtlasEdge result = null;
 
-        String guid = getId(ctx.getValue());
-        AtlasVertex entityVertex = context.getDiscoveryContext().getResolvedReference(guid);
+        AtlasObjectId guid = getId(ctx.getValue());
+        AtlasVertex entityVertex = context.getDiscoveryContext().getResolvedEntityVertex(guid);
         if ( ctx.getCurrentEdge().isPresent() ) {
             result = updateEdge(ctx.getAttributeDef(), ctx.getValue(), ctx.getCurrentEdge().get(), entityVertex);
         } else if (ctx.getValue() != null) {
@@ -166,12 +166,18 @@ public class EntityGraphMapper implements InstanceGraphMapper<AtlasEdge> {
     }
 
 
-    public String getId(Object value) throws AtlasBaseException {
-        if ( value != null) {
+    public AtlasObjectId getId(Object value) throws AtlasBaseException {
+        if (value != null) {
             if ( value instanceof  AtlasObjectId) {
-                return ((AtlasObjectId) value).getGuid();
+                return ((AtlasObjectId) value);
             } else if (value instanceof AtlasEntity) {
-                return ((AtlasEntity) value).getGuid();
+                return ((AtlasEntity) value).getAtlasObjectId();
+            } else if (value instanceof Map) {
+                AtlasObjectId ret = new AtlasObjectId((Map)value);
+
+                if (ret.isValid()) {
+                    return ret;
+                }
             }
 
             throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, (String) value);
@@ -211,7 +217,7 @@ public class EntityGraphMapper implements InstanceGraphMapper<AtlasEdge> {
     }
 
     public AtlasEntityType getInstanceType(Object val) throws AtlasBaseException {
-        String guid = getId(val);
+        AtlasObjectId guid = getId(val);
 
         if ( guid != null) {
             return (AtlasEntityType) getContext().getType(guid);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
index f6e5055..310b455 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityMutationContext.java
@@ -19,40 +19,41 @@ package org.apache.atlas.repository.store.graph.v1;
 
 import org.apache.atlas.model.instance.AtlasEntity;
 
+import org.apache.atlas.model.instance.AtlasObjectId;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.EntityGraphDiscoveryContext;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasType;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 public class EntityMutationContext {
-
-    private List<AtlasEntity> entitiesCreated  = new ArrayList<>();
-    private List<AtlasEntity> entitiesUpdated  = new ArrayList<>();
-
-    private EntityGraphDiscoveryContext context;
-    private Map<String, AtlasEntityType> entityVsType = new HashMap<>();
-    private Map<String, AtlasVertex> entityVsVertex = new HashMap<>();
+    private final EntityGraphDiscoveryContext         context;
+    private final List<AtlasEntity>                   entitiesCreated = new ArrayList<>();
+    private final List<AtlasEntity>                   entitiesUpdated = new ArrayList<>();
+    private final Map<AtlasObjectId, AtlasEntityType> entityVsType    = new HashMap<>();
+    private final Map<AtlasObjectId, AtlasVertex>     entityVsVertex  = new HashMap<>();
 
     public EntityMutationContext(final EntityGraphDiscoveryContext context) {
         this.context = context;
     }
 
     public void addCreated(AtlasEntity entity, AtlasEntityType type, AtlasVertex atlasVertex) {
+        AtlasObjectId objId = entity.getAtlasObjectId();
         entitiesCreated.add(entity);
-        entityVsVertex.put(entity.getGuid(), atlasVertex);
-        entityVsType.put(entity.getGuid(), type);
+        entityVsType.put(objId, type);
+        entityVsVertex.put(objId, atlasVertex);
     }
 
     public void addUpdated(AtlasEntity entity, AtlasEntityType type, AtlasVertex atlasVertex) {
+        AtlasObjectId objId = entity.getAtlasObjectId();
         entitiesUpdated.add(entity);
-        entityVsVertex.put(entity.getGuid(), atlasVertex);
-        entityVsType.put(entity.getGuid(), type);
+        entityVsType.put(objId, type);
+        entityVsVertex.put(objId, atlasVertex);
+    }
+
+    public EntityGraphDiscoveryContext getDiscoveryContext() {
+        return this.context;
     }
 
     public Collection<AtlasEntity> getCreatedEntities() {
@@ -64,26 +65,21 @@ public class EntityMutationContext {
     }
 
     public AtlasEntityType getType(AtlasEntity entity) {
-        return entityVsType.get(entity.getGuid());
+        return entityVsType.get(entity.getAtlasObjectId());
     }
 
-    public AtlasType getType(String entityId) {
+    public AtlasType getType(AtlasObjectId entityId) {
         return entityVsType.get(entityId);
     }
 
     public AtlasVertex getVertex(AtlasEntity entity) {
-        return entityVsVertex.get(entity.getGuid());
+        return entityVsVertex.get(entity.getAtlasObjectId());
     }
 
-    public AtlasVertex getVertex(String entityId) {
+    public AtlasVertex getVertex(AtlasObjectId entityId) {
         return entityVsVertex.get(entityId);
     }
 
-    public EntityGraphDiscoveryContext getDiscoveryContext() {
-        return this.context;
-    }
-
-    //TODO - equals/hashCode/toString
 
     @Override
     public boolean equals(final Object o) {
@@ -92,32 +88,29 @@ public class EntityMutationContext {
 
         final EntityMutationContext that = (EntityMutationContext) o;
 
-        if (entitiesCreated != null ? !entitiesCreated.equals(that.entitiesCreated) : that.entitiesCreated != null)
-            return false;
-        if (entitiesUpdated != null ? !entitiesUpdated.equals(that.entitiesUpdated) : that.entitiesUpdated != null)
-            return false;
-        if (context != null ? !context.equals(that.context) : that.context != null) return false;
-        if (entityVsType != null ? !entityVsType.equals(that.entityVsType) : that.entityVsType != null) return false;
-        return !(entityVsVertex != null ? !entityVsVertex.equals(that.entityVsVertex) : that.entityVsVertex != null);
-
+        return Objects.equals(context, that.context) &&
+               Objects.equals(entitiesCreated, that.entitiesCreated) &&
+               Objects.equals(entitiesUpdated, that.entitiesUpdated) &&
+               Objects.equals(entityVsType, that.entityVsType) &&
+               Objects.equals(entityVsVertex, that.entityVsVertex);
     }
 
     @Override
     public int hashCode() {
-        int result = entitiesCreated != null ? entitiesCreated.hashCode() : 0;
-        result = 31 * result + (entitiesUpdated != null ? entitiesUpdated.hashCode() : 0);
-        result = 31 * result + (context != null ? context.hashCode() : 0);
-        result = 31 * result + (entityVsType != null ? entityVsType.hashCode() : 0);
-        result = 31 * result + (entityVsVertex != null ? entityVsVertex.hashCode() : 0);
+        int result = (context != null ? context.hashCode() : 0);
+        result = 31 * result + entitiesCreated.hashCode();
+        result = 31 * result + entitiesUpdated.hashCode();
+        result = 31 * result + entityVsType.hashCode();
+        result = 31 * result + entityVsVertex.hashCode();
         return result;
     }
 
     @Override
     public String toString() {
         return "EntityMutationContext{" +
-            "entitiesCreated=" + entitiesCreated +
+            "context=" + context +
+            ", entitiesCreated=" + entitiesCreated +
             ", entitiesUpdated=" + entitiesUpdated +
-            ", context=" + context +
             ", entityVsType=" + entityVsType +
             ", entityVsVertex=" + entityVsVertex +
             '}';

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java
new file mode 100644
index 0000000..1d939fe
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityStream.java
@@ -0,0 +1,32 @@
+/**
+ * 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.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+
+public interface EntityStream {
+
+    boolean hasNext();
+
+    AtlasEntity next();
+
+    void reset();
+
+    AtlasEntity getById(AtlasObjectId id);
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
index d02b5a1..2ffd10e 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/IDBasedEntityResolver.java
@@ -37,67 +37,70 @@ import java.util.Map;
 
 public class IDBasedEntityResolver implements EntityResolver {
 
-    private Map<String, AtlasEntity> idToEntityMap = new HashMap<>();
-
-    private final GraphHelper graphHelper = GraphHelper.getInstance();
-
-    private EntityGraphDiscoveryContext context;
+    private final GraphHelper              graphHelper   = GraphHelper.getInstance();
+    private final Map<String, AtlasEntity> idToEntityMap = new HashMap<>();
+    private EntityGraphDiscoveryContext    context;
 
     @Override
     public void init(EntityGraphDiscoveryContext context) throws AtlasBaseException {
         this.context = context;
+
         for (AtlasEntity entity : context.getRootEntities()) {
             idToEntityMap.put(entity.getGuid(), entity);
         }
     }
 
     public EntityGraphDiscoveryContext resolveEntityReferences() throws AtlasBaseException {
-
-        if ( context == null) {
+        if (context == null) {
             throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, "Entity resolver not initialized");
         }
 
         List<AtlasObjectId> resolvedReferences = new ArrayList<>();
 
-        for (AtlasObjectId typeIdPair : context.getUnresolvedIdReferences()) {
-            if ( AtlasEntity.isAssigned(typeIdPair.getGuid())) {
+        for (AtlasObjectId objId : context.getUnresolvedIds()) {
+            if (objId.isAssignedGuid()) {
                 //validate in graph repo that given guid, typename exists
-                Optional<AtlasVertex> vertex = resolveGuid(typeIdPair);
+                Optional<AtlasVertex> vertex = resolveGuid(objId);
 
-                if ( vertex.isPresent() ) {
-                    context.addRepositoryResolvedReference(typeIdPair, vertex.get());
-                    resolvedReferences.add(typeIdPair);
+                if (vertex.isPresent()) {
+                    context.addResolvedId(objId, vertex.get());
+                    resolvedReferences.add(objId);
                 }
             } else {
                 //check if root references have this temporary id
-               if (!idToEntityMap.containsKey(typeIdPair.getGuid()) ) {
-                   throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, "Could not find an entity with the specified id " + typeIdPair + " in the request");
+               if (!idToEntityMap.containsKey(objId.getGuid()) ) {
+                   throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, objId.toString());
                }
+                resolvedReferences.add(objId);
             }
+
         }
 
-        context.removeUnResolvedIdReferences(resolvedReferences);
+        context.removeUnResolvedIds(resolvedReferences);
 
         //Resolve root references
         for (AtlasEntity entity : context.getRootEntities()) {
-            if ( !context.isResolved(entity.getGuid()) && AtlasEntity.isAssigned(entity.getGuid())) {
-                AtlasObjectId typeIdPair = new AtlasObjectId(entity.getTypeName(), entity.getGuid());
-                Optional<AtlasVertex> vertex = resolveGuid(typeIdPair);
+            AtlasObjectId objId = entity.getAtlasObjectId();
+
+            if (!context.isResolvedId(objId) && AtlasEntity.isAssigned(entity.getGuid())) {
+                Optional<AtlasVertex> vertex = resolveGuid(objId);
+
                 if (vertex.isPresent()) {
-                    context.addRepositoryResolvedReference(typeIdPair, vertex.get());
-                    context.removeUnResolvedIdReference(typeIdPair);
+                    context.addResolvedId(objId, vertex.get());
+                    context.removeUnResolvedId(objId);
                 }
             }
         }
+
         return context;
     }
 
-    private Optional<AtlasVertex> resolveGuid(AtlasObjectId typeIdPair) throws AtlasBaseException {
+    private Optional<AtlasVertex> resolveGuid(AtlasObjectId objId) throws AtlasBaseException {
         //validate in graph repo that given guid, typename exists
         AtlasVertex vertex = null;
         try {
-            vertex = graphHelper.findVertex(Constants.GUID_PROPERTY_KEY, typeIdPair.getGuid(),
-                Constants.TYPE_NAME_PROPERTY_KEY, typeIdPair.getTypeName(),
+            vertex = graphHelper.findVertex(Constants.GUID_PROPERTY_KEY, objId.getGuid(),
+                Constants.TYPE_NAME_PROPERTY_KEY, objId.getTypeName(),
                 Constants.STATE_PROPERTY_KEY, Id.EntityState.ACTIVE.name());
         } catch (EntityNotFoundException e) {
             //Ignore
@@ -105,7 +108,7 @@ public class IDBasedEntityResolver implements EntityResolver {
         if ( vertex != null ) {
             return Optional.of(vertex);
         } else {
-            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, typeIdPair.getGuid());
+            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, objId.getGuid());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d8c2a10e/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java
new file mode 100644
index 0000000..0d0b949
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/InMemoryMapEntityStream.java
@@ -0,0 +1,60 @@
+/**
+ * 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.model.instance.AtlasEntity;
+import org.apache.atlas.model.instance.AtlasObjectId;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class InMemoryMapEntityStream implements EntityStream {
+
+    private final Map<AtlasObjectId, AtlasEntity>                 entities = new HashMap<>();
+    private       Iterator<Map.Entry<AtlasObjectId, AtlasEntity>> iterator;
+
+    public InMemoryMapEntityStream(Map<String, AtlasEntity> entityMap) {
+        for (AtlasEntity entity : entityMap.values()) {
+            entities.put(entity.getAtlasObjectId(), entity);
+        }
+
+        this.iterator = entities.entrySet().iterator();
+    }
+
+    @Override
+    public boolean hasNext() {
+        return iterator.hasNext();
+    }
+
+    @Override
+    public AtlasEntity next() {
+        return iterator.hasNext() ? iterator.next().getValue() : null;
+    }
+
+    @Override
+    public void reset() {
+        iterator = entities.entrySet().iterator();
+    }
+
+    @Override
+    public AtlasEntity getById(final AtlasObjectId id) {
+        return entities.get(id);
+    }
+}