Repository: atlas Updated Branches: refs/heads/master e0bd96b73 -> 87a421ac1
ATLAS-1999: Use AtlasRelatedObjectId to display relationshipAttribute values during entity retrieval Project: http://git-wip-us.apache.org/repos/asf/atlas/repo Commit: http://git-wip-us.apache.org/repos/asf/atlas/commit/87a421ac Tree: http://git-wip-us.apache.org/repos/asf/atlas/tree/87a421ac Diff: http://git-wip-us.apache.org/repos/asf/atlas/diff/87a421ac Branch: refs/heads/master Commit: 87a421ac1d659c9111b8743df26f57e97cb640b3 Parents: e0bd96b Author: Sarath Subramanian <ssubraman...@hortonworks.com> Authored: Tue Aug 8 12:07:36 2017 -0700 Committer: Sarath Subramanian <ssubraman...@hortonworks.com> Committed: Tue Aug 8 12:07:36 2017 -0700 ---------------------------------------------------------------------- .../model/instance/AtlasRelatedObjectId.java | 119 ++++++++++++ .../org/apache/atlas/type/AtlasEntityType.java | 186 ++++++++++++++++++- .../org/apache/atlas/type/AtlasTypeUtil.java | 8 + .../atlas/repository/graph/GraphHelper.java | 13 +- .../graph/v1/AtlasRelationshipStoreV1.java | 74 +------- .../store/graph/v1/EntityGraphRetriever.java | 107 ++++++++++- .../graph/v1/AtlasRelationshipStoreV1Test.java | 30 ++- 7 files changed, 441 insertions(+), 96 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java new file mode 100644 index 0000000..bfea678 --- /dev/null +++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelatedObjectId.java @@ -0,0 +1,119 @@ +/** + * 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.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 java.io.Serializable; +import java.util.HashMap; +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; + +/** + * Reference to an object-instance of AtlasEntity type used in relationship attribute values + */ +@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE) +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown=true) +@XmlRootElement +@XmlAccessorType(XmlAccessType.PROPERTY) +public class AtlasRelatedObjectId extends AtlasObjectId implements Serializable { + private static final long serialVersionUID = 1L; + + public static final String KEY_RELATIONSHIP_GUID = "relationshipGuid"; + public static final String KEY_RELATIONSHIP_ATTRIBUTES = "relationshipAttributes"; + + private String displayText = null; + private String relationshipGuid = null; + private AtlasStruct relationshipAttributes; + + public AtlasRelatedObjectId() { } + + public AtlasRelatedObjectId(String guid, String typeName, String relationshipGuid, AtlasStruct relationshipAttributes) { + super(guid, typeName); + + setRelationshipGuid(relationshipGuid); + setRelationshipAttributes(relationshipAttributes); + } + + public AtlasRelatedObjectId(String guid, String typeName, Map<String, Object> uniqueAttributes, String displayText, + String relationshipGuid, AtlasStruct relationshipAttributes) { + super(guid, typeName, uniqueAttributes); + + setRelationshipGuid(relationshipGuid); + setDisplayText(displayText); + setRelationshipAttributes(relationshipAttributes); + } + + public String getDisplayText() { return displayText; } + + public void setDisplayText(String displayText) { this.displayText = displayText; } + + public String getRelationshipGuid() { return relationshipGuid; } + + public void setRelationshipGuid(String relationshipGuid) { this.relationshipGuid = relationshipGuid; } + + public AtlasStruct getRelationshipAttributes() { return relationshipAttributes; } + + public void setRelationshipAttributes(AtlasStruct relationshipAttributes) { this.relationshipAttributes = relationshipAttributes; } + + @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; } + AtlasRelatedObjectId that = (AtlasRelatedObjectId) o; + return Objects.equals(displayText, that.displayText) && + Objects.equals(relationshipGuid, that.relationshipGuid) && + Objects.equals(relationshipAttributes, that.relationshipAttributes); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), displayText, relationshipGuid, relationshipAttributes); + } + + @Override + public String toString() { + return toString(new StringBuilder()).toString(); + } + + @Override + public StringBuilder toString(StringBuilder sb) { + if (sb == null) { + sb = new StringBuilder(); + } + + sb.append("AtlasRelatedObjectId{"); + super.toString(sb); + sb.append("displayText='").append(displayText).append('\''); + sb.append(", relationshipGuid='").append(relationshipGuid).append('\''); + sb.append(", relationshipAttributes=").append(relationshipAttributes); + sb.append('}'); + + return sb; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/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 f89c556..9dad95d 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java @@ -22,6 +22,7 @@ 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.model.instance.AtlasStruct; import org.apache.atlas.model.typedef.AtlasEntityDef; import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef; import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType; @@ -266,7 +267,8 @@ public class AtlasEntityType extends AtlasStructType { return false; } } - return super.isValidValue(obj); + + return super.isValidValue(obj) && validateRelationshipAttributes(obj); } return true; @@ -339,8 +341,7 @@ public class AtlasEntityType extends AtlasStructType { ret = superType.validateValue(obj, objName, messages) && ret; } - ret = super.validateValue(obj, objName, messages) && ret; - + ret = super.validateValue(obj, objName, messages) && validateRelationshipAttributes(obj, objName, messages) && ret; } else { ret = false; messages.add(objName + ": invalid value type '" + obj.getClass().getName()); @@ -388,7 +389,7 @@ public class AtlasEntityType extends AtlasStructType { superType.normalizeAttributeValues(ent); } - super.normalizeAttributeValues(ent); + normalizeValues(ent); } } @@ -409,7 +410,7 @@ public class AtlasEntityType extends AtlasStructType { superType.normalizeAttributeValues(obj); } - super.normalizeAttributeValues(obj); + normalizeValues(obj); } } @@ -446,10 +447,13 @@ public class AtlasEntityType extends AtlasStructType { collectTypeHierarchyInfo(typeRegistry, allSuperTypeNames, allAttributes, visitedTypes); } + + /* * This method should not assume that resolveReferences() has been called on all superTypes. * this.entityDef is the only safe member to reference here */ + private void collectTypeHierarchyInfo(AtlasTypeRegistry typeRegistry, Set<String> allSuperTypeNames, Map<String, AtlasAttribute> allAttributes, @@ -480,10 +484,178 @@ public class AtlasEntityType extends AtlasStructType { } } } - boolean isAssignableFrom(AtlasObjectId objId) { boolean ret = AtlasTypeUtil.isValid(objId) && (StringUtils.equals(objId.getTypeName(), getTypeName()) || isSuperTypeOf(objId.getTypeName())); return ret; } -} + + private boolean validateRelationshipAttributes(Object obj) { + if (obj != null && MapUtils.isNotEmpty(relationshipAttributes)) { + if (obj instanceof AtlasEntity) { + AtlasEntity entityObj = (AtlasEntity) obj; + + for (AtlasAttribute attribute : relationshipAttributes.values()) { + Object attributeValue = entityObj.getRelationshipAttribute(attribute.getName()); + AtlasAttributeDef attributeDef = attribute.getAttributeDef(); + + if (!isAssignableValue(attributeValue, attributeDef)) { + return false; + } + } + } else if (obj instanceof Map) { + Map map = AtlasTypeUtil.toRelationshipAttributes((Map) obj); + + for (AtlasAttribute attribute : relationshipAttributes.values()) { + Object attributeValue = map.get(attribute.getName()); + AtlasAttributeDef attributeDef = attribute.getAttributeDef(); + + if (!isAssignableValue(attributeValue, attributeDef)) { + return false; + } + } + } else { + return false; + } + } + + return true; + } + + private boolean isAssignableValue(Object value, AtlasAttributeDef attributeDef) { + boolean ret = true; + + if (value != null) { + AtlasAttribute attribute = relationshipAttributes.get(attributeDef.getName()); + + if (attribute != null) { + AtlasType attrType = attribute.getAttributeType(); + + if (!isValidRelationshipType(attrType) && !attrType.isValidValue(value)) { + ret = false; + } + } + } + + return ret; + } + private boolean isValidRelationshipType(AtlasType attributeType) { + boolean ret = false; + + if (attributeType != null) { + if (attributeType instanceof AtlasArrayType) { + attributeType = ((AtlasArrayType) attributeType).getElementType(); + } + + if (attributeType instanceof AtlasObjectIdType || attributeType instanceof AtlasEntityType) { + ret = true; + } + } + + return ret; + } + + private void normalizeRelationshipAttributeValues(AtlasStruct obj) { + if (obj != null && obj instanceof AtlasEntity) { + AtlasEntity entityObj = (AtlasEntity) obj; + + for (AtlasAttribute attribute : relationshipAttributes.values()) { + String attributeName = attribute.getName(); + AtlasAttributeDef attributeDef = attribute.getAttributeDef(); + + if (((AtlasEntity) obj).hasRelationshipAttribute(attributeName)) { + Object attributeValue = getNormalizedValue(entityObj.getAttribute(attributeName), attributeDef); + + obj.setAttribute(attributeName, attributeValue); + } + } + } + } + + public void normalizeRelationshipAttributeValues(Map<String, Object> obj) { + if (obj != null) { + for (AtlasAttribute attribute : relationshipAttributes.values()) { + String attributeName = attribute.getName(); + AtlasAttributeDef attributeDef = attribute.getAttributeDef(); + + if (obj.containsKey(attributeName)) { + Object attributeValue = getNormalizedValue(obj.get(attributeName), attributeDef); + + obj.put(attributeName, attributeValue); + } + } + } + } + + private Object getNormalizedValue(Object value, AtlasAttributeDef attributeDef) { + AtlasAttribute attribute = relationshipAttributes.get(attributeDef.getName()); + + if (attribute != null) { + AtlasType attrType = attribute.getAttributeType(); + + if (isValidRelationshipType(attrType) && value != null) { + return attrType.getNormalizedValue(value); + } + } + + return null; + } + + private void normalizeValues(AtlasEntity ent) { + super.normalizeAttributeValues(ent); + + normalizeRelationshipAttributeValues(ent); + } + + private void normalizeValues(Map<String, Object> obj) { + super.normalizeAttributeValues(obj); + + normalizeRelationshipAttributeValues(obj); + } + + private boolean validateRelationshipAttributes(Object obj, String objName, List<String> messages) { + boolean ret = true; + + if (obj != null && MapUtils.isNotEmpty(relationshipAttributes)) { + if (obj instanceof AtlasEntity) { + AtlasEntity entityObj = (AtlasEntity) obj; + + for (AtlasAttribute attribute : relationshipAttributes.values()) { + String attributeName = attribute.getName(); + + if (attribute != null) { + AtlasType dataType = attribute.getAttributeType(); + Object value = entityObj.getAttribute(attributeName); + String fieldName = objName + "." + attributeName; + + if (isValidRelationshipType(dataType) && value != null) { + ret = dataType.validateValue(value, fieldName, messages) && ret; + } + } + + } + } else if (obj instanceof Map) { + Map attributes = AtlasTypeUtil.toStructAttributes((Map)obj); + + for (AtlasAttribute attribute : relationshipAttributes.values()) { + String attributeName = attribute.getName(); + + if (attribute != null) { + AtlasType dataType = attribute.getAttributeType(); + Object value = attributes.get(attributeName); + String fieldName = objName + "." + attributeName; + + if (isValidRelationshipType(dataType) && value != null) { + ret = dataType.validateValue(value, fieldName, messages) && ret; + } + } + } + } else { + ret = false; + messages.add(objName + "=" + obj + ": invalid value for type " + getTypeName()); + } + } + + return ret; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java ---------------------------------------------------------------------- diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java index 3f39541..427439c 100644 --- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java +++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java @@ -315,6 +315,14 @@ public class AtlasTypeUtil { return map; } + public static Map toRelationshipAttributes(Map map) { + if (map != null && map.containsKey("typeName") && map.containsKey("relationshipAttributes") && map.get("relationshipAttributes") instanceof Map) { + return (Map)map.get("relationshipAttributes"); + } + + return map; + } + public static AtlasObjectId getAtlasObjectId(AtlasEntity entity) { return new AtlasObjectId(entity.getGuid(), entity.getTypeName()); } http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/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 c47a89e..1ec5a72 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 @@ -22,6 +22,7 @@ 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.AtlasErrorCode; import org.apache.atlas.AtlasException; import org.apache.atlas.RequestContext; import org.apache.atlas.exception.AtlasBaseException; @@ -595,8 +596,16 @@ public final class GraphHelper { return findVertex(Constants.GUID_PROPERTY_KEY, guid); } - public AtlasEdge getEdgeForGUID(String guid) throws EntityNotFoundException { - return findEdge(Constants.GUID_PROPERTY_KEY, guid); + public AtlasEdge getEdgeForGUID(String guid) throws AtlasBaseException { + AtlasEdge ret = null; + + try { + ret = findEdge(Constants.GUID_PROPERTY_KEY, guid); + } catch (EntityNotFoundException e) { + new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid); + } + + return ret; } /** http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java index 49e08a0..278585d 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java @@ -116,13 +116,9 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { AtlasRelationship ret; - try { - AtlasEdge edge = graphHelper.getEdgeForGUID(guid); + AtlasEdge edge = graphHelper.getEdgeForGUID(guid); - ret = mapEdgeToAtlasRelationship(edge); - } catch (EntityNotFoundException ex) { - throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid); - } + ret = entityRetriever.mapEdgeToAtlasRelationship(edge); if (LOG.isDebugEnabled()) { LOG.debug("<== getById({}): {}", guid, ret); @@ -160,7 +156,7 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { AtlasEdge relationshipEdge = getRelationshipEdge(end1Vertex, end2Vertex, relationship); if (relationshipEdge != null) { - ret = mapEdgeToAtlasRelationship(relationshipEdge); + ret = entityRetriever.mapEdgeToAtlasRelationship(relationshipEdge); } else { validateRelationship(relationship); @@ -196,7 +192,7 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { } } - ret = mapEdgeToAtlasRelationship(relationshipEdge); + ret = entityRetriever.mapEdgeToAtlasRelationship(relationshipEdge); } else { throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_EXISTS, relationship.getTypeName(), @@ -379,68 +375,6 @@ public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore { return (entityType != null) ? entityType.getTypeAndAllSuperTypes() : new HashSet<String>(); } - private AtlasRelationship mapEdgeToAtlasRelationship(AtlasEdge edge) throws AtlasBaseException { - AtlasRelationship ret = new AtlasRelationship(); - - mapSystemAttributes(edge, ret); - - mapAttributes(edge, ret); - - return ret; - } - - private AtlasRelationship mapSystemAttributes(AtlasEdge edge, AtlasRelationship relationship) { - if (LOG.isDebugEnabled()) { - LOG.debug("Mapping system attributes for relationship"); - } - - relationship.setGuid(GraphHelper.getGuid(edge)); - relationship.setTypeName(GraphHelper.getTypeName(edge)); - - relationship.setCreatedBy(GraphHelper.getCreatedByAsString(edge)); - relationship.setUpdatedBy(GraphHelper.getModifiedByAsString(edge)); - - relationship.setCreateTime(new Date(GraphHelper.getCreatedTime(edge))); - relationship.setUpdateTime(new Date(GraphHelper.getModifiedTime(edge))); - - Integer version = GraphHelper.getVersion(edge); - - if (version == null) { - version = Integer.valueOf(1); - } - - relationship.setVersion(version.longValue()); - relationship.setStatus(GraphHelper.getEdgeStatus(edge)); - - AtlasVertex end1Vertex = edge.getOutVertex(); - AtlasVertex end2Vertex = edge.getInVertex(); - - relationship.setEnd1(new AtlasObjectId(GraphHelper.getGuid(end1Vertex), GraphHelper.getTypeName(end1Vertex))); - relationship.setEnd2(new AtlasObjectId(GraphHelper.getGuid(end2Vertex), GraphHelper.getTypeName(end2Vertex))); - - relationship.setLabel(edge.getLabel()); - - return relationship; - } - - private void mapAttributes(AtlasEdge edge, AtlasRelationship relationship) throws AtlasBaseException { - AtlasType objType = typeRegistry.getType(relationship.getTypeName()); - - if (!(objType instanceof AtlasRelationshipType)) { - throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, relationship.getTypeName()); - } - - AtlasRelationshipType relationshipType = (AtlasRelationshipType) objType; - - for (AtlasAttribute attribute : relationshipType.getAllAttributes().values()) { - // mapping only primitive attributes - Object attrValue = entityRetriever.mapVertexToPrimitive(edge, attribute.getQualifiedName(), - attribute.getAttributeDef()); - - relationship.setAttribute(attribute.getName(), attrValue); - } - } - private String getTypeNameFromObjectId(AtlasObjectId objectId) { String typeName = objectId.getTypeName(); http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java ---------------------------------------------------------------------- diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java index 31fc837..667c61b 100644 --- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java +++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphRetriever.java @@ -28,6 +28,8 @@ import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityExtInfo; import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo; import org.apache.atlas.model.instance.AtlasEntityHeader; import org.apache.atlas.model.instance.AtlasObjectId; +import org.apache.atlas.model.instance.AtlasRelatedObjectId; +import org.apache.atlas.model.instance.AtlasRelationship; import org.apache.atlas.model.instance.AtlasStruct; import org.apache.atlas.model.typedef.AtlasRelationshipDef; import org.apache.atlas.model.typedef.AtlasRelationshipEndDef; @@ -672,12 +674,12 @@ public final class EntityGraphRetriever { private AtlasObjectId mapRelatedVertexToObjectId(AtlasVertex entityVertex, AtlasAttribute attribute) throws AtlasBaseException { AtlasEdge edge = graphHelper.getEdgeForLabel(entityVertex, attribute.getRelationshipEdgeLabel(), attribute.getRelationshipEdgeDirection()); - return mapRelatedVertexToObjectId(entityVertex, edge); + return mapVertexToRelatedObjectId(entityVertex, edge); } - private List<AtlasObjectId> mapRelationshipArrayAttribute(AtlasVertex entityVertex, AtlasAttribute attribute) throws AtlasBaseException { - List<AtlasObjectId> ret = new ArrayList<>(); - Iterator<AtlasEdge> edges = null; + private List<AtlasRelatedObjectId> mapRelationshipArrayAttribute(AtlasVertex entityVertex, AtlasAttribute attribute) throws AtlasBaseException { + List<AtlasRelatedObjectId> ret = new ArrayList<>(); + Iterator<AtlasEdge> edges = null; if (attribute.getRelationshipEdgeDirection() == AtlasRelationshipEdgeDirection.IN) { edges = graphHelper.getIncomingEdgesByLabel(entityVertex, attribute.getRelationshipEdgeLabel()); @@ -689,17 +691,17 @@ public final class EntityGraphRetriever { while (edges.hasNext()) { AtlasEdge relationshipEdge = edges.next(); - AtlasObjectId objectId = mapRelatedVertexToObjectId(entityVertex, relationshipEdge); + AtlasRelatedObjectId relatedObjectId = mapVertexToRelatedObjectId(entityVertex, relationshipEdge); - ret.add(objectId); + ret.add(relatedObjectId); } } return ret; } - private AtlasObjectId mapRelatedVertexToObjectId(AtlasVertex entityVertex, AtlasEdge edge) throws AtlasBaseException { - AtlasObjectId ret = null; + private AtlasRelatedObjectId mapVertexToRelatedObjectId(AtlasVertex entityVertex, AtlasEdge edge) throws AtlasBaseException { + AtlasRelatedObjectId ret = null; if (GraphHelper.elementExists(edge)) { AtlasVertex referenceVertex = edge.getInVertex(); @@ -709,10 +711,97 @@ public final class EntityGraphRetriever { } if (referenceVertex != null) { - ret = new AtlasObjectId(GraphHelper.getGuid(referenceVertex), GraphHelper.getTypeName(referenceVertex)); + String entityTypeName = GraphHelper.getTypeName(referenceVertex); + String entityGuid = GraphHelper.getGuid(referenceVertex); + AtlasRelationship relationship = mapEdgeToAtlasRelationship(edge); + + ret = new AtlasRelatedObjectId(entityGuid, entityTypeName, relationship.getGuid(), + new AtlasStruct(relationship.getTypeName(), relationship.getAttributes())); + + Object displayText = getDisplayText(referenceVertex, entityTypeName); + + if (displayText != null) { + ret.setDisplayText(displayText.toString()); + } + } + } + + return ret; + } + + private Object getDisplayText(AtlasVertex entityVertex, String entityTypeName) throws AtlasBaseException { + AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName); + Object ret = null; + + if (entityType != null) { + ret = getVertexAttribute(entityVertex, entityType.getAttribute(AtlasClient.NAME)); + + if (ret == null) { + ret = getVertexAttribute(entityVertex, entityType.getAttribute(AtlasClient.QUALIFIED_NAME)); } } return ret; } + + public AtlasRelationship mapEdgeToAtlasRelationship(AtlasEdge edge) throws AtlasBaseException { + AtlasRelationship ret = new AtlasRelationship(); + + mapSystemAttributes(edge, ret); + + mapAttributes(edge, ret); + + return ret; + } + + private AtlasRelationship mapSystemAttributes(AtlasEdge edge, AtlasRelationship relationship) { + if (LOG.isDebugEnabled()) { + LOG.debug("Mapping system attributes for relationship"); + } + + relationship.setGuid(GraphHelper.getGuid(edge)); + relationship.setTypeName(GraphHelper.getTypeName(edge)); + + relationship.setCreatedBy(GraphHelper.getCreatedByAsString(edge)); + relationship.setUpdatedBy(GraphHelper.getModifiedByAsString(edge)); + + relationship.setCreateTime(new Date(GraphHelper.getCreatedTime(edge))); + relationship.setUpdateTime(new Date(GraphHelper.getModifiedTime(edge))); + + Integer version = GraphHelper.getVersion(edge); + + if (version == null) { + version = Integer.valueOf(1); + } + + relationship.setVersion(version.longValue()); + relationship.setStatus(GraphHelper.getEdgeStatus(edge)); + + AtlasVertex end1Vertex = edge.getOutVertex(); + AtlasVertex end2Vertex = edge.getInVertex(); + + relationship.setEnd1(new AtlasObjectId(GraphHelper.getGuid(end1Vertex), GraphHelper.getTypeName(end1Vertex))); + relationship.setEnd2(new AtlasObjectId(GraphHelper.getGuid(end2Vertex), GraphHelper.getTypeName(end2Vertex))); + + relationship.setLabel(edge.getLabel()); + + return relationship; + } + + private void mapAttributes(AtlasEdge edge, AtlasRelationship relationship) throws AtlasBaseException { + AtlasType objType = typeRegistry.getType(relationship.getTypeName()); + + if (!(objType instanceof AtlasRelationshipType)) { + throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_INVALID, relationship.getTypeName()); + } + + AtlasRelationshipType relationshipType = (AtlasRelationshipType) objType; + + for (AtlasAttribute attribute : relationshipType.getAllAttributes().values()) { + // mapping only primitive attributes + Object attrValue = mapVertexToPrimitive(edge, attribute.getQualifiedName(), attribute.getAttributeDef()); + + relationship.setAttribute(attribute.getName(), attrValue); + } + } } http://git-wip-us.apache.org/repos/asf/atlas/blob/87a421ac/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java index 77a591a..a35647d 100644 --- a/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java +++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1Test.java @@ -27,6 +27,7 @@ import org.apache.atlas.model.instance.AtlasEntity.AtlasEntitiesWithExtInfo; import org.apache.atlas.model.instance.AtlasEntity.AtlasEntityWithExtInfo; import org.apache.atlas.model.instance.AtlasEntityHeader; import org.apache.atlas.model.instance.AtlasObjectId; +import org.apache.atlas.model.instance.AtlasRelatedObjectId; import org.apache.atlas.model.instance.EntityMutationResponse; import org.apache.atlas.model.typedef.AtlasTypesDef; import org.apache.atlas.repository.graph.AtlasGraphProvider; @@ -45,6 +46,7 @@ import org.testng.annotations.Guice; import org.testng.annotations.Test; import javax.inject.Inject; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -456,17 +458,29 @@ public abstract class AtlasRelationshipStoreV1Test { assertTrue(collection != null && collection.isEmpty()); } - private static List<AtlasObjectId> toAtlasObjectIds(Object objectIds) { - if (objectIds instanceof List) { - return (List<AtlasObjectId>) objectIds; + private static List<AtlasObjectId> toAtlasObjectIds(Object object) { + List<AtlasObjectId> ret = new ArrayList<>(); + + if (object instanceof List) { + List<?> objectIds = (List) object; + + if (CollectionUtils.isNotEmpty(objectIds)) { + for (Object obj : objectIds) { + if (obj instanceof AtlasRelatedObjectId) { + AtlasRelatedObjectId relatedObjectId = (AtlasRelatedObjectId) obj; + ret.add(new AtlasObjectId(relatedObjectId.getGuid(), relatedObjectId.getTypeName(), relatedObjectId.getUniqueAttributes())); + } + } + } } - return null; + return ret; } - private static AtlasObjectId toAtlasObjectId(Object objectId) { - if (objectId instanceof AtlasObjectId) { - return (AtlasObjectId) objectId; + private static AtlasObjectId toAtlasObjectId(Object object) { + if (object instanceof AtlasRelatedObjectId) { + AtlasRelatedObjectId relatedObjectId = (AtlasRelatedObjectId) object; + return new AtlasObjectId(relatedObjectId.getGuid(), relatedObjectId.getTypeName(), relatedObjectId.getUniqueAttributes()); } return null; @@ -482,7 +496,7 @@ public abstract class AtlasRelationshipStoreV1Test { Object refValue = entity.getRelationshipAttribute(relationshipAttrName); assertTrue(refValue instanceof List); - List<AtlasObjectId> refList = (List<AtlasObjectId>) refValue; + List<AtlasObjectId> refList = toAtlasObjectIds(refValue); assertEquals(refList.size(), expectedValues.size()); if (expectedValues.size() > 0) {