ATLAS-1523: v2 implementation of get-entity by-guid/unique-attributes 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/808eb1d1 Tree: http://git-wip-us.apache.org/repos/asf/incubator-atlas/tree/808eb1d1 Diff: http://git-wip-us.apache.org/repos/asf/incubator-atlas/diff/808eb1d1 Branch: refs/heads/master Commit: 808eb1d1c314ae0445f05afa90ca90490e2723e8 Parents: 48477e2 Author: Sarath Subramanian <[email protected]> Authored: Tue Feb 7 15:25:38 2017 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Tue Feb 7 19:36:38 2017 -0800 ---------------------------------------------------------------------- .../org/apache/atlas/AtlasEntitiesClientV2.java | 43 +- .../java/org/apache/atlas/AtlasErrorCode.java | 3 +- .../model/discovery/AtlasSearchResult.java | 36 +- .../atlas/model/instance/AtlasEntity.java | 355 +++++++++++++++- .../atlas/model/instance/AtlasEntityHeader.java | 28 +- .../AtlasEntityHeaderWithAssociations.java | 143 ------- .../instance/AtlasEntityWithAssociations.java | 147 ------- .../atlas/discovery/EntityDiscoveryService.java | 12 +- .../atlas/repository/graph/GraphHelper.java | 73 +++- .../store/graph/AtlasEntityStore.java | 31 +- .../store/graph/v1/AtlasEntityStoreV1.java | 80 +++- .../store/graph/v1/AtlasGraphUtilsV1.java | 6 - .../store/graph/v1/GraphEntityMapper.java | 400 +++++++++++++++++++ .../store/graph/v1/AtlasEntityStoreV1Test.java | 4 +- .../apache/atlas/services/MetadataService.java | 3 +- .../org/apache/atlas/examples/QuickStartV2.java | 57 +-- .../adapters/AtlasEntityFormatConverter.java | 6 +- .../web/adapters/AtlasFormatConverter.java | 17 +- .../web/adapters/AtlasInstanceRestAdapters.java | 6 +- .../org/apache/atlas/web/rest/EntitiesREST.java | 13 +- .../org/apache/atlas/web/rest/EntityREST.java | 159 +++++--- .../apache/atlas/examples/QuickStartV2IT.java | 22 +- .../atlas/web/adapters/TestEntityREST.java | 13 +- .../atlas/web/resources/BaseResourceIT.java | 6 +- .../EntityDiscoveryJerseyResourceIT.java | 10 +- .../web/resources/EntityV2JerseyResourceIT.java | 31 +- 26 files changed, 1158 insertions(+), 546 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/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 2d6e708..be3088f 100644 --- a/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java +++ b/client/src/main/java/org/apache/atlas/AtlasEntitiesClientV2.java @@ -30,8 +30,9 @@ import org.apache.atlas.model.instance.AtlasClassification; import org.apache.atlas.model.instance.AtlasClassification.AtlasClassifications; import org.apache.atlas.model.instance.AtlasEntity; import org.apache.atlas.model.instance.AtlasEntity.AtlasEntities; -import org.apache.atlas.model.instance.AtlasEntityWithAssociations; +import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo; import org.apache.atlas.model.instance.EntityMutationResponse; +import org.apache.commons.collections.MapUtils; import org.apache.commons.configuration.Configuration; import org.apache.hadoop.security.UserGroupInformation; @@ -42,15 +43,14 @@ import com.sun.jersey.core.util.MultivaluedMapImpl; public class AtlasEntitiesClientV2 extends AtlasBaseClient { - private static final GenericType<List<AtlasEntityWithAssociations>> ENTITY_WITH_ASSOCIATIONS_LIST_TYPE = new GenericType<List<AtlasEntityWithAssociations>>(){}; + private static final GenericType<List<AtlasEntity>> ENTITY_LIST_TYPE = new GenericType<List<AtlasEntity>>(){}; public static final String ENTITY_API = BASE_URI + "v2/entity/"; public static final String ENTITIES_API = BASE_URI + "v2/entities/"; 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(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 GET_ENTITY_BY_ATTRIBUTE = new APIInfo(ENTITY_API + "uniqueAttribute/type/%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 DELETE_ENTITY_BY_GUID = new APIInfo(ENTITY_API + "guid/", HttpMethod.DELETE, Response.Status.OK); @@ -87,25 +87,21 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient { super(service, configuration); } - public List<AtlasEntityWithAssociations> getEntityByGuid(String guid) throws AtlasServiceException { + public AtlasEntityWithExtInfo getEntityByGuid(String guid) throws AtlasServiceException { - return callAPI(GET_ENTITY_BY_GUID, null, ENTITY_WITH_ASSOCIATIONS_LIST_TYPE, guid); + return callAPI(GET_ENTITY_BY_GUID, null, AtlasEntityWithExtInfo.class, guid); } public AtlasEntities getEntityByGuids(List<String> guids) throws AtlasServiceException { return callAPI(GET_ENTITY_BY_GUID, AtlasEntities.class, "guid", guids); } - public List<AtlasEntityWithAssociations> getEntityWithAssociationByGuid(String guid) throws AtlasServiceException { + public static final String PREFIX_ATTR = "attr:"; - return callAPI(formatPathForPathParams(GET_ENTITY_WITH_ASSOCIATION_BY_GUID, guid), null, ENTITY_WITH_ASSOCIATIONS_LIST_TYPE); - } - - public List<AtlasEntityWithAssociations> getEntityByAttribute(String type, String attribute, String value) throws AtlasServiceException { + public AtlasEntityWithExtInfo getEntityByAttribute(String type, Map<String, String> attributes) throws AtlasServiceException { + MultivaluedMap<String, String> queryParams = attributesToQueryParams(attributes); - MultivaluedMap<String, String> queryParams = new MultivaluedMapImpl(); - queryParams.add("value", value); - return callAPI(formatPathForPathParams(GET_ENTITY_BY_ATTRIBUTE, type, attribute), ENTITY_WITH_ASSOCIATIONS_LIST_TYPE, queryParams); + return callAPI(formatPathForPathParams(GET_ENTITY_BY_ATTRIBUTE, type), AtlasEntityWithExtInfo.class, queryParams); } public EntityMutationResponse updateEntityByAttribute(String type, String attribute, String value, AtlasEntity entity) throws AtlasServiceException { @@ -182,4 +178,23 @@ public class AtlasEntitiesClientV2 extends AtlasBaseClient { public AtlasEntity.AtlasEntities searchEntities(SearchFilter searchFilter) throws AtlasServiceException { return callAPI(GET_ENTITIES, AtlasEntity.AtlasEntities.class, searchFilter.getParams()); } + + private MultivaluedMap<String, String> attributesToQueryParams(Map<String, String> attributes) { + return attributesToQueryParams(attributes, null); + } + + private MultivaluedMap<String, String> attributesToQueryParams(Map<String, String> attributes, + MultivaluedMap<String, String> queryParams) { + if (queryParams == null) { + queryParams = new MultivaluedMapImpl(); + } + + if (MapUtils.isNotEmpty(attributes)) { + for (Map.Entry<String, String> e : attributes.entrySet()) { + queryParams.putSingle(PREFIX_ATTR + e.getKey(), e.getValue()); + } + } + + return queryParams; + } } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/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 f9895cf..7b11b70 100644 --- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java +++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java @@ -59,6 +59,7 @@ public enum AtlasErrorCode { CONSTRAINT_INVERSE_REF_INVERSE_ATTRIBUTE_NON_EXISTING(400, "ATLAS40028E", "{0}.{1}: invalid {2} constraint. Inverse attribute {3}.{4} does not exist"), CONSTRAINT_INVERSE_REF_INVERSE_ATTRIBUTE_INVALID_TYPE(400, "ATLAS40029E", "{0}.{1}: invalid {2} constraint. Inverse attribute {3}.{4} is not an entity type"), CONSTRAINT_OWNED_REF_ATTRIBUTE_INVALID_TYPE(400, "ATLAS40030E", "{0}.{1}: invalid {2} constraint. Attribute {3} is not an entity type"), + CANNOT_MAP_ATTRIBUTE(400, "ATLAS40027E", "cannot map attribute: {0} of type: {1} from vertex"), // All Not found enums go here TYPE_NAME_NOT_FOUND(404, "ATLAS4041E", "Given typename {0} was invalid"), @@ -82,7 +83,7 @@ public enum AtlasErrorCode { INDEX_ROLLBACK_FAILED(500, "ATLAS5003E", "Index rollback failed for {0}"), FAILED_TO_OBTAIN_TYPE_UPDATE_LOCK(500, "ATLAS5004E", "Failed to get the lock; another type update might be in progress. Please try again"), - INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND(400, "ATLAS40018E", "Instance {0} with unique attribute {1} does not exist"), + INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND(400, "ATLAS40018E", "Instance {0} with unique attribute {1}={2} does not exist"), UNRESOLVED_REFERENCES_FOUND(400, "ATLAS40010E", "Unresolved references: byId={0}; byUniqueAttributes={1}"), http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/intg/src/main/java/org/apache/atlas/model/discovery/AtlasSearchResult.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/model/discovery/AtlasSearchResult.java b/intg/src/main/java/org/apache/atlas/model/discovery/AtlasSearchResult.java index e0f24b1..c4c0063 100644 --- a/intg/src/main/java/org/apache/atlas/model/discovery/AtlasSearchResult.java +++ b/intg/src/main/java/org/apache/atlas/model/discovery/AtlasSearchResult.java @@ -17,7 +17,7 @@ */ package org.apache.atlas.model.discovery; -import org.apache.atlas.model.instance.AtlasEntityHeaderWithAssociations; +import org.apache.atlas.model.instance.AtlasEntityHeader; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.codehaus.jackson.annotate.JsonAutoDetect; @@ -42,11 +42,11 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL @XmlRootElement @XmlAccessorType(XmlAccessType.PROPERTY) public class AtlasSearchResult implements Serializable { - private String queryText; - private AtlasQueryType queryType; - private List<AtlasEntityHeaderWithAssociations> entities; - private AttributeSearchResult attributes; - private List<AtlasFullTextResult> fullTextResult; + private String queryText; + private AtlasQueryType queryType; + private List<AtlasEntityHeader> entities; + private AttributeSearchResult attributes; + private List<AtlasFullTextResult> fullTextResult; public AtlasSearchResult() {} @@ -66,9 +66,9 @@ public class AtlasSearchResult implements Serializable { public void setQueryType(AtlasQueryType queryType) { this.queryType = queryType; } - public List<AtlasEntityHeaderWithAssociations> getEntities() { return entities; } + public List<AtlasEntityHeader> getEntities() { return entities; } - public void setEntities(List<AtlasEntityHeaderWithAssociations> entities) { this.entities = entities; } + public void setEntities(List<AtlasEntityHeader> entities) { this.entities = entities; } public AttributeSearchResult getAttributes() { return attributes; } @@ -104,7 +104,7 @@ public class AtlasSearchResult implements Serializable { '}'; } - public void addEntity(AtlasEntityHeaderWithAssociations newEntity) { + public void addEntity(AtlasEntityHeader newEntity) { if (entities == null) { entities = new ArrayList<>(); } @@ -117,13 +117,13 @@ public class AtlasSearchResult implements Serializable { } } - public void removeEntity(AtlasEntityHeaderWithAssociations entity) { - List<AtlasEntityHeaderWithAssociations> entities = this.entities; + public void removeEntity(AtlasEntityHeader entity) { + List<AtlasEntityHeader> entities = this.entities; if (CollectionUtils.isNotEmpty(entities)) { - Iterator<AtlasEntityHeaderWithAssociations> iter = entities.iterator(); + Iterator<AtlasEntityHeader> iter = entities.iterator(); while (iter.hasNext()) { - AtlasEntityHeaderWithAssociations currEntity = iter.next(); + AtlasEntityHeader currEntity = iter.next(); if (StringUtils.equals(currEntity.getGuid(), entity.getGuid())) { iter.remove(); } @@ -184,19 +184,19 @@ public class AtlasSearchResult implements Serializable { @XmlRootElement @XmlAccessorType(XmlAccessType.PROPERTY) public static class AtlasFullTextResult { - AtlasEntityHeaderWithAssociations entity; - Double score; + AtlasEntityHeader entity; + Double score; public AtlasFullTextResult() {} - public AtlasFullTextResult(AtlasEntityHeaderWithAssociations entity, Double score) { + public AtlasFullTextResult(AtlasEntityHeader entity, Double score) { this.entity = entity; this.score = score; } - public AtlasEntityHeaderWithAssociations getEntity() { return entity; } + public AtlasEntityHeader getEntity() { return entity; } - public void setEntity(AtlasEntityHeaderWithAssociations entity) { this.entity = entity; } + public void setEntity(AtlasEntityHeader entity) { this.entity = entity; } public Double getScore() { return score; } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/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 de57145..af936cc 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 @@ -19,7 +19,10 @@ package org.apache.atlas.model.instance; import org.apache.atlas.model.PList; import org.apache.atlas.model.SearchFilter.SortType; +import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.model.typedef.AtlasEntityDef; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang.StringUtils; import org.codehaus.jackson.annotate.JsonAutoDetect; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.annotate.JsonIgnoreProperties; @@ -30,7 +33,9 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlSeeAlso; import java.io.Serializable; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -65,6 +70,8 @@ public class AtlasEntity extends AtlasStruct implements Serializable { private Date updateTime = null; private Long version = new Long(0); + private List<AtlasClassification> classifications; + @JsonIgnore private static AtomicLong s_nextId = new AtomicLong(System.nanoTime()); @@ -89,6 +96,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable { setUpdatedBy(null); setCreateTime(null); setUpdateTime(null); + setClassifications(null); } public AtlasEntity(AtlasEntity other) { @@ -102,6 +110,7 @@ public class AtlasEntity extends AtlasStruct implements Serializable { setCreateTime(other.getCreateTime()); setUpdateTime(other.getUpdateTime()); setVersion(other.getVersion()); + setClassifications(other.getClassifications()); } } @@ -161,6 +170,10 @@ public class AtlasEntity extends AtlasStruct implements Serializable { this.version = version; } + public List<AtlasClassification> getClassifications() { return classifications; } + + public void setClassifications(List<AtlasClassification> classifications) { this.classifications = classifications; } + @JsonIgnore public boolean isUnassigned() { return isUnAssigned(guid); @@ -210,6 +223,9 @@ public class AtlasEntity extends AtlasStruct implements Serializable { dumpDateField(", createTime=", createTime, sb); dumpDateField(", updateTime=", updateTime, sb); sb.append(", version=").append(version); + sb.append(", classifications=["); + AtlasBaseTypeDef.dumpObjects(classifications, sb); + sb.append(']'); sb.append(", "); super.toString(sb); sb.append('}'); @@ -230,12 +246,14 @@ public class AtlasEntity extends AtlasStruct implements Serializable { Objects.equals(updatedBy, that.updatedBy) && Objects.equals(createTime, that.createTime) && Objects.equals(updateTime, that.updateTime) && - Objects.equals(version, that.version); + Objects.equals(version, that.version) && + Objects.equals(classifications, that.classifications); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), guid, status, createdBy, updatedBy, createTime, updateTime, version); + return Objects.hash(super.hashCode(), guid, status, createdBy, updatedBy, createTime, updateTime, version, + classifications); } @Override @@ -244,6 +262,339 @@ public class AtlasEntity extends AtlasStruct implements Serializable { } /** + * An instance of an entity along with extended info - like hive_table, hive_database. + */ + @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown=true) + @XmlRootElement + @XmlAccessorType(XmlAccessType.PROPERTY) + public static class AtlasEntityExtInfo implements Serializable { + private static final long serialVersionUID = 1L; + + private Map<String, AtlasEntity> referredEntities; + + + public AtlasEntityExtInfo() { + setReferredEntities(null); + } + + public AtlasEntityExtInfo(Map<String, AtlasEntity> referredEntities) { + setReferredEntities(referredEntities); + } + + public AtlasEntityExtInfo(AtlasEntityExtInfo other) { + if (other != null) { + setReferredEntities(other.getReferredEntities()); + } + } + + public Map<String, AtlasEntity> getReferredEntities() { return referredEntities; } + + public void setReferredEntities(Map<String, AtlasEntity> referredEntities) { this.referredEntities = referredEntities; } + + @JsonIgnore + public final void addReferredEntity(String guid, AtlasEntity entity) { + Map<String, AtlasEntity> r = this.referredEntities; + + if (r == null) { + r = new HashMap<>(); + + this.referredEntities = r; + } + + if (guid != null) { + r.put(guid, entity); + } + } + + @JsonIgnore + public final AtlasEntity removeReferredEntity(String guid) { + Map<String, AtlasEntity> r = this.referredEntities; + + return r != null && guid != null ? r.remove(guid) : null; + } + + @JsonIgnore + public final AtlasEntity getReferredEntity(String guid) { + Map<String, AtlasEntity> r = this.referredEntities; + + return r != null && guid != null ? r.get(guid) : null; + } + + @JsonIgnore + public AtlasEntity getEntity(String guid) { + return getReferredEntity(guid); + } + + @JsonIgnore + public AtlasEntity removeEntity(String guid) { + Map<String, AtlasEntity> r = this.referredEntities; + + return r != null && guid != null ? r.remove(guid) : null; + } + + public void updateEntityGuid(String oldGuid, String newGuid) { + AtlasEntity entity = getEntity(oldGuid); + + if (entity != null) { + entity.setGuid(newGuid); + + if(removeEntity(oldGuid) != null) { + addReferredEntity(newGuid, entity); + } + } + } + + public boolean hasEntity(String guid) { + return getEntity(guid) != null; + } + + public void compact() { + // for derived classes to implement their own logic + } + + public StringBuilder toString(StringBuilder sb) { + if (sb == null) { + sb = new StringBuilder(); + } + + sb.append("AtlasEntityExtInfo{"); + sb.append("referredEntities={"); + AtlasBaseTypeDef.dumpObjects(referredEntities, sb); + sb.append("}"); + sb.append("}"); + + return sb; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + AtlasEntityExtInfo that = (AtlasEntityExtInfo) o; + return Objects.equals(referredEntities, that.referredEntities); + } + + @Override + public int hashCode() { + return Objects.hash(referredEntities); + } + + @Override + public String toString() { + return toString(new StringBuilder()).toString(); + } + } + + @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown=true) + @XmlRootElement + @XmlAccessorType(XmlAccessType.PROPERTY) + public static class AtlasEntityWithExtInfo extends AtlasEntityExtInfo { + private static final long serialVersionUID = 1L; + + private AtlasEntity entity; + + public AtlasEntityWithExtInfo() { + this(null, null); + } + + public AtlasEntityWithExtInfo(AtlasEntity entity) { + this(entity, null); + } + + public AtlasEntityWithExtInfo(AtlasEntity entity, AtlasEntityExtInfo extInfo) { + super(extInfo); + + this.entity = entity; + } + + public AtlasEntity getEntity() { return entity; } + + public void setEntity(AtlasEntity entity) { this.entity = entity; } + + @JsonIgnore + @Override + public AtlasEntity getEntity(String guid) { + AtlasEntity ret = super.getEntity(guid); + + if (ret == null && entity != null) { + if (StringUtils.equals(guid, entity.getGuid())) { + ret = entity; + } + } + + return ret; + } + + @JsonIgnore + @Override + public void compact() { + super.compact(); + + // remove 'entity' from referredEntities + if (entity != null) { + removeEntity(entity.getGuid()); + } + } + + @Override + public StringBuilder toString(StringBuilder sb) { + if (sb == null) { + sb = new StringBuilder(); + } + + sb.append("AtlasEntityWithExtInfo{"); + sb.append("entity=").append(entity).append(","); + super.toString(sb); + sb.append("}"); + + return sb; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + AtlasEntityWithExtInfo that = (AtlasEntityWithExtInfo) o; + return Objects.equals(entity, that.entity); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), entity); + } + } + + @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) + @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) + @JsonIgnoreProperties(ignoreUnknown=true) + @XmlRootElement + @XmlAccessorType(XmlAccessType.PROPERTY) + public static class AtlasEntitiesWithExtInfo extends AtlasEntityExtInfo { + private static final long serialVersionUID = 1L; + + private List<AtlasEntity> entities; + + public AtlasEntitiesWithExtInfo() { + this(null, null); + } + + public AtlasEntitiesWithExtInfo(List<AtlasEntity> entities) { + this(entities, null); + } + + public AtlasEntitiesWithExtInfo(List<AtlasEntity> entities, AtlasEntityExtInfo extInfo) { + super(extInfo); + + this.entities = entities; + } + + public List<AtlasEntity> getEntities() { return entities; } + + public void setEntities(List<AtlasEntity> entities) { this.entities = entities; } + + @JsonIgnore + @Override + public AtlasEntity getEntity(String guid) { + AtlasEntity ret = super.getEntity(guid); + + if (ret == null && CollectionUtils.isNotEmpty(entities)) { + for (AtlasEntity entity : entities) { + if (StringUtils.equals(guid, entity.getGuid())) { + ret = entity; + + break; + } + } + } + + return ret; + } + + public void addEntity(AtlasEntity entity) { + List<AtlasEntity> entities = this.entities; + + if (entities == null) { + entities = new ArrayList<>(); + + this.entities = entities; + } + + entities.add(entity); + } + + public void removeEntity(AtlasEntity entity) { + List<AtlasEntity> entities = this.entities; + + if (entity != null && entities != null) { + entities.remove(entity); + } + } + + @Override + public void compact() { + super.compact(); + + // remove 'entities' from referredEntities + if (CollectionUtils.isNotEmpty(entities)) { + for (AtlasEntity entity : entities) { + removeReferredEntity(entity.getGuid()); + } + } + } + + @Override + public StringBuilder toString(StringBuilder sb) { + if (sb == null) { + sb = new StringBuilder(); + } + + sb.append("AtlasEntitiesWithExtInfo{"); + sb.append("entities=["); + AtlasBaseTypeDef.dumpObjects(entities, sb); + sb.append("],"); + super.toString(sb); + sb.append("}"); + + return sb; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + + if (o == null || getClass() != o.getClass()) { + return false; + } + + AtlasEntitiesWithExtInfo that = (AtlasEntitiesWithExtInfo) o; + return Objects.equals(entities, that.entities); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), entities); + } + } + + /** * REST serialization friendly list. */ @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeader.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeader.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeader.java index 5797a69..93a77e0 100644 --- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeader.java +++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeader.java @@ -18,7 +18,6 @@ package org.apache.atlas.model.instance; import java.io.Serializable; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -49,9 +48,10 @@ import org.codehaus.jackson.map.annotate.JsonSerialize; public class AtlasEntityHeader extends AtlasStruct implements Serializable { private static final long serialVersionUID = 1L; - private String guid = null; - private AtlasEntity.Status status = AtlasEntity.Status.ACTIVE; - private String displayText = null; + private String guid = null; + private AtlasEntity.Status status = AtlasEntity.Status.ACTIVE; + private String displayText = null; + private List<String> classificationNames = null; public AtlasEntityHeader() { this(null, null); @@ -67,12 +67,15 @@ public class AtlasEntityHeader extends AtlasStruct implements Serializable { public AtlasEntityHeader(String typeName, Map<String, Object> attributes) { super(typeName, attributes); + + setClassificationNames(null); } public AtlasEntityHeader(String typeName, String guid, Map<String, Object> attributes) { super(typeName, attributes); setGuid(guid); + setClassificationNames(null); } @@ -83,6 +86,7 @@ public class AtlasEntityHeader extends AtlasStruct implements Serializable { setGuid(other.getGuid()); setStatus(other.getStatus()); setDisplayText(other.getDisplayText()); + setClassificationNames(other.getClassificationNames()); } } @@ -110,6 +114,14 @@ public class AtlasEntityHeader extends AtlasStruct implements Serializable { this.displayText = displayText; } + public List<String> getClassificationNames(){ + return classificationNames; + } + + public void setClassificationNames(List<String> classificationNames) { + this.classificationNames = classificationNames; + } + @Override public StringBuilder toString(StringBuilder sb) { if (sb == null) { @@ -120,6 +132,9 @@ public class AtlasEntityHeader extends AtlasStruct implements Serializable { sb.append("guid='").append(guid).append('\''); sb.append(", status=").append(status); sb.append(", displayText=").append(displayText); + sb.append(", classificationNames=["); + dumpObjects(classificationNames, sb); + sb.append("],"); sb.append(", "); super.toString(sb); sb.append('}'); @@ -135,12 +150,13 @@ public class AtlasEntityHeader extends AtlasStruct implements Serializable { AtlasEntityHeader that = (AtlasEntityHeader) o; return Objects.equals(guid, that.guid) && status == that.status && - Objects.equals(displayText, that.displayText); + Objects.equals(displayText, that.displayText) && + Objects.equals(classificationNames, that.classificationNames); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), guid, status, displayText); + return Objects.hash(super.hashCode(), guid, status, displayText, classificationNames); } @Override http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeaderWithAssociations.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeaderWithAssociations.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeaderWithAssociations.java deleted file mode 100644 index ed1adb4..0000000 --- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityHeaderWithAssociations.java +++ /dev/null @@ -1,143 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.atlas.model.instance; - -import org.apache.atlas.model.PList; -import org.apache.atlas.model.SearchFilter; -import org.apache.atlas.model.typedef.AtlasEntityDef; -import org.codehaus.jackson.annotate.JsonAutoDetect; -import org.codehaus.jackson.annotate.JsonIgnoreProperties; -import org.codehaus.jackson.map.annotate.JsonSerialize; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSeeAlso; -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE; -import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY; - -/** - * An instance of an entity and its associations - like hive_table, hive_database. - */ -@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) -@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown=true) -@XmlRootElement -@XmlAccessorType(XmlAccessType.PROPERTY) -public class AtlasEntityHeaderWithAssociations extends AtlasEntityHeader implements Serializable{ - private static final long serialVersionUID = 1L; - - private List<String> classificationNames; - - public AtlasEntityHeaderWithAssociations(){ - this(null, null); - } - - public AtlasEntityHeaderWithAssociations(AtlasEntityDef entityDef) { - this(entityDef != null ? entityDef.getName() : null, null); - } - - public AtlasEntityHeaderWithAssociations(String typeName, Map<String, Object> attributes) { - super(typeName, attributes); - setClassificationNames(null); - } - - public AtlasEntityHeaderWithAssociations(AtlasEntityHeaderWithAssociations other) { - super(other); - - if (other != null) { - setClassificationNames(other.getClassificationNames()); - } - } - - public List<String> getClassificationNames(){ - return classificationNames; - } - - public void setClassificationNames(List<String> classificationNames) { - this.classificationNames = classificationNames; - } - - - @Override - public StringBuilder toString(StringBuilder sb) { - if (sb == null) { - sb = new StringBuilder(); - } - - sb.append("AtlasEntityHeaderwithAssociations{"); - sb.append(", classificationNames=["); - dumpObjects(classificationNames, sb); - sb.append("],"); - super.toString(sb); - sb.append('}'); - - return sb; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - AtlasEntityHeaderWithAssociations that = (AtlasEntityHeaderWithAssociations) o; - return Objects.equals(classificationNames, that.classificationNames); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), classificationNames); - } - - @Override - public String toString() { - return toString(new StringBuilder()).toString(); - } - - /** - * REST serialization friendly list. - */ - @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) - @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown=true) - @XmlRootElement - @XmlAccessorType(XmlAccessType.PROPERTY) - @XmlSeeAlso(AtlasEntity.class) - public static class AtlasEntityHeadersWithAssociations extends PList<AtlasEntityHeaderWithAssociations> { - private static final long serialVersionUID = 1L; - - public AtlasEntityHeadersWithAssociations() { - super(); - } - - public AtlasEntityHeadersWithAssociations(List<AtlasEntityHeaderWithAssociations> list) { - super(list); - } - - public AtlasEntityHeadersWithAssociations(List list, long startIndex, int pageSize, long totalCount, - SearchFilter.SortType sortType, String sortBy) { - super(list, startIndex, pageSize, totalCount, sortType, sortBy); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/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 deleted file mode 100644 index abcf276..0000000 --- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntityWithAssociations.java +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.atlas.model.instance; - -import org.apache.atlas.model.PList; -import org.apache.atlas.model.SearchFilter.SortType; -import org.apache.atlas.model.typedef.AtlasEntityDef; -import org.codehaus.jackson.annotate.JsonAutoDetect; -import org.codehaus.jackson.annotate.JsonIgnoreProperties; -import org.codehaus.jackson.map.annotate.JsonSerialize; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSeeAlso; -import java.io.Serializable; -import java.util.List; -import java.util.Map; -import java.util.Objects; - -import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE; -import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY; - - -/** - * An instance of an entity - like hive_table, hive_database along with its assictaed classifications, terms etc. - */ -@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) -@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown=true) -@XmlRootElement -@XmlAccessorType(XmlAccessType.PROPERTY) -public class AtlasEntityWithAssociations extends AtlasEntity implements Serializable { - private static final long serialVersionUID = 1L; - - List<AtlasClassification> classifications; - - public AtlasEntityWithAssociations() { - this(null, null); - } - - public AtlasEntityWithAssociations(String typeName) { - this(typeName, null); - } - - public AtlasEntityWithAssociations(AtlasEntityDef entityDef) { - this(entityDef != null ? entityDef.getName() : null, null); - } - - public AtlasEntityWithAssociations(String typeName, Map<String, Object> attributes) { - super(typeName, attributes); - setClassifications(null); - } - - public AtlasEntityWithAssociations(AtlasEntityWithAssociations other) { - super(other); - - setClassifications(other != null ? other.getClassifications() : null); - } - - public AtlasEntityWithAssociations(AtlasEntity other) { - super(other); - } - - @Override - public StringBuilder toString(StringBuilder sb) { - if (sb == null) { - sb = new StringBuilder(); - } - - sb.append("AtlasEntityWithAssociations{"); - sb.append("classifications='").append(classifications).append('\''); - sb.append(", "); - super.toString(sb); - sb.append('}'); - - return sb; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - if (!super.equals(o)) return false; - AtlasEntityWithAssociations that = (AtlasEntityWithAssociations) o; - return Objects.equals(classifications, that.classifications); - } - - @Override - public int hashCode() { - return Objects.hash(super.hashCode(), classifications); - } - - public List<AtlasClassification> getClassifications() { - return classifications; - } - - public void setClassifications(final List<AtlasClassification> classifications) { - this.classifications = classifications; - } - - @Override - public String toString() { - return toString(new StringBuilder()).toString(); - } - - /** - * REST serialization friendly list. - */ - @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) - @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) - @JsonIgnoreProperties(ignoreUnknown=true) - @XmlRootElement - @XmlAccessorType(XmlAccessType.PROPERTY) - @XmlSeeAlso(AtlasEntityWithAssociations.class) - public static class AtlasEntitiesWithAssociations extends PList<AtlasEntityWithAssociations> { - private static final long serialVersionUID = 1L; - - public AtlasEntitiesWithAssociations() { - super(); - } - - public AtlasEntitiesWithAssociations(List<AtlasEntityWithAssociations> list) { - super(list); - } - - public AtlasEntitiesWithAssociations(List list, long startIndex, int pageSize, long totalCount, - SortType sortType, String sortBy) { - super(list, startIndex, pageSize, totalCount, sortType, sortBy); - } - } -} http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java index 2b4561d..da06230 100644 --- a/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java +++ b/repository/src/main/java/org/apache/atlas/discovery/EntityDiscoveryService.java @@ -26,7 +26,7 @@ import org.apache.atlas.discovery.graph.DefaultGraphPersistenceStrategy; import org.apache.atlas.exception.AtlasBaseException; import org.apache.atlas.model.discovery.AtlasSearchResult; import org.apache.atlas.model.instance.AtlasEntity.Status; -import org.apache.atlas.model.instance.AtlasEntityHeaderWithAssociations; +import org.apache.atlas.model.instance.AtlasEntityHeader; import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.query.Expressions.AliasExpression; import org.apache.atlas.query.Expressions.Expression; @@ -97,7 +97,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { if (firstElement instanceof AtlasVertex) { for (Object element : queryResult) { if (element instanceof AtlasVertex) { - ret.addEntity(toAtlasEntityHeaderwithAssociations((AtlasVertex)element)); + ret.addEntity(toAtlasEntityHeader((AtlasVertex)element)); } else { LOG.warn("searchUsingDslQuery({}): expected an AtlasVertex; found unexpected entry in result {}", dslQuery, element); } @@ -115,7 +115,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { Object entry = ((List)value).get(0); if (entry instanceof AtlasVertex) { - ret.addEntity(toAtlasEntityHeaderwithAssociations((AtlasVertex)entry)); + ret.addEntity(toAtlasEntityHeader((AtlasVertex)entry)); } } } @@ -159,7 +159,7 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { String guid = vertex != null ? vertex.getProperty(Constants.GUID_PROPERTY_KEY, String.class) : null; if (guid != null) { - AtlasEntityHeaderWithAssociations entity = toAtlasEntityHeaderwithAssociations(vertex); + AtlasEntityHeader entity = toAtlasEntityHeader(vertex); Double score = idxQueryResult.getScore(); ret.add(new AtlasFullTextResult(entity, score)); } @@ -204,12 +204,12 @@ public class EntityDiscoveryService implements AtlasDiscoveryService { return new QueryParams(limit, offset); } - private AtlasEntityHeaderWithAssociations toAtlasEntityHeaderwithAssociations(AtlasVertex vertex) { + private AtlasEntityHeader toAtlasEntityHeader(AtlasVertex vertex) { if (vertex == null) { return null; } - AtlasEntityHeaderWithAssociations ret = new AtlasEntityHeaderWithAssociations(); + AtlasEntityHeader ret = new AtlasEntityHeader(); String typeName = vertex.getProperty(Constants.TYPE_NAME_PROPERTY_KEY, String.class); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java index 89e978d..65de1e5 100755 --- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java +++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphHelper.java @@ -18,23 +18,13 @@ package org.apache.atlas.repository.graph; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.Stack; -import java.util.UUID; - +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import org.apache.atlas.ApplicationProperties; import org.apache.atlas.AtlasException; import org.apache.atlas.RequestContext; +import org.apache.atlas.model.instance.AtlasEntity.Status; import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.RepositoryException; import org.apache.atlas.repository.graphdb.AtlasEdge; @@ -43,6 +33,7 @@ import org.apache.atlas.repository.graphdb.AtlasElement; import org.apache.atlas.repository.graphdb.AtlasGraph; import org.apache.atlas.repository.graphdb.AtlasGraphQuery; import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.type.AtlasType; import org.apache.atlas.typesystem.IReferenceableInstance; import org.apache.atlas.typesystem.ITypedInstance; import org.apache.atlas.typesystem.ITypedReferenceableInstance; @@ -70,9 +61,19 @@ import org.codehaus.jettison.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.Stack; +import java.util.UUID; /** * Utility class for graph operations. @@ -596,8 +597,8 @@ public final class GraphHelper { public static String getQualifiedFieldName(IDataType dataType, String attributeName) throws AtlasException { return dataType.getTypeCategory() == DataTypes.TypeCategory.STRUCT ? dataType.getName() + "." + attributeName - // else class or trait - : ((HierarchicalType) dataType).getQualifiedName(attributeName); + // else class or trait + : ((HierarchicalType) dataType).getQualifiedName(attributeName); } public static String getTraitLabel(String typeName, String attrName) { @@ -649,10 +650,15 @@ public final class GraphHelper { return element.getProperty(Constants.VERSION_PROPERTY_KEY, Integer.class); } + + public static String getStateAsString(AtlasElement element) { return element.getProperty(Constants.STATE_PROPERTY_KEY, String.class); } + public static Status getStatus(AtlasElement element) { + return (getState(element) == Id.EntityState.DELETED) ? Status.DELETED : Status.ACTIVE; + } //Added conditions in fetching system attributes to handle test failures in GremlinTest where these properties are not set public static String getCreatedByAsString(AtlasElement element){ @@ -812,6 +818,7 @@ public final class GraphHelper { } return Collections.emptyList(); } + /** * Guid and AtlasVertex combo */ @@ -974,6 +981,12 @@ public final class GraphHelper { } + public static boolean isReference(AtlasType type) { + return ((type.getTypeCategory() == org.apache.atlas.model.TypeCategory.STRUCT) || + (type.getTypeCategory() == org.apache.atlas.model.TypeCategory.ENTITY)); + + } + public static void setArrayElementsProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName, List<Object> values) { String actualPropertyName = GraphHelper.encodePropertyKey(propertyName); if(GraphHelper.isReference(elementType)) { @@ -1004,6 +1017,27 @@ public final class GraphHelper { } } + public static Object getMapValueProperty(AtlasType elementType, AtlasVertex instanceVertex, String propertyName) { + String vertexPropertyName = GraphHelper.encodePropertyKey(propertyName); + + if (GraphHelper.isReference(elementType)) { + return instanceVertex.getProperty(vertexPropertyName, AtlasEdge.class); + } else { + return instanceVertex.getProperty(vertexPropertyName, Object.class).toString(); + } + } + + // newly added + public static List<Object> getArrayElementsProperty(AtlasType elementType, AtlasVertex instanceVertex, String propertyName) { + String encodedPropertyName = GraphHelper.encodePropertyKey(propertyName); + if(GraphHelper.isReference(elementType)) { + return (List)instanceVertex.getListProperty(encodedPropertyName, AtlasEdge.class); + } + else { + return (List)instanceVertex.getListProperty(encodedPropertyName); + } + } + public static List<Object> getArrayElementsProperty(IDataType elementType, AtlasVertex instanceVertex, String propertyName) { String actualPropertyName = GraphHelper.encodePropertyKey(propertyName); if(GraphHelper.isReference(elementType)) { @@ -1014,7 +1048,6 @@ public final class GraphHelper { } } - public static void dumpToLog(final AtlasGraph<?,?> graph) { LOG.debug("*******************Graph Dump****************************"); LOG.debug("Vertices of {}", graph); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/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 ed0fabb..4cfc012 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 @@ -19,12 +19,12 @@ package org.apache.atlas.repository.store.graph; import org.apache.atlas.exception.AtlasBaseException; -import org.apache.atlas.model.SearchFilter; 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.EntityMutations; +import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo; +import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo; import org.apache.atlas.model.instance.EntityMutationResponse; +import org.apache.atlas.type.AtlasEntityType; import org.apache.atlas.type.AtlasTypeRegistry; import java.util.List; @@ -45,9 +45,9 @@ public interface AtlasEntityStore { * * Get entity definition by its guid * @param guid - * @return + * @return AtlasEntity */ - AtlasEntity getById(String guid); + AtlasEntityWithExtInfo getById(String guid) throws AtlasBaseException; /** * Delete an entity by its guid @@ -71,15 +71,7 @@ public interface AtlasEntityStore { * @return * @throws AtlasBaseException */ - AtlasEntity.AtlasEntities getByIds(List<String> guid) throws AtlasBaseException; - - /** - * Batch GET to retrieve entities and their associations by their ID - * @param guid - * @return - * @throws AtlasBaseException - */ - AtlasEntityWithAssociations getWithAssociationsByIds(List<String> guid) throws AtlasBaseException; + AtlasEntitiesWithExtInfo getByIds(List<String> guid) throws AtlasBaseException; /* * Return list of deleted entity guids @@ -89,12 +81,12 @@ public interface AtlasEntityStore { /** * * Get an eneity by its unique attribute - * @param typeName - * @param attrName - * @param attrValue - * @return + * @param entityType + * @param uniqAttributes + * @return AtlasEntity */ - AtlasEntity getByUniqueAttribute(String typeName, String attrName, String attrValue); + AtlasEntityWithExtInfo getByUniqueAttribute(AtlasEntityType entityType, Map<String, Object> uniqAttributes) + throws AtlasBaseException; /** * @deprecated @@ -134,5 +126,4 @@ public interface AtlasEntityStore { * Delete classification(s) */ void deleteClassifications(String guid, List<String> classificationNames) throws AtlasBaseException; - } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/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 9e08282..a95ae8e 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 @@ -18,9 +18,7 @@ package org.apache.atlas.repository.store.graph.v1; -import java.util.ArrayList; -import java.util.List; - +import com.google.inject.Inject; import org.apache.atlas.AtlasErrorCode; import org.apache.atlas.GraphTransaction; import org.apache.atlas.RequestContextV1; @@ -28,9 +26,16 @@ import org.apache.atlas.exception.AtlasBaseException; 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.AtlasEntity.AtlasEntityWithExtInfo; +import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo; +import org.apache.atlas.model.instance.AtlasEntity.Status; import org.apache.atlas.model.instance.AtlasObjectId; import org.apache.atlas.model.instance.EntityMutationResponse; +import org.apache.atlas.repository.graph.AtlasGraphProvider; +import org.apache.atlas.repository.graph.GraphHelper; +import org.apache.atlas.repository.Constants; +import org.apache.atlas.repository.graphdb.AtlasGraph; +import org.apache.atlas.repository.graphdb.AtlasGraphQuery; import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.repository.store.graph.AtlasEntityStore; import org.apache.atlas.repository.store.graph.EntityGraphDiscovery; @@ -41,22 +46,28 @@ import org.apache.atlas.type.AtlasTypeRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; import java.util.Map; -import com.google.inject.Inject; - public class AtlasEntityStoreV1 implements AtlasEntityStore { protected AtlasTypeRegistry typeRegistry; + protected final GraphHelper graphHelper = GraphHelper.getInstance(); - private EntityGraphMapper graphMapper; + private final EntityGraphMapper graphMapper; + private final GraphEntityMapper entityMapper; + private final AtlasGraph graph; private static final Logger LOG = LoggerFactory.getLogger(AtlasEntityStoreV1.class); @Inject - public AtlasEntityStoreV1(EntityGraphMapper vertexMapper) { - this.graphMapper = vertexMapper; + public AtlasEntityStoreV1(EntityGraphMapper vertexMapper, GraphEntityMapper entityMapper) { + this.graphMapper = vertexMapper; + this.entityMapper = entityMapper; + this.graph = AtlasGraphProvider.getGraphInstance(); } @Inject @@ -65,8 +76,43 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore { } @Override - public AtlasEntity getById(final String guid) { - return null; + public AtlasEntityWithExtInfo getById(final String guid) throws AtlasBaseException { + if (LOG.isDebugEnabled()) { + LOG.debug("Retrieving entity with guid={}", guid); + } + + return entityMapper.toAtlasEntity(guid, true); + } + + @Override + public AtlasEntityWithExtInfo getByUniqueAttribute(AtlasEntityType entityType, Map<String, Object> uniqAttributes) throws AtlasBaseException { + String entityTypeName = entityType.getTypeName(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Retrieving entity with type={} and attributes={}: values={}", entityTypeName, uniqAttributes); + } + + AtlasGraphQuery query = graph.query(); + + for (Map.Entry<String, Object> e : uniqAttributes.entrySet()) { + String attrName = e.getKey(); + Object attrValue = e.getValue(); + + query = query.has(entityType.getQualifiedAttributeName(attrName), attrValue); + } + + Iterator<AtlasVertex> result = query.has(Constants.ENTITY_TYPE_PROPERTY_KEY, entityTypeName) + .has(Constants.STATE_PROPERTY_KEY, Status.ACTIVE.name()) + .vertices().iterator(); + AtlasVertex entityVertex = result.hasNext() ? result.next() : null; + + if (entityVertex == null) { + throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, entityTypeName, uniqAttributes.keySet().toString(), uniqAttributes.values().toString()); + } + + String guid = GraphHelper.getGuid(entityVertex); + + return entityMapper.toAtlasEntity(guid, true); } @Override @@ -96,12 +142,7 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore { } @Override - public AtlasEntity.AtlasEntities getByIds(final List<String> guid) throws AtlasBaseException { - return null; - } - - @Override - public AtlasEntityWithAssociations getWithAssociationsByIds(final List<String> guid) throws AtlasBaseException { + public AtlasEntitiesWithExtInfo getByIds(final List<String> guids) throws AtlasBaseException { return null; } @@ -111,11 +152,6 @@ public class AtlasEntityStoreV1 implements AtlasEntityStore { } @Override - public AtlasEntity getByUniqueAttribute(final String typeName, final String attrName, final String attrValue) { - return null; - } - - @Override public EntityMutationResponse updateByUniqueAttribute(final String typeName, final String attributeName, final String attributeValue, final AtlasEntity entity) throws AtlasBaseException { return null; } http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java index 7fe5e14..bddac7a 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasGraphUtilsV1.java @@ -21,11 +21,9 @@ import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; import org.apache.atlas.AtlasErrorCode; -import org.apache.atlas.AtlasException; 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.AtlasStruct; import org.apache.atlas.model.typedef.AtlasBaseTypeDef; import org.apache.atlas.repository.Constants; import org.apache.atlas.repository.graph.GraphHelper; @@ -34,14 +32,10 @@ import org.apache.atlas.repository.graphdb.AtlasElement; import org.apache.atlas.repository.graphdb.AtlasVertex; import org.apache.atlas.type.AtlasStructType; import org.apache.atlas.type.AtlasType; -import org.apache.atlas.typesystem.persistence.Id; -import org.apache.atlas.typesystem.types.DataTypes; -import org.apache.atlas.typesystem.types.IDataType; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/GraphEntityMapper.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/GraphEntityMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/GraphEntityMapper.java new file mode 100644 index 0000000..a0d8940 --- /dev/null +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/GraphEntityMapper.java @@ -0,0 +1,400 @@ +/** + * 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 com.google.inject.Inject; +import com.google.inject.Singleton; +import org.apache.atlas.AtlasErrorCode; +import org.apache.atlas.AtlasException; +import org.apache.atlas.exception.AtlasBaseException; +import org.apache.atlas.model.instance.AtlasClassification; +import org.apache.atlas.model.instance.AtlasEntity; +import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityExtInfo; +import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo; +import org.apache.atlas.model.instance.AtlasObjectId; +import org.apache.atlas.model.instance.AtlasStruct; +import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; +import org.apache.atlas.repository.Constants; +import org.apache.atlas.repository.graph.GraphHelper; +import org.apache.atlas.repository.graphdb.AtlasEdge; +import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; +import org.apache.atlas.repository.graphdb.AtlasVertex; +import org.apache.atlas.type.AtlasArrayType; +import org.apache.atlas.type.AtlasMapType; +import org.apache.atlas.type.AtlasStructType; +import org.apache.atlas.type.AtlasStructType.AtlasAttribute; +import org.apache.atlas.type.AtlasType; +import org.apache.atlas.type.AtlasTypeRegistry; +import org.apache.commons.collections.CollectionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_BIGDECIMAL; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_BIGINTEGER; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_BOOLEAN; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_BYTE; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_DATE; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_DOUBLE; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_FLOAT; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_INT; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_LONG; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_SHORT; +import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_STRING; +import static org.apache.atlas.repository.graph.GraphHelper.EDGE_LABEL_PREFIX; + +@Singleton +public final class GraphEntityMapper { + private static final Logger LOG = LoggerFactory.getLogger(GraphEntityMapper.class); + private static final GraphHelper graphHelper = GraphHelper.getInstance(); + + @Inject + protected AtlasTypeRegistry typeRegistry; + + public AtlasEntityWithExtInfo toAtlasEntity(String guid, boolean includeReferences) throws AtlasBaseException { + AtlasEntityExtInfo entityExtInfo = includeReferences ? new AtlasEntityExtInfo() : null; + AtlasEntity entity = mapVertexToAtlasEntity(guid, entityExtInfo); + AtlasEntityWithExtInfo ret = new AtlasEntityWithExtInfo(entity, entityExtInfo); + + ret.compact(); + + return ret; + } + + private AtlasEntity mapVertexToAtlasEntity(String guid, AtlasEntityExtInfo entityExtInfo) throws AtlasBaseException { + AtlasEntity entity = entityExtInfo != null ? entityExtInfo.getEntity(guid) : null; + + if (entity != null) { + return entity; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("Mapping graph vertex to atlas entity for guid {}", guid); + } + + try { + AtlasVertex entityVertex = graphHelper.getVertexForGUID(guid); + entity = new AtlasEntity(); + + if (entityExtInfo != null) { + entityExtInfo.addReferredEntity(guid, entity); + } + + mapSystemAttributes(entityVertex, entity); + + mapAttributes(entityVertex, entity, entityExtInfo); + + mapClassifications(entityVertex, entity, entityExtInfo); + + } catch (AtlasException e) { + throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid); + } + + return entity; + } + + private AtlasEntity mapSystemAttributes(AtlasVertex entityVertex, AtlasEntity entity) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mapping system attributes for type {}", entity.getTypeName()); + } + + entity.setGuid(GraphHelper.getGuid(entityVertex)); + entity.setTypeName(GraphHelper.getSingleValuedProperty(entityVertex, Constants.ENTITY_TYPE_PROPERTY_KEY, String.class)); + entity.setStatus(GraphHelper.getStatus(entityVertex)); + entity.setVersion(GraphHelper.getVersion(entityVertex).longValue()); + + entity.setCreatedBy(GraphHelper.getCreatedByAsString(entityVertex)); + entity.setUpdatedBy(GraphHelper.getModifiedByAsString(entityVertex)); + + entity.setCreateTime(new Date(GraphHelper.getCreatedTime(entityVertex))); + entity.setUpdateTime(new Date(GraphHelper.getModifiedTime(entityVertex))); + + return entity; + } + + private void mapAttributes(AtlasVertex entityVertex, AtlasStruct struct, AtlasEntityExtInfo entityExtInfo) throws AtlasBaseException { + AtlasType objType = typeRegistry.getType(struct.getTypeName()); + + if (!(objType instanceof AtlasStructType)) { + throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, struct.getTypeName()); + } + + AtlasStructType structType = (AtlasStructType) objType; + Collection<AtlasAttribute> attributes = structType.getAllAttributes().values(); + + if (CollectionUtils.isNotEmpty(attributes)) { + for (AtlasAttribute attribute : attributes) { + Object attrValue = mapVertexToAttribute(entityVertex, attribute, entityExtInfo); + + struct.setAttribute(attribute.getName(), attrValue); + } + } + } + + private void mapClassifications(AtlasVertex entityVertex, AtlasEntity entity, AtlasEntityExtInfo entityExtInfo) throws AtlasBaseException { + List<String> classficationNames = GraphHelper.getTraitNames(entityVertex); + + if (CollectionUtils.isNotEmpty(classficationNames)) { + List<AtlasClassification> classifications = new ArrayList<>(); + + for (String classficationName : classficationNames) { + if (LOG.isDebugEnabled()) { + LOG.debug("mapping classification {} to atlas entity", classficationName); + } + + Iterable<AtlasEdge> edges = entityVertex.getEdges(AtlasEdgeDirection.OUT, classficationName); + + AtlasEdge edge = (edges != null && edges.iterator().hasNext()) ? edges.iterator().next() : null; + + if (edge != null) { + AtlasClassification classification = new AtlasClassification(classficationName); + + mapAttributes(edge.getInVertex(), classification, entityExtInfo); + + classifications.add(classification); + } + } + + entity.setClassifications(classifications); + } + } + + private Object mapVertexToAttribute(AtlasVertex entityVertex, AtlasAttribute attribute, AtlasEntityExtInfo entityExtInfo) throws AtlasBaseException { + Object ret = null; + AtlasType attrType = attribute.getAttributeType(); + String vertexPropertyName = attribute.getQualifiedName(); + String edgeLabel = EDGE_LABEL_PREFIX + vertexPropertyName; + boolean isOwnedAttribute = attribute.isOwnedRef(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Mapping vertex {} to atlas entity {}.{}", entityVertex, attribute.getDefinedInDef().getName(), attribute.getName()); + } + + switch (attrType.getTypeCategory()) { + case PRIMITIVE: + ret = mapVertexToPrimitive(entityVertex, vertexPropertyName, attribute.getAttributeDef()); + break; + case ENUM: + ret = GraphHelper.getProperty(entityVertex, vertexPropertyName); + break; + case STRUCT: + ret = mapVertexToStruct(entityVertex, edgeLabel, null, entityExtInfo); + break; + case ENTITY: + ret = mapVertexToObjectId(entityVertex, edgeLabel, null, entityExtInfo, isOwnedAttribute); + break; + case ARRAY: + ret = mapVertexToArray(entityVertex, (AtlasArrayType) attrType, vertexPropertyName, entityExtInfo, isOwnedAttribute); + break; + case MAP: + ret = mapVertexToMap(entityVertex, (AtlasMapType) attrType, vertexPropertyName, entityExtInfo, isOwnedAttribute); + break; + case CLASSIFICATION: + // do nothing + break; + } + + return ret; + } + + private Map<String, Object> mapVertexToMap(AtlasVertex entityVertex, AtlasMapType atlasMapType, final String propertyName, + AtlasEntityExtInfo entityExtInfo, boolean isOwnedAttribute) throws AtlasBaseException { + Map<String, Object> ret = new HashMap<>(); + List<String> mapKeys = GraphHelper.getListProperty(entityVertex, propertyName); + AtlasType mapValueType = atlasMapType.getValueType(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Mapping map attribute {} for vertex {}", atlasMapType.getTypeName(), entityVertex); + } + + if (CollectionUtils.isEmpty(mapKeys)) { + return null; + } + + for (String mapKey : mapKeys) { + final String keyPropertyName = propertyName + "." + mapKey; + final String edgeLabel = EDGE_LABEL_PREFIX + keyPropertyName; + final Object keyValue = GraphHelper.getMapValueProperty(mapValueType, entityVertex, keyPropertyName); + + Object mapValue = mapVertexToCollectionEntry(entityVertex, mapValueType, keyValue, edgeLabel, entityExtInfo, isOwnedAttribute); + if (mapValue != null) { + ret.put(mapKey, mapValue); + } + } + + return ret; + } + + private List<Object> mapVertexToArray(AtlasVertex entityVertex, AtlasArrayType arrayType, String propertyName, + AtlasEntityExtInfo entityExtInfo, boolean isOwnedAttribute) throws AtlasBaseException { + AtlasType arrayElementType = arrayType.getElementType(); + List<Object> arrayElements = GraphHelper.getArrayElementsProperty(arrayElementType, entityVertex, propertyName); + List arrValues = new ArrayList(); + String edgeLabel = EDGE_LABEL_PREFIX + propertyName; + + if (LOG.isDebugEnabled()) { + LOG.debug("Mapping array attribute {} for vertex {}", arrayElementType.getTypeName(), entityVertex); + } + + if (CollectionUtils.isEmpty(arrayElements)) { + return null; + } + + for (Object element : arrayElements) { + Object arrValue = mapVertexToCollectionEntry(entityVertex, arrayElementType, element, + edgeLabel, entityExtInfo, isOwnedAttribute); + + arrValues.add(arrValue); + } + + return arrValues; + } + + private Object mapVertexToCollectionEntry(AtlasVertex entityVertex, AtlasType arrayElement, Object value, String edgeLabel, + AtlasEntityExtInfo entityExtInfo, boolean isOwnedAttribute) throws AtlasBaseException { + Object ret = null; + + switch (arrayElement.getTypeCategory()) { + case PRIMITIVE: + case ENUM: + ret = value; + break; + + case ARRAY: + case MAP: + case CLASSIFICATION: + break; + + case STRUCT: + ret = mapVertexToStruct(entityVertex, edgeLabel, (AtlasEdge) value, entityExtInfo); + break; + + case ENTITY: + ret = mapVertexToObjectId(entityVertex, edgeLabel, (AtlasEdge) value, entityExtInfo, isOwnedAttribute); + break; + + default: + break; + } + + return ret; + } + + private Object mapVertexToPrimitive(AtlasVertex entityVertex, final String vertexPropertyName, AtlasAttributeDef attrDef) { + Object ret = null; + + if (GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Object.class) == null) { + return null; + } + + switch (attrDef.getTypeName().toLowerCase()) { + case ATLAS_TYPE_STRING: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, String.class); + break; + case ATLAS_TYPE_SHORT: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Short.class); + break; + case ATLAS_TYPE_INT: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Integer.class); + break; + case ATLAS_TYPE_BIGINTEGER: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, BigInteger.class); + break; + case ATLAS_TYPE_BOOLEAN: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Boolean.class); + break; + case ATLAS_TYPE_BYTE: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Byte.class); + break; + case ATLAS_TYPE_LONG: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Long.class); + break; + case ATLAS_TYPE_FLOAT: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Float.class); + break; + case ATLAS_TYPE_DOUBLE: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Double.class); + break; + case ATLAS_TYPE_BIGDECIMAL: + ret = GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, BigDecimal.class); + break; + case ATLAS_TYPE_DATE: + ret = new Date(GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Long.class)); + break; + default: + break; + } + + return ret; + } + + private AtlasObjectId mapVertexToObjectId(AtlasVertex entityVertex, final String edgeLabel, final AtlasEdge optionalEdge, + AtlasEntityExtInfo entityExtInfo, boolean isOwnedAttribute) throws AtlasBaseException { + AtlasObjectId ret = new AtlasObjectId(); + AtlasEdge edge; + + if (optionalEdge == null) { + edge = graphHelper.getEdgeForLabel(entityVertex, edgeLabel); + } else { + edge = optionalEdge; + } + + if (GraphHelper.elementExists(edge)) { + final AtlasVertex referenceVertex = edge.getInVertex(); + final String guid = GraphHelper.getSingleValuedProperty(referenceVertex, Constants.GUID_PROPERTY_KEY, String.class); + final String typeName = GraphHelper.getTypeName(referenceVertex); + + if (entityExtInfo != null && isOwnedAttribute) { + mapVertexToAtlasEntity(guid, entityExtInfo); + } + + ret = new AtlasObjectId(typeName, guid); + } + + return ret; + } + + private AtlasStruct mapVertexToStruct(AtlasVertex entityVertex, final String edgeLabel, final AtlasEdge optionalEdge, + AtlasEntityExtInfo entityExtInfo) throws AtlasBaseException { + AtlasStruct ret = null; + AtlasEdge edge; + + if (optionalEdge == null) { + edge = graphHelper.getEdgeForLabel(entityVertex, edgeLabel); + } else { + edge = optionalEdge; + } + + if (GraphHelper.elementExists(edge)) { + final AtlasVertex referenceVertex = edge.getInVertex(); + ret = new AtlasStruct(GraphHelper.getSingleValuedProperty(referenceVertex, Constants.ENTITY_TYPE_PROPERTY_KEY, String.class)); + + mapAttributes(referenceVertex, ret, entityExtInfo); + } + + return ret; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java index 6cbb602..197e46a 100644 --- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java +++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasEntityStoreV1Test.java @@ -35,8 +35,6 @@ import org.apache.atlas.model.typedef.AtlasTypesDef; import org.apache.atlas.repository.graph.AtlasGraphProvider; import org.apache.atlas.repository.graph.GraphBackedSearchIndexer; import org.apache.atlas.repository.store.graph.AtlasEntityStore; -import org.apache.atlas.repository.store.graph.EntityGraphDiscovery; -import org.apache.atlas.repository.store.graph.EntityResolver; import org.apache.atlas.services.MetadataService; import org.apache.atlas.store.AtlasTypeDefStore; import org.apache.atlas.type.AtlasArrayType; @@ -135,7 +133,7 @@ public class AtlasEntityStoreV1Test { MapVertexMapper mapVertexMapper = new MapVertexMapper(deleteHandler); - entityStore = new AtlasEntityStoreV1(new EntityGraphMapper(arrVertexMapper, mapVertexMapper, deleteHandler)); + entityStore = new AtlasEntityStoreV1(new EntityGraphMapper(arrVertexMapper, mapVertexMapper, deleteHandler), new GraphEntityMapper()); entityStore.init(typeRegistry); RequestContextV1.clear(); http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/808eb1d1/server-api/src/main/java/org/apache/atlas/services/MetadataService.java ---------------------------------------------------------------------- diff --git a/server-api/src/main/java/org/apache/atlas/services/MetadataService.java b/server-api/src/main/java/org/apache/atlas/services/MetadataService.java index 9b2bc9e..e0fb66c 100644 --- a/server-api/src/main/java/org/apache/atlas/services/MetadataService.java +++ b/server-api/src/main/java/org/apache/atlas/services/MetadataService.java @@ -29,7 +29,6 @@ import org.apache.atlas.typesystem.Referenceable; import org.apache.atlas.typesystem.Struct; import org.apache.atlas.typesystem.IStruct; import org.apache.atlas.typesystem.types.cache.TypeCache; -import org.apache.atlas.utils.ParamChecker; import org.codehaus.jettison.json.JSONObject; import java.util.List; @@ -49,7 +48,7 @@ public interface MetadataService { */ JSONObject createType(String typeDefinition) throws AtlasException; - /** + /**z * Updates the given types in the type definition * @param typeDefinition * @return
