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) {

Reply via email to