ATLAS-1522: V2 entity API changes to accept only AtlasObjectId for child references
Signed-off-by: Madhan Neethiraj <[email protected]> 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 <[email protected]> Authored: Fri Feb 3 04:15:41 2017 -0800 Committer: Madhan Neethiraj <[email protected]> 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); + } +}
