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

[01/14] incubator-atlas git commit: ATLAS-1826 : UI Create Entity : Type doesn't list the inverseRef constrained attribute options when name length is less than 3 (qinglin, xia via kbhatt).

Repository: incubator-atlas
Updated Branches:
  refs/heads/feature-odf f5e0d528b -> 242b5585c


ATLAS-1826 : UI Create Entity : Type doesn't list the inverseRef constrained attribute options when name length is less than 3 (qinglin,xia via kbhatt).


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

Branch: refs/heads/feature-odf
Commit: edd4aa9ad8f4a27ece75fe0d110b6b740ccd2005
Parents: f5e0d52
Author: kevalbhatt <kb...@apache.org>
Authored: Wed Jun 7 11:30:16 2017 +0530
Committer: kevalbhatt <kb...@apache.org>
Committed: Wed Jun 7 11:39:48 2017 +0530

----------------------------------------------------------------------
 dashboardv2/public/js/views/entity/CreateEntityLayoutView.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/edd4aa9a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
index d31a122..704062f 100644
--- a/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
+++ b/dashboardv2/public/js/views/entity/CreateEntityLayoutView.js
@@ -719,7 +719,7 @@ define(['require',
                                 return markup;
                             },
                             data: select2Options,
-                            minimumInputLength: 3
+                            minimumInputLength: 1
                         });
                     }
                     $this.select2(select2Option);


[06/14] incubator-atlas git commit: ATLAS-1872: Spring fix for Kerberos and bean ordering/default

Posted by ma...@apache.org.
ATLAS-1872: Spring fix for Kerberos and bean ordering/default


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

Branch: refs/heads/feature-odf
Commit: 82b6f727ca272b1e86625bfaa89bb5d638a0805c
Parents: 6b9399e
Author: apoorvnaik <ap...@apache.org>
Authored: Mon Jun 12 11:06:21 2017 -0700
Committer: apoorvnaik <ap...@apache.org>
Committed: Mon Jun 12 16:26:44 2017 -0700

----------------------------------------------------------------------
 .../audit/HBaseBasedAuditRepository.java        |  2 +-
 .../audit/NoopEntityAuditRepository.java        |  2 +-
 .../atlas/web/listeners/LoginProcessor.java     |  4 ---
 .../atlas/web/setup/KerberosAwareListener.java  | 33 ++++++++++++++++++++
 webapp/src/main/webapp/WEB-INF/web.xml          |  2 +-
 5 files changed, 36 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/82b6f727/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java
index 89ca748..06e518e 100644
--- a/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java
+++ b/repository/src/main/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepository.java
@@ -73,7 +73,7 @@ import java.util.Map;
  */
 @Singleton
 @Component
-@ConditionalOnAtlasProperty(property = "atlas.EntityAuditRepository.impl")
+@ConditionalOnAtlasProperty(property = "atlas.EntityAuditRepository.impl", isDefault = true)
 public class HBaseBasedAuditRepository implements Service, EntityAuditRepository, ActiveStateChangeHandler {
     private static final Logger LOG = LoggerFactory.getLogger(HBaseBasedAuditRepository.class);
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/82b6f727/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java b/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java
index 7c39ce9..c382601 100644
--- a/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java
+++ b/repository/src/main/java/org/apache/atlas/repository/audit/NoopEntityAuditRepository.java
@@ -32,7 +32,7 @@ import java.util.List;
  */
 @Singleton
 @Component
-@ConditionalOnAtlasProperty(property = "atlas.EntityAuditRepository.impl", isDefault = true)
+@ConditionalOnAtlasProperty(property = "atlas.EntityAuditRepository.impl")
 public class NoopEntityAuditRepository implements EntityAuditRepository {
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/82b6f727/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java b/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java
index e21656e..cc2ef8a 100644
--- a/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java
+++ b/webapp/src/main/java/org/apache/atlas/web/listeners/LoginProcessor.java
@@ -26,9 +26,7 @@ import org.apache.hadoop.security.UserGroupInformation;
 import org.apache.hadoop.util.Shell;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Component;
 
-import javax.annotation.PostConstruct;
 import java.io.IOException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
@@ -36,7 +34,6 @@ import java.net.UnknownHostException;
 /**
  * A class capable of performing a simple or kerberos login.
  */
-@Component
 public class LoginProcessor {
 
     private static final Logger LOG = LoggerFactory.getLogger(LoginProcessor.class);
@@ -49,7 +46,6 @@ public class LoginProcessor {
      * Perform a SIMPLE login based on established OS identity or a kerberos based login using the configured
      * principal and keytab (via atlas-application.properties).
      */
-    @PostConstruct
     public void login() {
         // first, let's see if we're running in a hadoop cluster and have the env configured
         boolean isHadoopCluster = isHadoopCluster();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/82b6f727/webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java b/webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java
new file mode 100644
index 0000000..47373b8
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/setup/KerberosAwareListener.java
@@ -0,0 +1,33 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.web.setup;
+
+import org.apache.atlas.web.listeners.LoginProcessor;
+import org.springframework.web.context.ContextLoaderListener;
+
+import javax.servlet.ServletContextEvent;
+
+public class KerberosAwareListener extends ContextLoaderListener {
+    @Override
+    public void contextInitialized(ServletContextEvent event) {
+        LoginProcessor loginProcessor = new LoginProcessor();
+        loginProcessor.login();
+
+        super.contextInitialized(event);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/82b6f727/webapp/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/webapp/src/main/webapp/WEB-INF/web.xml b/webapp/src/main/webapp/WEB-INF/web.xml
index d2d08f5..9b5c3b1 100755
--- a/webapp/src/main/webapp/WEB-INF/web.xml
+++ b/webapp/src/main/webapp/WEB-INF/web.xml
@@ -70,7 +70,7 @@
     </listener>
 
     <listener>
-        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
+        <listener-class>org.apache.atlas.web.setup.KerberosAwareListener</listener-class>
     </listener>
 
 


[03/14] incubator-atlas git commit: ATLAS-1804: Testcase fix for PAM authentication

Posted by ma...@apache.org.
ATLAS-1804: Testcase fix for PAM authentication


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

Branch: refs/heads/feature-odf
Commit: e0072e5ff293adee07554174b0318f0b70027072
Parents: aa6d87e
Author: nixonrodrigues <ni...@apache.org>
Authored: Thu Jun 8 20:58:16 2017 +0530
Committer: nixonrodrigues <ni...@apache.org>
Committed: Fri Jun 9 00:47:22 2017 +0530

----------------------------------------------------------------------
 webapp/src/test/resources/test-spring-security.xml | 2 ++
 1 file changed, 2 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/e0072e5f/webapp/src/test/resources/test-spring-security.xml
----------------------------------------------------------------------
diff --git a/webapp/src/test/resources/test-spring-security.xml b/webapp/src/test/resources/test-spring-security.xml
index 0ef15d7..4455b0a 100644
--- a/webapp/src/test/resources/test-spring-security.xml
+++ b/webapp/src/test/resources/test-spring-security.xml
@@ -62,10 +62,12 @@
         <beans:constructor-arg ref="userDetailsService"/>
     </beans:bean>
     <beans:bean id="atlasADProvider" class="org.apache.atlas.web.security.AtlasADAuthenticationProvider"/>
+    <beans:bean id="atlasPamProvider" class="org.apache.atlas.web.security.AtlasPamAuthenticationProvider"/>
     <beans:bean id="atlasAuthenticationProvider" class="org.apache.atlas.web.security.AtlasAuthenticationProvider">
         <beans:constructor-arg index="0" ref="atlasLDAPProvider"/>
         <beans:constructor-arg index="1" ref="atlasFileProvider"/>
         <beans:constructor-arg index="2" ref="atlasADProvider"/>
+        <beans:constructor-arg index="3" ref="atlasPamProvider"/>
     </beans:bean>
 
     <beans:bean id="krbAuthenticationFilter" class="org.apache.atlas.web.filters.AtlasAuthenticationFilter">


[09/14] incubator-atlas git commit: ATLAS-1873: renamed AtlasRelationshipEndPoint to AtlasRelationshipEnd

Posted by ma...@apache.org.
ATLAS-1873: renamed AtlasRelationshipEndPoint to AtlasRelationshipEnd

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


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

Branch: refs/heads/feature-odf
Commit: 1de6016df57c13100e18f7278c560fb3f4e50500
Parents: c2c05d6
Author: David Radley <da...@uk.ibm.com>
Authored: Wed Jun 14 22:08:55 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Wed Jun 14 22:29:05 2017 -0700

----------------------------------------------------------------------
 .../org/apache/atlas/repository/Constants.java  |   4 +-
 .../java/org/apache/atlas/AtlasErrorCode.java   |  14 +-
 .../model/typedef/AtlasRelationshipDef.java     |  91 ++++-----
 .../model/typedef/AtlasRelationshipEndDef.java  | 193 +++++++++++++++++++
 .../typedef/AtlasRelationshipEndPointDef.java   | 193 -------------------
 .../atlas/type/AtlasRelationshipType.java       |  42 ++--
 .../model/typedef/TestAtlasRelationshipDef.java |  12 +-
 .../atlas/type/TestAtlasRelationshipType.java   |  20 +-
 .../graph/v1/AtlasRelationshipDefStoreV1.java   |  24 +--
 9 files changed, 297 insertions(+), 296 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/common/src/main/java/org/apache/atlas/repository/Constants.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java
index b07934b..ac02252 100644
--- a/common/src/main/java/org/apache/atlas/repository/Constants.java
+++ b/common/src/main/java/org/apache/atlas/repository/Constants.java
@@ -58,8 +58,8 @@ public final class Constants {
     public static final String TYPEOPTIONS_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type.options";
 
     // relationship def constants
-    public static final String RELATIONSHIPTYPE_ENDPOINT1_KEY = "endPointDef1";
-    public static final String RELATIONSHIPTYPE_ENDPOINT2_KEY = "endPointDef2";
+    public static final String RELATIONSHIPTYPE_END1_KEY = "endDef1";
+    public static final String RELATIONSHIPTYPE_END2_KEY = "endDef2";
     public static final String RELATIONSHIPTYPE_CATEGORY_KEY = "relationshipCategory";
     public static final String RELATIONSHIPTYPE_TAG_PROPAGATION_KEY = "tagPropagation";
     /**

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/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 ca2f3d0..6c33f40 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -71,14 +71,14 @@ public enum AtlasErrorCode {
     BAD_REQUEST(400, "ATLAS-400-00-029", "{0}"),
     PARAMETER_PARSING_FAILED(400, "ATLAS-400-00-02A", "Parameter parsing failed at: {0}"),
     MISSING_MANDATORY_ATTRIBUTE(400, "ATLAS-400-00-02B", "Mandatory field {0}.{1} has empty/null value"),
-    RELATIONSHIPDEF_INSUFFICIENT_ENDPOINTS(400,  "ATLAS-400-00-02C", "Relationship def {0} creation attempted without 2 end points"),
-    RELATIONSHIPDEF_DOUBLE_CONTAINERS(400,  "ATLAS-400-00-02D", "Relationship def {0} creation attempted with both end points as containers"),
+    RELATIONSHIPDEF_INSUFFICIENT_ENDS(400,  "ATLAS-400-00-02C", "relationshipDef {0} creation attempted without 2 ends"),
+    RELATIONSHIPDEF_DOUBLE_CONTAINERS(400,  "ATLAS-400-00-02D", "relationshipDef {0} creation attempted with both ends as containers"),
     RELATIONSHIPDEF_UNSUPPORTED_ATTRIBUTE_TYPE(400,  "ATLAS-400-00-02F", "Cannot set an Attribute with type {0} on relationship def {1}, as it is not a primitive type "),
-    RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER(400,  "ATLAS-400-00-030", "ASSOCIATION relationship def {0} creation attempted with an endpoint specifying isContainer"),
-    RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER(400,  "ATLAS-400-00-031", "COMPOSITION relationship def {0} creation attempted without an endpoint specifying isContainer"),
-    RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER(400,  "ATLAS-400-00-032", "AGGREGATION relationship def {0} creation attempted without an endpoint specifying isContainer"),
-    RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400,  "ATLAS-400-00-033", "COMPOSITION relationship def {0} cannot have a SET cardinality and be a container"),
-    RELATIONSHIPDEF_LIST_ON_ENDPOINT(400,  "ATLAS-400-00-034", "relationship def {0} cannot have a LIST cardinality on an endpoint"),
+    RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER(400,  "ATLAS-400-00-030", "ASSOCIATION relationshipDef {0} creation attempted with an end specifying isContainer"),
+    RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER(400,  "ATLAS-400-00-031", "COMPOSITION relationshipDef {0} creation attempted without an end specifying isContainer"),
+    RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER(400,  "ATLAS-400-00-032", "AGGREGATION relationshipDef {0} creation attempted without an end specifying isContainer"),
+    RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400,  "ATLAS-400-00-033", "COMPOSITION relationshipDef {0} cannot have a SET cardinality and be a container"),
+    RELATIONSHIPDEF_LIST_ON_END(400,  "ATLAS-400-00-034", "relationshipDef {0} cannot have a LIST cardinality on an end"),
     // All Not found enums go here
     TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
     TYPE_GUID_NOT_FOUND(404, "ATLAS-404-00-002", "Given type guid {0} was invalid"),

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
index eb8330e..fc820d4 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
@@ -39,8 +39,8 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
  * As with other typeDefs the AtlasRelationshipDef has a name. Once created the RelationshipDef has a guid.
  * The name and the guid are the 2 ways that the RelationshipDef is identified.
  *
- * RelationshipDefs have 2 endpoints, each of which specify cardinality, an EntityDef type name and name and optionally
- * whether the endpoint is a container.
+ * RelationshipDefs have 2 ends, each of which specify cardinality, an EntityDef type name and name and optionally
+ * whether the end is a container.
  * RelationshipDefs can have AttributeDefs - though only primitive types are allowed.
  * RelationshipDefs have a relationshipCategory specifying the UML type of relationship required
  * RelationshipDefs also have a PropogateTag - indicating which way tags could flow over the relationships.
@@ -51,9 +51,9 @@ import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONL
  * RelationshipDefs introduce new atributes to the entity instances. For example
  * EntityDef A might have attributes attr1,attr2,attr3
  * EntityDef B might have attributes attr4,attr5,attr6
- * RelationshipDef AtoB might define 2 endpoints
- *  endpoint1:  type A, name attr7
- *  endpoint1:  type B, name attr8
+ * RelationshipDef AtoB might define 2 ends
+ *  end1:  type A, name attr7
+ *  end1:  type B, name attr8
  *
  * When an instance of EntityDef A is created, it will have attributes attr1,attr2,attr3,attr7
  * When an instance of EntityDef B is created, it will have attributes attr4,attr5,attr6,attr8
@@ -88,11 +88,11 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
      * PropagateTags indicates whether tags should propagate across the relationship instance.
      * Tags can propagate:
      * NONE - not at all
-     * ONE_TO_TWO - from endpoint 1 to 2
-     * TWO_TO_ONE - from endpoint 2 to 1
+     * ONE_TO_TWO - from end 1 to 2
+     * TWO_TO_ONE - from end 2 to 1
      * BOTH - both ways
      *
-     * Care needs to be taken when specifying. The use cases we are aware of this flag being useful are :
+     * Care needs to be taken when specifying. The use cases we are aware of where this flag is useful:
      *
      * - propagating confidentiality classifications from a table to columns - ONE_TO_TWO could be used here
      * - propagating classifications around Glossary synonyms - BOTH could be used here.
@@ -104,10 +104,10 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
         NONE, ONE_TO_TWO, TWO_TO_ONE, BOTH
     };
 
-    private RelationshipCategory         relationshipCategory;
-    private PropagateTags                propagateTags;
-    private AtlasRelationshipEndPointDef endPointDef1;
-    private AtlasRelationshipEndPointDef endPointDef2;
+    private RelationshipCategory    relationshipCategory;
+    private PropagateTags           propagateTags;
+    private AtlasRelationshipEndDef endDef1;
+    private AtlasRelationshipEndDef endDef2;
 
     /**
      * AtlasRelationshipDef contructor
@@ -130,22 +130,23 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
      *            and AGGREGATION
      * @param propagatetags
      *            -
-     * @param endPointDef1
-     *            - first endpoint. As endpoint specifies an entity
-     *            type and an attribute name. the attribute name then appears in
+     * @param endDef1
+     *            - first end. An end specifies an entity type and an attribute name. the attribute name then appears in
      *            the relationship instance
-     * @param endPointDef2
-     *            - second endpoint. The endpoints are defined as 1
-     *            ad 2 to avoid implying a direction. So we do not use to and
-     *            from.
+     * @param endDef2
+     *            - second end. An end specifies an entity type and an attribute name. the attribute name then appears in
+     *            the relationship instance
+     *
+     *            The ends are defined as 1 and 2 to avoid implying a direction. So we do not use to and from.
+     *
      * @throws AtlasBaseException
      */
     public AtlasRelationshipDef(String name, String description, String typeVersion,
                                 RelationshipCategory relationshipCategory,
                                 PropagateTags propagatetags,
-                                AtlasRelationshipEndPointDef endPointDef1,
-                                AtlasRelationshipEndPointDef endPointDef2) throws AtlasBaseException {
-        this(name, description, typeVersion, relationshipCategory,propagatetags, endPointDef1, endPointDef2,
+                                AtlasRelationshipEndDef endDef1,
+                                AtlasRelationshipEndDef endDef2) throws AtlasBaseException {
+        this(name, description, typeVersion, relationshipCategory,propagatetags, endDef1, endDef2,
              new ArrayList<AtlasAttributeDef>());
     }
 
@@ -162,12 +163,12 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
      *            and AGGREGATION
      * @param propagatetags
      *            -
-     * @param endPointDef1
-     *            - First endpoint. As endpoint specifies an entity
+     * @param endDef1
+     *            - First end. As end specifies an entity
      *            type and an attribute name. the attribute name then appears in
      *            the relationship instance
-     * @param endPointDef2
-     *            - Second endpoint. The endpoints are defined as 1
+     * @param endDef2
+     *            - Second end. The ends are defined as 1
      *            ad 2 to avoid implying a direction. So we do not use to and
      *            from.
      * @param attributeDefs
@@ -175,15 +176,15 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
      */
     public AtlasRelationshipDef(String name, String description, String typeVersion,
                                 RelationshipCategory relationshipCategory,
-                                PropagateTags propagatetags, AtlasRelationshipEndPointDef endPointDef1,
-                                AtlasRelationshipEndPointDef endPointDef2, List<AtlasAttributeDef> attributeDefs)
+                                PropagateTags propagatetags, AtlasRelationshipEndDef endDef1,
+                                AtlasRelationshipEndDef endDef2, List<AtlasAttributeDef> attributeDefs)
             {
         super(TypeCategory.RELATIONSHIP, name, description, typeVersion, attributeDefs, null);
 
         setRelationshipCategory(relationshipCategory);
         setPropagateTags(propagatetags);
-        setEndPointDef1(endPointDef1);
-        setEndPointDef2(endPointDef2);
+        setEndDef1(endDef1);
+        setEndDef2(endDef2);
     }
 
     public void setRelationshipCategory(RelationshipCategory relationshipCategory) {
@@ -202,20 +203,20 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
         return this.propagateTags;
     }
 
-    public void setEndPointDef1(AtlasRelationshipEndPointDef endPointDef1) {
-        this.endPointDef1 = endPointDef1;
+    public void setEndDef1(AtlasRelationshipEndDef endDef1) {
+        this.endDef1 = endDef1;
     }
 
-    public AtlasRelationshipEndPointDef getEndPointDef1() {
-        return this.endPointDef1;
+    public AtlasRelationshipEndDef getEndDef1() {
+        return this.endDef1;
     }
 
-    public void setEndPointDef2(AtlasRelationshipEndPointDef endPointDef2) {
-        this.endPointDef2 = endPointDef2;
+    public void setEndDef2(AtlasRelationshipEndDef endDef2) {
+        this.endDef2 = endDef2;
     }
 
-    public AtlasRelationshipEndPointDef getEndPointDef2() {
-        return this.endPointDef2;
+    public AtlasRelationshipEndDef getEndDef2() {
+        return this.endDef2;
     }
 
     public AtlasRelationshipDef(AtlasRelationshipDef other) throws AtlasBaseException {
@@ -224,8 +225,8 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
         if (other != null) {
             setRelationshipCategory(other.getRelationshipCategory());
             setPropagateTags(other.getPropagateTags());
-            setEndPointDef1(other.getEndPointDef1());
-            setEndPointDef2(other.getEndPointDef2());
+            setEndDef1(other.getEndDef1());
+            setEndDef2(other.getEndDef2());
         }
     }
     @Override
@@ -241,9 +242,9 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
         sb.append(',');
         sb.append(this.propagateTags);
         sb.append(',');
-        sb.append(this.endPointDef1.toString());
+        sb.append(this.endDef1.toString());
         sb.append(',');
-        sb.append(this.endPointDef2.toString());
+        sb.append(this.endDef2.toString());
         sb.append('}');
         return sb;
     }
@@ -262,14 +263,14 @@ public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Seri
             return false;
         if (!Objects.equals(propagateTags, that.getPropagateTags()))
             return false;
-        if (!Objects.equals(endPointDef1, that.getEndPointDef1()))
+        if (!Objects.equals(endDef1, that.getEndDef1()))
             return false;
-        return (Objects.equals(endPointDef2, that.getEndPointDef2()));
+        return (Objects.equals(endDef2, that.getEndDef2()));
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), relationshipCategory, propagateTags, endPointDef1, endPointDef2);
+        return Objects.hash(super.hashCode(), relationshipCategory, propagateTags, endDef1, endDef2);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
new file mode 100644
index 0000000..000d747
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
@@ -0,0 +1,193 @@
+/**
+ * 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.typedef;
+
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
+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.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+/**
+ * The relationshipEndDef represents an end of the relationship. The end of the relationship is defined by a type, an
+ * attribute name, cardinality and whether it  is the container end of the relationship.
+ */
+@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasRelationshipEndDef implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * The type associated with the end.
+     */
+    private String type;
+    /**
+     * The name of the attribute for this end
+     */
+    private String name;
+
+    /**
+     * When set this indicates that this end is the container end
+     */
+    private boolean isContainer;
+    /**
+     * This is the cardinality of the end
+     */
+    private Cardinality cardinality;
+
+    /**
+     * Base constructor
+     */
+    public AtlasRelationshipEndDef() {
+        this(null, null, Cardinality.SINGLE, false);
+    }
+
+    /**
+     *
+     * @param typeName
+     *   - The name of an entityDef type
+     * @param name
+     *   - The name of the new attribute that the entity instance will pick up.
+     * @param cardinality
+     *   - this indicates whether the end is SINGLE (1) or SET (many)
+     */
+    public AtlasRelationshipEndDef(String typeName, String name, Cardinality cardinality) {
+        this(typeName, name, cardinality, false);
+    }
+
+    /**
+     *
+     * @param typeName
+     *   - The name of an entityDef type
+     * @param name
+     *   - The name of the new attribute that the entity instance will pick up.
+     * @param cardinality
+     *   - whether the end is SINGLE (1) or SET (many)
+     * @param isContainer
+     *   - whether the end is a container or not
+     */
+    public AtlasRelationshipEndDef(String typeName, String name, Cardinality cardinality, boolean isContainer) {
+        setType(typeName);
+        setName(name);
+        setCardinality(cardinality);
+        setIsContainer(isContainer);
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * set whether this end is a container or not.
+     * @param isContainer
+     */
+    public void setIsContainer(boolean isContainer) {
+        this.isContainer = isContainer;
+    }
+
+    public boolean getIsContainer() {
+        return isContainer;
+    }
+
+    /**
+     * set the cardinality SINGLE or SET on the end.
+     * @param cardinality
+     */
+    public void setCardinality(AtlasStructDef.AtlasAttributeDef.Cardinality cardinality) {
+        this.cardinality = cardinality;
+    }
+
+    /**
+     *
+     * @return the cardinality
+     */
+    public Cardinality getCardinality() {
+        return this.cardinality;
+    }
+
+    /**
+     * Construct using an existing AtlasRelationshipEndDef
+     * @param other
+     */
+    public AtlasRelationshipEndDef(AtlasRelationshipEndDef other) {
+        if (other != null) {
+            setType(other.getType());
+            setName(other.getName());
+            setIsContainer(other.getIsContainer());
+            setCardinality(other.getCardinality());
+        }
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("AtlasRelationshipEndDef{");
+        sb.append("type='").append(type).append('\'');
+        sb.append(", name==>'").append(name).append('\'');
+        sb.append(", isContainer==>'").append(isContainer).append('\'');
+        sb.append(", cardinality==>'").append(cardinality).append('\'');
+        sb.append('}');
+
+        return sb;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        AtlasRelationshipEndDef that = (AtlasRelationshipEndDef) o;
+        return Objects.equals(type, that.type) && Objects.equals(name, that.name)
+                && (isContainer == that.isContainer) && (cardinality == that.cardinality);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, getName(), isContainer, cardinality);
+    }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java
deleted file mode 100644
index dde8416..0000000
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java
+++ /dev/null
@@ -1,193 +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.typedef;
-
-import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
-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.Objects;
-
-import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
-import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
-
-/**
- * The relationshipEndPointsDef represents an end of the relationship. The end of the relationship is defined by a type, an
- * attribute name, cardinality and whether it  is the container end of the relationship.
- */
-@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
-@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
-@JsonIgnoreProperties(ignoreUnknown = true)
-@XmlRootElement
-@XmlAccessorType(XmlAccessType.PROPERTY)
-public class AtlasRelationshipEndPointDef implements Serializable {
-    private static final long serialVersionUID = 1L;
-    /**
-     * The type associated with the endpoint.
-     */
-    private String type;
-    /**
-     * The name of the attribute for this endpoint
-     */
-    private String name;
-
-    /**
-     * When set this indicates that this end is the container end
-     */
-    private boolean isContainer;
-    /**
-     * This is the cardinality of the end point
-     */
-    private Cardinality cardinality;
-
-    /**
-     * Base constructor
-     */
-    public AtlasRelationshipEndPointDef() {
-        this(null, null, Cardinality.SINGLE, false);
-    }
-
-    /**
-     *
-     * @param typeName
-     *   - The name of an entityDef type
-     * @param name
-     *   - The name of the new attribute that the entity instance will pick up.
-     * @param cardinality
-     *   - this indicates whether the end point is SINGLE (1) or SET (many)
-     */
-    public AtlasRelationshipEndPointDef(String typeName, String name, Cardinality cardinality) {
-        this(typeName, name, cardinality, false);
-    }
-
-    /**
-     *
-     * @param typeName
-     *   - The name of an entityDef type
-     * @param name
-     *   - The name of the new attribute that the entity instance will pick up.
-     * @param cardinality
-     *   - whether the end point is SINGLE (1) or SET (many)
-     * @param isContainer
-     *   - whether the end point is a container or not
-     */
-    public AtlasRelationshipEndPointDef(String typeName, String name, Cardinality cardinality, boolean isContainer) {
-        setType(typeName);
-        setName(name);
-        setCardinality(cardinality);
-        setIsContainer(isContainer);
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public String getName() {
-        return this.name;
-    }
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-    /**
-     * set whether this endpoint is a container or not.
-     * @param isContainer
-     */
-    public void setIsContainer(boolean isContainer) {
-        this.isContainer = isContainer;
-    }
-
-    public boolean getIsContainer() {
-        return isContainer;
-    }
-
-    /**
-     * set the cardinality SINGLE or SET on the endpoint.
-     * @param cardinality
-     */
-    public void setCardinality(AtlasStructDef.AtlasAttributeDef.Cardinality cardinality) {
-        this.cardinality = cardinality;
-    }
-
-    /**
-     *
-     * @return the cardinality
-     */
-    public Cardinality getCardinality() {
-        return this.cardinality;
-    }
-
-    /**
-     * Construct using an existing AtlasRelationshipEndPointDef
-     * @param other
-     */
-    public AtlasRelationshipEndPointDef(AtlasRelationshipEndPointDef other) {
-        if (other != null) {
-            setType(other.getType());
-            setName(other.getName());
-            setIsContainer(other.getIsContainer());
-            setCardinality(other.getCardinality());
-        }
-    }
-
-    public StringBuilder toString(StringBuilder sb) {
-        if (sb == null) {
-            sb = new StringBuilder();
-        }
-
-        sb.append("AtlasRelationshipEndPointsDef{");
-        sb.append("type='").append(type).append('\'');
-        sb.append(", name==>'").append(name).append('\'');
-        sb.append(", isContainer==>'").append(isContainer).append('\'');
-        sb.append(", cardinality==>'").append(cardinality).append('\'');
-        sb.append('}');
-
-        return sb;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o)
-            return true;
-        if (o == null || getClass() != o.getClass())
-            return false;
-        AtlasRelationshipEndPointDef that = (AtlasRelationshipEndPointDef) o;
-        return Objects.equals(type, that.type) && Objects.equals(name, that.name)
-                && (isContainer == that.isContainer) && (cardinality == that.cardinality);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(type, getName(), isContainer, cardinality);
-    }
-
-    @Override
-    public String toString() {
-        return toString(new StringBuilder()).toString();
-    }
-}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
index 6328108..eb2fc48 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
@@ -22,7 +22,7 @@ import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
-import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -103,49 +103,49 @@ public class AtlasRelationshipType extends AtlasStructType {
      * @throws AtlasBaseException
      */
     public static void validateAtlasRelationshipDef(AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
-        AtlasRelationshipEndPointDef endPointDef1 = relationshipDef.getEndPointDef1();
-        AtlasRelationshipEndPointDef endPointDef2 = relationshipDef.getEndPointDef2();
-        boolean                      isContainer1 = endPointDef1.getIsContainer();
-        boolean                      isContainer2 = endPointDef2.getIsContainer();
-        RelationshipCategory relationshipCategory = relationshipDef.getRelationshipCategory();
-        String                       name         = relationshipDef.getName();
+        AtlasRelationshipEndDef endDef1              = relationshipDef.getEndDef1();
+        AtlasRelationshipEndDef endDef2              = relationshipDef.getEndDef2();
+        boolean                 isContainer1         = endDef1.getIsContainer();
+        boolean                 isContainer2         = endDef2.getIsContainer();
+        RelationshipCategory    relationshipCategory = relationshipDef.getRelationshipCategory();
+        String                  name                 = relationshipDef.getName();
 
         if (isContainer1 && isContainer2) {
             // we support 0 or 1 of these flags.
             throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_DOUBLE_CONTAINERS, name);
         }
         if ((isContainer1 || isContainer2)) {
-            // we have an isContainer defined in an endpoint
+            // we have an isContainer defined in an end
             if (relationshipCategory == RelationshipCategory.ASSOCIATION) {
                 // associations are not containment relaitonships - so do not allow an endpoiint with isContainer
                 throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER, name);
             }
         } else {
-            // we do not have an isContainer defined in an endpoint
+            // we do not have an isContainer defined in an end
             if (relationshipCategory == RelationshipCategory.COMPOSITION) {
-                // COMPOSITION needs one endpoint to be the container.
+                // COMPOSITION needs one end to be the container.
                 throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER, name);
             } else if (relationshipCategory == RelationshipCategory.AGGREGATION) {
-                // AGGREGATION needs one endpoint to be the container.
+                // AGGREGATION needs one end to be the container.
                 throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER, name);
             }
         }
         if (relationshipCategory == RelationshipCategory.COMPOSITION) {
             // composition containers should not be multiple cardinality
-            if (endPointDef1 != null &&
-                    endPointDef1.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
-                    endPointDef1.getIsContainer()) {
+            if (endDef1 != null &&
+                    endDef1.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
+                    endDef1.getIsContainer()) {
                 throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER, name);
             }
-            if (endPointDef2 != null && endPointDef2 != null &&
-                    endPointDef2.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
-                    endPointDef2.getIsContainer()) {
+            if (endDef2 != null && endDef2 != null &&
+                    endDef2.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
+                    endDef2.getIsContainer()) {
                 throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER, name);
             }
         }
-        if ((endPointDef1 != null && endPointDef1.getCardinality() == AtlasAttributeDef.Cardinality.LIST) ||
-                (endPointDef2 != null && endPointDef2.getCardinality() == AtlasAttributeDef.Cardinality.LIST)) {
-            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT, name);
+        if ((endDef1 != null && endDef1.getCardinality() == AtlasAttributeDef.Cardinality.LIST) ||
+                (endDef2 != null && endDef2.getCardinality() == AtlasAttributeDef.Cardinality.LIST)) {
+            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_END, name);
         }
     }
-}
\ No newline at end of file
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
index 78efa6e..7989a24 100644
--- a/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
+++ b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
@@ -38,8 +38,8 @@ public class TestAtlasRelationshipDef {
     @Test
     public void testRelationshipDefSerDeEmpty() throws AtlasBaseException {
 
-        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
-        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep1 = new AtlasRelationshipEndDef("typeA", "attr1", Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep2 = new AtlasRelationshipEndDef("typeB", "attr2", Cardinality.SINGLE);
         AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
                 RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
 
@@ -58,8 +58,8 @@ public class TestAtlasRelationshipDef {
     @Test
     public void testRelationshipDefSerDeAttributes() throws AtlasBaseException {
 
-        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
-        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep1 = new AtlasRelationshipEndDef("typeA", "attr1", Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep2 = new AtlasRelationshipEndDef("typeB", "attr2", Cardinality.SINGLE);
         AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
                 RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
         relationshipDef.setAttributeDefs(
@@ -77,8 +77,8 @@ public class TestAtlasRelationshipDef {
     @Test
     public void testRelationshipEquals() throws AtlasBaseException {
 
-        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
-        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep1 = new AtlasRelationshipEndDef("typeA", "attr1", Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep2 = new AtlasRelationshipEndDef("typeB", "attr2", Cardinality.SINGLE);
         AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
                 RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
         List<AtlasStructDef.AtlasAttributeDef> attributeDefs = ModelTestUtil.newAttributeDefsWithAllBuiltInTypesForRelationship(PREFIX_ATTRIBUTE_NAME);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
index 6af374a..7a4e9fd 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
@@ -20,20 +20,20 @@ package org.apache.atlas.type;
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
-import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.testng.annotations.Test;
 
-import static org.testng.AssertJUnit.fail;
+import static org.testng.Assert.fail;
 public class TestAtlasRelationshipType {
     @Test
     public void testvalidateAtlasRelationshipDef() throws AtlasBaseException {
-        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
-        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
-        AtlasRelationshipEndPointDef ep3 = new AtlasRelationshipEndPointDef("typeC", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
-        AtlasRelationshipEndPointDef ep4 = new AtlasRelationshipEndPointDef("typeD", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
-        AtlasRelationshipEndPointDef ep5 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SET,true);
-        AtlasRelationshipEndPointDef ep6 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST,true);
+        AtlasRelationshipEndDef ep1 = new AtlasRelationshipEndDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep2 = new AtlasRelationshipEndDef("typeB", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        AtlasRelationshipEndDef ep3 = new AtlasRelationshipEndDef("typeC", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
+        AtlasRelationshipEndDef ep4 = new AtlasRelationshipEndDef("typeD", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
+        AtlasRelationshipEndDef ep5 = new AtlasRelationshipEndDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SET,true);
+        AtlasRelationshipEndDef ep6 = new AtlasRelationshipEndDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST,true);
         AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
                 AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
         AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
@@ -88,7 +88,7 @@ public class TestAtlasRelationshipType {
             AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
             fail("This call is expected to fail");
         } catch (AtlasBaseException abe) {
-            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT)) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_END)) {
                 fail("This call expected a different error");
             }
         }
@@ -98,7 +98,7 @@ public class TestAtlasRelationshipType {
             AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
             fail("This call is expected to fail");
         } catch (AtlasBaseException abe) {
-            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT)) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_END)) {
                 fail("This call expected a different error");
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/1de6016d/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
index 96cd8d1..6992e22 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
@@ -22,7 +22,7 @@ import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
-import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
@@ -347,9 +347,9 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
     private void updateVertexPreCreate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType,
                                        AtlasVertex vertex) throws AtlasBaseException {
         AtlasStructDefStoreV1.updateVertexPreCreate(relationshipDef, relationshipType, vertex, typeDefStore);
-        // Update endpoints
-        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT1_KEY, AtlasType.toJson(relationshipDef.getEndPointDef1()));
-        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT2_KEY, AtlasType.toJson(relationshipDef.getEndPointDef2()));
+        // Update ends
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_END1_KEY, AtlasType.toJson(relationshipDef.getEndDef1()));
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_END2_KEY, AtlasType.toJson(relationshipDef.getEndDef2()));
         // Update RelationshipCategory
         vertex.setProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, relationshipDef.getRelationshipCategory().name());
         vertex.setProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, relationshipDef.getPropagateTags().name());
@@ -358,8 +358,8 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
     private void updateVertexPreUpdate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType,
                                        AtlasVertex vertex) throws AtlasBaseException {
         AtlasStructDefStoreV1.updateVertexPreUpdate(relationshipDef, relationshipType, vertex, typeDefStore);
-        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT1_KEY, AtlasType.toJson(relationshipDef.getEndPointDef1()));
-        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT2_KEY, AtlasType.toJson(relationshipDef.getEndPointDef2()));
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_END1_KEY, AtlasType.toJson(relationshipDef.getEndDef1()));
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_END2_KEY, AtlasType.toJson(relationshipDef.getEndDef2()));
         // Update RelationshipCategory
         vertex.setProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, relationshipDef.getRelationshipCategory().name());
         vertex.setProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, relationshipDef.getPropagateTags().name());
@@ -372,14 +372,14 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
             String name         = vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY, String.class);
             String description  = vertex.getProperty(Constants.TYPEDESCRIPTION_PROPERTY_KEY, String.class);
             String version      = vertex.getProperty(Constants.TYPEVERSION_PROPERTY_KEY, String.class);
-            String endPoint1Str = vertex.getProperty(Constants.RELATIONSHIPTYPE_ENDPOINT1_KEY, String.class);
-            String endPoint2Str = vertex.getProperty(Constants.RELATIONSHIPTYPE_ENDPOINT2_KEY, String.class);
+            String end1Str = vertex.getProperty(Constants.RELATIONSHIPTYPE_END1_KEY, String.class);
+            String end2Str = vertex.getProperty(Constants.RELATIONSHIPTYPE_END2_KEY, String.class);
             String relationStr  = vertex.getProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, String.class);
             String propagateStr = vertex.getProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, String.class);
 
-            // set the endpoints
-            AtlasRelationshipEndPointDef endPointDef1 = AtlasType.fromJson(endPoint1Str, AtlasRelationshipEndPointDef.class);
-            AtlasRelationshipEndPointDef endPointDef2 = AtlasType.fromJson(endPoint2Str, AtlasRelationshipEndPointDef.class);
+            // set the ends
+            AtlasRelationshipEndDef endDef1 = AtlasType.fromJson(end1Str, AtlasRelationshipEndDef.class);
+            AtlasRelationshipEndDef endDef2 = AtlasType.fromJson(end2Str, AtlasRelationshipEndDef.class);
 
             // set the relationship Category
             RelationshipCategory relationshipCategory = null;
@@ -397,7 +397,7 @@ public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 impleme
                 }
             }
 
-            ret = new AtlasRelationshipDef(name, description, version, relationshipCategory,  propagateTags, endPointDef1, endPointDef2);
+            ret = new AtlasRelationshipDef(name, description, version, relationshipCategory,  propagateTags, endDef1, endDef2);
 
             // add in the attributes
             AtlasStructDefStoreV1.toStructDef(vertex, ret, typeDefStore);


[05/14] incubator-atlas git commit: ATLAS-1852: create relationship-def

Posted by ma...@apache.org.
ATLAS-1852: create relationship-def

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


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

Branch: refs/heads/feature-odf
Commit: 6b9399e00dcd2fb2b231c91064dfe15f46feaf1d
Parents: e0072e5
Author: David Radley <da...@uk.ibm.com>
Authored: Sun Jun 11 11:57:50 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sun Jun 11 12:26:19 2017 -0700

----------------------------------------------------------------------
 .../org/apache/atlas/repository/Constants.java  |   6 +
 .../java/org/apache/atlas/AtlasErrorCode.java   |   9 +-
 .../org/apache/atlas/model/TypeCategory.java    |   2 +-
 .../atlas/model/typedef/AtlasBaseTypeDef.java   |  16 +
 .../model/typedef/AtlasRelationshipDef.java     | 279 +++++++++++++
 .../typedef/AtlasRelationshipEndPointDef.java   | 193 +++++++++
 .../atlas/model/typedef/AtlasTypesDef.java      |  66 ++-
 .../apache/atlas/store/AtlasTypeDefStore.java   |  10 +
 .../atlas/type/AtlasRelationshipType.java       | 151 +++++++
 .../apache/atlas/type/AtlasTypeRegistry.java    |  99 +++--
 .../org/apache/atlas/type/AtlasTypeUtil.java    |  39 +-
 .../org/apache/atlas/model/ModelTestUtil.java   |  68 ++-
 .../model/typedef/TestAtlasRelationshipDef.java |  96 +++++
 .../atlas/type/TestAtlasRelationshipType.java   | 107 +++++
 .../store/graph/AtlasRelationshipDefStore.java  |  52 +++
 .../store/graph/AtlasTypeDefGraphStore.java     | 135 ++++--
 .../graph/v1/AtlasRelationshipDefStoreV1.java   | 409 +++++++++++++++++++
 .../graph/v1/AtlasTypeDefGraphStoreV1.java      |  58 +--
 .../atlas/typesystem/types/DataTypes.java       |   3 +-
 .../examples/CreateTypesFromJsonFileUtil.java   | 109 +++++
 .../examples/UpdateTypesFromJsonFileUtil.java   | 108 +++++
 .../atlas/web/resources/TypesResource.java      |   2 +-
 .../org/apache/atlas/web/rest/TypesREST.java    |  49 ++-
 23 files changed, 1923 insertions(+), 143 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/common/src/main/java/org/apache/atlas/repository/Constants.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java b/common/src/main/java/org/apache/atlas/repository/Constants.java
index bcdf08c..b07934b 100644
--- a/common/src/main/java/org/apache/atlas/repository/Constants.java
+++ b/common/src/main/java/org/apache/atlas/repository/Constants.java
@@ -57,6 +57,11 @@ public final class Constants {
     public static final String TYPEVERSION_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type.version";
     public static final String TYPEOPTIONS_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "type.options";
 
+    // relationship def constants
+    public static final String RELATIONSHIPTYPE_ENDPOINT1_KEY = "endPointDef1";
+    public static final String RELATIONSHIPTYPE_ENDPOINT2_KEY = "endPointDef2";
+    public static final String RELATIONSHIPTYPE_CATEGORY_KEY = "relationshipCategory";
+    public static final String RELATIONSHIPTYPE_TAG_PROPAGATION_KEY = "tagPropagation";
     /**
      * Trait names property key and index name.
      */
@@ -92,6 +97,7 @@ public final class Constants {
     public static final String QUALIFIED_NAME = "Referenceable.qualifiedName";
     public static final String TYPE_NAME_PROPERTY_KEY = INTERNAL_PROPERTY_KEY_PREFIX + "typeName";
 
+
     private Constants() {
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/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 d723b2a..ca2f3d0 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -71,7 +71,14 @@ public enum AtlasErrorCode {
     BAD_REQUEST(400, "ATLAS-400-00-029", "{0}"),
     PARAMETER_PARSING_FAILED(400, "ATLAS-400-00-02A", "Parameter parsing failed at: {0}"),
     MISSING_MANDATORY_ATTRIBUTE(400, "ATLAS-400-00-02B", "Mandatory field {0}.{1} has empty/null value"),
-
+    RELATIONSHIPDEF_INSUFFICIENT_ENDPOINTS(400,  "ATLAS-400-00-02C", "Relationship def {0} creation attempted without 2 end points"),
+    RELATIONSHIPDEF_DOUBLE_CONTAINERS(400,  "ATLAS-400-00-02D", "Relationship def {0} creation attempted with both end points as containers"),
+    RELATIONSHIPDEF_UNSUPPORTED_ATTRIBUTE_TYPE(400,  "ATLAS-400-00-02F", "Cannot set an Attribute with type {0} on relationship def {1}, as it is not a primitive type "),
+    RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER(400,  "ATLAS-400-00-030", "ASSOCIATION relationship def {0} creation attempted with an endpoint specifying isContainer"),
+    RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER(400,  "ATLAS-400-00-031", "COMPOSITION relationship def {0} creation attempted without an endpoint specifying isContainer"),
+    RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER(400,  "ATLAS-400-00-032", "AGGREGATION relationship def {0} creation attempted without an endpoint specifying isContainer"),
+    RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400,  "ATLAS-400-00-033", "COMPOSITION relationship def {0} cannot have a SET cardinality and be a container"),
+    RELATIONSHIPDEF_LIST_ON_ENDPOINT(400,  "ATLAS-400-00-034", "relationship def {0} cannot have a LIST cardinality on an endpoint"),
     // All Not found enums go here
     TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
     TYPE_GUID_NOT_FOUND(404, "ATLAS-404-00-002", "Given type guid {0} was invalid"),

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/TypeCategory.java b/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
index e47a8a7..f06f64f 100644
--- a/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
+++ b/intg/src/main/java/org/apache/atlas/model/TypeCategory.java
@@ -18,5 +18,5 @@
 package org.apache.atlas.model;
 
 public enum TypeCategory {
-    PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP
+    PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP, RELATIONSHIP
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java
index 7308eb7..1ccab22 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasBaseTypeDef.java
@@ -91,6 +91,22 @@ public abstract class AtlasBaseTypeDef implements java.io.Serializable {
         ATLAS_TYPE_BIGDECIMAL,
         ATLAS_TYPE_STRING,
     };
+    /**
+     * The list of types that are valid for relationships. These are the
+     * primitive attributes and date.
+     */
+    public static final String[] ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES = { ATLAS_TYPE_BOOLEAN,
+            ATLAS_TYPE_BYTE,
+            ATLAS_TYPE_SHORT,
+            ATLAS_TYPE_INT,
+            ATLAS_TYPE_LONG,
+            ATLAS_TYPE_FLOAT,
+            ATLAS_TYPE_DOUBLE,
+            ATLAS_TYPE_BIGINTEGER,
+            ATLAS_TYPE_BIGDECIMAL,
+            ATLAS_TYPE_STRING,
+            ATLAS_TYPE_DATE
+    };
 
     public static final String[] ATLAS_BUILTIN_TYPES = {
         ATLAS_TYPE_BOOLEAN,

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
new file mode 100644
index 0000000..eb8330e
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipDef.java
@@ -0,0 +1,279 @@
+/**
+ * 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.typedef;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.TypeCategory;
+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.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+/**
+ * AtlasRelationshipDef is a TypeDef that defines a relationship.
+ *
+ * As with other typeDefs the AtlasRelationshipDef has a name. Once created the RelationshipDef has a guid.
+ * The name and the guid are the 2 ways that the RelationshipDef is identified.
+ *
+ * RelationshipDefs have 2 endpoints, each of which specify cardinality, an EntityDef type name and name and optionally
+ * whether the endpoint is a container.
+ * RelationshipDefs can have AttributeDefs - though only primitive types are allowed.
+ * RelationshipDefs have a relationshipCategory specifying the UML type of relationship required
+ * RelationshipDefs also have a PropogateTag - indicating which way tags could flow over the relationships.
+ *
+ * The way EntityDefs and RelationshipDefs are intended to be used is that EntityDefs will define AttributeDefs these AttributeDefs
+ * will not specify an EntityDef type name as their types.
+ *
+ * RelationshipDefs introduce new atributes to the entity instances. For example
+ * EntityDef A might have attributes attr1,attr2,attr3
+ * EntityDef B might have attributes attr4,attr5,attr6
+ * RelationshipDef AtoB might define 2 endpoints
+ *  endpoint1:  type A, name attr7
+ *  endpoint1:  type B, name attr8
+ *
+ * When an instance of EntityDef A is created, it will have attributes attr1,attr2,attr3,attr7
+ * When an instance of EntityDef B is created, it will have attributes attr4,attr5,attr6,attr8
+ *
+ * In this way relationshipDefs can be authored separately from entityDefs and can inject relationship attributes into
+ * the entity instances
+ *
+ */
+@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasRelationshipDef extends AtlasStructDef implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * The Relationship category determines the style of relationship around containment and lifecycle.
+     * UML terminology is used for the values.
+     * ASSOCIATION is a relationship with no containment.
+     * COMPOSITION and AGGREGATION are containment relationships.
+     * The difference being in the lifecycles of the container and its children. In the COMPOSITION case,
+     * the children cannot exist without the container. For AGGREGATION, the life cycles
+     * of the container and children are totally independant.
+     */
+    public enum RelationshipCategory {
+        ASSOCIATION, AGGREGATION, COMPOSITION
+    };
+
+    /**
+     * PropagateTags indicates whether tags should propagate across the relationship instance.
+     * Tags can propagate:
+     * NONE - not at all
+     * ONE_TO_TWO - from endpoint 1 to 2
+     * TWO_TO_ONE - from endpoint 2 to 1
+     * BOTH - both ways
+     *
+     * Care needs to be taken when specifying. The use cases we are aware of this flag being useful are :
+     *
+     * - propagating confidentiality classifications from a table to columns - ONE_TO_TWO could be used here
+     * - propagating classifications around Glossary synonyms - BOTH could be used here.
+     *
+     * There is an expectation that further enhancements will allow more granular control of tag propagation and will
+     * address how to resolve conflicts.
+     */
+    public enum PropagateTags {
+        NONE, ONE_TO_TWO, TWO_TO_ONE, BOTH
+    };
+
+    private RelationshipCategory         relationshipCategory;
+    private PropagateTags                propagateTags;
+    private AtlasRelationshipEndPointDef endPointDef1;
+    private AtlasRelationshipEndPointDef endPointDef2;
+
+    /**
+     * AtlasRelationshipDef contructor
+     * @throws AtlasBaseException
+     */
+    public AtlasRelationshipDef() throws AtlasBaseException {
+        this(null, null, null, null,null, null, null);
+    }
+
+    /**
+     * Create a relationshipDef without attributeDefs
+     * @param name
+     *            - the name of the relationship type
+     * @param description
+     *            - an optional description
+     * @param typeVersion
+     *            - version - that defaults to 1.0
+     * @param relationshipCategory
+     *            - there are 3 sorts of relationship category ASSOCIATION, COMPOSITION
+     *            and AGGREGATION
+     * @param propagatetags
+     *            -
+     * @param endPointDef1
+     *            - first endpoint. As endpoint specifies an entity
+     *            type and an attribute name. the attribute name then appears in
+     *            the relationship instance
+     * @param endPointDef2
+     *            - second endpoint. The endpoints are defined as 1
+     *            ad 2 to avoid implying a direction. So we do not use to and
+     *            from.
+     * @throws AtlasBaseException
+     */
+    public AtlasRelationshipDef(String name, String description, String typeVersion,
+                                RelationshipCategory relationshipCategory,
+                                PropagateTags propagatetags,
+                                AtlasRelationshipEndPointDef endPointDef1,
+                                AtlasRelationshipEndPointDef endPointDef2) throws AtlasBaseException {
+        this(name, description, typeVersion, relationshipCategory,propagatetags, endPointDef1, endPointDef2,
+             new ArrayList<AtlasAttributeDef>());
+    }
+
+    /**
+     * Create a relationshipDef with attributeDefs
+     * @param name
+     *            - the name of the relationship type
+     * @param description
+     *            - an optional description
+     * @param typeVersion
+     *            - version - that defaults to 1.0
+     * @param relationshipCategory
+     *            - there are 3 sorts of relationship category ASSOCIATION, COMPOSITION
+     *            and AGGREGATION
+     * @param propagatetags
+     *            -
+     * @param endPointDef1
+     *            - First endpoint. As endpoint specifies an entity
+     *            type and an attribute name. the attribute name then appears in
+     *            the relationship instance
+     * @param endPointDef2
+     *            - Second endpoint. The endpoints are defined as 1
+     *            ad 2 to avoid implying a direction. So we do not use to and
+     *            from.
+     * @param attributeDefs
+     *            - these are the attributes on the relationship itself.
+     */
+    public AtlasRelationshipDef(String name, String description, String typeVersion,
+                                RelationshipCategory relationshipCategory,
+                                PropagateTags propagatetags, AtlasRelationshipEndPointDef endPointDef1,
+                                AtlasRelationshipEndPointDef endPointDef2, List<AtlasAttributeDef> attributeDefs)
+            {
+        super(TypeCategory.RELATIONSHIP, name, description, typeVersion, attributeDefs, null);
+
+        setRelationshipCategory(relationshipCategory);
+        setPropagateTags(propagatetags);
+        setEndPointDef1(endPointDef1);
+        setEndPointDef2(endPointDef2);
+    }
+
+    public void setRelationshipCategory(RelationshipCategory relationshipCategory) {
+        this.relationshipCategory = relationshipCategory;
+    }
+
+    public RelationshipCategory getRelationshipCategory() {
+        return this.relationshipCategory;
+    }
+
+    public void setPropagateTags(PropagateTags propagateTags) {
+        this.propagateTags=propagateTags;
+    }
+
+    public PropagateTags getPropagateTags() {
+        return this.propagateTags;
+    }
+
+    public void setEndPointDef1(AtlasRelationshipEndPointDef endPointDef1) {
+        this.endPointDef1 = endPointDef1;
+    }
+
+    public AtlasRelationshipEndPointDef getEndPointDef1() {
+        return this.endPointDef1;
+    }
+
+    public void setEndPointDef2(AtlasRelationshipEndPointDef endPointDef2) {
+        this.endPointDef2 = endPointDef2;
+    }
+
+    public AtlasRelationshipEndPointDef getEndPointDef2() {
+        return this.endPointDef2;
+    }
+
+    public AtlasRelationshipDef(AtlasRelationshipDef other) throws AtlasBaseException {
+        super(other);
+
+        if (other != null) {
+            setRelationshipCategory(other.getRelationshipCategory());
+            setPropagateTags(other.getPropagateTags());
+            setEndPointDef1(other.getEndPointDef1());
+            setEndPointDef2(other.getEndPointDef2());
+        }
+    }
+    @Override
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("AtlasRelationshipDef{");
+        super.toString(sb);
+        sb.append(',');
+        sb.append(this.relationshipCategory);
+        sb.append(',');
+        sb.append(this.propagateTags);
+        sb.append(',');
+        sb.append(this.endPointDef1.toString());
+        sb.append(',');
+        sb.append(this.endPointDef2.toString());
+        sb.append('}');
+        return sb;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        //AttributeDefs are checked in the super
+        if (!super.equals(o))
+            return false;
+        AtlasRelationshipDef that = (AtlasRelationshipDef) o;
+        if (!Objects.equals(relationshipCategory, that.getRelationshipCategory()))
+            return false;
+        if (!Objects.equals(propagateTags, that.getPropagateTags()))
+            return false;
+        if (!Objects.equals(endPointDef1, that.getEndPointDef1()))
+            return false;
+        return (Objects.equals(endPointDef2, that.getEndPointDef2()));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), relationshipCategory, propagateTags, endPointDef1, endPointDef2);
+    }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java
new file mode 100644
index 0000000..dde8416
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndPointDef.java
@@ -0,0 +1,193 @@
+/**
+ * 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.typedef;
+
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
+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.Objects;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+/**
+ * The relationshipEndPointsDef represents an end of the relationship. The end of the relationship is defined by a type, an
+ * attribute name, cardinality and whether it  is the container end of the relationship.
+ */
+@JsonAutoDetect(getterVisibility = PUBLIC_ONLY, setterVisibility = PUBLIC_ONLY, fieldVisibility = NONE)
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown = true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasRelationshipEndPointDef implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * The type associated with the endpoint.
+     */
+    private String type;
+    /**
+     * The name of the attribute for this endpoint
+     */
+    private String name;
+
+    /**
+     * When set this indicates that this end is the container end
+     */
+    private boolean isContainer;
+    /**
+     * This is the cardinality of the end point
+     */
+    private Cardinality cardinality;
+
+    /**
+     * Base constructor
+     */
+    public AtlasRelationshipEndPointDef() {
+        this(null, null, Cardinality.SINGLE, false);
+    }
+
+    /**
+     *
+     * @param typeName
+     *   - The name of an entityDef type
+     * @param name
+     *   - The name of the new attribute that the entity instance will pick up.
+     * @param cardinality
+     *   - this indicates whether the end point is SINGLE (1) or SET (many)
+     */
+    public AtlasRelationshipEndPointDef(String typeName, String name, Cardinality cardinality) {
+        this(typeName, name, cardinality, false);
+    }
+
+    /**
+     *
+     * @param typeName
+     *   - The name of an entityDef type
+     * @param name
+     *   - The name of the new attribute that the entity instance will pick up.
+     * @param cardinality
+     *   - whether the end point is SINGLE (1) or SET (many)
+     * @param isContainer
+     *   - whether the end point is a container or not
+     */
+    public AtlasRelationshipEndPointDef(String typeName, String name, Cardinality cardinality, boolean isContainer) {
+        setType(typeName);
+        setName(name);
+        setCardinality(cardinality);
+        setIsContainer(isContainer);
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * set whether this endpoint is a container or not.
+     * @param isContainer
+     */
+    public void setIsContainer(boolean isContainer) {
+        this.isContainer = isContainer;
+    }
+
+    public boolean getIsContainer() {
+        return isContainer;
+    }
+
+    /**
+     * set the cardinality SINGLE or SET on the endpoint.
+     * @param cardinality
+     */
+    public void setCardinality(AtlasStructDef.AtlasAttributeDef.Cardinality cardinality) {
+        this.cardinality = cardinality;
+    }
+
+    /**
+     *
+     * @return the cardinality
+     */
+    public Cardinality getCardinality() {
+        return this.cardinality;
+    }
+
+    /**
+     * Construct using an existing AtlasRelationshipEndPointDef
+     * @param other
+     */
+    public AtlasRelationshipEndPointDef(AtlasRelationshipEndPointDef other) {
+        if (other != null) {
+            setType(other.getType());
+            setName(other.getName());
+            setIsContainer(other.getIsContainer());
+            setCardinality(other.getCardinality());
+        }
+    }
+
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("AtlasRelationshipEndPointsDef{");
+        sb.append("type='").append(type).append('\'');
+        sb.append(", name==>'").append(name).append('\'');
+        sb.append(", isContainer==>'").append(isContainer).append('\'');
+        sb.append(", cardinality==>'").append(cardinality).append('\'');
+        sb.append('}');
+
+        return sb;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o)
+            return true;
+        if (o == null || getClass() != o.getClass())
+            return false;
+        AtlasRelationshipEndPointDef that = (AtlasRelationshipEndPointDef) o;
+        return Objects.equals(type, that.type) && Objects.equals(name, that.name)
+                && (isContainer == that.isContainer) && (cardinality == that.cardinality);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(type, getName(), isContainer, cardinality);
+    }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
index af95bff..66ae503 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasTypesDef.java
@@ -17,11 +17,8 @@
  */
 package org.apache.atlas.model.typedef;
 
-import org.apache.commons.collections.CollectionUtils;
-import org.codehaus.jackson.annotate.JsonAutoDetect;
-import org.codehaus.jackson.annotate.JsonIgnore;
-import org.codehaus.jackson.annotate.JsonIgnoreProperties;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -31,8 +28,11 @@ import javax.xml.bind.annotation.XmlAccessType;
 import javax.xml.bind.annotation.XmlAccessorType;
 import javax.xml.bind.annotation.XmlRootElement;
 
-import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
-import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+import org.apache.commons.collections.CollectionUtils;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.annotate.JsonIgnoreProperties;
+import org.codehaus.jackson.map.annotate.JsonSerialize;
 
 @JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
 @JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
@@ -44,29 +44,50 @@ public class AtlasTypesDef {
     private List<AtlasStructDef>         structDefs;
     private List<AtlasClassificationDef> classificationDefs;
     private List<AtlasEntityDef>         entityDefs;
+    private List<AtlasRelationshipDef>   relationshipDefs;
 
     public AtlasTypesDef() {
         enumDefs           = new ArrayList<>();
         structDefs         = new ArrayList<>();
         classificationDefs = new ArrayList<>();
         entityDefs         = new ArrayList<>();
-    }
-
+        relationshipDefs   = new ArrayList<>();
+    }
+
+    /**
+     * tolerate typeDef creations that do not contain relationshipDefs, so that
+     * the older calls will still work.
+     * @param enumDefs
+     * @param structDefs
+     * @param classificationDefs
+     * @param entityDefs
+     */
+    public AtlasTypesDef(List<AtlasEnumDef> enumDefs, List<AtlasStructDef> structDefs,
+                         List<AtlasClassificationDef> classificationDefs, List<AtlasEntityDef> entityDefs) {
+       this(enumDefs, structDefs, classificationDefs, entityDefs,new ArrayList<AtlasRelationshipDef>());
+    }
+    /**
+     * Create the TypesDef. This created definitions for each of the types.
+     * @param enumDefs
+     * @param structDefs
+     * @param classificationDefs
+     * @param entityDefs
+     * @param relationshipDefs
+     */
     public AtlasTypesDef(List<AtlasEnumDef>           enumDefs,
                          List<AtlasStructDef>         structDefs,
                          List<AtlasClassificationDef> classificationDefs,
-                         List<AtlasEntityDef>         entityDefs) {
+                         List<AtlasEntityDef>         entityDefs,
+                         List<AtlasRelationshipDef>   relationshipDefs) {
         this.enumDefs           = enumDefs;
         this.structDefs         = structDefs;
         this.classificationDefs = classificationDefs;
         this.entityDefs         = entityDefs;
+        this.relationshipDefs   = relationshipDefs;
     }
-
-
     public List<AtlasEnumDef> getEnumDefs() {
         return enumDefs;
     }
-
     public void setEnumDefs(List<AtlasEnumDef> enumDefs) {
         this.enumDefs = enumDefs;
     }
@@ -94,7 +115,13 @@ public class AtlasTypesDef {
     public void setClassificationDefs(List<AtlasClassificationDef> classificationDefs) {
         this.classificationDefs = classificationDefs;
     }
+    public List<AtlasRelationshipDef> getRelationshipDefs() {
+        return relationshipDefs;
+    }
 
+    public void setRelationshipDefs(List<AtlasRelationshipDef> relationshipDefs) {
+        this.relationshipDefs = relationshipDefs;
+    }
 
     public boolean hasClassificationDef(String name) {
         return hasTypeDef(classificationDefs, name);
@@ -111,6 +138,9 @@ public class AtlasTypesDef {
     public boolean hasEntityDef(String name) {
         return hasTypeDef(entityDefs, name);
     }
+    public boolean hasRelationshipDef(String name) {
+        return hasTypeDef(relationshipDefs, name);
+    }
 
 
     private <T extends AtlasBaseTypeDef> boolean hasTypeDef(Collection<T> typeDefs, String name) {
@@ -130,7 +160,8 @@ public class AtlasTypesDef {
         return CollectionUtils.isEmpty(enumDefs) &&
                 CollectionUtils.isEmpty(structDefs) &&
                 CollectionUtils.isEmpty(classificationDefs) &&
-                CollectionUtils.isEmpty(entityDefs);
+                CollectionUtils.isEmpty(entityDefs) &&
+                CollectionUtils.isEmpty(relationshipDefs);
     }
 
     public void clear() {
@@ -149,8 +180,10 @@ public class AtlasTypesDef {
         if (entityDefs != null) {
             entityDefs.clear();
         }
+        if (relationshipDefs != null) {
+            relationshipDefs.clear();
+        }
     }
-
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
             sb = new StringBuilder();
@@ -169,6 +202,9 @@ public class AtlasTypesDef {
         sb.append("entityDefs={");
         AtlasBaseTypeDef.dumpObjects(entityDefs, sb);
         sb.append("}");
+        sb.append("relationshipDefs={");
+        AtlasBaseTypeDef.dumpObjects(relationshipDefs, sb);
+        sb.append("}");
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java b/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
index 198bd8f..e1c5a7f 100644
--- a/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
+++ b/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
@@ -24,6 +24,7 @@ import org.apache.atlas.model.typedef.AtlasClassificationDef;
 import org.apache.atlas.model.typedef.AtlasClassificationDef.AtlasClassificationDefs;
 import org.apache.atlas.model.typedef.AtlasEntityDef;
 import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
 
@@ -76,6 +77,15 @@ public interface AtlasTypeDefStore {
     AtlasEntityDef updateEntityDefByName(String name, AtlasEntityDef entityDef) throws AtlasBaseException;
 
     AtlasEntityDef updateEntityDefByGuid(String guid, AtlasEntityDef entityDef) throws AtlasBaseException;
+    /* RelationshipDef operations */
+
+    AtlasRelationshipDef getRelationshipDefByName(String name) throws AtlasBaseException;
+
+    AtlasRelationshipDef getRelationshipDefByGuid(String guid) throws AtlasBaseException;
+
+    AtlasRelationshipDef updateRelationshipDefByName(String name, AtlasRelationshipDef structDef) throws AtlasBaseException;
+
+    AtlasRelationshipDef updateRelationshipDefByGuid(String guid, AtlasRelationshipDef structDef) throws AtlasBaseException;
 
     /* Bulk Operations */
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
new file mode 100644
index 0000000..6328108
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
@@ -0,0 +1,151 @@
+/**
+ * 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.type;
+
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * class that implements behaviour of an relationship-type.
+ */
+public class AtlasRelationshipType extends AtlasStructType {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipType.class);
+
+    private final AtlasRelationshipDef relationshipDef;
+
+    public AtlasRelationshipType(AtlasRelationshipDef relationshipDef) {
+        super(relationshipDef);
+
+        this.relationshipDef = relationshipDef;
+    }
+
+    public AtlasRelationshipType(AtlasRelationshipDef relationshipDef, AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+        super(relationshipDef);
+
+        this.relationshipDef = relationshipDef;
+
+        resolveReferences(typeRegistry);
+    }
+    public AtlasRelationshipDef getRelationshipDef() { return relationshipDef; }
+
+    @Override
+    public void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+        super.resolveReferences(typeRegistry);
+
+        validateAtlasRelationshipDef(this.relationshipDef);
+    }
+
+    @Override
+    public boolean isValidValue(Object obj) {
+        boolean ret = true;
+
+        if (obj != null) {
+           validateAtlasRelationshipType((AtlasRelationshipType) obj);
+           ret = super.isValidValue(obj);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public boolean isValidValueForUpdate(Object obj) {
+        boolean ret = true;
+
+        if (obj != null) {
+            validateAtlasRelationshipType((AtlasRelationshipType) obj);
+            ret = super.isValidValueForUpdate(obj);
+        }
+
+        return ret;
+    }
+    /**
+     * Validate the fields in the the RelationshipType are consistent with respect to themselves.
+     * @param type
+     * @throws AtlasBaseException
+     */
+    private boolean validateAtlasRelationshipType(AtlasRelationshipType type) {
+        boolean isValid = false;
+        try {
+            validateAtlasRelationshipDef(type.getRelationshipDef());
+            isValid = true;
+        } catch (AtlasBaseException abe) {
+            LOG.error("Validation error for AtlasRelationshipType", abe);
+        }
+        return isValid;
+    }
+
+    /**
+     * Throw an exception so we can junit easily.
+     * @param relationshipDef
+     * @throws AtlasBaseException
+     */
+    public static void validateAtlasRelationshipDef(AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
+        AtlasRelationshipEndPointDef endPointDef1 = relationshipDef.getEndPointDef1();
+        AtlasRelationshipEndPointDef endPointDef2 = relationshipDef.getEndPointDef2();
+        boolean                      isContainer1 = endPointDef1.getIsContainer();
+        boolean                      isContainer2 = endPointDef2.getIsContainer();
+        RelationshipCategory relationshipCategory = relationshipDef.getRelationshipCategory();
+        String                       name         = relationshipDef.getName();
+
+        if (isContainer1 && isContainer2) {
+            // we support 0 or 1 of these flags.
+            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_DOUBLE_CONTAINERS, name);
+        }
+        if ((isContainer1 || isContainer2)) {
+            // we have an isContainer defined in an endpoint
+            if (relationshipCategory == RelationshipCategory.ASSOCIATION) {
+                // associations are not containment relaitonships - so do not allow an endpoiint with isContainer
+                throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER, name);
+            }
+        } else {
+            // we do not have an isContainer defined in an endpoint
+            if (relationshipCategory == RelationshipCategory.COMPOSITION) {
+                // COMPOSITION needs one endpoint to be the container.
+                throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER, name);
+            } else if (relationshipCategory == RelationshipCategory.AGGREGATION) {
+                // AGGREGATION needs one endpoint to be the container.
+                throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER, name);
+            }
+        }
+        if (relationshipCategory == RelationshipCategory.COMPOSITION) {
+            // composition containers should not be multiple cardinality
+            if (endPointDef1 != null &&
+                    endPointDef1.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
+                    endPointDef1.getIsContainer()) {
+                throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER, name);
+            }
+            if (endPointDef2 != null && endPointDef2 != null &&
+                    endPointDef2.getCardinality() == AtlasAttributeDef.Cardinality.SET &&
+                    endPointDef2.getIsContainer()) {
+                throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER, name);
+            }
+        }
+        if ((endPointDef1 != null && endPointDef1.getCardinality() == AtlasAttributeDef.Cardinality.LIST) ||
+                (endPointDef2 != null && endPointDef2.getCardinality() == AtlasAttributeDef.Cardinality.LIST)) {
+            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT, name);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
index 1b3526b..aebd4d1 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -17,12 +17,30 @@
  */
 package org.apache.atlas.type;
 
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_PREFIX;
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_SUFFIX;
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_KEY_VAL_SEP;
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_PREFIX;
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_SUFFIX;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.inject.Singleton;
+
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
 import org.apache.atlas.model.typedef.AtlasClassificationDef;
 import org.apache.atlas.model.typedef.AtlasEntityDef;
 import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
 import org.apache.commons.collections.CollectionUtils;
@@ -30,19 +48,6 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
-
-import javax.inject.Singleton;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-
-import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;
-
 /**
  * registry for all types defined in Atlas.
  */
@@ -183,7 +188,6 @@ public class AtlasTypeRegistry {
 
 
     public Collection<AtlasEntityDef> getAllEntityDefs() { return registryData.entityDefs.getAll(); }
-
     public AtlasEntityDef getEntityDefByGuid(String guid) {
         return registryData.entityDefs.getTypeDefByGuid(guid);
     }
@@ -193,12 +197,20 @@ public class AtlasTypeRegistry {
     }
 
     public Collection<String> getAllEntityDefNames() { return registryData.entityDefs.getAllNames(); }
-
     public Collection<AtlasEntityType> getAllEntityTypes() { return registryData.entityDefs.getAllTypes(); }
-
     public AtlasEntityType getEntityTypeByName(String name) { return registryData.entityDefs.getTypeByName(name); }
+    /**
+     * @return relationshipTypes
+     */
+    public Collection<AtlasRelationshipType> getAllRelationshipTypes() { return registryData.relationshipDefs.getAllTypes(); }
 
-
+    public AtlasRelationshipDef getRelationshipDefByGuid(String guid) {
+        return registryData.relationshipDefs.getTypeDefByGuid(guid);
+    }
+    public AtlasRelationshipDef getRelationshipDefByName(String name) {
+        return registryData.relationshipDefs.getTypeDefByName(name);
+    }
+    public AtlasRelationshipType getRelationshipTypeByName(String name) { return registryData.relationshipDefs.getTypeByName(name); }
     public AtlasTransientTypeRegistry lockTypeRegistryForUpdate() throws AtlasBaseException {
         return lockTypeRegistryForUpdate(DEFAULT_LOCK_MAX_WAIT_TIME_IN_SECONDS);
     }
@@ -218,6 +230,7 @@ public class AtlasTypeRegistry {
         final TypeDefCache<AtlasStructDef, AtlasStructType>                   structDefs;
         final TypeDefCache<AtlasClassificationDef, AtlasClassificationType>   classificationDefs;
         final TypeDefCache<AtlasEntityDef, AtlasEntityType>                   entityDefs;
+        final TypeDefCache<AtlasRelationshipDef, AtlasRelationshipType>       relationshipDefs;
         final TypeDefCache<? extends AtlasBaseTypeDef, ? extends AtlasType>[] allDefCaches;
 
         RegistryData() {
@@ -226,7 +239,8 @@ public class AtlasTypeRegistry {
             structDefs         = new TypeDefCache<>(allTypes);
             classificationDefs = new TypeDefCache<>(allTypes);
             entityDefs         = new TypeDefCache<>(allTypes);
-            allDefCaches       = new TypeDefCache[] { enumDefs, structDefs, classificationDefs, entityDefs };
+            relationshipDefs   = new TypeDefCache<>(allTypes);
+            allDefCaches       = new TypeDefCache[] { enumDefs, structDefs, classificationDefs, entityDefs, relationshipDefs };
 
             init();
         }
@@ -284,6 +298,7 @@ public class AtlasTypeRegistry {
                 structDefs.updateGuid(typeName, guid);
                 classificationDefs.updateGuid(typeName, guid);
                 entityDefs.updateGuid(typeName, guid);
+                relationshipDefs.updateGuid(typeName, guid);
             }
         }
 
@@ -293,6 +308,7 @@ public class AtlasTypeRegistry {
                 structDefs.removeTypeDefByGuid(guid);
                 classificationDefs.removeTypeDefByGuid(guid);
                 entityDefs.removeTypeDefByGuid(guid);
+                relationshipDefs.removeTypeDefByGuid(guid);
             }
         }
 
@@ -302,6 +318,7 @@ public class AtlasTypeRegistry {
                 structDefs.removeTypeDefByName(typeName);
                 classificationDefs.removeTypeDefByName(typeName);
                 entityDefs.removeTypeDefByName(typeName);
+                relationshipDefs.removeTypeDefByName(typeName);
             }
         }
 
@@ -311,6 +328,7 @@ public class AtlasTypeRegistry {
             structDefs.clear();
             classificationDefs.clear();
             entityDefs.clear();
+            relationshipDefs.clear();
 
             init();
         }
@@ -403,6 +421,7 @@ public class AtlasTypeRegistry {
                 addTypesWithNoRefResolve(typesDef.getStructDefs());
                 addTypesWithNoRefResolve(typesDef.getClassificationDefs());
                 addTypesWithNoRefResolve(typesDef.getEntityDefs());
+                addTypesWithNoRefResolve(typesDef.getRelationshipDefs());
 
                 resolveReferences();
             }
@@ -502,6 +521,7 @@ public class AtlasTypeRegistry {
                 updateTypesWithNoRefResolve(typesDef.getStructDefs());
                 updateTypesWithNoRefResolve(typesDef.getClassificationDefs());
                 updateTypesWithNoRefResolve(typesDef.getEntityDefs());
+                updateTypesWithNoRefResolve(typesDef.getRelationshipDefs());
             }
 
             if (LOG.isDebugEnabled()) {
@@ -515,6 +535,7 @@ public class AtlasTypeRegistry {
                 removeTypesWithNoRefResolve(typesDef.getStructDefs());
                 removeTypesWithNoRefResolve(typesDef.getClassificationDefs());
                 removeTypesWithNoRefResolve(typesDef.getEntityDefs());
+                removeTypesWithNoRefResolve(typesDef.getRelationshipDefs());
 
                 resolveReferences();
             }
@@ -546,6 +567,9 @@ public class AtlasTypeRegistry {
                 case ENTITY:
                     registryData.entityDefs.removeTypeDefByName(typeDef.getName());
                     break;
+                case RELATIONSHIP:
+                    registryData.relationshipDefs.removeTypeDefByName(typeDef.getName());
+                    break;
             }
             deletedTypes.add(typeDef);
         }
@@ -564,6 +588,9 @@ public class AtlasTypeRegistry {
                 case ENTITY:
                     registryData.entityDefs.removeTypeDefByGuid(typeDef.getGuid());
                     break;
+                case RELATIONSHIP:
+                    registryData.relationshipDefs.removeTypeDefByGuid(typeDef.getGuid());
+                    break;
             }
             deletedTypes.add(typeDef);
         }
@@ -641,11 +668,15 @@ public class AtlasTypeRegistry {
                     AtlasClassificationDef classificationDef = (AtlasClassificationDef) typeDef;
 
                     registryData.classificationDefs.addType(classificationDef,
-                                                            new AtlasClassificationType(classificationDef));
+                            new AtlasClassificationType(classificationDef));
                 } else if (typeDef.getClass().equals(AtlasEntityDef.class)) {
                     AtlasEntityDef entityDef = (AtlasEntityDef) typeDef;
 
                     registryData.entityDefs.addType(entityDef, new AtlasEntityType(entityDef));
+                } else if (typeDef.getClass().equals(AtlasRelationshipDef.class)) {
+                    AtlasRelationshipDef relationshipDef = (AtlasRelationshipDef) typeDef;
+
+                    registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
                 }
 
                 addedTypes.add(typeDef);
@@ -659,7 +690,7 @@ public class AtlasTypeRegistry {
         private void addTypesWithNoRefResolve(Collection<? extends AtlasBaseTypeDef> typeDefs) throws AtlasBaseException {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("==> AtlasTypeRegistry.addTypesWithNoRefResolve(length={})",
-                          (typeDefs == null ? 0 : typeDefs.size()));
+                        (typeDefs == null ? 0 : typeDefs.size()));
             }
 
             if (CollectionUtils.isNotEmpty(typeDefs)) {
@@ -670,7 +701,7 @@ public class AtlasTypeRegistry {
 
             if (LOG.isDebugEnabled()) {
                 LOG.debug("<== AtlasTypeRegistry.addTypesWithNoRefResolve(length={})",
-                          (typeDefs == null ? 0 : typeDefs.size()));
+                        (typeDefs == null ? 0 : typeDefs.size()));
             }
         }
 
@@ -714,12 +745,17 @@ public class AtlasTypeRegistry {
 
                     registryData.classificationDefs.removeTypeDefByGuid(guid);
                     registryData.classificationDefs.addType(classificationDef,
-                                                            new AtlasClassificationType(classificationDef));
+                            new AtlasClassificationType(classificationDef));
                 } else if (typeDef.getClass().equals(AtlasEntityDef.class)) {
                     AtlasEntityDef entityDef = (AtlasEntityDef) typeDef;
 
                     registryData.entityDefs.removeTypeDefByGuid(guid);
                     registryData.entityDefs.addType(entityDef, new AtlasEntityType(entityDef));
+                } else if (typeDef.getClass().equals(AtlasRelationshipDef.class)) {
+                    AtlasRelationshipDef relationshipDef = (AtlasRelationshipDef) typeDef;
+
+                    registryData.relationshipDefs.removeTypeDefByGuid(guid);
+                    registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
                 }
 
                 updatedTypes.add(typeDef);
@@ -751,12 +787,17 @@ public class AtlasTypeRegistry {
 
                     registryData.classificationDefs.removeTypeDefByName(name);
                     registryData.classificationDefs.addType(classificationDef,
-                                                            new AtlasClassificationType(classificationDef));
+                            new AtlasClassificationType(classificationDef));
                 } else if (typeDef.getClass().equals(AtlasEntityDef.class)) {
                     AtlasEntityDef entityDef = (AtlasEntityDef) typeDef;
 
                     registryData.entityDefs.removeTypeDefByName(name);
                     registryData.entityDefs.addType(entityDef, new AtlasEntityType(entityDef));
+                } else if (typeDef.getClass().equals(AtlasRelationshipDef.class)) {
+                    AtlasRelationshipDef relationshipDef = (AtlasRelationshipDef) typeDef;
+
+                    registryData.relationshipDefs.removeTypeDefByName(name);
+                    registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
                 }
 
                 updatedTypes.add(typeDef);
@@ -770,7 +811,7 @@ public class AtlasTypeRegistry {
         private void updateTypesWithNoRefResolve(Collection<? extends AtlasBaseTypeDef> typeDefs) {
             if (LOG.isDebugEnabled()) {
                 LOG.debug("==> AtlasTypeRegistry.updateTypesWithNoRefResolve(length={})",
-                                                                             (typeDefs == null ? 0 : typeDefs.size()));
+                        (typeDefs == null ? 0 : typeDefs.size()));
             }
 
             if (CollectionUtils.isNotEmpty(typeDefs)) {
@@ -781,7 +822,7 @@ public class AtlasTypeRegistry {
 
             if (LOG.isDebugEnabled()) {
                 LOG.debug("<== AtlasTypeRegistry.updateTypesWithNoRefResolve(length={})",
-                                                                              (typeDefs == null ? 0 : typeDefs.size()));
+                        (typeDefs == null ? 0 : typeDefs.size()));
             }
         }
     }
@@ -808,7 +849,7 @@ public class AtlasTypeRegistry {
                 }
             } else {
                 LOG.warn("lockTypeRegistryForUpdate(): already locked. currentLockCount={}",
-                         typeRegistryUpdateLock.getHoldCount());
+                        typeRegistryUpdateLock.getHoldCount());
             }
 
             try {
@@ -842,8 +883,8 @@ public class AtlasTypeRegistry {
                 try {
                     if (typeRegistryUnderUpdate != ttr) {
                         LOG.error("releaseTypeRegistryForUpdate(): incorrect typeRegistry returned for release" +
-                                  ": found=" + ttr + "; expected=" + typeRegistryUnderUpdate,
-                                  new Exception().fillInStackTrace());
+                                        ": found=" + ttr + "; expected=" + typeRegistryUnderUpdate,
+                                new Exception().fillInStackTrace());
                     } else if (typeRegistryUpdateLock.getHoldCount() == 1) {
                         if (ttr != null && commitUpdates) {
                             typeRegistry.registryData = ttr.registryData;
@@ -861,7 +902,7 @@ public class AtlasTypeRegistry {
                 }
             } else {
                 LOG.error("releaseTypeRegistryForUpdate(): current thread does not hold the lock",
-                          new Exception().fillInStackTrace());
+                        new Exception().fillInStackTrace());
             }
 
             LOG.debug("<== releaseTypeRegistryForUpdate()");

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/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 c0135f5..3125668 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
@@ -18,47 +18,23 @@
 package org.apache.atlas.type;
 
 import com.google.common.collect.ImmutableSet;
-
-import org.apache.atlas.AtlasErrorCode;
-import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity;
 import org.apache.atlas.model.instance.AtlasEntityHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
-import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
-import org.apache.atlas.model.typedef.AtlasClassificationDef;
-import org.apache.atlas.model.typedef.AtlasEntityDef;
-import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.*;
 import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
-import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
-import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
-import org.apache.atlas.model.typedef.AtlasTypesDef;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang.StringUtils;
 
-
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_PREFIX;
-import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_ARRAY_SUFFIX;
-import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_KEY_VAL_SEP;
-import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_PREFIX;
-import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_TYPE_MAP_SUFFIX;
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.*;
 
 /**
  * Utility methods for AtlasType/AtlasTypeDef.
@@ -294,6 +270,11 @@ public class AtlasTypeUtil {
                 headerList.add(new AtlasTypeDefHeader(entityDef));
             }
         }
+        if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
+            for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
+                headerList.add(new AtlasTypeDefHeader(relationshipDef));
+            }
+        }
 
         return headerList;
     }
@@ -390,6 +371,10 @@ public class AtlasTypeUtil {
             sb.append("entityDefs=[");
             dumpTypeNames(typesDef.getEntityDefs(), sb);
             sb.append("]");
+
+            sb.append("relationshipDefs=[");
+            dumpTypeNames(typesDef.getRelationshipDefs(), sb);
+            sb.append("]");
         }
         sb.append("}");
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java b/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
index 084bcc4..e1ca889 100644
--- a/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
+++ b/intg/src/test/java/org/apache/atlas/model/ModelTestUtil.java
@@ -21,12 +21,8 @@ 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.AtlasStruct;
-import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
-import org.apache.atlas.model.typedef.AtlasClassificationDef;
-import org.apache.atlas.model.typedef.AtlasEntityDef;
-import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.*;
 import org.apache.atlas.model.typedef.AtlasEnumDef.AtlasEnumElementDef;
-import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
@@ -43,6 +39,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_BUILTIN_TYPES;
 import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_PRIMITIVE_TYPES;
+import static org.apache.atlas.model.typedef.AtlasBaseTypeDef.ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES;
 
 
 public final class  ModelTestUtil {
@@ -441,6 +438,67 @@ public final class  ModelTestUtil {
         return ret;
     }
 
+    /**
+     * Valid types for attributes in relationships. This has good coverage of all attribute type and includes enums
+     * maps and arrays.
+     * This test does not use getRandomBuiltInType() style - so that it is deterministic.
+     *
+     * It does cover very nested maps / arrays.
+     * @param attrNamePrefix
+     * @return
+     */
+    public static List<AtlasAttributeDef> newAttributeDefsWithAllBuiltInTypesForRelationship(String attrNamePrefix) {
+        List<AtlasAttributeDef> ret = new ArrayList<>();
+
+        // add enum types
+        ret.add(getAttributeDef(attrNamePrefix, ENUM_DEF.getName()));
+        ret.add(getAttributeDef(attrNamePrefix, ENUM_DEF_WITH_NO_DEFAULT.getName()));
+        // add array of enum types
+        ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(ENUM_DEF.getName())));
+        ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(ENUM_DEF_WITH_NO_DEFAULT.getName())));
+
+
+        for (String attributeType : ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES) {
+
+            // simple attributes
+            ret.add(getAttributeDef(attrNamePrefix, attributeType));
+            // array
+            ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(attributeType)));
+            // map types with enum as key
+            ret.add(getAttributeDef(attrNamePrefix,
+                    AtlasBaseTypeDef.getMapTypeName(ENUM_DEF.getName(), attributeType)));
+            // map types with enum as key no default
+            ret.add(getAttributeDef(attrNamePrefix,
+                    AtlasBaseTypeDef.getMapTypeName(ENUM_DEF_WITH_NO_DEFAULT.getName(), attributeType)));
+             // map types attribute as key enum no default as value
+            ret.add(getAttributeDef(attrNamePrefix,
+                    AtlasBaseTypeDef.getMapTypeName(attributeType, ENUM_DEF_WITH_NO_DEFAULT.getName())));
+            // map types with enum as value
+            ret.add(getAttributeDef(attrNamePrefix,
+                    AtlasBaseTypeDef.getMapTypeName(attributeType, ENUM_DEF.getName())));
+
+            for (String attributeType2 : ATLAS_RELATIONSHIP_ATTRIBUTE_TYPES) {
+                // add map types
+                ret.add(getAttributeDef(attrNamePrefix,
+                        AtlasBaseTypeDef.getMapTypeName(attributeType, attributeType2)));
+                // add array of arrays
+                ret.add(getAttributeDef(attrNamePrefix,
+                        AtlasBaseTypeDef.getArrayTypeName(AtlasBaseTypeDef.getArrayTypeName(attributeType2))));
+                // add array of maps
+                ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getArrayTypeName(
+                        AtlasBaseTypeDef.getMapTypeName(attributeType, attributeType2))));
+                // add map of arrays
+                ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getMapTypeName(attributeType,
+                        AtlasBaseTypeDef.getArrayTypeName(attributeType2))));
+                // add map of maps
+                ret.add(getAttributeDef(attrNamePrefix, AtlasBaseTypeDef.getMapTypeName(attributeType,
+                        AtlasBaseTypeDef.getMapTypeName(attributeType, attributeType2))));
+            }
+        }
+
+        return ret;
+    }
+
     public static String getDefaultAttributeName(String attrType) {
         return PREFIX_ATTRIBUTE_NAME + attrType;
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
new file mode 100644
index 0000000..78efa6e
--- /dev/null
+++ b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasRelationshipDef.java
@@ -0,0 +1,96 @@
+/**
+ * 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.typedef;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.ModelTestUtil;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
+import org.apache.atlas.type.AtlasType;
+import org.testng.annotations.Test;
+
+import java.util.List;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNotNull;
+
+public class TestAtlasRelationshipDef {
+
+    private static final String PREFIX_ATTRIBUTE_NAME = "reltests-";
+    private List<AtlasStructDef.AtlasAttributeDef> attributeDefs;
+
+    @Test
+    public void testRelationshipDefSerDeEmpty() throws AtlasBaseException {
+
+        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
+        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
+        AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+
+        String jsonString = AtlasType.toJson(relationshipDef);
+        System.out.println(jsonString);
+        assertNotNull(jsonString);
+
+        AtlasRelationshipDef relationshipDef2 = AtlasType.fromJson(jsonString, AtlasRelationshipDef.class);
+        String jsonString2 = AtlasType.toJson(relationshipDef2);
+
+        assertEquals(jsonString, jsonString2);
+        assertEquals(relationshipDef2, relationshipDef,
+                "Incorrect serialization/deserialization of AtlasRelationshipDef");
+    }
+
+    @Test
+    public void testRelationshipDefSerDeAttributes() throws AtlasBaseException {
+
+        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
+        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
+        AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+        relationshipDef.setAttributeDefs(
+                ModelTestUtil.newAttributeDefsWithAllBuiltInTypesForRelationship(PREFIX_ATTRIBUTE_NAME));
+        String jsonString = AtlasType.toJson(relationshipDef);
+        assertNotNull(jsonString);
+
+        AtlasRelationshipDef relationshipDef2 = AtlasType.fromJson(jsonString, AtlasRelationshipDef.class);
+        String jsonString2 = AtlasType.toJson(relationshipDef2);
+
+        assertEquals(jsonString, jsonString2);
+        assertEquals(relationshipDef2, relationshipDef,
+                "Incorrect serialization/deserialization of AtlasRelationshipDef");
+    }
+    @Test
+    public void testRelationshipEquals() throws AtlasBaseException {
+
+        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", Cardinality.SINGLE);
+        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", Cardinality.SINGLE);
+        AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+        List<AtlasStructDef.AtlasAttributeDef> attributeDefs = ModelTestUtil.newAttributeDefsWithAllBuiltInTypesForRelationship(PREFIX_ATTRIBUTE_NAME);
+        relationshipDef1.setAttributeDefs(attributeDefs);
+        AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+        relationshipDef2.setAttributeDefs(attributeDefs);
+        assertEquals(relationshipDef1,relationshipDef2);
+
+        AtlasRelationshipDef relationshipDef3 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+
+        assertNotEquals(relationshipDef1,relationshipDef3);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
new file mode 100644
index 0000000..6af374a
--- /dev/null
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasRelationshipType.java
@@ -0,0 +1,107 @@
+/**
+ * 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.type;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.testng.annotations.Test;
+
+import static org.testng.AssertJUnit.fail;
+public class TestAtlasRelationshipType {
+    @Test
+    public void testvalidateAtlasRelationshipDef() throws AtlasBaseException {
+        AtlasRelationshipEndPointDef ep1 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        AtlasRelationshipEndPointDef ep2 = new AtlasRelationshipEndPointDef("typeB", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        AtlasRelationshipEndPointDef ep3 = new AtlasRelationshipEndPointDef("typeC", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
+        AtlasRelationshipEndPointDef ep4 = new AtlasRelationshipEndPointDef("typeD", "attr2", AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE, true);
+        AtlasRelationshipEndPointDef ep5 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.SET,true);
+        AtlasRelationshipEndPointDef ep6 = new AtlasRelationshipEndPointDef("typeA", "attr1", AtlasStructDef.AtlasAttributeDef.Cardinality.LIST,true);
+        AtlasRelationshipDef relationshipDef1 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+        AtlasRelationshipDef relationshipDef2 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep3);
+        AtlasRelationshipDef relationshipDef3 = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                AtlasRelationshipDef.RelationshipCategory.AGGREGATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep3);
+
+        try {
+            AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                    AtlasRelationshipDef.RelationshipCategory.ASSOCIATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep3, ep2);
+            AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
+            fail("This call is expected to fail");
+        } catch (AtlasBaseException abe) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_ASSOCIATION_AND_CONTAINER)) {
+                fail("This call expected a different error");
+            }
+        }
+        try {
+            AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                    AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+            AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
+            fail("This call is expected to fail");
+        } catch (AtlasBaseException abe) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_NO_CONTAINER)) {
+                fail("This call expected a different error");
+            }
+        }
+        try {
+            AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                    AtlasRelationshipDef.RelationshipCategory.AGGREGATION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep2);
+            AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
+            fail("This call is expected to fail");
+        } catch (AtlasBaseException abe) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER)) {
+                fail("This call expected a different error");
+            }
+        }
+
+        try {
+            AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                    AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep5);
+            AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
+            fail("This call is expected to fail");
+        } catch (AtlasBaseException abe) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER)) {
+                fail("This call expected a different error");
+            }
+        }
+        try {
+            AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                    AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep1, ep6);
+            AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
+            fail("This call is expected to fail");
+        } catch (AtlasBaseException abe) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT)) {
+                fail("This call expected a different error");
+            }
+        }
+        try {
+            AtlasRelationshipDef relationshipDef = new AtlasRelationshipDef("emptyRelationshipDef", "desc 1", "version1",
+                    AtlasRelationshipDef.RelationshipCategory.COMPOSITION, AtlasRelationshipDef.PropagateTags.ONE_TO_TWO, ep6, ep1);
+            AtlasRelationshipType.validateAtlasRelationshipDef(relationshipDef);
+            fail("This call is expected to fail");
+        } catch (AtlasBaseException abe) {
+            if (!abe.getAtlasErrorCode().equals(AtlasErrorCode.RELATIONSHIPDEF_LIST_ON_ENDPOINT)) {
+                fail("This call expected a different error");
+            }
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipDefStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipDefStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipDefStore.java
new file mode 100644
index 0000000..df67958
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipDefStore.java
@@ -0,0 +1,52 @@
+/**
+ * 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;
+
+import java.util.List;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
+
+/**
+ * Interface for graph persistence store for AtlasRelationshipDef
+ */
+public interface AtlasRelationshipDefStore {
+    Object preCreate(AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
+
+    AtlasRelationshipDef create(AtlasRelationshipDef relationshipDef, Object preCreateResult) throws AtlasBaseException;
+
+    List<AtlasRelationshipDef> getAll() throws AtlasBaseException;
+
+    AtlasRelationshipDef getByName(String name) throws AtlasBaseException;
+
+    AtlasRelationshipDef getByGuid(String guid) throws AtlasBaseException;
+
+    AtlasRelationshipDef update(AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
+
+    AtlasRelationshipDef updateByName(String name, AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
+
+    AtlasRelationshipDef updateByGuid(String guid, AtlasRelationshipDef relationshipDef) throws AtlasBaseException;
+
+    Object preDeleteByName(String name) throws AtlasBaseException;
+
+    void deleteByName(String name, Object preDeleteResult) throws AtlasBaseException;
+
+    Object preDeleteByGuid(String guid) throws AtlasBaseException;
+
+    void deleteByGuid(String guid, Object preDeleteResult) throws AtlasBaseException;
+}


[14/14] incubator-atlas git commit: ATLAS-1856: AtlasRelationship instance implementation Java/REST

Posted by ma...@apache.org.
ATLAS-1856: AtlasRelationship instance implementation Java/REST

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


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

Branch: refs/heads/feature-odf
Commit: 242b5585c97a9565ac35641d8a1ed8ee3a8fd883
Parents: c2d5275
Author: Sarath Subramanian <ss...@hortonworks.com>
Authored: Mon Jun 19 18:54:20 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Mon Jun 19 20:38:53 2017 -0700

----------------------------------------------------------------------
 .../atlas/authorize/AtlasResourceTypes.java     |   2 +-
 .../simple/AtlasAuthorizationUtils.java         |   2 +
 .../atlas/authorize/simple/PolicyParser.java    |   2 +
 .../repository/graphdb/AtlasGraphQuery.java     |   6 +
 .../titan/query/NativeTitanGraphQuery.java      |   6 +
 .../graphdb/titan/query/TitanGraphQuery.java    |  25 +-
 .../titan0/query/NativeTitan0GraphQuery.java    |   6 +
 .../repository/graphdb/titan1/Titan1Graph.java  |  17 +-
 .../titan1/query/NativeTitan1GraphQuery.java    |   8 +
 .../java/org/apache/atlas/AtlasErrorCode.java   |   4 +
 .../atlas/model/instance/AtlasRelationship.java | 243 ++++++++++++
 .../model/typedef/AtlasRelationshipEndDef.java  |  56 ++-
 .../org/apache/atlas/type/AtlasEntityType.java  |   4 +
 .../atlas/type/AtlasRelationshipType.java       |  25 ++
 .../apache/atlas/type/AtlasTypeRegistry.java    |   3 +
 .../atlas/repository/graph/GraphHelper.java     |  64 ++--
 .../store/graph/AtlasRelationshipStore.java     |  53 +++
 .../store/graph/v1/AtlasGraphUtilsV1.java       |  13 +
 .../graph/v1/AtlasRelationshipStoreV1.java      | 365 +++++++++++++++++++
 .../store/graph/v1/EntityGraphRetriever.java    |   3 +-
 .../typestore/GraphBackedTypeStore.java         |   4 +
 .../test/java/org/apache/atlas/TestModules.java |   3 +
 .../apache/atlas/web/rest/RelationshipREST.java | 137 +++++++
 23 files changed, 1001 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/authorization/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
----------------------------------------------------------------------
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java b/authorization/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
index deccf84..925b6b1 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/AtlasResourceTypes.java
@@ -19,5 +19,5 @@
 package org.apache.atlas.authorize;
 
 public enum AtlasResourceTypes {
-    UNKNOWN, ENTITY, TYPE, OPERATION, TAXONOMY, TERM
+    UNKNOWN, ENTITY, TYPE, OPERATION, TAXONOMY, TERM, RELATION
 }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
----------------------------------------------------------------------
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
index 93d988e..bb3157a 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
@@ -139,6 +139,8 @@ public class AtlasAuthorizationUtils {
             if (contextPath.contains("/terms")) {
                 resourceTypes.add(AtlasResourceTypes.TERM);
             }
+        } else if (api.startsWith("relation")) {
+            resourceTypes.add(AtlasResourceTypes.RELATION);
         } else {
             LOG.error("Unable to find Atlas Resource corresponding to : {}\nSetting {}"
                     , api, AtlasResourceTypes.UNKNOWN.name());

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/authorization/src/main/java/org/apache/atlas/authorize/simple/PolicyParser.java
----------------------------------------------------------------------
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/simple/PolicyParser.java b/authorization/src/main/java/org/apache/atlas/authorize/simple/PolicyParser.java
index 7ef49e6..acf7388 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/simple/PolicyParser.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/simple/PolicyParser.java
@@ -231,6 +231,8 @@ public class PolicyParser {
                     resourceType = AtlasResourceTypes.TAXONOMY;
                 } else if (type.equalsIgnoreCase("TERM")) {
                     resourceType = AtlasResourceTypes.TERM;
+                } else if (type.equalsIgnoreCase("RELATION")) {
+                    resourceType = AtlasResourceTypes.RELATION;
                 } else {
                     Log.warn(type + " is invalid resource please check PolicyStore file");
                     continue;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
----------------------------------------------------------------------
diff --git a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
index bd7b35e..841edf7 100644
--- a/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
+++ b/graphdb/api/src/main/java/org/apache/atlas/repository/graphdb/AtlasGraphQuery.java
@@ -60,6 +60,12 @@ public interface AtlasGraphQuery<V, E> {
      */
     Iterable<AtlasVertex<V, E>> vertices();
 
+    /**
+     * Executes the query and returns the matching edges.
+     * @return
+     */
+    Iterable<AtlasEdge<V, E>> edges();
+
 
     /**
      * Adds a predicate that the returned vertices must have the specified

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/NativeTitanGraphQuery.java
----------------------------------------------------------------------
diff --git a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/NativeTitanGraphQuery.java b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/NativeTitanGraphQuery.java
index 662a270..0211ff0 100644
--- a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/NativeTitanGraphQuery.java
+++ b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/NativeTitanGraphQuery.java
@@ -19,6 +19,7 @@ package org.apache.atlas.repository.graphdb.titan.query;
 
 import java.util.Collection;
 
+import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 
@@ -39,6 +40,11 @@ public interface NativeTitanGraphQuery<V, E> {
      */
     Iterable<AtlasVertex<V, E>> vertices();
 
+    /**
+     * Executes the graph query.
+     * @return
+     */
+    Iterable<AtlasEdge<V, E>> edges();
 
     /**
      * Adds an in condition to the query.

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/TitanGraphQuery.java
----------------------------------------------------------------------
diff --git a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/TitanGraphQuery.java b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/TitanGraphQuery.java
index 056088c..0077a21 100644
--- a/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/TitanGraphQuery.java
+++ b/graphdb/common/src/main/java/org/apache/atlas/repository/graphdb/titan/query/TitanGraphQuery.java
@@ -22,6 +22,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
@@ -121,8 +122,10 @@ public abstract class TitanGraphQuery<V, E> implements AtlasGraphQuery<V, E> {
 
     @Override
     public Iterable<AtlasVertex<V, E>> vertices() {
-        LOG.debug("Executing: ");
-        LOG.debug(queryCondition.toString());
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Executing: " + queryCondition.toString());
+        }
+
         //compute the overall result by unioning the results from all of the
         //AndConditions together.
         Set<AtlasVertex<V, E>> result = new HashSet<>();
@@ -136,6 +139,24 @@ public abstract class TitanGraphQuery<V, E> implements AtlasGraphQuery<V, E> {
     }
 
     @Override
+    public Iterable<AtlasEdge<V, E>> edges() {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Executing: " + queryCondition.toString());
+        }
+
+        //compute the overall result by unioning the results from all of the
+        //AndConditions together.
+        Set<AtlasEdge<V, E>> result = new HashSet<>();
+        for(AndCondition andExpr : queryCondition.getAndTerms()) {
+            NativeTitanGraphQuery<V, E> andQuery = andExpr.create(getQueryFactory());
+            for(AtlasEdge<V, E> edge : andQuery.edges()) {
+                result.add(edge);
+            }
+        }
+        return result;
+    }
+
+    @Override
     public AtlasGraphQuery<V, E> has(String propertyKey, ComparisionOperator operator,
             Object value) {
         queryCondition.andWith(new HasPredicate(propertyKey, operator, value));

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
----------------------------------------------------------------------
diff --git a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
index 5ad176b..7ec6ffe 100644
--- a/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
+++ b/graphdb/titan0/src/main/java/org/apache/atlas/repository/graphdb/titan0/query/NativeTitan0GraphQuery.java
@@ -19,6 +19,7 @@ package org.apache.atlas.repository.graphdb.titan0.query;
 
 import java.util.Collection;
 
+import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
@@ -54,6 +55,11 @@ public class NativeTitan0GraphQuery implements NativeTitanGraphQuery<Titan0Verte
         return graph.wrapVertices(it);
     }
 
+    @Override
+    public Iterable<AtlasEdge<Titan0Vertex, Titan0Edge>> edges() {
+        Iterable it = query.edges();
+        return graph.wrapEdges(it);
+    }
 
     @Override
     public void in(String propertyName, Collection<?> values) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/Titan1Graph.java
----------------------------------------------------------------------
diff --git a/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/Titan1Graph.java b/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/Titan1Graph.java
index e829d91..ffb6b37 100644
--- a/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/Titan1Graph.java
+++ b/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/Titan1Graph.java
@@ -384,11 +384,6 @@ public class Titan1Graph implements AtlasGraph<Titan1Vertex, Titan1Edge> {
         return expr;
     }
 
-    public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> wrapEdges(Iterator<Edge> it) {
-        Iterable<Edge> iterable = new IteratorToIterableAdapter<Edge>(it);
-        return wrapEdges(iterable);
-    }
-
     public Iterable<AtlasVertex<Titan1Vertex, Titan1Edge>> wrapVertices(Iterator<? extends Vertex> it) {
         Iterable<? extends Vertex> iterable = new IteratorToIterableAdapter<>(it);
         return wrapVertices(iterable);
@@ -406,15 +401,21 @@ public class Titan1Graph implements AtlasGraph<Titan1Vertex, Titan1Edge> {
 
     }
 
-    public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> wrapEdges(Iterable<Edge> it) {
-        Iterable<Edge> result = (Iterable<Edge>) it;
-        return Iterables.transform(result, new Function<Edge, AtlasEdge<Titan1Vertex, Titan1Edge>>() {
+    public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> wrapEdges(Iterator<? extends Edge> it) {
+        Iterable<? extends Edge> iterable = new IteratorToIterableAdapter<>(it);
+        return wrapEdges(iterable);
+    }
+
+    public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> wrapEdges(Iterable<? extends Edge> it) {
+
+        return Iterables.transform(it, new Function<Edge, AtlasEdge<Titan1Vertex, Titan1Edge>>() {
 
             @Override
             public AtlasEdge<Titan1Vertex, Titan1Edge> apply(Edge input) {
                 return GraphDbObjectFactory.createEdge(Titan1Graph.this, input);
             }
         });
+
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/query/NativeTitan1GraphQuery.java
----------------------------------------------------------------------
diff --git a/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/query/NativeTitan1GraphQuery.java b/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/query/NativeTitan1GraphQuery.java
index 9dc175b..1ca900d 100644
--- a/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/query/NativeTitan1GraphQuery.java
+++ b/graphdb/titan1/src/main/java/org/apache/atlas/repository/graphdb/titan1/query/NativeTitan1GraphQuery.java
@@ -19,6 +19,8 @@ package org.apache.atlas.repository.graphdb.titan1.query;
 
 import java.util.Collection;
 
+import com.thinkaurelius.titan.core.TitanEdge;
+import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasGraphQuery.ComparisionOperator;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.graphdb.titan.query.NativeTitanGraphQuery;
@@ -53,6 +55,12 @@ public class NativeTitan1GraphQuery implements NativeTitanGraphQuery<Titan1Verte
     }
 
     @Override
+    public Iterable<AtlasEdge<Titan1Vertex, Titan1Edge>> edges() {
+        Iterable<TitanEdge> it = query.edges();
+        return graph.wrapEdges(it);
+    }
+
+    @Override
     public void in(String propertyName, Collection<? extends Object> values) {
         query.has(propertyName, Contain.IN, values);
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/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 6c33f40..e8971a8 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -79,6 +79,8 @@ public enum AtlasErrorCode {
     RELATIONSHIPDEF_AGGREGATION_NO_CONTAINER(400,  "ATLAS-400-00-032", "AGGREGATION relationshipDef {0} creation attempted without an end specifying isContainer"),
     RELATIONSHIPDEF_COMPOSITION_SET_CONTAINER(400,  "ATLAS-400-00-033", "COMPOSITION relationshipDef {0} cannot have a SET cardinality and be a container"),
     RELATIONSHIPDEF_LIST_ON_END(400,  "ATLAS-400-00-034", "relationshipDef {0} cannot have a LIST cardinality on an end"),
+    RELATIONSHIPDEF_INVALID_END_TYPE(400,  "ATLAS-400-00-035", "relationshipDef {0} has invalid end type {1}"),
+    INVALID_RELATIONSHIP_END_TYPE(400, "ATLAS-400-00-036", "invalid end type for relationship {0}: expected {1}, found {2}"),
     // All Not found enums go here
     TYPE_NAME_NOT_FOUND(404, "ATLAS-404-00-001", "Given typename {0} was invalid"),
     TYPE_GUID_NOT_FOUND(404, "ATLAS-404-00-002", "Given type guid {0} was invalid"),
@@ -90,11 +92,13 @@ public enum AtlasErrorCode {
     INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND(404, "ATLAS-404-00-009", "Instance {0} with unique attribute {1} does not exist"),
     REFERENCED_ENTITY_NOT_FOUND(404, "ATLAS-404-00-00A", "Referenced entity {0} is not found"),
     INSTANCE_NOT_FOUND(404, "ATLAS-404-00-00B", "Given instance is invalid/not found: {0}"),
+    RELATIONSHIP_GUID_NOT_FOUND(404, "ATLAS-404-00-00C", "Given relationship guid {0} is invalid/not found"),
 
      // All data conflict errors go here
     TYPE_ALREADY_EXISTS(409, "ATLAS-409-00-001", "Given type {0} already exists"),
     TYPE_HAS_REFERENCES(409, "ATLAS-409-00-002", "Given type {0} has references"),
     INSTANCE_ALREADY_EXISTS(409, "ATLAS-409-00-003", "failed to update entity: {0}"),
+    RELATIONSHIP_ALREADY_EXISTS(409, "ATLAS-409-00-004", "relationship {0} already exists between entities {1} and {2}"),
 
      // All internal errors go here
     INTERNAL_ERROR(500, "ATLAS-500-00-001", "Internal server error {0}"),

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelationship.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelationship.java b/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelationship.java
new file mode 100644
index 0000000..8d2e7ec
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasRelationship.java
@@ -0,0 +1,243 @@
+/**
+ * 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.typedef.AtlasRelationshipDef;
+import org.codehaus.jackson.annotate.JsonAutoDetect;
+import org.codehaus.jackson.annotate.JsonIgnore;
+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.Date;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.NONE;
+import static org.codehaus.jackson.annotate.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+
+/**
+ * Atlas relationship instance.
+ */
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasRelationship extends AtlasStruct implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private String        guid       = null;
+    private AtlasObjectId end1       = null;
+    private AtlasObjectId end2       = null;
+    private Status        status     = Status.ACTIVE;
+    private String        createdBy  = null;
+    private String        updatedBy  = null;
+    private Date          createTime = null;
+    private Date          updateTime = null;
+    private Long          version    = 0L;
+
+    public enum Status { ACTIVE, DELETED }
+
+    @JsonIgnore
+    private static AtomicLong s_nextId = new AtomicLong(System.nanoTime());
+
+    public AtlasRelationship() {
+        super();
+
+        init();
+    }
+
+    public AtlasRelationship(String typeName) {
+        this(typeName, null);
+    }
+
+    public AtlasRelationship(String typeName, Map<String, Object> attributes) {
+        super(typeName, attributes);
+
+        init();
+    }
+
+    public AtlasRelationship(String typeName, AtlasObjectId end1, AtlasObjectId end2) {
+        super(typeName);
+
+        init(nextInternalId(), end1, end2, null, null, null, null, null, 0L);
+    }
+
+    public AtlasRelationship(String typeName, String attrName, Object attrValue) {
+        super(typeName, attrName, attrValue);
+
+        init();
+    }
+
+    public AtlasRelationship(AtlasRelationshipDef relationshipDef) {
+        this(relationshipDef != null ? relationshipDef.getName() : null);
+    }
+
+    public AtlasRelationship(AtlasRelationship other) {
+        super(other);
+
+        if (other != null) {
+            init(other.guid, other.end1, other.end2, other.status, other.createdBy, other.updatedBy,
+                 other.createTime, other.updateTime, other.version);
+        }
+    }
+
+    public String getGuid() {
+        return guid;
+    }
+
+    public void setGuid(String guid) {
+        this.guid = guid;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public String getCreatedBy() {
+        return createdBy;
+    }
+
+    public void setCreatedBy(String createdBy) {
+        this.createdBy = createdBy;
+    }
+
+    public String getUpdatedBy() {
+        return updatedBy;
+    }
+
+    public void setUpdatedBy(String updatedBy) {
+        this.updatedBy = updatedBy;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public Long getVersion() {
+        return version;
+    }
+
+    public void setVersion(Long version) {
+        this.version = version;
+    }
+
+    public AtlasObjectId getEnd1() { return end1; }
+
+    public void setEnd1(AtlasObjectId end1) { this.end1 = end1; }
+
+    public AtlasObjectId getEnd2() { return end2; }
+
+    public void setEnd2(AtlasObjectId end2) { this.end2 = end2; }
+
+    private static String nextInternalId() {
+        return "-" + Long.toString(s_nextId.getAndIncrement());
+    }
+
+    public String getRelationshipLabel() { return "r:" + super.getTypeName(); }
+
+    private void init() {
+        init(nextInternalId(), null, null, null, null, null, null, null, 0L);
+    }
+
+    private void init(String guid, AtlasObjectId end1, AtlasObjectId end2,
+                      Status status, String createdBy, String updatedBy,
+                      Date createTime, Date updateTime, Long version) {
+        setGuid(guid);
+        setEnd1(end1);
+        setEnd2(end2);
+        setStatus(status);
+        setCreatedBy(createdBy);
+        setUpdatedBy(updatedBy);
+        setCreateTime(createTime);
+        setUpdateTime(updateTime);
+        setVersion(version);
+    }
+
+    @Override
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("AtlasRelationship{");
+        super.toString(sb);
+        sb.append("guid='").append(guid).append('\'');
+        sb.append(", end1=").append(end1);
+        sb.append(", end2=").append(end2);
+        sb.append(", status=").append(status);
+        sb.append(", createdBy='").append(createdBy).append('\'');
+        sb.append(", updatedBy='").append(updatedBy).append('\'');
+        dumpDateField(", createTime=", createTime, sb);
+        dumpDateField(", updateTime=", updateTime, sb);
+        sb.append(", version=").append(version);
+        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; }
+
+        AtlasRelationship that = (AtlasRelationship) o;
+        return Objects.equals(guid, that.guid)             &&
+               Objects.equals(end1, that.end1)             &&
+               Objects.equals(end2, that.end2)             &&
+               status == that.status                       &&
+               Objects.equals(createdBy, that.createdBy)   &&
+               Objects.equals(updatedBy, that.updatedBy)   &&
+               Objects.equals(createTime, that.createTime) &&
+               Objects.equals(updateTime, that.updateTime) &&
+               Objects.equals(version, that.version);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), guid, end1, end2, status, createdBy, updatedBy, createTime, updateTime, version);
+    }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
index 000d747..34e932e 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasRelationshipEndDef.java
@@ -18,6 +18,7 @@
 package org.apache.atlas.model.typedef;
 
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
+import org.apache.commons.lang.StringUtils;
 import org.codehaus.jackson.annotate.JsonAutoDetect;
 import org.codehaus.jackson.annotate.JsonIgnoreProperties;
 import org.codehaus.jackson.map.annotate.JsonSerialize;
@@ -59,6 +60,10 @@ public class AtlasRelationshipEndDef implements Serializable {
      * This is the cardinality of the end
      */
     private Cardinality cardinality;
+    /**
+     * legacy edge label name of the endpoint
+     */
+    private String legacyLabel;
 
     /**
      * Base constructor
@@ -92,10 +97,29 @@ public class AtlasRelationshipEndDef implements Serializable {
      *   - whether the end is a container or not
      */
     public AtlasRelationshipEndDef(String typeName, String name, Cardinality cardinality, boolean isContainer) {
+        this(typeName, name, cardinality, isContainer, null);
+    }
+
+    public AtlasRelationshipEndDef(String typeName, String name, Cardinality cardinality, boolean isContainer, String legacyLabel) {
         setType(typeName);
         setName(name);
         setCardinality(cardinality);
         setIsContainer(isContainer);
+        setLegacyLabel(legacyLabel);
+    }
+
+    /**
+     * Construct using an existing AtlasRelationshipEndDef
+     * @param other
+     */
+    public AtlasRelationshipEndDef(AtlasRelationshipEndDef other) {
+        if (other != null) {
+            setType(other.getType());
+            setName(other.getName());
+            setIsContainer(other.getIsContainer());
+            setCardinality(other.getCardinality());
+            setLegacyLabel(other.getLegacyLabel());
+        }
     }
 
     public void setType(String type) {
@@ -142,18 +166,15 @@ public class AtlasRelationshipEndDef implements Serializable {
         return this.cardinality;
     }
 
-    /**
-     * Construct using an existing AtlasRelationshipEndDef
-     * @param other
-     */
-    public AtlasRelationshipEndDef(AtlasRelationshipEndDef other) {
-        if (other != null) {
-            setType(other.getType());
-            setName(other.getName());
-            setIsContainer(other.getIsContainer());
-            setCardinality(other.getCardinality());
-        }
-    }
+    public boolean isContainer() { return isContainer; }
+
+    public void setContainer(boolean container) { isContainer = container; }
+
+    public String getLegacyLabel() { return legacyLabel; }
+
+    public void setLegacyLabel(String legacyLabel) {  this.legacyLabel = legacyLabel; }
+
+    public boolean hasLegacyRelation() { return StringUtils.isNotEmpty(getLegacyLabel()) ? true : false; }
 
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
@@ -165,6 +186,7 @@ public class AtlasRelationshipEndDef implements Serializable {
         sb.append(", name==>'").append(name).append('\'');
         sb.append(", isContainer==>'").append(isContainer).append('\'');
         sb.append(", cardinality==>'").append(cardinality).append('\'');
+        sb.append(", legacyLabel==>'").append(legacyLabel).append('\'');
         sb.append('}');
 
         return sb;
@@ -177,13 +199,17 @@ public class AtlasRelationshipEndDef implements Serializable {
         if (o == null || getClass() != o.getClass())
             return false;
         AtlasRelationshipEndDef that = (AtlasRelationshipEndDef) o;
-        return Objects.equals(type, that.type) && Objects.equals(name, that.name)
-                && (isContainer == that.isContainer) && (cardinality == that.cardinality);
+
+        return Objects.equals(type, that.type) &&
+               Objects.equals(name, that.name) &&
+               isContainer == that.isContainer &&
+               cardinality == that.cardinality &&
+               Objects.equals(legacyLabel, that.legacyLabel);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(type, getName(), isContainer, cardinality);
+        return Objects.hash(type, getName(), isContainer, cardinality, legacyLabel);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/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 0ff1582..a29f7fb 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -128,6 +128,10 @@ public class AtlasEntityType extends AtlasStructType {
         return StringUtils.isNotEmpty(entityTypeName) && allSubTypes.contains(entityTypeName);
     }
 
+    public boolean isTypeOrSuperTypeOf(String entityTypeName) {
+        return StringUtils.isNotEmpty(entityTypeName) && typeAndAllSubTypes.contains(entityTypeName);
+    }
+
     public boolean isSubTypeOf(AtlasEntityType entityType) {
         return entityType != null && allSuperTypes.contains(entityType.getTypeName());
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
index eb2fc48..296c06c 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasRelationshipType.java
@@ -35,6 +35,8 @@ public class AtlasRelationshipType extends AtlasStructType {
     private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipType.class);
 
     private final AtlasRelationshipDef relationshipDef;
+    private       AtlasEntityType      end1Type;
+    private       AtlasEntityType      end2Type;
 
     public AtlasRelationshipType(AtlasRelationshipDef relationshipDef) {
         super(relationshipDef);
@@ -55,6 +57,24 @@ public class AtlasRelationshipType extends AtlasStructType {
     public void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
         super.resolveReferences(typeRegistry);
 
+        String end1TypeName = relationshipDef != null && relationshipDef.getEndDef1() != null ? relationshipDef.getEndDef1().getType() : null;
+        String end2TypeName = relationshipDef != null && relationshipDef.getEndDef2() != null ? relationshipDef.getEndDef2().getType() : null;
+
+        AtlasType type1 = typeRegistry.getType(end1TypeName);
+        AtlasType type2 = typeRegistry.getType(end2TypeName);
+
+        if (type1 instanceof AtlasEntityType) {
+            end1Type = (AtlasEntityType)type1;
+        } else {
+            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END_TYPE, getTypeName(), end1TypeName);
+        }
+
+        if (type2 instanceof AtlasEntityType) {
+            end2Type = (AtlasEntityType)type2;
+        } else {
+            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIPDEF_INVALID_END_TYPE, getTypeName(), end2TypeName);
+        }
+
         validateAtlasRelationshipDef(this.relationshipDef);
     }
 
@@ -81,6 +101,11 @@ public class AtlasRelationshipType extends AtlasStructType {
 
         return ret;
     }
+
+    public AtlasEntityType getEnd1Type() { return end1Type; }
+
+    public AtlasEntityType getEnd2Type() { return end2Type; }
+
     /**
      * Validate the fields in the the RelationshipType are consistent with respect to themselves.
      * @param type

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
index aebd4d1..29fae1c 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -186,6 +186,7 @@ public class AtlasTypeRegistry {
         return registryData.classificationDefs.getTypeByName(name);
     }
 
+    public Collection<AtlasRelationshipDef> getAllRelationshipDefs() { return registryData.relationshipDefs.getAll(); }
 
     public Collection<AtlasEntityDef> getAllEntityDefs() { return registryData.entityDefs.getAll(); }
     public AtlasEntityDef getEntityDefByGuid(String guid) {
@@ -211,6 +212,7 @@ public class AtlasTypeRegistry {
         return registryData.relationshipDefs.getTypeDefByName(name);
     }
     public AtlasRelationshipType getRelationshipTypeByName(String name) { return registryData.relationshipDefs.getTypeByName(name); }
+
     public AtlasTransientTypeRegistry lockTypeRegistryForUpdate() throws AtlasBaseException {
         return lockTypeRegistryForUpdate(DEFAULT_LOCK_MAX_WAIT_TIME_IN_SECONDS);
     }
@@ -347,6 +349,7 @@ public class AtlasTypeRegistry {
             addTypesWithNoRefResolve(parent.getAllStructDefs());
             addTypesWithNoRefResolve(parent.getAllClassificationDefs());
             addTypesWithNoRefResolve(parent.getAllEntityDefs());
+            addTypesWithNoRefResolve(parent.getAllRelationshipDefs());
 
             addedTypes.clear();
             updatedTypes.clear();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/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 ca7fad0..329dd7a 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
@@ -24,7 +24,9 @@ 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.exception.AtlasBaseException;
 import org.apache.atlas.model.instance.AtlasEntity.Status;
+import org.apache.atlas.model.instance.AtlasRelationship;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.RepositoryException;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
@@ -259,31 +261,42 @@ public final class GraphHelper {
      * Searches for a AtlasVertex with prop1=key1 && prop2=key2
      * @param args
      * @return AtlasVertex with the given property keys
-     * @throws EntityNotFoundException
+     * @throws AtlasBaseException
      */
     public AtlasVertex findVertex(Object... args) throws EntityNotFoundException {
+        return (AtlasVertex) findElement(true, args);
+    }
+
+    /**
+     * Args of the format prop1, key1, prop2, key2...
+     * Searches for a AtlasEdge with prop1=key1 && prop2=key2
+     * @param args
+     * @return AtlasEdge with the given property keys
+     * @throws AtlasBaseException
+     */
+    public AtlasEdge findEdge(Object... args) throws EntityNotFoundException {
+        return (AtlasEdge) findElement(false, args);
+    }
+
+    private AtlasElement findElement(boolean isVertexSearch, Object... args) throws EntityNotFoundException {
         AtlasGraphQuery query = graph.query();
-        for (int i = 0 ; i < args.length; i+=2) {
-            query = query.has((String) args[i], args[i+1]);
+
+        for (int i = 0; i < args.length; i += 2) {
+            query = query.has((String) args[i], args[i + 1]);
         }
 
-        Iterator<AtlasVertex> results = query.vertices().iterator();
-        // returning one since entityType, qualifiedName should be unique
-        AtlasVertex vertex = results.hasNext() ? results.next() : null;
+        Iterator<AtlasElement> results = isVertexSearch ? query.vertices().iterator() : query.edges().iterator();
+        AtlasElement           element = (results != null && results.hasNext()) ? results.next() : null;
 
-        if (vertex == null) {
-            String conditionStr = getConditionString(args);
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Could not find a vertex with {}", conditionStr);
-            }
-            throw new EntityNotFoundException("Could not find an entity in the repository with " + conditionStr);
-        } else {
-            if (LOG.isDebugEnabled()) {
-                LOG.debug("Found a vertex {} with {}", string(vertex), getConditionString(args));
-            }
+        if (element == null) {
+            throw new EntityNotFoundException("Could not find " + (isVertexSearch ? "vertex" : "edge") + " with condition: " + getConditionString(args));
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Found {} with condition {}", string(element), getConditionString(args));
         }
 
-        return vertex;
+        return element;
     }
 
     //In some cases of parallel APIs, the edge is added, but get edge by label doesn't return the edge. ATLAS-1104
@@ -534,6 +547,9 @@ 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);
+    }
 
     /**
      * Finds the Vertices that correspond to the given property values.  Property
@@ -646,12 +662,12 @@ public final class GraphHelper {
         return getIdFromVertex(getTypeName(vertex), vertex);
     }
 
-    public static String getGuid(AtlasVertex vertex) {
-        return vertex.<String>getProperty(Constants.GUID_PROPERTY_KEY, String.class);
+    public static String getGuid(AtlasElement element) {
+        return element.<String>getProperty(Constants.GUID_PROPERTY_KEY, String.class);
     }
 
-    public static String getTypeName(AtlasVertex instanceVertex) {
-        return instanceVertex.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY, String.class);
+    public static String getTypeName(AtlasElement element) {
+        return element.getProperty(Constants.ENTITY_TYPE_PROPERTY_KEY, String.class);
     }
 
     public static Id.EntityState getState(AtlasElement element) {
@@ -663,8 +679,6 @@ 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);
     }
@@ -673,6 +687,10 @@ public final class GraphHelper {
         return (getState(element) == Id.EntityState.DELETED) ? Status.DELETED : Status.ACTIVE;
     }
 
+    public static AtlasRelationship.Status getEdgeStatus(AtlasElement element) {
+        return (getState(element) == Id.EntityState.DELETED) ? AtlasRelationship.Status.DELETED : AtlasRelationship.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){
         return element.getProperty(Constants.CREATED_BY_KEY, String.class);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipStore.java
new file mode 100644
index 0000000..341711a
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasRelationshipStore.java
@@ -0,0 +1,53 @@
+/**
+ * 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;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasRelationship;
+
+/**
+ * Persistence/Retrieval API for AtlasRelationship
+ */
+public interface AtlasRelationshipStore {
+    /**
+     * Create a new relationship instance.
+     * @param relationship relationship instance definition
+     * @return AtlasRelationship d
+     */
+    AtlasRelationship create(AtlasRelationship relationship) throws AtlasBaseException;
+
+    /**
+     * Update an existing relationship instance.
+     * @param relationship relationship instance definition
+     * @return AtlasRelationship d
+     */
+    AtlasRelationship update(AtlasRelationship relationship) throws AtlasBaseException;
+
+    /**
+     * Retrieve a relationship instance using guid.
+     * @param guid relationship instance guid
+     * @return AtlasRelationship
+     */
+    AtlasRelationship getById(String guid) throws AtlasBaseException;
+
+    /**
+     * Delete a relationship instance using guid.
+     * @param guid relationship instance guid
+     */
+    void deleteById(String guid) throws AtlasBaseException;
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/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 560b338..00fe94b 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
@@ -35,6 +35,7 @@ import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
 import org.apache.atlas.type.AtlasType;
 import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -234,6 +235,18 @@ public class AtlasGraphUtilsV1 {
         return vertex;
     }
 
+    public static String getTypeNameFromGuid(String guid) {
+        String ret = null;
+
+        if (StringUtils.isNotEmpty(guid)) {
+            AtlasVertex vertex = AtlasGraphUtilsV1.findByGuid(guid);
+
+            ret = (vertex != null) ? AtlasGraphUtilsV1.getTypeName(vertex) : null;
+        }
+
+        return ret;
+    }
+
     public static boolean typeHasInstanceVertex(String typeName) throws AtlasBaseException {
         AtlasGraphQuery query = AtlasGraphProvider.getGraphInstance()
                 .query()

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/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
new file mode 100644
index 0000000..8fe4888
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipStoreV1.java
@@ -0,0 +1,365 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.annotation.GraphTransaction;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasObjectId;
+import org.apache.atlas.model.instance.AtlasRelationship;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.repository.RepositoryException;
+import org.apache.atlas.repository.graph.GraphHelper;
+import org.apache.atlas.repository.graphdb.AtlasEdge;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasRelationshipType;
+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.atlas.type.AtlasTypeUtil;
+import org.apache.atlas.typesystem.exception.EntityNotFoundException;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import javax.inject.Inject;
+import java.util.Date;
+import java.util.Map;
+import java.util.UUID;
+
+@Component
+public class AtlasRelationshipStoreV1 implements AtlasRelationshipStore {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipStoreV1.class);
+
+    private final AtlasTypeRegistry    typeRegistry;
+    private final EntityGraphRetriever entityRetriever;
+    private final GraphHelper          graphHelper = GraphHelper.getInstance();
+
+    @Inject
+    public AtlasRelationshipStoreV1(AtlasTypeRegistry typeRegistry) {
+        this.typeRegistry    = typeRegistry;
+        this.entityRetriever = new EntityGraphRetriever(typeRegistry);
+    }
+
+    @Override
+    @GraphTransaction
+    public AtlasRelationship create(AtlasRelationship relationship) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> create({})", relationship);
+        }
+
+        validateRelationship(relationship);
+
+        String      relationshipLabel = relationship.getRelationshipLabel();
+        AtlasVertex end1Vertex        = getVertexFromEndPoint(relationship.getEnd1());
+        AtlasVertex end2Vertex        = getVertexFromEndPoint(relationship.getEnd2());
+
+        AtlasRelationship ret;
+
+        // create relationship between two vertex
+        try {
+            AtlasEdge relationshipEdge = getRelationshipEdge(end1Vertex, end2Vertex, relationshipLabel);
+
+            if (relationshipEdge == null) {
+                relationshipEdge = createRelationEdge(end1Vertex, end2Vertex, relationship);
+
+                AtlasRelationshipType relationType = typeRegistry.getRelationshipTypeByName(relationship.getTypeName());
+
+                if (MapUtils.isNotEmpty(relationType.getAllAttributes())) {
+                    for (AtlasAttribute attr : relationType.getAllAttributes().values()) {
+                        String attrName  = attr.getName();
+                        Object attrValue = relationship.getAttribute(attrName);
+
+                        AtlasGraphUtilsV1.setProperty(relationshipEdge, attr.getVertexPropertyName(), attrValue);
+                    }
+                }
+
+                // create legacy edges if mentioned in relationDef
+                createLegacyEdges(relationType.getRelationshipDef(), end1Vertex, end2Vertex);
+
+                ret = mapEdgeToAtlasRelationship(relationshipEdge);
+
+            } else {
+                throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_ALREADY_EXISTS, relationship.getTypeName(),
+                                             relationship.getEnd1().getGuid(), relationship.getEnd2().getGuid());
+            }
+        } catch (RepositoryException e) {
+            throw new AtlasBaseException(AtlasErrorCode.INTERNAL_ERROR, e);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== create({}): {}", relationship, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    @GraphTransaction
+    public AtlasRelationship update(AtlasRelationship relationship) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> update({})", relationship);
+        }
+
+        AtlasRelationship ret = null;
+
+        // TODO: update(relationship) implementation
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== update({}): {}", relationship, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    @GraphTransaction
+    public AtlasRelationship getById(String guid) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> getById({})", guid);
+        }
+
+        AtlasRelationship ret;
+
+        try {
+            AtlasEdge edge = graphHelper.getEdgeForGUID(guid);
+
+            ret = mapEdgeToAtlasRelationship(edge);
+        } catch (EntityNotFoundException ex) {
+            throw new AtlasBaseException(AtlasErrorCode.RELATIONSHIP_GUID_NOT_FOUND, guid);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== getById({}): {}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    @GraphTransaction
+    public void deleteById(String guid) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> deleteById({})", guid);
+        }
+
+        // TODO: deleteById(guid) implementation
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== deleteById({}): {}", guid);
+        }
+    }
+
+    private void validateRelationship(AtlasRelationship relationship) throws AtlasBaseException {
+        if (relationship == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "AtlasRelationship is null");
+        }
+
+        String                relationshipName = relationship.getTypeName();
+        AtlasRelationshipType relationshipType = typeRegistry.getRelationshipTypeByName(relationshipName);
+
+        if (relationshipType == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_VALUE, "unknown relationship '" + relationshipName + "'");
+        }
+
+        AtlasObjectId end1 = relationship.getEnd1();
+
+        if (end1 == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "end1 is null");
+        }
+
+        String end1TypeName = end1.getTypeName();
+
+        if (StringUtils.isBlank(end1TypeName)) {
+            end1TypeName = AtlasGraphUtilsV1.getTypeNameFromGuid(end1.getGuid());
+        }
+
+        if (!relationshipType.getEnd1Type().isTypeOrSuperTypeOf(end1TypeName)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_END_TYPE, relationshipName,
+                                         relationshipType.getEnd1Type().getTypeName(), end1TypeName);
+        }
+
+        AtlasObjectId end2 = relationship.getEnd2();
+
+        if (end2 == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, "end2 is null");
+        }
+
+        String end2TypeName = end2.getTypeName();
+
+        if (StringUtils.isBlank(end2TypeName)) {
+            end2TypeName = AtlasGraphUtilsV1.getTypeNameFromGuid(end2.getGuid());
+        }
+
+        if (!relationshipType.getEnd2Type().isTypeOrSuperTypeOf(end2TypeName)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_RELATIONSHIP_END_TYPE, relationshipName,
+                                         relationshipType.getEnd2Type().getTypeName(), end2TypeName);
+        }
+
+        validateEnd(end1);
+
+        validateEnd(end2);
+    }
+
+    private void validateEnd(AtlasObjectId end) throws AtlasBaseException {
+        String              guid             = end.getGuid();
+        String              typeName         = end.getTypeName();
+        Map<String, Object> uniqueAttributes = end.getUniqueAttributes();
+        AtlasVertex         endVertex        = AtlasGraphUtilsV1.findByGuid(guid);
+
+        if (!AtlasTypeUtil.isValidGuid(guid) || endVertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        } else if (MapUtils.isNotEmpty(uniqueAttributes))  {
+            AtlasEntityType entityType = typeRegistry.getEntityTypeByName(typeName);
+
+            if (AtlasGraphUtilsV1.findByUniqueAttributes(entityType, uniqueAttributes) == null) {
+                throw new AtlasBaseException(AtlasErrorCode.INSTANCE_BY_UNIQUE_ATTRIBUTE_NOT_FOUND, typeName, uniqueAttributes.toString());
+            }
+        }
+    }
+
+    private AtlasEdge getRelationshipEdge(AtlasVertex fromVertex, AtlasVertex toVertex, String relationshipLabel) {
+        AtlasEdge ret = graphHelper.getEdgeForLabel(fromVertex, relationshipLabel);
+
+        if (ret != null) {
+            AtlasVertex inVertex = ret.getInVertex();
+
+            if (inVertex != null) {
+                if (!StringUtils.equals(AtlasGraphUtilsV1.getIdFromVertex(inVertex),
+                                       AtlasGraphUtilsV1.getIdFromVertex(toVertex))) {
+                    ret = null;
+                }
+            }
+        }
+
+        return ret;
+    }
+
+    private int getRelationVersion(AtlasRelationship relationship) {
+        Long ret = relationship != null ? relationship.getVersion() : null;
+
+        return (ret != null) ? ret.intValue() : 0;
+    }
+
+    private AtlasVertex getVertexFromEndPoint(AtlasObjectId endPoint) {
+        AtlasVertex ret = null;
+
+        if (StringUtils.isNotEmpty(endPoint.getGuid())) {
+            ret = AtlasGraphUtilsV1.findByGuid(endPoint.getGuid());
+
+        } else if (StringUtils.isNotEmpty(endPoint.getTypeName()) && MapUtils.isNotEmpty(endPoint.getUniqueAttributes())) {
+            AtlasEntityType entityType = typeRegistry.getEntityTypeByName(endPoint.getTypeName());
+
+            ret = AtlasGraphUtilsV1.findByUniqueAttributes(entityType, endPoint.getUniqueAttributes());
+        }
+
+        return ret;
+    }
+
+    private void createLegacyEdges(AtlasRelationshipDef relationshipDef, AtlasVertex fromVertex, AtlasVertex toVertex) throws RepositoryException {
+        if (relationshipDef != null) {
+            AtlasRelationshipEndDef endDef1 = relationshipDef.getEndDef1();
+            AtlasRelationshipEndDef endDef2 = relationshipDef.getEndDef2();
+
+            if (endDef1 != null && endDef1.hasLegacyRelation()) {
+                graphHelper.getOrCreateEdge(fromVertex, toVertex, endDef1.getLegacyLabel());
+            }
+
+            if (endDef2 != null && endDef2.hasLegacyRelation()) {
+                graphHelper.getOrCreateEdge(toVertex, fromVertex, endDef2.getLegacyLabel());
+            }
+        }
+    }
+
+    private AtlasEdge createRelationEdge(AtlasVertex fromVertex, AtlasVertex toVertex, AtlasRelationship relationship) throws RepositoryException {
+        AtlasEdge ret = graphHelper.getOrCreateEdge(fromVertex, toVertex, relationship.getRelationshipLabel());
+
+        // add additional properties to edge
+        if (ret != null) {
+            final String guid = UUID.randomUUID().toString();
+
+            AtlasGraphUtilsV1.setProperty(ret, Constants.ENTITY_TYPE_PROPERTY_KEY, relationship.getTypeName());
+            AtlasGraphUtilsV1.setProperty(ret, Constants.GUID_PROPERTY_KEY, guid);
+            AtlasGraphUtilsV1.setProperty(ret, Constants.VERSION_PROPERTY_KEY, getRelationVersion(relationship));
+        }
+
+        return ret;
+    }
+
+    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)));
+
+        relationship.setVersion(GraphHelper.getVersion(edge).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)));
+
+        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);
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/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 66f20da..9a8695a 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
@@ -34,6 +34,7 @@ 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.AtlasElement;
 import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.type.*;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
@@ -460,7 +461,7 @@ public final class EntityGraphRetriever {
         return ret;
     }
 
-    private Object mapVertexToPrimitive(AtlasVertex entityVertex, final String vertexPropertyName, AtlasAttributeDef attrDef) {
+    public Object mapVertexToPrimitive(AtlasElement entityVertex, final String vertexPropertyName, AtlasAttributeDef attrDef) {
         Object ret = null;
 
         if (GraphHelper.getSingleValuedProperty(entityVertex, vertexPropertyName, Object.class) == null) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/repository/src/main/java/org/apache/atlas/repository/typestore/GraphBackedTypeStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/typestore/GraphBackedTypeStore.java b/repository/src/main/java/org/apache/atlas/repository/typestore/GraphBackedTypeStore.java
index 7a064b6..2dd339c 100644
--- a/repository/src/main/java/org/apache/atlas/repository/typestore/GraphBackedTypeStore.java
+++ b/repository/src/main/java/org/apache/atlas/repository/typestore/GraphBackedTypeStore.java
@@ -273,6 +273,10 @@ public class GraphBackedTypeStore implements ITypeStore {
                 traits.add(new HierarchicalTypeDefinition(TraitType.class, typeName, typeDescription, superTypes, attributes));
                 break;
 
+            case RELATIONSHIP:
+                // v1 typesystem is not notified on new relation type
+                break;
+
             default:
                 throw new IllegalArgumentException("Unhandled type category " + typeCategory);
             }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/repository/src/test/java/org/apache/atlas/TestModules.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/TestModules.java b/repository/src/test/java/org/apache/atlas/TestModules.java
index 095af41..d28956d 100644
--- a/repository/src/test/java/org/apache/atlas/TestModules.java
+++ b/repository/src/test/java/org/apache/atlas/TestModules.java
@@ -47,9 +47,11 @@ import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.impexp.ExportService;
 import org.apache.atlas.repository.store.graph.AtlasEntityDefStore;
 import org.apache.atlas.repository.store.graph.AtlasEntityStore;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
 import org.apache.atlas.repository.store.graph.v1.AtlasEntityChangeNotifier;
 import org.apache.atlas.repository.store.graph.v1.AtlasEntityDefStoreV1;
 import org.apache.atlas.repository.store.graph.v1.AtlasEntityStoreV1;
+import org.apache.atlas.repository.store.graph.v1.AtlasRelationshipStoreV1;
 import org.apache.atlas.repository.store.graph.v1.AtlasTypeDefGraphStoreV1;
 import org.apache.atlas.repository.store.graph.v1.DeleteHandlerV1;
 import org.apache.atlas.repository.store.graph.v1.EntityGraphMapper;
@@ -152,6 +154,7 @@ public class TestModules {
             typeDefChangeListenerMultibinder.addBinding().to(GraphBackedSearchIndexer.class).asEagerSingleton();
 
             bind(AtlasEntityStore.class).to(AtlasEntityStoreV1.class);
+            bind(AtlasRelationshipStore.class).to(AtlasRelationshipStoreV1.class);
 
             // bind the MetadataService interface to an implementation
             bind(MetadataService.class).to(DefaultMetadataService.class).asEagerSingleton();

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/242b5585/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java
new file mode 100644
index 0000000..144080a
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/RelationshipREST.java
@@ -0,0 +1,137 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.web.rest;
+
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.instance.AtlasRelationship;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipStore;
+import org.apache.atlas.utils.AtlasPerfTracer;
+import org.apache.atlas.web.util.Servlets;
+import org.slf4j.Logger;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+
+/**
+ * REST interface for entity relationships.
+ */
+@Path("v2/relation")
+@Singleton
+@Service
+public class RelationshipREST {
+    private static final Logger PERF_LOG = AtlasPerfTracer.getPerfLogger("rest.RelationshipREST");
+
+    private final AtlasRelationshipStore relationshipStore;
+
+    @Inject
+    public RelationshipREST(AtlasRelationshipStore relationshipStore) {
+        this.relationshipStore = relationshipStore;
+    }
+
+    /**
+     * Create a new relationship between entities.
+     */
+    @POST
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasRelationship create(AtlasRelationship relationship) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "RelationshipREST.create(" + relationship + ")");
+            }
+
+            return relationshipStore.create(relationship);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    /**
+     * Update an existing relationship between entities.
+     */
+    @PUT
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasRelationship update(AtlasRelationship relationship) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "RelationshipREST.update(" + relationship + ")");
+            }
+
+            return relationshipStore.update(relationship);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    /**
+     * Get relationship information between entities using guid.
+     */
+    @GET
+    @Path("/guid/{guid}")
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasRelationship getById(@PathParam("guid") String guid) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "RelationshipREST.getById(" + guid + ")");
+            }
+
+            return relationshipStore.getById(guid);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    /**
+     * Delete a relationship between entities using guid.
+     */
+    @DELETE
+    @Path("/guid/{guid}")
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public void deleteById(@PathParam("guid") String guid) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, "RelationshipREST.deleteById(" + guid + ")");
+            }
+
+            relationshipStore.deleteById(guid);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+}


[12/14] incubator-atlas git commit: ATLAS-1878 - Fix for NPE when a request without any query path lands on atlas

Posted by ma...@apache.org.
ATLAS-1878 - Fix for NPE when a request without any query path lands on atlas


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

Branch: refs/heads/feature-odf
Commit: 906f36517bd13cb3f5318e7843ebfd0276a2975f
Parents: c6081dd
Author: nixonrodrigues <ni...@apache.org>
Authored: Fri Jun 16 19:29:07 2017 +0530
Committer: nixonrodrigues <ni...@apache.org>
Committed: Sun Jun 18 20:12:23 2017 +0530

----------------------------------------------------------------------
 .../apache/atlas/authorize/simple/AtlasAuthorizationUtils.java  | 5 +++++
 1 file changed, 5 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/906f3651/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
----------------------------------------------------------------------
diff --git a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
index e907bf5..93d988e 100644
--- a/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
+++ b/authorization/src/main/java/org/apache/atlas/authorize/simple/AtlasAuthorizationUtils.java
@@ -44,6 +44,11 @@ public class AtlasAuthorizationUtils {
         if (isDebugEnabled) {
             LOG.debug("==> getApi({})", contextPath);
         }
+
+        if(contextPath == null){
+            contextPath = "";
+        }
+
         if (contextPath.startsWith(BASE_URL)) {
             contextPath = contextPath.substring(BASE_URL.length());
         } else {


[11/14] incubator-atlas git commit: ATLAS-1875: updated gremlin search to include vertex id in the result

Posted by ma...@apache.org.
ATLAS-1875: updated gremlin search to include vertex id in the result

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


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

Branch: refs/heads/feature-odf
Commit: c6081ddcfdb4c8100a4b099405ac8d397fbf9583
Parents: d9f62cb
Author: Christian Rieck <ch...@dnvgl.com>
Authored: Fri Jun 16 10:45:22 2017 +0200
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sat Jun 17 10:29:19 2017 -0700

----------------------------------------------------------------------
 .../graph/GraphBackedDiscoveryService.java      | 25 ++++++++++++++---
 .../GraphBackedDiscoveryServiceTest.java        | 28 +++++++++++++++++++-
 2 files changed, 48 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c6081ddc/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java b/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
index 083c34d..aed8659 100755
--- a/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
+++ b/repository/src/main/java/org/apache/atlas/discovery/graph/GraphBackedDiscoveryService.java
@@ -71,6 +71,22 @@ public class GraphBackedDiscoveryService implements DiscoveryService {
     private final DefaultGraphPersistenceStrategy graphPersistenceStrategy;
 
     public final static String SCORE = "score";
+    /**
+     * Where the vertex' internal gremlin id is stored in the Map produced by extractResult()
+     */
+    public final static String GREMLIN_ID_KEY = "id";
+    /**
+     * Where the id of an edge's incoming vertex is stored in the Map produced by extractResult()
+     */
+    public final static String GREMLIN_INVERTEX_KEY = "inVertex";
+    /**
+     * Where the id of an edge's outgoing vertex is stored in the Map produced by extractResult()
+     */
+    public final static String GREMLIN_OUTVERTEX_KEY = "outVertex";
+    /**
+     * Where an edge's label is stored in the Map produced by extractResult()
+     */
+    public final static String GREMLIN_LABEL_KEY = "label";
 
     @Inject
     GraphBackedDiscoveryService(MetadataRepository metadataRepository, AtlasGraph atlasGraph)
@@ -223,15 +239,16 @@ public class GraphBackedDiscoveryService implements DiscoveryService {
                             oRow.put(key, propertyValue.toString());
                         }
                     }
+                    oRow.put(GREMLIN_ID_KEY, vertex.getId().toString());
 
                 } else if (value instanceof String) {
                     oRow.put("", value.toString());
                 } else if(value instanceof AtlasEdge) {
                     AtlasEdge edge = (AtlasEdge) value;
-                    oRow.put("id", edge.getId().toString());
-                    oRow.put("label", edge.getLabel());
-                    oRow.put("inVertex", edge.getInVertex().getId().toString());
-                    oRow.put("outVertex", edge.getOutVertex().getId().toString());
+                    oRow.put(GREMLIN_ID_KEY, edge.getId().toString());
+                    oRow.put(GREMLIN_LABEL_KEY, edge.getLabel());
+                    oRow.put(GREMLIN_INVERTEX_KEY, edge.getInVertex().getId().toString());
+                    oRow.put(GREMLIN_OUTVERTEX_KEY, edge.getOutVertex().getId().toString());
                     for (String propertyKey : edge.getPropertyKeys()) {
                         oRow.put(propertyKey, GraphHelper.getProperty(edge, propertyKey).toString());
                     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c6081ddc/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java b/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
index 834abe1..675ab8a 100755
--- a/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
@@ -227,6 +227,32 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
         assertEquals(rows.length(), 1);
     }
 
+    
+    /*
+     * https://issues.apache.org/jira/browse/ATLAS-1875
+     */
+    @Test
+    public void testGremlinSearchReturnVertexId() throws Exception {
+       List<Map<String,String>> gremlinResults = discoveryService.searchByGremlin("g.V.range(0,0).collect()");
+       assertEquals(gremlinResults.size(), 1);
+       Map<String, String> properties = gremlinResults.get(0);
+       Assert.assertTrue(properties.containsKey(GraphBackedDiscoveryService.GREMLIN_ID_KEY));
+    }
+    
+    /*
+     * https://issues.apache.org/jira/browse/ATLAS-1875
+     */
+    @Test
+    public void testGremlinSearchReturnEdgeIds() throws Exception {
+       List<Map<String,String>> gremlinResults = discoveryService.searchByGremlin("g.E.range(0,0).collect()");
+       assertEquals(gremlinResults.size(), 1);
+       Map<String, String> properties = gremlinResults.get(0);
+       Assert.assertTrue(properties.containsKey(GraphBackedDiscoveryService.GREMLIN_INVERTEX_KEY));
+       Assert.assertTrue(properties.containsKey(GraphBackedDiscoveryService.GREMLIN_OUTVERTEX_KEY));
+       Assert.assertTrue(properties.containsKey(GraphBackedDiscoveryService.GREMLIN_LABEL_KEY));
+    }
+
+
     @Test
     public void testSearchByDSLReturnsEntity() throws Exception {
         String dslQuery = "from Department";
@@ -1284,4 +1310,4 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
     private boolean isGremlin3() {
         return TestUtils.getGraph().getSupportedGremlinVersion() == GremlinVersion.THREE;
     }
-}
\ No newline at end of file
+}


[07/14] incubator-atlas git commit: ATLAS-1823 - UI - Change in base path URL for few api/images to make it relative from path it is accessed.

Posted by ma...@apache.org.
ATLAS-1823 - UI - Change in base path URL for few api/images to make it relative from path it is accessed.


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

Branch: refs/heads/feature-odf
Commit: 894a91f6097969073c8356fd6aac6490b6b619d9
Parents: 82b6f72
Author: nixonrodrigues <ni...@apache.org>
Authored: Mon May 22 13:43:50 2017 +0530
Committer: nixonrodrigues <ni...@apache.org>
Committed: Tue Jun 13 12:04:13 2017 +0530

----------------------------------------------------------------------
 dashboardv2/public/css/scss/main.scss                  |  2 +-
 dashboardv2/public/index.html                          |  2 +-
 dashboardv2/public/js/utils/UrlLinks.js                |  4 ++--
 dashboardv2/public/js/views/graph/LineageLayoutView.js | 12 ++++++------
 4 files changed, 10 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/894a91f6/dashboardv2/public/css/scss/main.scss
----------------------------------------------------------------------
diff --git a/dashboardv2/public/css/scss/main.scss b/dashboardv2/public/css/scss/main.scss
index 4b73577..a608c95 100644
--- a/dashboardv2/public/css/scss/main.scss
+++ b/dashboardv2/public/css/scss/main.scss
@@ -104,7 +104,7 @@ $color_suva_gray_approx: #868686;
 $tag_color:#4A90E2;
 $delete_link:#BB5838;
 //urls
-$url_0: url(../img/loading.gif);
+$url_0: url(img/loading.gif);
 .card {
     background: $white none repeat scroll 0 0;
     //Instead of the line below you could use @include box-shadow($shadow-1, $shadow-2, $shadow-3, $shadow-4, $shadow-5, $shadow-6, $shadow-7, $shadow-8, $shadow-9, $shadow-10)

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/894a91f6/dashboardv2/public/index.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/index.html b/dashboardv2/public/index.html
index 72e11fb..5fff304 100644
--- a/dashboardv2/public/index.html
+++ b/dashboardv2/public/index.html
@@ -63,7 +63,7 @@
             <header id="new-header" class="clearfix"></header>
             <div id="new-page-wrapper">
                 <div>
-                    <img class="initialLoading" src="../img/ring.gif">
+                    <img class="initialLoading" src="img/ring.gif">
                 </div>
             </div>
         </div>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/894a91f6/dashboardv2/public/js/utils/UrlLinks.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/utils/UrlLinks.js b/dashboardv2/public/js/utils/UrlLinks.js
index 82bd082..c692d8d 100644
--- a/dashboardv2/public/js/utils/UrlLinks.js
+++ b/dashboardv2/public/js/utils/UrlLinks.js
@@ -20,8 +20,8 @@ define(['require', 'utils/Enums'], function(require, Enums) {
     'use strict';
 
     var UrlLinks = {
-        baseUrl: '/api/atlas',
-        baseUrlV2: '/api/atlas/v2',
+        baseUrl: 'api/atlas',
+        baseUrlV2: 'api/atlas/v2',
         typedefsUrl: function() {
             return {
                 defs: this.baseUrlV2 + '/types/typedefs',

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/894a91f6/dashboardv2/public/js/views/graph/LineageLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/graph/LineageLayoutView.js b/dashboardv2/public/js/views/graph/LineageLayoutView.js
index f98672b..46f7117 100644
--- a/dashboardv2/public/js/views/graph/LineageLayoutView.js
+++ b/dashboardv2/public/js/views/graph/LineageLayoutView.js
@@ -254,19 +254,19 @@ define(['require',
                             if (node) {
                                 if (node.isProcess) {
                                     if (Enums.entityStateReadOnly[node.status]) {
-                                        return '../img/icon-gear-delete.png';
+                                        return 'img/icon-gear-delete.png';
                                     } else if (node.id == that.guid) {
-                                        return '../img/icon-gear-active.png';
+                                        return 'img/icon-gear-active.png';
                                     } else {
-                                        return '../img/icon-gear.png';
+                                        return 'img/icon-gear.png';
                                     }
                                 } else {
                                     if (Enums.entityStateReadOnly[node.status]) {
-                                        return '../img/icon-table-delete.png';
+                                        return 'img/icon-table-delete.png';
                                     } else if (node.id == that.guid) {
-                                        return '../img/icon-table-active.png';
+                                        return 'img/icon-table-active.png';
                                     } else {
-                                        return '../img/icon-table.png';
+                                        return 'img/icon-table.png';
                                     }
                                 }
                             }


[08/14] incubator-atlas git commit: ATLAS-1832: If no attribute is present in tag then showing edit-button for a tag in tags tab on entity page.

Posted by ma...@apache.org.
ATLAS-1832: If no attribute is present in tag then showing edit-button for a tag in tags tab on entity page.

Signed-off-by: nixonrodrigues <ni...@apache.org>


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

Branch: refs/heads/feature-odf
Commit: c2c05d673071073f036d18a2d82460f3025310cf
Parents: 894a91f
Author: Kalyani <ka...@freestoneinfotech.com>
Authored: Tue Jun 13 12:21:54 2017 +0530
Committer: nixonrodrigues <ni...@apache.org>
Committed: Tue Jun 13 12:53:11 2017 +0530

----------------------------------------------------------------------
 .../js/templates/audit/CreateAuditTableLayoutView_tmpl.html | 2 +-
 dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js | 9 +++++++--
 2 files changed, 8 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c2c05d67/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html b/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
index fc8e6cc..736b957 100644
--- a/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
+++ b/dashboardv2/public/js/templates/audit/CreateAuditTableLayoutView_tmpl.html
@@ -23,4 +23,4 @@
     <tbody data-id="auditValue">
     </tbody>
 </table>
-<h3 data-id="noData" style="display:none">No details to show</h3>
+<h4 data-id="noData" style="display:none">No details to show</h4>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c2c05d67/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
----------------------------------------------------------------------
diff --git a/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js b/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
index cdbd00f..45cdd6b 100644
--- a/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
+++ b/dashboardv2/public/js/views/tag/TagDetailTableLayoutView.js
@@ -155,11 +155,16 @@ define(['require',
                             sortable: false,
                             formatter: _.extend({}, Backgrid.CellFormatter.prototype, {
                                 fromRaw: function(rawValue, model) {
-                                    return '<button class="btn btn-atlasAction btn-atlas no-margin-bottom typeLOV" data-id="delete" data-name="' + model.get('typeName') + '"><i class="fa fa-trash"></i></button> <button class="btn btn-atlasAction btn-atlas no-margin-bottom typeLOV" data-id="edit" data-name="' + model.get('typeName') + '"><i class="fa fa-pencil"></i></button>';
+                                    var deleteData = '<button class="btn btn-atlasAction btn-atlas no-margin-bottom typeLOV" data-id="delete" data-name="' + model.get('typeName') + '"><i class="fa fa-trash"></i></button>',
+                                        editData = '<button class="btn btn-atlasAction btn-atlas no-margin-bottom typeLOV" data-id="edit" data-name="' + model.get('typeName') + '"><i class="fa fa-pencil"></i></button>';
+                                    if (model.get('attributes') === undefined) {
+                                        return deleteData;
+                                    } else {
+                                        return deleteData + editData;
+                                    }
                                 }
                             })
                         },
-
                     },
                     this.tagTermCollection);
             },


[10/14] incubator-atlas git commit: ATLAS-1863: added support for default value for attributes

Posted by ma...@apache.org.
ATLAS-1863: added support for default value for attributes

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


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

Branch: refs/heads/feature-odf
Commit: d9f62cb5a97d033448567688bd21e7a4ea25d65a
Parents: 1de6016
Author: rdsolani <rd...@gmail.com>
Authored: Thu Jun 15 19:32:37 2017 +0530
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri Jun 16 08:14:14 2017 -0700

----------------------------------------------------------------------
 .../atlas/model/typedef/AtlasStructDef.java     | 23 ++++++++-
 .../org/apache/atlas/type/AtlasArrayType.java   |  4 ++
 .../org/apache/atlas/type/AtlasEntityType.java  |  8 +++
 .../org/apache/atlas/type/AtlasMapType.java     |  4 ++
 .../org/apache/atlas/type/AtlasStructType.java  | 11 +++-
 .../java/org/apache/atlas/type/AtlasType.java   |  4 ++
 .../test/java/org/apache/atlas/TestUtilsV2.java | 53 ++++++++++++++++++++
 .../apache/atlas/type/TestAtlasArrayType.java   |  2 +-
 .../store/graph/v1/AtlasStructDefStoreV1.java   |  2 +
 .../store/graph/v1/EntityGraphMapper.java       | 13 +++--
 .../store/graph/v1/AtlasEntityStoreV1Test.java  | 43 ++++++++++++++++
 11 files changed, 158 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
index aee4907..3a5c43a 100644
--- a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasStructDef.java
@@ -271,16 +271,23 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
         private int                      valuesMaxCount;
         private boolean                  isUnique;
         private boolean                  isIndexable;
+        private String                   defaultValue;
+
         private List<AtlasConstraintDef> constraints;
 
         public AtlasAttributeDef() { this(null, null); }
 
         public AtlasAttributeDef(String name, String typeName) {
             this(name, typeName, false, Cardinality.SINGLE, COUNT_NOT_SET, COUNT_NOT_SET, false, false, null);
+
+        }
+        public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality,
+                                 int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, List<AtlasConstraintDef> constraints) {
+            this(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, null, constraints);
         }
 
         public AtlasAttributeDef(String name, String typeName, boolean isOptional, Cardinality cardinality,
-                                 int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable,
+                                 int valuesMinCount, int valuesMaxCount, boolean isUnique, boolean isIndexable, String defaultValue,
                                  List<AtlasConstraintDef> constraints) {
             setName(name);
             setTypeName(typeName);
@@ -290,6 +297,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
             setValuesMaxCount(valuesMaxCount);
             setIsUnique(isUnique);
             setIsIndexable(isIndexable);
+            setDefaultValue(defaultValue);
             setConstraints(constraints);
         }
 
@@ -303,6 +311,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
                 setValuesMaxCount(other.getValuesMaxCount());
                 setIsUnique(other.getIsUnique());
                 setIsIndexable(other.getIsIndexable());
+                setDefaultValue(other.getDefaultValue());
                 setConstraints(other.getConstraints());
             }
         }
@@ -365,6 +374,14 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
             return isIndexable;
         }
 
+        public String getDefaultValue(){
+            return defaultValue;
+        }
+
+        public void setDefaultValue(String defaultValue){
+            this.defaultValue = defaultValue;
+        }
+
         public void setIsIndexable(boolean idexable) {
             isIndexable = idexable;
         }
@@ -409,6 +426,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
             sb.append(", valuesMaxCount=").append(valuesMaxCount);
             sb.append(", isUnique=").append(isUnique);
             sb.append(", isIndexable=").append(isIndexable);
+            sb.append(", defaultValue=").append(defaultValue);
             sb.append(", constraints=[");
             if (CollectionUtils.isNotEmpty(constraints)) {
                 int i = 0;
@@ -439,12 +457,13 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
                     Objects.equals(name, that.name) &&
                     Objects.equals(typeName, that.typeName) &&
                     cardinality == that.cardinality &&
+                    Objects.equals(defaultValue, that.defaultValue) &&
                     Objects.equals(constraints, that.constraints);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, constraints);
+            return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, defaultValue, constraints);
         }
 
         @Override

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java b/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java
index 2d386f1..de3394f 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasArrayType.java
@@ -201,6 +201,10 @@ public class AtlasArrayType extends AtlasType {
             return null;
         }
 
+        if (obj instanceof String){
+             obj = AtlasType.fromJson(obj.toString(), List.class);
+        }
+
         if (obj instanceof List || obj instanceof Set) {
             List<Object> ret = new ArrayList<>();
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/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 6516d48..0ff1582 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -146,6 +146,14 @@ public class AtlasEntityType extends AtlasStructType {
     }
 
     @Override
+    public AtlasEntity createDefaultValue(Object defaultValue){
+        AtlasEntity ret = new AtlasEntity(entityDef.getName());
+
+        populateDefaultValues(ret);
+
+        return ret;
+    }
+    @Override
     public boolean isValidValue(Object obj) {
         if (obj != null) {
             for (AtlasEntityType superType : superTypes) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java b/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java
index 385a9ae..90c898a 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasMapType.java
@@ -148,6 +148,10 @@ public class AtlasMapType extends AtlasType {
             return null;
         }
 
+        if (obj instanceof String) {
+            obj = AtlasType.fromJson(obj.toString(), Map.class);
+        }
+
         if (obj instanceof Map) {
             Map<Object, Object> ret = new HashMap<>();
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
index 0eeaf9c..c2e0be5 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -186,6 +186,15 @@ public class AtlasStructType extends AtlasType {
         return  ret;
     }
 
+    @Override
+    public Object createDefaultValue(Object defaultValue) {
+        AtlasStruct ret = new AtlasStruct(structDef.getName());
+
+        populateDefaultValues(ret);
+
+        return  ret;
+    }
+
     public Map<String, AtlasAttribute> getAllAttributes() {
         return allAttributes;
     }
@@ -480,7 +489,7 @@ public class AtlasStructType extends AtlasType {
             if (attribute != null) {
                 AtlasType dataType = attribute.getAttributeType();
 
-                ret = dataType.createDefaultValue();
+                ret = dataType.createDefaultValue(attributeDef.getDefaultValue());
             }
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/main/java/org/apache/atlas/type/AtlasType.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasType.java b/intg/src/main/java/org/apache/atlas/type/AtlasType.java
index 28d0a07..f05cfd6 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasType.java
@@ -66,6 +66,10 @@ public abstract class AtlasType {
         return createDefaultValue();
     }
 
+    public Object createDefaultValue(Object val){
+        return val == null ? createDefaultValue() : getNormalizedValue(val);
+    }
+
     public abstract boolean isValidValue(Object obj);
 
     public abstract Object getNormalizedValue(Object obj);

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
index 2a6ea92..9774583 100755
--- a/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestUtilsV2.java
@@ -35,6 +35,7 @@ import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasTypeUtil;
 import org.apache.commons.lang.RandomStringUtils;
 
@@ -877,6 +878,58 @@ public final class TestUtilsV2 {
         return ret;
     }
 
+    public static AtlasEntityWithExtInfo createprimitiveEntityV2() {
+
+        AtlasEntity defaultprimitive = new AtlasEntity(createPrimitiveEntityDef());
+        defaultprimitive.setAttribute("name", "testname");
+        defaultprimitive.setAttribute("description","test");
+        defaultprimitive.setAttribute("check","check");
+
+        AtlasEntityWithExtInfo ret = new AtlasEntityWithExtInfo(defaultprimitive);
+
+        return ret;
+
+    }
+
+
+    public static AtlasEntityDef createPrimitiveEntityDef() {
+
+        AtlasEntityDef newtestEntityDef = new AtlasEntityDef("newtest");
+        AtlasAttributeDef attrName = new AtlasAttributeDef("name", AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+
+        AtlasAttributeDef attrDescription = new AtlasAttributeDef("description", AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+        attrDescription.setIsOptional(false);
+
+        AtlasAttributeDef attrcheck = new AtlasAttributeDef("check", AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+        attrcheck.setIsOptional(true);
+
+        AtlasAttributeDef attrSourceCode = new AtlasAttributeDef("sourcecode", AtlasBaseTypeDef.ATLAS_TYPE_STRING);
+        attrSourceCode.setDefaultValue("Hello World");
+        attrSourceCode.setIsOptional(true);
+
+        AtlasAttributeDef attrCost = new AtlasAttributeDef("Cost", AtlasBaseTypeDef.ATLAS_TYPE_INT);
+        attrCost.setIsOptional(true);
+        attrCost.setDefaultValue("30");
+
+        AtlasAttributeDef attrDiskUsage = new AtlasAttributeDef("diskUsage", AtlasBaseTypeDef.ATLAS_TYPE_FLOAT);
+        attrDiskUsage.setIsOptional(true);
+        attrDiskUsage.setDefaultValue("70.50");
+
+        AtlasAttributeDef attrisStoreUse = new AtlasAttributeDef("isstoreUse", AtlasBaseTypeDef.ATLAS_TYPE_BOOLEAN);
+        attrisStoreUse.setIsOptional(true);
+        attrisStoreUse.setDefaultValue("true");
+
+        newtestEntityDef.addAttribute(attrName);
+        newtestEntityDef.addAttribute(attrDescription);
+        newtestEntityDef.addAttribute(attrcheck);
+        newtestEntityDef.addAttribute(attrSourceCode);
+        newtestEntityDef.addAttribute(attrCost);
+        newtestEntityDef.addAttribute(attrDiskUsage);
+        newtestEntityDef.addAttribute(attrisStoreUse);
+
+        return newtestEntityDef;
+    }
+
     public static AtlasEntity createColumnEntity(AtlasEntity tableEntity) {
         return createColumnEntity(tableEntity, "col" + seq.addAndGet(1));
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java
----------------------------------------------------------------------
diff --git a/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java b/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java
index e882473..f123b3c 100644
--- a/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java
+++ b/intg/src/test/java/org/apache/atlas/type/TestAtlasArrayType.java
@@ -59,7 +59,7 @@ public class TestAtlasArrayType {
         };
 
         invalidValues = new Object[] {
-            new String[] { "1", "abcd", "3", "xyz", "5" }, "1", Byte.valueOf((byte)1), Short.valueOf((short)1),
+            Byte.valueOf((byte)1), Short.valueOf((short)1),
             Integer.valueOf(1), Long.valueOf(1L), Float.valueOf(1), Double.valueOf(1), BigInteger.valueOf(1),
             BigDecimal.valueOf(1),
         };

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java
index 1c6cfc7..62729e7 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasStructDefStoreV1.java
@@ -511,6 +511,7 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
         attribInfo.put("isIndexable", attributeDef.getIsIndexable());
         attribInfo.put("isComposite", attribute.isOwnedRef());
         attribInfo.put("reverseAttributeName", attribute.getInverseRefAttributeName());
+        attribInfo.put("defaultValue", attributeDef.getDefaultValue());
 
         final int lower;
         final int upper;
@@ -549,6 +550,7 @@ public class AtlasStructDefStoreV1 extends AtlasAbstractDefStoreV1 implements At
         ret.setTypeName((String) attribInfo.get("dataType"));
         ret.setIsUnique((Boolean) attribInfo.get("isUnique"));
         ret.setIsIndexable((Boolean) attribInfo.get("isIndexable"));
+        ret.setDefaultValue((String) attribInfo.get("defaultValue"));
 
         if ((Boolean)attribInfo.get("isComposite")) {
             ret.addConstraint(new AtlasConstraintDef(AtlasConstraintDef.CONSTRAINT_TYPE_OWNED_REF));

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
index 80cd1ee..ebf6a20 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/EntityGraphMapper.java
@@ -33,7 +33,6 @@ import org.apache.atlas.model.instance.EntityMutations.EntityOperation;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.RepositoryException;
-import org.apache.atlas.repository.graph.AtlasGraphProvider;
 import org.apache.atlas.repository.graph.GraphHelper;
 import org.apache.atlas.repository.graphdb.AtlasEdge;
 import org.apache.atlas.repository.graphdb.AtlasGraph;
@@ -259,13 +258,17 @@ public class EntityGraphMapper {
 
     private void mapAttribute(AtlasAttribute attribute, Object attrValue, AtlasVertex vertex, EntityOperation op, EntityMutationContext context) throws AtlasBaseException {
         if (attrValue == null) {
+            AtlasAttributeDef attributeDef = attribute.getAttributeDef();
             AtlasType attrType = attribute.getAttributeType();
-
             if (attrType.getTypeCategory() == TypeCategory.PRIMITIVE) {
-                if (attribute.getAttributeDef().getIsOptional()) {
-                    attrValue = attrType.createOptionalDefaultValue();
+                if (attributeDef.getDefaultValue() != null) {
+                    attrValue = attrType.createDefaultValue(attributeDef.getDefaultValue());
                 } else {
-                    attrValue = attrType.createDefaultValue();
+                    if (attribute.getAttributeDef().getIsOptional()) {
+                        attrValue = attrType.createOptionalDefaultValue();
+                    } else {
+                        attrValue = attrType.createDefaultValue();
+                    }
                 }
             }
         }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/d9f62cb5/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 44067b9..2ac0fc6 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
@@ -77,6 +77,7 @@ import static org.apache.atlas.TestUtils.COLUMNS_ATTR_NAME;
 import static org.apache.atlas.TestUtils.COLUMN_TYPE;
 import static org.apache.atlas.TestUtils.NAME;
 import static org.apache.atlas.TestUtils.randomString;
+import static org.apache.atlas.TestUtilsV2.STORAGE_DESC_TYPE;
 import static org.apache.atlas.TestUtilsV2.TABLE_TYPE;
 import static org.mockito.Mockito.mock;
 import static org.testng.Assert.assertEquals;
@@ -104,6 +105,7 @@ public class AtlasEntityStoreV1Test {
     private AtlasEntitiesWithExtInfo deptEntity;
     private AtlasEntityWithExtInfo   dbEntity;
     private AtlasEntityWithExtInfo   tblEntity;
+    private AtlasEntityWithExtInfo   primitiveEntity;
 
     AtlasEntityChangeNotifier mockChangeNotifier = mock(AtlasEntityChangeNotifier.class);
     @Inject
@@ -130,6 +132,14 @@ public class AtlasEntityStoreV1Test {
         deptEntity = TestUtilsV2.createDeptEg2();
         dbEntity   = TestUtilsV2.createDBEntityV2();
         tblEntity  = TestUtilsV2.createTableEntityV2(dbEntity.getEntity());
+
+        AtlasTypesDef typesDef11 = new  AtlasTypesDef();
+        List primitiveEntityDef = new ArrayList<AtlasEntityDef>();
+        primitiveEntityDef.add(TestUtilsV2.createPrimitiveEntityDef());
+        typesDef11.setEntityDefs(primitiveEntityDef);
+        typeDefStore.createTypesDef( typesDef11 );
+
+        primitiveEntity = TestUtilsV2.createprimitiveEntityV2();
     }
 
     @AfterClass
@@ -144,6 +154,39 @@ public class AtlasEntityStoreV1Test {
     }
 
     @Test
+    public void testDefaultValueForPrimitiveTypes() throws Exception  {
+
+        init();
+
+        EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(primitiveEntity), false);
+        List<AtlasEntityHeader> entitiesCreatedResponse = response.getEntitiesByOperation(EntityOperation.CREATE);
+        final Map<EntityOperation, List<AtlasEntityHeader>> entitiesMutated = response.getMutatedEntities();
+        List<AtlasEntityHeader> entitiesCreatedwithdefault = entitiesMutated.get(EntityOperation.CREATE);
+
+        AtlasEntity entityCreated   = getEntityFromStore(entitiesCreatedResponse.get(0));
+
+
+        Map attributesMap = entityCreated.getAttributes();
+        String description = (String) attributesMap.get("description");
+        String check = (String) attributesMap.get("check");
+        String   sourceCode =  (String) attributesMap.get("sourcecode");
+        float   diskUsage =  (float) attributesMap.get("diskUsage");
+        boolean   isstoreUse =  (boolean) attributesMap.get("isstoreUse");
+        int cost = (int)attributesMap.get("Cost");
+
+
+        assertEquals(description,"test");
+        assertEquals(check,"check");
+
+        //defaultValue
+        assertEquals(diskUsage,70.5f);
+        assertEquals(isstoreUse,true);
+        assertEquals(sourceCode,"Hello World");
+        assertEquals(cost,30);
+    }
+
+
+    @Test
     public void testCreate() throws Exception {
         init();
         EntityMutationResponse response = entityStore.createOrUpdate(new AtlasEntityStream(deptEntity), false);


[02/14] incubator-atlas git commit: ATLAS-1804 : Allow PAM for authentication.

Posted by ma...@apache.org.
ATLAS-1804 : Allow PAM for authentication.

Signed-off-by: nixonrodrigues <ni...@apache.org>


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

Branch: refs/heads/feature-odf
Commit: aa6d87e1c8f373f6c2ef0ca5586d03f64339c236
Parents: edd4aa9
Author: shiwang <sh...@us.ibm.com>
Authored: Wed Jun 7 13:56:31 2017 -0700
Committer: nixonrodrigues <ni...@apache.org>
Committed: Thu Jun 8 18:26:36 2017 +0530

----------------------------------------------------------------------
 webapp/pom.xml                                  |  12 +
 .../security/AtlasAuthenticationProvider.java   |  18 +-
 .../AtlasPamAuthenticationProvider.java         | 155 +++++++++++++
 .../atlas/web/security/PamLoginModule.java      | 221 +++++++++++++++++++
 .../apache/atlas/web/security/PamPrincipal.java |  84 +++++++
 .../web/security/UserAuthorityGranter.java      |  35 +++
 6 files changed, 523 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa6d87e1/webapp/pom.xml
----------------------------------------------------------------------
diff --git a/webapp/pom.xml b/webapp/pom.xml
index 4cc0112..465d2a5 100755
--- a/webapp/pom.xml
+++ b/webapp/pom.xml
@@ -476,6 +476,18 @@
             <groupId>com.webcohesion.enunciate</groupId>
             <artifactId>enunciate-core-annotations</artifactId>
         </dependency>
+        <!-- PAM -->
+        <dependency>
+            <groupId>org.kohsuke</groupId>
+            <artifactId>libpam4j</artifactId>
+            <version>1.8</version>
+        </dependency>
+
+        <dependency>
+            <groupId>net.java.dev.jna</groupId>
+            <artifactId>jna</artifactId>
+            <version>4.1.0</version>
+        </dependency>
     </dependencies>
 
     <build>

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa6d87e1/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java b/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java
index 80d6604..6827aec 100644
--- a/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java
+++ b/webapp/src/main/java/org/apache/atlas/web/security/AtlasAuthenticationProvider.java
@@ -34,10 +34,12 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
             .getLogger(AtlasAuthenticationProvider.class);
 
     private boolean fileAuthenticationMethodEnabled = true;
+    private boolean pamAuthenticationEnabled = false;
     private String ldapType = "NONE";
     public static final String FILE_AUTH_METHOD = "atlas.authentication.method.file";
     public static final String LDAP_AUTH_METHOD = "atlas.authentication.method.ldap";
     public static final String LDAP_TYPE = "atlas.authentication.method.ldap.type";
+    public static final String PAM_AUTH_METHOD = "atlas.authentication.method.pam";
 
 
 
@@ -49,13 +51,17 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
 
     final AtlasADAuthenticationProvider adAuthenticationProvider;
 
+    final AtlasPamAuthenticationProvider pamAuthenticationProvider;
+
     @Inject
     public AtlasAuthenticationProvider(AtlasLdapAuthenticationProvider ldapAuthenticationProvider,
                                        AtlasFileAuthenticationProvider fileAuthenticationProvider,
-                                       AtlasADAuthenticationProvider adAuthenticationProvider) {
+                                       AtlasADAuthenticationProvider adAuthenticationProvider,
+                                       AtlasPamAuthenticationProvider pamAuthenticationProvider) {
         this.ldapAuthenticationProvider = ldapAuthenticationProvider;
         this.fileAuthenticationProvider = fileAuthenticationProvider;
         this.adAuthenticationProvider = adAuthenticationProvider;
+        this.pamAuthenticationProvider = pamAuthenticationProvider;
     }
 
     @PostConstruct
@@ -65,6 +71,8 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
 
             this.fileAuthenticationMethodEnabled = configuration.getBoolean(FILE_AUTH_METHOD, true);
 
+            this.pamAuthenticationEnabled = configuration.getBoolean(PAM_AUTH_METHOD, false);
+
             boolean ldapAuthenticationEnabled = configuration.getBoolean(LDAP_AUTH_METHOD, false);
 
             if (ldapAuthenticationEnabled) {
@@ -102,13 +110,19 @@ public class AtlasAuthenticationProvider extends AtlasAbstractAuthenticationProv
                 } catch (Exception ex) {
                     LOG.error("Error while AD authentication", ex);
                 }
+            } else if (pamAuthenticationEnabled) {
+                try {
+                    authentication = pamAuthenticationProvider.authenticate(authentication);
+                } catch (Exception ex) {
+                    LOG.error("Error while PAM authentication", ex);
+                }
             }
         }
 
         if (authentication != null) {
             if (authentication.isAuthenticated()) {
                 return authentication;
-            } else if (fileAuthenticationMethodEnabled) {  // If the LDAP/AD authentication fails try the local filebased login method
+            } else if (fileAuthenticationMethodEnabled) {  // If the LDAP/AD/PAM authentication fails try the local filebased login method
                 authentication = fileAuthenticationProvider.authenticate(authentication);
 
                 if (authentication != null && authentication.isAuthenticated()) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa6d87e1/webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java b/webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java
new file mode 100644
index 0000000..9a5a183
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/security/AtlasPamAuthenticationProvider.java
@@ -0,0 +1,155 @@
+/*
+ * 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.web.security;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.web.model.User;
+import org.apache.commons.configuration.ConfigurationConverter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.authentication.jaas.DefaultJaasAuthenticationProvider;
+import org.springframework.security.authentication.jaas.memory.InMemoryConfiguration;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.GrantedAuthority;
+import org.springframework.security.core.userdetails.UserDetails;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.security.auth.login.AppConfigurationEntry;
+import javax.security.auth.login.Configuration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+
+@Component
+public class AtlasPamAuthenticationProvider extends AtlasAbstractAuthenticationProvider {
+
+    private static Logger LOG = LoggerFactory.getLogger(AtlasPamAuthenticationProvider.class);
+    private boolean isDebugEnabled = LOG.isDebugEnabled();
+    private static String loginModuleName = "org.apache.atlas.web.security.PamLoginModule";
+    private static AppConfigurationEntry.LoginModuleControlFlag controlFlag =
+            AppConfigurationEntry.LoginModuleControlFlag.REQUIRED;
+    private Map<String, String> options = new HashMap<String, String>();
+    private boolean groupsFromUGI;
+    private DefaultJaasAuthenticationProvider jaasAuthenticationProvider =
+            new DefaultJaasAuthenticationProvider();
+
+    @PostConstruct
+    public void setup() {
+        setPamProperties();
+        init();
+    }
+
+    @Override
+    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
+        Authentication auth = getPamAuthentication(authentication);
+        if (auth != null && auth.isAuthenticated()) {
+            return auth;
+        } else {
+            throw new AtlasAuthenticationException("PAM Authentication Failed");
+        }
+    }
+
+    private Authentication getPamAuthentication(Authentication authentication) {
+        if (isDebugEnabled) {
+            LOG.debug("==> AtlasPamAuthenticationProvider getPamAuthentication");
+        }
+        try {
+            String userName = authentication.getName();
+            String userPassword = "";
+            if (authentication.getCredentials() != null) {
+                userPassword = authentication.getCredentials().toString();
+            }
+
+            // getting user authenticated
+            if (userName != null && userPassword != null
+                    && !userName.trim().isEmpty()
+                    && !userPassword.trim().isEmpty()) {
+                final List<GrantedAuthority> grantedAuths = getAuthorities(userName);
+
+                final UserDetails principal = new User(userName, userPassword,
+                        grantedAuths);
+
+                final Authentication finalAuthentication = new UsernamePasswordAuthenticationToken(
+                        principal, userPassword, grantedAuths);
+
+                authentication = jaasAuthenticationProvider
+                        .authenticate(finalAuthentication);
+
+                if(groupsFromUGI) {
+                    authentication = getAuthenticationWithGrantedAuthorityFromUGI(authentication);
+                } else {
+                    authentication = getAuthenticationWithGrantedAuthority(authentication);
+                }
+                return authentication;
+            } else {
+                return authentication;
+            }
+
+        } catch (Exception e) {
+            LOG.debug("Pam Authentication Failed:", e);
+        }
+        if (isDebugEnabled) {
+            LOG.debug("<== AtlasPamAuthenticationProvider getPamAuthentication");
+        }
+        return authentication;
+    }
+
+    private void setPamProperties() {
+        try {
+            this.groupsFromUGI = ApplicationProperties.get().getBoolean("atlas.authentication.method.pam.ugi-groups", true);
+            Properties properties = ConfigurationConverter.getProperties(ApplicationProperties.get()
+                    .subset("atlas.authentication.method.pam"));
+            for (String key : properties.stringPropertyNames()) {
+                String value = properties.getProperty(key);
+                options.put(key, value);
+            }
+            if (!options.containsKey("service")) {
+                options.put("service", "atlas-login");
+            }
+        } catch (Exception e) {
+            LOG.error("Exception while setLdapProperties", e);
+        }
+    }
+
+    private void init() {
+        try {
+            AppConfigurationEntry appConfigurationEntry = new AppConfigurationEntry(
+                    loginModuleName, controlFlag, options);
+            AppConfigurationEntry[] appConfigurationEntries = new AppConfigurationEntry[]{appConfigurationEntry};
+            Map<String, AppConfigurationEntry[]> appConfigurationEntriesOptions =
+                    new HashMap<String, AppConfigurationEntry[]>();
+            appConfigurationEntriesOptions.put("SPRINGSECURITY",
+                    appConfigurationEntries);
+            Configuration configuration = new InMemoryConfiguration(
+                    appConfigurationEntriesOptions);
+            jaasAuthenticationProvider.setConfiguration(configuration);
+            UserAuthorityGranter authorityGranter = new UserAuthorityGranter();
+            UserAuthorityGranter[] authorityGranters = new UserAuthorityGranter[]{authorityGranter};
+            jaasAuthenticationProvider.setAuthorityGranters(authorityGranters);
+            jaasAuthenticationProvider.afterPropertiesSet();
+        } catch (Exception e) {
+            LOG.error("Failed to init PAM Authentication", e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa6d87e1/webapp/src/main/java/org/apache/atlas/web/security/PamLoginModule.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/PamLoginModule.java b/webapp/src/main/java/org/apache/atlas/web/security/PamLoginModule.java
new file mode 100644
index 0000000..802f6f1
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/security/PamLoginModule.java
@@ -0,0 +1,221 @@
+/*
+ * 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.web.security;
+
+import org.jvnet.libpam.PAM;
+import org.jvnet.libpam.PAMException;
+import org.jvnet.libpam.UnixUser;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.*;
+import javax.security.auth.login.FailedLoginException;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class PamLoginModule extends Object implements LoginModule {
+    public static final String SERVICE_KEY = "service";
+
+    private PAM pam;
+    private Subject subject;
+    private CallbackHandler callbackHandler;
+    private Map<String, ?> options;
+
+    private String username;
+    private String password;
+
+    private boolean authSucceeded;
+    private PamPrincipal principal;
+
+    public PamLoginModule()
+    {
+        super();
+        authSucceeded = false;
+    }
+
+    @Override
+    public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options)
+    {
+        this.subject = subject;
+        this.callbackHandler = callbackHandler;
+        this.options = new HashMap<>(options);
+    }
+
+    @Override
+    public boolean login() throws LoginException
+    {
+        initializePam();
+        obtainUserAndPassword();
+        return performLogin();
+    }
+
+    private void initializePam() throws LoginException
+    {
+        String service = (String) options.get(SERVICE_KEY);
+        if (service == null)
+        {
+            throw new LoginException("Error: PAM service was not defined");
+        }
+        createPam(service);
+    }
+
+    private void createPam(String service) throws LoginException
+    {
+        try
+        {
+            pam = new PAM(service);
+        }
+        catch (PAMException ex)
+        {
+            LoginException le = new LoginException("Error initializing PAM");
+            le.initCause(ex);
+            throw le;
+        }
+    }
+
+    private void obtainUserAndPassword() throws LoginException
+    {
+        if (callbackHandler == null)
+        {
+            throw new LoginException("Error: no CallbackHandler available  to gather authentication information from the user");
+        }
+
+        try
+        {
+            NameCallback nameCallback = new NameCallback("username");
+            PasswordCallback passwordCallback = new PasswordCallback("password", false);
+
+            invokeCallbackHandler(nameCallback, passwordCallback);
+
+            initUserName(nameCallback);
+            initPassword(passwordCallback);
+        }
+        catch (IOException | UnsupportedCallbackException ex)
+        {
+            LoginException le = new LoginException("Error in callbacks");
+            le.initCause(ex);
+            throw le;
+        }
+    }
+
+    private void invokeCallbackHandler(NameCallback nameCallback, PasswordCallback passwordCallback) throws IOException, UnsupportedCallbackException
+    {
+        Callback[] callbacks = new Callback[2];
+        callbacks[0] = nameCallback;
+        callbacks[1] = passwordCallback;
+
+        callbackHandler.handle(callbacks);
+    }
+
+    private void initUserName(NameCallback nameCallback)
+    {
+        username = nameCallback.getName();
+    }
+
+    private void initPassword(PasswordCallback passwordCallback)
+    {
+        char[] password = passwordCallback.getPassword();
+        if (password != null) {
+            this.password = new String(password);
+        }
+        passwordCallback.clearPassword();
+    }
+
+    private boolean performLogin() throws LoginException
+    {
+        try
+        {
+            UnixUser user = pam.authenticate(username, password);
+            principal = new PamPrincipal(user);
+            authSucceeded = true;
+
+            return true;
+        }
+        catch (PAMException ex)
+        {
+            LoginException le = new FailedLoginException("Invalid username or password");
+            le.initCause(ex);
+            throw le;
+        }
+    }
+
+    @Override
+    public boolean commit() throws LoginException
+    {
+        if (authSucceeded == false)
+        {
+            return false;
+        }
+
+        if (subject.isReadOnly())
+        {
+            cleanup();
+            throw new LoginException("Subject is read-only");
+        }
+
+        Set<Principal> principals = subject.getPrincipals();
+        if (principals.contains(principal) == false)
+        {
+            principals.add(principal);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean abort() throws LoginException
+    {
+        if (authSucceeded == false)
+        {
+            return false;
+        }
+
+        cleanup();
+        return true;
+    }
+
+    @Override
+    public boolean logout() throws LoginException
+    {
+        if (subject.isReadOnly())
+        {
+            cleanup();
+            throw new LoginException("Subject is read-only");
+        }
+
+        subject.getPrincipals().remove(principal);
+
+        cleanup();
+        return true;
+    }
+
+    private void cleanup()
+    {
+        authSucceeded = false;
+        username = null;
+        password = null;
+        principal = null;
+        pam.dispose();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa6d87e1/webapp/src/main/java/org/apache/atlas/web/security/PamPrincipal.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/PamPrincipal.java b/webapp/src/main/java/org/apache/atlas/web/security/PamPrincipal.java
new file mode 100644
index 0000000..e7c80af
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/security/PamPrincipal.java
@@ -0,0 +1,84 @@
+/*
+ * 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.web.security;
+
+import org.jvnet.libpam.UnixUser;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Set;
+
+public class PamPrincipal extends Object implements Principal {
+    private String userName;
+    private String gecos;
+    private String homeDir;
+    private String shell;
+    private int uid;
+    private int gid;
+    private Set<String> groups;
+
+    public PamPrincipal(UnixUser user)
+    {
+        super();
+        userName = user.getUserName();
+        gecos = user.getGecos();
+        homeDir = user.getDir();
+        shell = user.getShell();
+        uid = user.getUID();
+        gid = user.getGID();
+        groups = Collections.unmodifiableSet(user.getGroups());
+    }
+
+    @Override
+    public String getName()
+    {
+        return userName;
+    }
+
+    public String getGecos()
+    {
+        return gecos;
+    }
+
+    public String getHomeDir()
+    {
+        return homeDir;
+    }
+
+    public String getShell()
+    {
+        return shell;
+    }
+
+    public int getUid()
+    {
+        return uid;
+    }
+
+    public int getGid()
+    {
+        return gid;
+    }
+
+    public Set<String> getGroups()
+    {
+        return groups;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/aa6d87e1/webapp/src/main/java/org/apache/atlas/web/security/UserAuthorityGranter.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/security/UserAuthorityGranter.java b/webapp/src/main/java/org/apache/atlas/web/security/UserAuthorityGranter.java
new file mode 100644
index 0000000..430dbd9
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/web/security/UserAuthorityGranter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.web.security;
+
+import org.springframework.security.authentication.jaas.AuthorityGranter;
+
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Set;
+
+public class UserAuthorityGranter implements AuthorityGranter {
+
+    @Override
+    public Set<String> grant(Principal principal) {
+        Collections.singleton("DATA_SCIENTIST");
+        return null;
+    }
+}


[13/14] incubator-atlas git commit: ATLAS-1866: DSL 'like' operator fails for associated entity attributes

Posted by ma...@apache.org.
ATLAS-1866: DSL 'like' operator fails for associated entity attributes


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

Branch: refs/heads/feature-odf
Commit: c2d52759ff7ce70f0a17e6f7f2ac46f7e160b647
Parents: 906f365
Author: Madhan Neethiraj <ma...@apache.org>
Authored: Sun Jun 18 17:27:55 2017 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Sun Jun 18 17:30:51 2017 -0700

----------------------------------------------------------------------
 .../java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java | 4 +---
 .../java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java | 3 +--
 .../apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java  | 3 +++
 3 files changed, 5 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c2d52759/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
index 5f8bb80..27de0ed 100644
--- a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
+++ b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin2ExpressionFactory.java
@@ -40,7 +40,6 @@ import org.apache.atlas.groovy.LogicalExpression.LogicalOperator;
 import org.apache.atlas.groovy.RangeExpression;
 import org.apache.atlas.groovy.TernaryOperatorExpression;
 import org.apache.atlas.groovy.TraversalStepType;
-import org.apache.atlas.query.Expressions;
 import org.apache.atlas.query.GraphPersistenceStrategies;
 import org.apache.atlas.query.TypeUtils.FieldInfo;
 import org.apache.atlas.typesystem.types.IDataType;
@@ -154,9 +153,8 @@ public class Gremlin2ExpressionFactory extends GremlinExpressionFactory {
         GroovyExpression nameExpr    = new FieldExpression(itExpr, propertyName);
         GroovyExpression matchesExpr = new FunctionCallExpression(nameExpr, MATCHES, escapePropertyValue(propertyValue));
         GroovyExpression closureExpr = new ClosureExpression(matchesExpr);
-        GroovyExpression filterExpr  = new FunctionCallExpression(parent, FILTER_METHOD, closureExpr);
 
-        return filterExpr;
+        return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, closureExpr);
     }
 
     private GroovyExpression escapePropertyValue(GroovyExpression propertyValue) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c2d52759/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
index aaec6fe..750cd84 100644
--- a/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
+++ b/repository/src/main/java/org/apache/atlas/gremlin/Gremlin3ExpressionFactory.java
@@ -250,9 +250,8 @@ public class Gremlin3ExpressionFactory extends GremlinExpressionFactory {
         GroovyExpression nameExpr    = new FieldExpression(itExpr, propertyName);
         GroovyExpression matchesExpr = new FunctionCallExpression(nameExpr, MATCHES, escapePropertyValue(propertyValue));
         GroovyExpression closureExpr = new ClosureExpression(matchesExpr);
-        GroovyExpression filterExpr  = new FunctionCallExpression(parent, FILTER_METHOD, closureExpr);
 
-        return filterExpr;
+        return new FunctionCallExpression(TraversalStepType.FILTER, parent, FILTER_METHOD, closureExpr);
     }
 
     private GroovyExpression escapePropertyValue(GroovyExpression propertyValue) {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/c2d52759/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
----------------------------------------------------------------------
diff --git a/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java b/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
index 675ab8a..236134d 100755
--- a/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
+++ b/repository/src/test/java/org/apache/atlas/discovery/GraphBackedDiscoveryServiceTest.java
@@ -290,6 +290,9 @@ public class GraphBackedDiscoveryServiceTest extends BaseRepositoryTest {
                 {"hive_db where hive_db.name like \"R???rt?*\" or hive_db.name like \"S?l?s\" or hive_db.name like\"Log*\"", 3},
                 {"hive_db where hive_db.name like \"R???rt?*\" and hive_db.name like \"S?l?s\" and hive_db.name like\"Log*\"", 0},
                 {"hive_table where name like 'sales*', db where name like 'Sa?es'", 1},
+                {"hive_table where name like 'sales*' and db.name like 'Sa?es'", 1},
+                {"hive_table where db.name like \"Sa*\"", 4},
+                {"hive_table where db.name like \"Sa*\" and name like \"*dim\"", 3},
         };
     }
 


[04/14] incubator-atlas git commit: ATLAS-1852: create relationship-def

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
index 17b7e17..aefd168 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasTypeDefGraphStore.java
@@ -26,24 +26,13 @@ import org.apache.atlas.listener.ActiveStateChangeHandler;
 import org.apache.atlas.listener.ChangedTypeDefs;
 import org.apache.atlas.listener.TypeDefChangeListener;
 import org.apache.atlas.model.SearchFilter;
-import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
-import org.apache.atlas.model.typedef.AtlasClassificationDef;
-import org.apache.atlas.model.typedef.AtlasEntityDef;
-import org.apache.atlas.model.typedef.AtlasEnumDef;
-import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.model.typedef.*;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasConstraintDef;
-import org.apache.atlas.model.typedef.AtlasTypesDef;
 import org.apache.atlas.repository.util.FilterUtil;
 import org.apache.atlas.store.AtlasTypeDefStore;
-import org.apache.atlas.type.AtlasClassificationType;
-import org.apache.atlas.type.AtlasEntityType;
-import org.apache.atlas.type.AtlasEnumType;
-import org.apache.atlas.type.AtlasStructType;
-import org.apache.atlas.type.AtlasType;
-import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.type.*;
 import org.apache.atlas.type.AtlasTypeRegistry.AtlasTransientTypeRegistry;
-import org.apache.atlas.type.AtlasTypeUtil;
 import org.apache.atlas.util.AtlasRepositoryConfiguration;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.Predicate;
@@ -83,6 +72,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
 
     protected abstract AtlasEntityDefStore getEntityDefStore(AtlasTypeRegistry typeRegistry);
 
+    protected abstract AtlasRelationshipDefStore getRelationshipDefStore(AtlasTypeRegistry typeRegistry);
+
     @Override
     public void init() throws AtlasBaseException {
         AtlasTransientTypeRegistry ttr           = null;
@@ -96,7 +87,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
             AtlasTypesDef typesDef = new AtlasTypesDef(getEnumDefStore(ttr).getAll(),
                     getStructDefStore(ttr).getAll(),
                     getClassificationDefStore(ttr).getAll(),
-                    getEntityDefStore(ttr).getAll());
+                    getEntityDefStore(ttr).getAll(),
+                    getRelationshipDefStore(ttr).getAll());
 
             rectifyTypeErrorsIfAny(typesDef);
 
@@ -167,6 +159,27 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
 
         return ret;
     }
+    @Override
+    public AtlasRelationshipDef getRelationshipDefByName(String name) throws AtlasBaseException {
+        AtlasRelationshipDef ret = typeRegistry.getRelationshipDefByName(name);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef getRelationshipDefByGuid(String guid) throws AtlasBaseException {
+        AtlasRelationshipDef ret = typeRegistry.getRelationshipDefByGuid(guid);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        return ret;
+    }
 
     @Override
     @GraphTransaction
@@ -268,21 +281,36 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
     @GraphTransaction
     public AtlasEntityDef updateEntityDefByGuid(String guid, AtlasEntityDef entityDef) throws AtlasBaseException {
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
-
         tryUpdateByGUID(guid, entityDef, ttr);
-
         return getEntityDefStore(ttr).updateByGuid(guid, entityDef);
     }
 
     @Override
     @GraphTransaction
+    public AtlasRelationshipDef updateRelationshipDefByName(String name, AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
+        AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
+        tryUpdateByName(name, relationshipDef, ttr);
+        return getRelationshipDefStore(ttr).updateByName(name, relationshipDef);
+    }
+
+    @Override
+    @GraphTransaction
+    public AtlasRelationshipDef updateRelationshipDefByGuid(String guid, AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
+        AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
+        tryUpdateByGUID(guid, relationshipDef, ttr);
+        return getRelationshipDefStore(ttr).updateByGuid(guid, relationshipDef);
+    }
+
+    @Override
+    @GraphTransaction
     public AtlasTypesDef createTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classifications={}, entities={})",
+            LOG.debug("==> AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classifications={}, entities={}, relationships={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
-                    CollectionUtils.size(typesDef.getEntityDefs()));
+                    CollectionUtils.size(typesDef.getEntityDefs()),
+                    CollectionUtils.size(typesDef.getRelationshipDefs()));
         }
 
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -292,11 +320,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
         AtlasTypesDef ret = addToGraphStore(typesDef, ttr);
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classfications={}, entities={})",
+            LOG.debug("<== AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
-                    CollectionUtils.size(typesDef.getEntityDefs()));
+                    CollectionUtils.size(typesDef.getEntityDefs()),
+                    CollectionUtils.size(typesDef.getRelationshipDefs()));
         }
 
         return ret;
@@ -359,11 +388,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
     @GraphTransaction
     public AtlasTypesDef updateTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={})",
+            LOG.debug("==> AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships{})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
-                    CollectionUtils.size(typesDef.getEntityDefs()));
+                    CollectionUtils.size(typesDef.getEntityDefs()),
+                    CollectionUtils.size(typesDef.getRelationshipDefs()));
         }
 
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -397,11 +427,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
     @GraphTransaction
     public void deleteTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> AtlasTypeDefGraphStore.deleteTypesDef(enums={}, structs={}, classfications={}, entities={})",
+            LOG.debug("==> AtlasTypeDefGraphStore.deleteTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
-                    CollectionUtils.size(typesDef.getEntityDefs()));
+                    CollectionUtils.size(typesDef.getEntityDefs()),
+                    CollectionUtils.size(typesDef.getRelationshipDefs()));
         }
 
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -410,11 +441,25 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
         AtlasStructDefStore         structDefStore   = getStructDefStore(ttr);
         AtlasClassificationDefStore classifiDefStore = getClassificationDefStore(ttr);
         AtlasEntityDefStore         entityDefStore   = getEntityDefStore(ttr);
+        AtlasRelationshipDefStore   relationshipDefStore = getRelationshipDefStore(ttr);
 
         List<Object> preDeleteStructDefs   = new ArrayList<>();
         List<Object> preDeleteClassifiDefs = new ArrayList<>();
         List<Object> preDeleteEntityDefs   = new ArrayList<>();
+        List<Object> preDeleteRelationshipDefs = new ArrayList<>();
 
+        // pre deletes
+
+        // do the relationships first.
+        if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
+            for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
+                if (StringUtils.isNotBlank(relationshipDef.getGuid())) {
+                    preDeleteRelationshipDefs.add(relationshipDefStore.preDeleteByGuid(relationshipDef.getGuid()));
+                } else {
+                    preDeleteRelationshipDefs.add(relationshipDefStore.preDeleteByName(relationshipDef.getName()));
+                }
+            }
+        }
         if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
             for (AtlasStructDef structDef : typesDef.getStructDefs()) {
                 if (StringUtils.isNotBlank(structDef.getGuid())) {
@@ -445,6 +490,21 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
             }
         }
 
+        // run the actual deletes
+
+        // run the relationshipDef delete first - in case there is a enumDef or entityDef dependancy that is going to be deleted.
+        if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
+            int i = 0;
+            for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
+                if (StringUtils.isNotBlank(relationshipDef.getGuid())) {
+                    relationshipDefStore.deleteByGuid(relationshipDef.getGuid(), preDeleteRelationshipDefs.get(i));
+                } else {
+                    relationshipDefStore.deleteByName(relationshipDef.getName(), preDeleteRelationshipDefs.get(i));
+                }
+                i++;
+            }
+        }
+
         if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
             int i = 0;
             for (AtlasStructDef structDef : typesDef.getStructDefs()) {
@@ -532,6 +592,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
             }
         }
 
+        for(AtlasRelationshipType relationshipType : typeRegistry.getAllRelationshipTypes()) {
+            if (searchPredicates.evaluate(relationshipType)) {
+                typesDef.getRelationshipDefs().add(relationshipType.getRelationshipDef());
+            }
+        }
+
         return typesDef;
     }
 
@@ -691,11 +757,14 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
         AtlasStructDefStore         structDefStore   = getStructDefStore(ttr);
         AtlasClassificationDefStore classifiDefStore = getClassificationDefStore(ttr);
         AtlasEntityDefStore         entityDefStore   = getEntityDefStore(ttr);
+        AtlasRelationshipDefStore   relationshipDefStore   = getRelationshipDefStore(ttr);
 
         List<Object> preCreateStructDefs   = new ArrayList<>();
         List<Object> preCreateClassifiDefs = new ArrayList<>();
         List<Object> preCreateEntityDefs   = new ArrayList<>();
+        List<Object> preCreateRelationshipDefs   = new ArrayList<>();
 
+        // for enumerations run the create
         if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
             for (AtlasEnumDef enumDef : typesDef.getEnumDefs()) {
                 AtlasEnumDef createdDef = enumDefStore.create(enumDef);
@@ -705,6 +774,7 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
                 ret.getEnumDefs().add(createdDef);
             }
         }
+        // run the preCreates
 
         if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
             for (AtlasStructDef structDef : typesDef.getStructDefs()) {
@@ -724,6 +794,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
+            for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
+                preCreateRelationshipDefs.add(relationshipDefStore.preCreate(relationshipDef));
+            }
+        }
+
         if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
             int i = 0;
             for (AtlasStructDef structDef : typesDef.getStructDefs()) {
@@ -759,6 +835,17 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore, Activ
                 i++;
             }
         }
+        if (CollectionUtils.isNotEmpty(typesDef.getRelationshipDefs())) {
+            int i = 0;
+            for (AtlasRelationshipDef relationshipDef : typesDef.getRelationshipDefs()) {
+                AtlasRelationshipDef createdDef = relationshipDefStore.create(relationshipDef, preCreateRelationshipDefs.get(i));
+
+                ttr.updateGuid(createdDef.getName(), createdDef.getGuid());
+
+                ret.getRelationshipDefs().add(createdDef);
+                i++;
+            }
+        }
 
         return ret;
     }

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
new file mode 100644
index 0000000..96cd8d1
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasRelationshipDefStoreV1.java
@@ -0,0 +1,409 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.atlas.repository.store.graph.v1;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
+import org.apache.atlas.model.typedef.AtlasRelationshipEndPointDef;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
+import org.apache.atlas.type.AtlasRelationshipType;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * RelationshipDef store in v1 format.
+ */
+public class AtlasRelationshipDefStoreV1 extends AtlasAbstractDefStoreV1 implements AtlasRelationshipDefStore {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasRelationshipDefStoreV1.class);
+
+    public AtlasRelationshipDefStoreV1(AtlasTypeDefGraphStoreV1 typeDefStore, AtlasTypeRegistry typeRegistry) {
+        super(typeDefStore, typeRegistry);
+    }
+
+    @Override
+    public AtlasVertex preCreate(AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.preCreate({})", relationshipDef);
+        }
+
+        validateType(relationshipDef);
+
+        AtlasType type = typeRegistry.getType(relationshipDef.getName());
+
+        if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.RELATIONSHIP) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, relationshipDef.getName(), TypeCategory.RELATIONSHIP.name());
+        }
+
+        AtlasVertex ret = typeDefStore.findTypeVertexByName(relationshipDef.getName());
+
+        if (ret != null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_ALREADY_EXISTS, relationshipDef.getName());
+        }
+
+        ret = typeDefStore.createTypeVertex(relationshipDef);
+
+        updateVertexPreCreate(relationshipDef, (AtlasRelationshipType) type, ret);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.preCreate({}): {}", relationshipDef, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef create(AtlasRelationshipDef relationshipDef, Object preCreateResult)
+            throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.create({}, {})", relationshipDef, preCreateResult);
+        }
+
+        AtlasVertex vertex;
+
+        if (preCreateResult == null || !(preCreateResult instanceof AtlasVertex)) {
+            vertex = preCreate(relationshipDef);
+        } else {
+            vertex = (AtlasVertex) preCreateResult;
+        }
+
+        AtlasRelationshipDef ret = toRelationshipDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.create({}, {}): {}", relationshipDef, preCreateResult, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public List<AtlasRelationshipDef> getAll() throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.getAll()");
+        }
+
+        List<AtlasRelationshipDef> ret = new ArrayList<>();
+        Iterator<AtlasVertex> vertices = typeDefStore.findTypeVerticesByCategory(TypeCategory.RELATIONSHIP);
+
+        while (vertices.hasNext()) {
+            ret.add(toRelationshipDef(vertices.next()));
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.getAll(): count={}", ret.size());
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef getByName(String name) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.getByName({})", name);
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.RELATIONSHIP);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        vertex.getProperty(Constants.TYPE_CATEGORY_PROPERTY_KEY, TypeCategory.class);
+
+        AtlasRelationshipDef ret = toRelationshipDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.getByName({}): {}", name, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef getByGuid(String guid) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.getByGuid({})", guid);
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.RELATIONSHIP);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        AtlasRelationshipDef ret = toRelationshipDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.getByGuid({}): {}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef update(AtlasRelationshipDef relationshipDef) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.update({})", relationshipDef);
+        }
+
+        validateType(relationshipDef);
+
+        AtlasRelationshipDef ret = StringUtils.isNotBlank(relationshipDef.getGuid())
+                ? updateByGuid(relationshipDef.getGuid(), relationshipDef)
+                : updateByName(relationshipDef.getName(), relationshipDef);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.update({}): {}", relationshipDef, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef updateByName(String name, AtlasRelationshipDef relationshipDef)
+            throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.updateByName({}, {})", name, relationshipDef);
+        }
+
+        validateType(relationshipDef);
+
+        AtlasType type = typeRegistry.getType(relationshipDef.getName());
+
+        if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.RELATIONSHIP) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, relationshipDef.getName(), TypeCategory.RELATIONSHIP.name());
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.RELATIONSHIP);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        updateVertexPreUpdate(relationshipDef, (AtlasRelationshipType) type, vertex);
+
+        AtlasRelationshipDef ret = toRelationshipDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.updateByName({}, {}): {}", name, relationshipDef, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasRelationshipDef updateByGuid(String guid, AtlasRelationshipDef relationshipDef)
+            throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.updateByGuid({})", guid);
+        }
+
+        validateType(relationshipDef);
+
+        AtlasType type = typeRegistry.getTypeByGuid(guid);
+
+        if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.RELATIONSHIP) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, relationshipDef.getName(), TypeCategory.RELATIONSHIP.name());
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.RELATIONSHIP);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        updateVertexPreUpdate(relationshipDef, (AtlasRelationshipType) type, vertex);
+        // TODO delete / create edges to entitytypes
+        AtlasRelationshipDef ret = toRelationshipDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.updateByGuid({}): {}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasVertex preDeleteByName(String name) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.preDeleteByName({})", name);
+        }
+
+        AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, TypeCategory.RELATIONSHIP);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        if (AtlasGraphUtilsV1.typeHasInstanceVertex(name)) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, name);
+        }
+
+        // TODO delete the edges to the other types
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.preDeleteByName({}): {}", name, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public void deleteByName(String name, Object preDeleteResult) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.deleteByName({}, {})", name, preDeleteResult);
+        }
+
+        AtlasVertex vertex;
+
+        if (preDeleteResult == null || !(preDeleteResult instanceof AtlasVertex)) {
+            vertex = preDeleteByName(name);
+        } else {
+            vertex = (AtlasVertex) preDeleteResult;
+        }
+
+        typeDefStore.deleteTypeVertex(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.deleteByName({}, {})", name, preDeleteResult);
+        }
+    }
+
+    @Override
+    public AtlasVertex preDeleteByGuid(String guid) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.preDeleteByGuid({})", guid);
+        }
+
+        AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, TypeCategory.RELATIONSHIP);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        String typeName = AtlasGraphUtilsV1.getProperty(ret, Constants.TYPENAME_PROPERTY_KEY, String.class);
+
+        if (AtlasGraphUtilsV1.typeHasInstanceVertex(typeName)) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_HAS_REFERENCES, typeName);
+        }
+
+        // TODO delete the edges to the other types
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.preDeleteByGuid({}): {}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public void deleteByGuid(String guid, Object preDeleteResult) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasRelationshipDefStoreV1.deleteByGuid({}, {})", guid, preDeleteResult);
+        }
+
+        AtlasVertex vertex;
+
+        if (preDeleteResult == null || !(preDeleteResult instanceof AtlasVertex)) {
+            vertex = preDeleteByGuid(guid);
+        } else {
+            vertex = (AtlasVertex) preDeleteResult;
+        }
+
+        typeDefStore.deleteTypeVertex(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasRelationshipDefStoreV1.deleteByGuid({}, {})", guid, preDeleteResult);
+        }
+    }
+
+    private void updateVertexPreCreate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType,
+                                       AtlasVertex vertex) throws AtlasBaseException {
+        AtlasStructDefStoreV1.updateVertexPreCreate(relationshipDef, relationshipType, vertex, typeDefStore);
+        // Update endpoints
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT1_KEY, AtlasType.toJson(relationshipDef.getEndPointDef1()));
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT2_KEY, AtlasType.toJson(relationshipDef.getEndPointDef2()));
+        // Update RelationshipCategory
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, relationshipDef.getRelationshipCategory().name());
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, relationshipDef.getPropagateTags().name());
+    }
+
+    private void updateVertexPreUpdate(AtlasRelationshipDef relationshipDef, AtlasRelationshipType relationshipType,
+                                       AtlasVertex vertex) throws AtlasBaseException {
+        AtlasStructDefStoreV1.updateVertexPreUpdate(relationshipDef, relationshipType, vertex, typeDefStore);
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT1_KEY, AtlasType.toJson(relationshipDef.getEndPointDef1()));
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_ENDPOINT2_KEY, AtlasType.toJson(relationshipDef.getEndPointDef2()));
+        // Update RelationshipCategory
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, relationshipDef.getRelationshipCategory().name());
+        vertex.setProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, relationshipDef.getPropagateTags().name());
+    }
+
+    private AtlasRelationshipDef toRelationshipDef(AtlasVertex vertex) throws AtlasBaseException {
+        AtlasRelationshipDef ret = null;
+
+        if (vertex != null && typeDefStore.isTypeVertex(vertex, TypeCategory.RELATIONSHIP)) {
+            String name         = vertex.getProperty(Constants.TYPENAME_PROPERTY_KEY, String.class);
+            String description  = vertex.getProperty(Constants.TYPEDESCRIPTION_PROPERTY_KEY, String.class);
+            String version      = vertex.getProperty(Constants.TYPEVERSION_PROPERTY_KEY, String.class);
+            String endPoint1Str = vertex.getProperty(Constants.RELATIONSHIPTYPE_ENDPOINT1_KEY, String.class);
+            String endPoint2Str = vertex.getProperty(Constants.RELATIONSHIPTYPE_ENDPOINT2_KEY, String.class);
+            String relationStr  = vertex.getProperty(Constants.RELATIONSHIPTYPE_CATEGORY_KEY, String.class);
+            String propagateStr = vertex.getProperty(Constants.RELATIONSHIPTYPE_TAG_PROPAGATION_KEY, String.class);
+
+            // set the endpoints
+            AtlasRelationshipEndPointDef endPointDef1 = AtlasType.fromJson(endPoint1Str, AtlasRelationshipEndPointDef.class);
+            AtlasRelationshipEndPointDef endPointDef2 = AtlasType.fromJson(endPoint2Str, AtlasRelationshipEndPointDef.class);
+
+            // set the relationship Category
+            RelationshipCategory relationshipCategory = null;
+            for (RelationshipCategory value : RelationshipCategory.values()) {
+                if (value.name().equals(relationStr)) {
+                    relationshipCategory = value;
+                }
+            }
+
+            // set the propagateTags
+            PropagateTags propagateTags = null;
+            for (PropagateTags value : PropagateTags.values()) {
+                if (value.name().equals(propagateStr)) {
+                    propagateTags = value;
+                }
+            }
+
+            ret = new AtlasRelationshipDef(name, description, version, relationshipCategory,  propagateTags, endPointDef1, endPointDef2);
+
+            // add in the attributes
+            AtlasStructDefStoreV1.toStructDef(vertex, ret, typeDefStore);
+        }
+
+        return ret;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasTypeDefGraphStoreV1.java
----------------------------------------------------------------------
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasTypeDefGraphStoreV1.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasTypeDefGraphStoreV1.java
index f0c8380..2ba4144 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasTypeDefGraphStoreV1.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v1/AtlasTypeDefGraphStoreV1.java
@@ -19,6 +19,17 @@ package org.apache.atlas.repository.store.graph.v1;
 
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Preconditions;
+
+import static org.apache.atlas.repository.Constants.TYPE_CATEGORY_PROPERTY_KEY;
+import static org.apache.atlas.repository.Constants.VERTEX_TYPE_PROPERTY_KEY;
+import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.VERTEX_TYPE;
+
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.listener.TypeDefChangeListener;
@@ -31,6 +42,7 @@ import org.apache.atlas.repository.graphdb.AtlasVertex;
 import org.apache.atlas.repository.store.graph.AtlasClassificationDefStore;
 import org.apache.atlas.repository.store.graph.AtlasEntityDefStore;
 import org.apache.atlas.repository.store.graph.AtlasEnumDefStore;
+import org.apache.atlas.repository.store.graph.AtlasRelationshipDefStore;
 import org.apache.atlas.repository.store.graph.AtlasStructDefStore;
 import org.apache.atlas.repository.store.graph.AtlasTypeDefGraphStore;
 import org.apache.atlas.type.AtlasType;
@@ -45,16 +57,6 @@ import org.springframework.stereotype.Component;
 import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-
-import static org.apache.atlas.repository.Constants.TYPE_CATEGORY_PROPERTY_KEY;
-import static org.apache.atlas.repository.Constants.VERTEX_TYPE_PROPERTY_KEY;
-import static org.apache.atlas.repository.store.graph.v1.AtlasGraphUtilsV1.VERTEX_TYPE;
 
 
 /**
@@ -110,6 +112,12 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
     }
 
     @Override
+    protected AtlasRelationshipDefStore getRelationshipDefStore(AtlasTypeRegistry typeRegistry) {
+        return new AtlasRelationshipDefStoreV1(this, typeRegistry);
+    }
+
+
+    @Override
     @PostConstruct
     public void init() throws AtlasBaseException {
         LOG.debug("==> AtlasTypeDefGraphStoreV1.init()");
@@ -124,34 +132,34 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
     @VisibleForTesting
     public AtlasVertex findTypeVertexByName(String typeName) {
         Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
-                                             .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
-                                             .vertices().iterator();
+                .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
+                .vertices().iterator();
 
         return (results != null && results.hasNext()) ? (AtlasVertex) results.next() : null;
     }
 
     AtlasVertex findTypeVertexByNameAndCategory(String typeName, TypeCategory category) {
         Iterator results = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
-                                             .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
-                                             .has(TYPE_CATEGORY_PROPERTY_KEY, category)
-                                             .vertices().iterator();
+                .has(Constants.TYPENAME_PROPERTY_KEY, typeName)
+                .has(TYPE_CATEGORY_PROPERTY_KEY, category)
+                .vertices().iterator();
 
         return (results != null && results.hasNext()) ? (AtlasVertex) results.next() : null;
     }
 
     AtlasVertex findTypeVertexByGuid(String typeGuid) {
         Iterator<AtlasVertex> vertices = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
-                                                      .has(Constants.GUID_PROPERTY_KEY, typeGuid)
-                                                      .vertices().iterator();
+                .has(Constants.GUID_PROPERTY_KEY, typeGuid)
+                .vertices().iterator();
 
         return (vertices != null && vertices.hasNext()) ? vertices.next() : null;
     }
 
     AtlasVertex findTypeVertexByGuidAndCategory(String typeGuid, TypeCategory category) {
         Iterator<AtlasVertex> vertices = atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
-                                                      .has(Constants.GUID_PROPERTY_KEY, typeGuid)
-                                                      .has(TYPE_CATEGORY_PROPERTY_KEY, category)
-                                                      .vertices().iterator();
+                .has(Constants.GUID_PROPERTY_KEY, typeGuid)
+                .has(TYPE_CATEGORY_PROPERTY_KEY, category)
+                .vertices().iterator();
 
         return (vertices != null && vertices.hasNext()) ? vertices.next() : null;
     }
@@ -159,8 +167,8 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
     Iterator<AtlasVertex> findTypeVerticesByCategory(TypeCategory category) {
 
         return (Iterator<AtlasVertex>) atlasGraph.query().has(VERTEX_TYPE_PROPERTY_KEY, VERTEX_TYPE)
-                                                 .has(TYPE_CATEGORY_PROPERTY_KEY, category)
-                                                 .vertices().iterator();
+                .has(TYPE_CATEGORY_PROPERTY_KEY, category)
+                .vertices().iterator();
     }
 
     AtlasVertex createTypeVertex(AtlasBaseTypeDef typeDef) {
@@ -246,7 +254,6 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
         for (AtlasEdge edge : edges) {
             atlasGraph.removeEdge(edge);
         }
-
         atlasGraph.removeVertex(vertex);
     }
 
@@ -343,7 +350,7 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
     }
 
     void createSuperTypeEdges(AtlasVertex vertex, Set<String> superTypes, TypeCategory typeCategory)
-        throws AtlasBaseException {
+            throws AtlasBaseException {
         Set<String> currentSuperTypes = getSuperTypeNames(vertex);
 
         if (CollectionUtils.isNotEmpty(superTypes)) {
@@ -385,6 +392,9 @@ public class AtlasTypeDefGraphStoreV1 extends AtlasTypeDefGraphStore {
 
             case ENUM:
                 return TypeCategory.ENUM;
+
+            case RELATIONSHIP:
+                return TypeCategory.RELATIONSHIP;
         }
 
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/typesystem/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
----------------------------------------------------------------------
diff --git a/typesystem/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java b/typesystem/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
index 21d5f1a..f9f4abe 100755
--- a/typesystem/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
+++ b/typesystem/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
@@ -86,7 +86,8 @@ public class DataTypes {
         MAP,
         STRUCT,
         TRAIT,
-        CLASS
+        CLASS,
+        RELATIONSHIP
     }
 
     public static abstract class PrimitiveType<T> extends AbstractDataType<T> {

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/webapp/src/main/java/org/apache/atlas/examples/CreateTypesFromJsonFileUtil.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/examples/CreateTypesFromJsonFileUtil.java b/webapp/src/main/java/org/apache/atlas/examples/CreateTypesFromJsonFileUtil.java
new file mode 100644
index 0000000..82d6f2e
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/examples/CreateTypesFromJsonFileUtil.java
@@ -0,0 +1,109 @@
+/**
+ * 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.examples;
+
+import java.io.Console;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasBaseClient;
+import org.apache.atlas.AtlasClientV2;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.utils.AuthenticationUtil;
+import org.apache.commons.configuration.Configuration;
+
+import com.google.common.annotations.VisibleForTesting;
+
+/**
+ * A driver that sets up types supplied in a file.  
+ */
+public class CreateTypesFromJsonFileUtil  extends AtlasBaseClient{
+    public static final String ATLAS_REST_ADDRESS = "atlas.rest.address";
+
+    public static void main(String[] args) throws Exception {
+
+        Console console = System.console();
+        if (console == null) {
+            System.err.println("No console.");
+            System.exit(1);
+        }
+        String[] basicAuthUsernamePassword = null;
+        if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
+            basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
+        }
+        AtlasClientV2 atlasClientV2 = getAtlasClientV2(args, basicAuthUsernamePassword);
+
+
+        String createFileName = console.readLine("Enter fileName containing TypeDefs for create:- ");
+        File createFile = new File(createFileName);
+        String createJsonStr = new String( Files.readAllBytes(createFile.toPath()), StandardCharsets.UTF_8);
+
+        System.err.println("create json is :\n" + createJsonStr);
+
+        runTypeCreation(createJsonStr,atlasClientV2);
+//        String updateFileName = console.readLine("Enter fileName containing TypeDefs for update:- ");
+//        File updateFile = new File(updateFileName);
+//        String updateJsonStr = new String( Files.readAllBytes(updateFile.toPath()), StandardCharsets.UTF_8);
+//        System.err.println("update json is :\n" + updateJsonStr);
+//        runTypeUpdate(updateJsonStr,atlasClientV2);
+    }
+
+    @VisibleForTesting
+    static void runTypeCreation(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
+        AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
+        atlasClientV2.createAtlasTypeDefs(typesDef);
+    }
+    @VisibleForTesting
+    static void runTypeUpdate(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
+        AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
+        atlasClientV2.updateAtlasTypeDefs(typesDef);
+    }
+
+    private static AtlasClientV2 getAtlasClientV2(String[] args, String[] basicAuthUsernamePassword) throws AtlasException {
+        String[] urls = getServerUrl(args);
+
+        AtlasClientV2 atlasClientV2;
+
+        if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
+            atlasClientV2 =new AtlasClientV2(urls,basicAuthUsernamePassword);
+        } else {
+            atlasClientV2 = new AtlasClientV2(urls);
+        }
+        return atlasClientV2;
+    }
+
+    static String[] getServerUrl(String[] args) throws AtlasException {
+        if (args.length > 0) {
+            return args[0].split(",");
+        }
+
+        Configuration configuration = ApplicationProperties.get();
+        String[] urls = configuration.getStringArray(ATLAS_REST_ADDRESS);
+        if (urls == null || urls.length == 0) {
+            System.out.println("Usage: quick_start.py <atlas endpoint of format <http/https>://<atlas-fqdn>:<atlas port> like http://localhost:21000>");
+            System.exit(-1);
+        }
+
+        return urls;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/webapp/src/main/java/org/apache/atlas/examples/UpdateTypesFromJsonFileUtil.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/examples/UpdateTypesFromJsonFileUtil.java b/webapp/src/main/java/org/apache/atlas/examples/UpdateTypesFromJsonFileUtil.java
new file mode 100644
index 0000000..3b67706
--- /dev/null
+++ b/webapp/src/main/java/org/apache/atlas/examples/UpdateTypesFromJsonFileUtil.java
@@ -0,0 +1,108 @@
+/**
+ * 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.examples;
+
+import com.google.common.annotations.VisibleForTesting;
+import org.apache.atlas.ApplicationProperties;
+import org.apache.atlas.AtlasBaseClient;
+import org.apache.atlas.AtlasClientV2;
+import org.apache.atlas.AtlasException;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.utils.AuthenticationUtil;
+import org.apache.commons.configuration.Configuration;
+
+import java.io.Console;
+import java.io.File;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+
+/**
+ * A driver that sets up types supplied in a file.  
+ */
+public class UpdateTypesFromJsonFileUtil extends AtlasBaseClient{
+    public static final String ATLAS_REST_ADDRESS = "atlas.rest.address";
+
+    public static void main(String[] args) throws Exception {
+
+        Console console = System.console();
+        if (console == null) {
+            System.err.println("No console.");
+            System.exit(1);
+        }
+        String[] basicAuthUsernamePassword = null;
+        if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
+            basicAuthUsernamePassword = AuthenticationUtil.getBasicAuthenticationInput();
+        }
+        AtlasClientV2 atlasClientV2 = getAtlasClientV2(args, basicAuthUsernamePassword);
+
+
+        String createFileName = console.readLine("Enter fileName containing TypeDefs for create:- ");
+        File createFile = new File(createFileName);
+        String createJsonStr = new String( Files.readAllBytes(createFile.toPath()), StandardCharsets.UTF_8);
+
+        System.err.println("create json is :\n" + createJsonStr);
+
+        runTypeCreation(createJsonStr,atlasClientV2);
+//        String updateFileName = console.readLine("Enter fileName containing TypeDefs for update:- ");
+//        File updateFile = new File(updateFileName);
+//        String updateJsonStr = new String( Files.readAllBytes(updateFile.toPath()), StandardCharsets.UTF_8);
+//        System.err.println("update json is :\n" + updateJsonStr);
+//        runTypeUpdate(updateJsonStr,atlasClientV2);
+    }
+
+    @VisibleForTesting
+    static void runTypeCreation(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
+        AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
+        atlasClientV2.createAtlasTypeDefs(typesDef);
+    }
+    @VisibleForTesting
+    static void runTypeUpdate(String jsonStr,AtlasClientV2 atlasClientV2) throws Exception {
+        AtlasTypesDef typesDef = AtlasType.fromJson(jsonStr, AtlasTypesDef.class);
+        atlasClientV2.updateAtlasTypeDefs(typesDef);
+    }
+
+    private static AtlasClientV2 getAtlasClientV2(String[] args, String[] basicAuthUsernamePassword) throws AtlasException {
+        String[] urls = getServerUrl(args);
+
+        AtlasClientV2 atlasClientV2;
+
+        if (!AuthenticationUtil.isKerberosAuthenticationEnabled()) {
+            atlasClientV2 =new AtlasClientV2(urls,basicAuthUsernamePassword);
+        } else {
+            atlasClientV2 = new AtlasClientV2(urls);
+        }
+        return atlasClientV2;
+    }
+
+    static String[] getServerUrl(String[] args) throws AtlasException {
+        if (args.length > 0) {
+            return args[0].split(",");
+        }
+
+        Configuration configuration = ApplicationProperties.get();
+        String[] urls = configuration.getStringArray(ATLAS_REST_ADDRESS);
+        if (urls == null || urls.length == 0) {
+            System.out.println("Usage: quick_start.py <atlas endpoint of format <http/https>://<atlas-fqdn>:<atlas port> like http://localhost:21000>");
+            System.exit(-1);
+        }
+
+        return urls;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java b/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java
index 08121d8..f70593a 100755
--- a/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java
+++ b/webapp/src/main/java/org/apache/atlas/web/resources/TypesResource.java
@@ -266,7 +266,7 @@ public class TypesResource {
      * Return the list of type names in the type system which match the specified filter.
      *
      * @return list of type names
-     * @param typeCategory returns types whose category is the given typeCategory
+     * @param typeCategory returns types whose relationshipCategory is the given typeCategory
      * @param supertype returns types which contain the given supertype
      * @param notsupertype returns types which do not contain the given supertype
      *

http://git-wip-us.apache.org/repos/asf/incubator-atlas/blob/6b9399e0/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
----------------------------------------------------------------------
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java b/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
index c32f36e..59ea338 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/TypesREST.java
@@ -19,13 +19,7 @@ package org.apache.atlas.web.rest;
 
 import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.model.SearchFilter;
-import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
-import org.apache.atlas.model.typedef.AtlasClassificationDef;
-import org.apache.atlas.model.typedef.AtlasEntityDef;
-import org.apache.atlas.model.typedef.AtlasEnumDef;
-import org.apache.atlas.model.typedef.AtlasStructDef;
-import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
-import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.model.typedef.*;
 import org.apache.atlas.store.AtlasTypeDefStore;
 import org.apache.atlas.type.AtlasTypeUtil;
 import org.apache.atlas.utils.AtlasPerfTracer;
@@ -37,14 +31,7 @@ import org.springframework.stereotype.Service;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
-import javax.ws.rs.GET;
-import javax.ws.rs.POST;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
+import javax.ws.rs.*;
 import javax.ws.rs.core.Context;
 import java.util.List;
 import java.util.Set;
@@ -269,7 +256,39 @@ public class TypesREST {
 
         return ret;
     }
+    /**
+     * Get the relationship definition by it's name (unique)
+     * @param name relationship name
+     * @return relationship definition
+     * @throws AtlasBaseException
+     * @HTTP 200 On successful lookup of the the relationship definition by it's name
+     * @HTTP 404 On Failed lookup for the given name
+     */
+    @GET
+    @Path("/relationshipdef/name/{name}")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasRelationshipDef getRelationshipDefByName(@PathParam("name") String name) throws AtlasBaseException {
+        AtlasRelationshipDef ret = typeDefStore.getRelationshipDefByName(name);
+
+        return ret;
+    }
 
+    /**
+     * Get the relationship definition for the given guid
+     * @param guid relationship guid
+     * @return relationship definition
+     * @throws AtlasBaseException
+     * @HTTP 200 On successful lookup of the the relationship definition by it's guid
+     * @HTTP 404 On Failed lookup for the given guid
+     */
+    @GET
+    @Path("/relationshipdef/guid/{guid}")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    public AtlasRelationshipDef getRelationshipDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
+        AtlasRelationshipDef ret = typeDefStore.getRelationshipDefByGuid(guid);
+
+        return ret;
+    }
     /* Bulk API operation */
 
     /**