You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@atlas.apache.org by sa...@apache.org on 2020/01/10 23:05:31 UTC

[atlas] branch branch-2.0 updated: ATLAS-3486: Introduce Atlas NamespaceDef

This is an automated email from the ASF dual-hosted git repository.

sarath pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/atlas.git


The following commit(s) were added to refs/heads/branch-2.0 by this push:
     new 926a198  ATLAS-3486: Introduce Atlas NamespaceDef
926a198 is described below

commit 926a198c228928d278d1b336eb42c8f22d4bce3b
Author: Aadarsh Jajodia <aa...@gmail.com>
AuthorDate: Fri Jan 10 11:43:01 2020 -0800

    ATLAS-3486: Introduce Atlas NamespaceDef
    
    Signed-off-by: Sarath Subramanian <sa...@apache.org>
    (cherry picked from commit 6d94f39cf3b6207bc095310eebbe3292071be68b)
---
 .../main/java/org/apache/atlas/AtlasErrorCode.java |   5 +
 .../java/org/apache/atlas/model/TypeCategory.java  |   2 +-
 .../atlas/model/typedef/AtlasNamespaceDef.java     |  88 ++++++
 .../apache/atlas/model/typedef/AtlasStructDef.java |  33 +-
 .../apache/atlas/model/typedef/AtlasTypesDef.java  |  35 ++-
 .../org/apache/atlas/store/AtlasTypeDefStore.java  |   6 +
 .../org/apache/atlas/type/AtlasEntityType.java     |  58 +++-
 .../org/apache/atlas/type/AtlasNamespaceType.java  | 184 +++++++++++
 .../org/apache/atlas/type/AtlasStructType.java     |  45 +++
 .../org/apache/atlas/type/AtlasTypeRegistry.java   |  52 ++-
 .../java/org/apache/atlas/type/AtlasTypeUtil.java  |  10 +
 .../apache/atlas/typesystem/types/DataTypes.java   |   3 +-
 .../org/apache/atlas/TestRelationshipUtilsV2.java  |  21 +-
 .../atlas/model/typedef/TestAtlasNamespaceDef.java |  84 +++++
 .../repository/graph/GraphBackedSearchIndexer.java |   1 +
 .../atlas/repository/impexp/ExportService.java     |   1 +
 .../repository/impexp/ExportTypeProcessor.java     |  15 +-
 .../bootstrap/AtlasTypeDefStoreInitializer.java    |  25 +-
 .../store/graph/AtlasTypeDefGraphStore.java        | 117 +++++--
 .../store/graph/v2/AtlasNamespaceDefStoreV2.java   | 347 +++++++++++++++++++++
 .../store/graph/v2/AtlasTypeDefGraphStoreV2.java   |  36 ++-
 .../graph/v2/AtlasNamespaceDefStoreV2Test.java     | 319 +++++++++++++++++++
 .../org/apache/atlas/examples/QuickStartV2.java    |  28 +-
 .../java/org/apache/atlas/web/rest/TypesREST.java  |  38 +++
 24 files changed, 1486 insertions(+), 67 deletions(-)

diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 3ebd70d..2054513 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -161,6 +161,11 @@ public enum AtlasErrorCode {
     INVALID_LABEL_LENGTH(400, "ATLAS-400-00-9B", "Invalid label: {0}, label size should not be greater than {1}"),
     INVALID_LABEL_CHARACTERS(400, "ATLAS-400-00-9C", "Invalid label: {0}, label should contain alphanumeric characters, '_' or '-'"),
     INVALID_PROPAGATION_TYPE(400, "ATLAS-400-00-9D", "Invalid propagation {0} for relationship-type={1}. Default value is {2}"),
+    DUPLICATE_NAMESPACE_ATTRIBUTE(400, "ATLAS-400-00-094", "Duplicate Namespace Attributes: {0} not allowed within the same namespace: {1}"),
+    APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED(400, "ATLAS-400-00-095", "Cannot remove applicableEntityTypes in Attribute Def: {1}, defined in namespace: {2}"),
+    NAMESPACE_DEF_MANDATORY_ATTRIBUTE_NOT_ALLOWED(400, "ATLAS-400-00-096", "{0}.{1} : namespaces can not have mandatory attribute"),
+    NAMESPACE_DEF_UNIQUE_ATTRIBUTE_NOT_ALLOWED(400, "ATLAS-400-00-097", "{0}.{1} : namespaces can not have unique attribute"),
+    NAMESPACE_DEF_ATTRIBUTE_TYPE_INVALID(400, "ATLAS-400-00-098", "{0}.{1}: invalid attribute type. Namespace attribute cannot be of type entity/classification/struct/namespace"),
 
     UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to perform {1}"),
 
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 f06f64f..cbcd0a3 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, RELATIONSHIP
+    PRIMITIVE, OBJECT_ID_TYPE, ENUM, STRUCT, CLASSIFICATION, ENTITY, ARRAY, MAP, RELATIONSHIP, NAMESPACE
 }
diff --git a/intg/src/main/java/org/apache/atlas/model/typedef/AtlasNamespaceDef.java b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasNamespaceDef.java
new file mode 100644
index 0000000..713a2c2
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/model/typedef/AtlasNamespaceDef.java
@@ -0,0 +1,88 @@
+/**
+ * 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 com.fasterxml.jackson.annotation.JsonAutoDetect;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import org.apache.atlas.model.TypeCategory;
+
+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.List;
+import java.util.Map;
+
+import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.NONE;
+import static com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility.PUBLIC_ONLY;
+
+@JsonAutoDetect(getterVisibility=PUBLIC_ONLY, setterVisibility=PUBLIC_ONLY, fieldVisibility=NONE)
+@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
+@JsonIgnoreProperties(ignoreUnknown=true)
+@XmlRootElement
+@XmlAccessorType(XmlAccessType.PROPERTY)
+public class AtlasNamespaceDef extends AtlasStructDef implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    public static final String ATTR_OPTION_APPLICABLE_ENTITY_TYPES = "applicableEntityTypes";
+    public static final String ATTR_MAX_STRING_LENGTH = "maxStrLength";
+    public static final String ATTR_VALID_PATTERN = "validPattern";
+
+    public AtlasNamespaceDef() {
+        this(null, null, null, null);
+    }
+
+    public AtlasNamespaceDef(String name, String description) {
+        this(name, description, null, null, null);
+    }
+
+    public AtlasNamespaceDef(String name, String description, String typeVersion) {
+        this(name, description, typeVersion, null, null);
+    }
+
+    public AtlasNamespaceDef(String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs) {
+        this(name, description, typeVersion, attributeDefs, null);
+    }
+
+    public AtlasNamespaceDef(String name, String description, String typeVersion, List<AtlasAttributeDef> attributeDefs, Map<String, String> options) {
+        super(TypeCategory.NAMESPACE, name, description, typeVersion, attributeDefs, options);
+    }
+
+    public AtlasNamespaceDef(AtlasNamespaceDef other) {
+        super(other);
+    }
+
+    @Override
+    public String toString() {
+        return toString(new StringBuilder()).toString();
+    }
+
+    @Override
+    public StringBuilder toString(StringBuilder sb) {
+        if (sb == null) {
+            sb = new StringBuilder();
+        }
+
+        sb.append("AtlasNamespaceDef{");
+        super.toString(sb);
+        sb.append('}');
+
+        return sb;
+    }
+}
\ No newline at end of file
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 bb7ead0..1d4e37b 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
@@ -290,9 +290,9 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
         private String                   description;
         private int                      searchWeight = DEFAULT_SEARCHWEIGHT;
         private IndexType                indexType    = null;
-
         private List<AtlasConstraintDef> constraints;
         private Map<String, String>      options;
+        private String                   displayName;
 
         public AtlasAttributeDef() { this(null, null); }
 
@@ -373,9 +373,18 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
                 setDescription((other.getDescription()));
                 setSearchWeight(other.getSearchWeight());
                 setIndexType(other.getIndexType());
+                setDisplayName(other.getDisplayName());
             }
         }
 
+        public void setDisplayName(String displayName) {
+            this.displayName = displayName;
+        }
+
+        public String getDisplayName() {
+            return displayName;
+        }
+
         public int getSearchWeight() {
             return searchWeight;
         }
@@ -510,6 +519,22 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
                     getOptions().get(AtlasAttributeDef.ATTRDEF_OPTION_SOFT_REFERENCE).equals(STRING_TRUE);
         }
 
+        @JsonIgnore
+        public void setOption(String name, String value) {
+            if (this.options == null) {
+                this.options = new HashMap<>();
+            }
+
+            this.options.put(name, value);
+        }
+
+        @JsonIgnore
+        public String getOption(String name) {
+            Map<String, String> option = this.options;
+
+            return option != null ? option.get(name) : null;
+        }
+
         public String getDescription() {
             return description;
         }
@@ -538,6 +563,7 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
             sb.append(", options='").append(options).append('\'');
             sb.append(", searchWeight='").append(searchWeight).append('\'');
             sb.append(", indexType='").append(indexType).append('\'');
+            sb.append(", displayName='").append(displayName).append('\'');
             sb.append(", constraints=[");
             if (CollectionUtils.isNotEmpty(constraints)) {
                 int i = 0;
@@ -574,12 +600,13 @@ public class AtlasStructDef extends AtlasBaseTypeDef implements Serializable {
                     Objects.equals(constraints, that.constraints) &&
                     Objects.equals(options, that.options) &&
                     Objects.equals(searchWeight, that.searchWeight) &&
-                    Objects.equals(indexType, that.indexType);
+                    Objects.equals(indexType, that.indexType) &&
+                    Objects.equals(displayName, that.displayName);
         }
 
         @Override
         public int hashCode() {
-            return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, includeInNotification, defaultValue, constraints, options, description, searchWeight, indexType);
+            return Objects.hash(name, typeName, isOptional, cardinality, valuesMinCount, valuesMaxCount, isUnique, isIndexable, includeInNotification, defaultValue, constraints, options, description, searchWeight, indexType, displayName);
         }
 
         @Override
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 3634fdf..81ea946 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
@@ -47,6 +47,7 @@ public class AtlasTypesDef {
     private List<AtlasClassificationDef> classificationDefs;
     private List<AtlasEntityDef>         entityDefs;
     private List<AtlasRelationshipDef>   relationshipDefs;
+    private List<AtlasNamespaceDef>      namespaceDefs;
 
     public AtlasTypesDef() {
         enumDefs           = new ArrayList<>();
@@ -54,6 +55,7 @@ public class AtlasTypesDef {
         classificationDefs = new ArrayList<>();
         entityDefs         = new ArrayList<>();
         relationshipDefs   = new ArrayList<>();
+        namespaceDefs      = new ArrayList<>();
     }
 
     /**
@@ -66,7 +68,7 @@ public class AtlasTypesDef {
      */
     public AtlasTypesDef(List<AtlasEnumDef> enumDefs, List<AtlasStructDef> structDefs,
                          List<AtlasClassificationDef> classificationDefs, List<AtlasEntityDef> entityDefs) {
-       this(enumDefs, structDefs, classificationDefs, entityDefs,new ArrayList<AtlasRelationshipDef>());
+       this(enumDefs, structDefs, classificationDefs, entityDefs, new ArrayList<>(), new ArrayList<>());
     }
     /**
      * Create the TypesDef. This created definitions for each of the types.
@@ -81,12 +83,23 @@ public class AtlasTypesDef {
                          List<AtlasClassificationDef> classificationDefs,
                          List<AtlasEntityDef>         entityDefs,
                          List<AtlasRelationshipDef>   relationshipDefs) {
+        this(enumDefs, structDefs, classificationDefs, entityDefs, relationshipDefs, new ArrayList<>());
+    }
+
+    public AtlasTypesDef(List<AtlasEnumDef>           enumDefs,
+                         List<AtlasStructDef>         structDefs,
+                         List<AtlasClassificationDef> classificationDefs,
+                         List<AtlasEntityDef>         entityDefs,
+                         List<AtlasRelationshipDef>   relationshipDefs,
+                         List<AtlasNamespaceDef>      namespaceDefs) {
         this.enumDefs           = enumDefs;
         this.structDefs         = structDefs;
         this.classificationDefs = classificationDefs;
         this.entityDefs         = entityDefs;
         this.relationshipDefs   = relationshipDefs;
+        this.namespaceDefs      = namespaceDefs;
     }
+
     public List<AtlasEnumDef> getEnumDefs() {
         return enumDefs;
     }
@@ -125,6 +138,14 @@ public class AtlasTypesDef {
         this.relationshipDefs = relationshipDefs;
     }
 
+    public void setNamespaceDefs(List<AtlasNamespaceDef> namespaceDefs) {
+        this.namespaceDefs = namespaceDefs;
+    }
+
+    public List<AtlasNamespaceDef> getNamespaceDefs() {
+        return namespaceDefs;
+    }
+
     public boolean hasClassificationDef(String name) {
         return hasTypeDef(classificationDefs, name);
     }
@@ -144,6 +165,9 @@ public class AtlasTypesDef {
         return hasTypeDef(relationshipDefs, name);
     }
 
+    public boolean hasNamespaceDef(String name) {
+        return hasTypeDef(namespaceDefs, name);
+    }
 
     private <T extends AtlasBaseTypeDef> boolean hasTypeDef(Collection<T> typeDefs, String name) {
         if (CollectionUtils.isNotEmpty(typeDefs)) {
@@ -163,7 +187,8 @@ public class AtlasTypesDef {
                 CollectionUtils.isEmpty(structDefs) &&
                 CollectionUtils.isEmpty(classificationDefs) &&
                 CollectionUtils.isEmpty(entityDefs) &&
-                CollectionUtils.isEmpty(relationshipDefs);
+                CollectionUtils.isEmpty(relationshipDefs) &&
+                CollectionUtils.isEmpty(namespaceDefs);
     }
 
     public void clear() {
@@ -185,6 +210,10 @@ public class AtlasTypesDef {
         if (relationshipDefs != null) {
             relationshipDefs.clear();
         }
+
+        if (namespaceDefs != null) {
+            namespaceDefs.clear();
+        }
     }
     public StringBuilder toString(StringBuilder sb) {
         if (sb == null) {
@@ -206,6 +235,8 @@ public class AtlasTypesDef {
         sb.append("}");
         sb.append("relationshipDefs={");
         AtlasBaseTypeDef.dumpObjects(relationshipDefs, sb);
+        sb.append("namespaceDefs={");
+        AtlasBaseTypeDef.dumpObjects(namespaceDefs, sb);
         sb.append("}");
 
         return sb;
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 4ee68a9..b08ace4 100644
--- a/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
+++ b/intg/src/main/java/org/apache/atlas/store/AtlasTypeDefStore.java
@@ -23,6 +23,7 @@ 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.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
@@ -85,6 +86,11 @@ public interface AtlasTypeDefStore {
 
     AtlasRelationshipDef updateRelationshipDefByGuid(String guid, AtlasRelationshipDef structDef) throws AtlasBaseException;
 
+    /* Namespace Def operations */
+    AtlasNamespaceDef getNamespaceDefByName(String name) throws AtlasBaseException;
+
+    AtlasNamespaceDef getNamespaceDefByGuid(String guid) throws AtlasBaseException;
+
     /* Bulk Operations */
 
     AtlasTypesDef createTypesDef(AtlasTypesDef atlasTypesDef) throws AtlasBaseException;
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 4742d1c..02d6d58 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasEntityType.java
@@ -31,6 +31,7 @@ import org.apache.atlas.model.typedef.AtlasEntityDef.AtlasRelationshipAttributeD
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType;
+import org.apache.atlas.type.AtlasNamespaceType.AtlasNamespaceAttribute;
 import org.apache.atlas.utils.AtlasEntityUtil;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
@@ -47,6 +48,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+
 /**
  * class that implements behaviour of an entity-type.
  */
@@ -72,22 +74,23 @@ public class AtlasEntityType extends AtlasStructType {
     private final AtlasEntityDef entityDef;
     private final String         typeQryStr;
 
-    private List<AtlasEntityType>                    superTypes                 = Collections.emptyList();
-    private Set<String>                              allSuperTypes              = Collections.emptySet();
-    private Set<String>                              subTypes                   = Collections.emptySet();
-    private Set<String>                              allSubTypes                = Collections.emptySet();
-    private Set<String>                              typeAndAllSubTypes         = Collections.emptySet();
-    private Set<String>                              typeAndAllSuperTypes       = Collections.emptySet();
-    private Map<String, Map<String, AtlasAttribute>> relationshipAttributes     = Collections.emptyMap();
-    private List<AtlasAttribute>                     ownedRefAttributes         = Collections.emptyList();
-    private String                                   typeAndAllSubTypesQryStr   = "";
-    private boolean                                  isInternalType             = false;
-    private Map<String, AtlasAttribute>              headerAttributes           = Collections.emptyMap();
-    private Map<String, AtlasAttribute>              minInfoAttributes          = Collections.emptyMap();
-    private List<AtlasAttribute>                     dynAttributes              = Collections.emptyList();
-    private List<AtlasAttribute>                     dynEvalTriggerAttributes   = Collections.emptyList();
-    private Map<String,List<TemplateToken>>          parsedTemplates            = Collections.emptyMap();
-    private Set<String>                              tagPropagationEdges        = Collections.emptySet();
+    private List<AtlasEntityType>                      superTypes                 = Collections.emptyList();
+    private Set<String>                                allSuperTypes              = Collections.emptySet();
+    private Set<String>                                subTypes                   = Collections.emptySet();
+    private Set<String>                                allSubTypes                = Collections.emptySet();
+    private Set<String>                                typeAndAllSubTypes         = Collections.emptySet();
+    private Set<String>                                typeAndAllSuperTypes       = Collections.emptySet();
+    private Map<String, Map<String, AtlasAttribute>>   relationshipAttributes     = Collections.emptyMap();
+    private List<AtlasAttribute>                       ownedRefAttributes         = Collections.emptyList();
+    private String                                     typeAndAllSubTypesQryStr   = "";
+    private boolean                                    isInternalType             = false;
+    private Map<String, AtlasAttribute>                headerAttributes           = Collections.emptyMap();
+    private Map<String, AtlasAttribute>                minInfoAttributes          = Collections.emptyMap();
+    private List<AtlasAttribute>                       dynAttributes              = Collections.emptyList();
+    private List<AtlasAttribute>                       dynEvalTriggerAttributes   = Collections.emptyList();
+    private Map<String,List<TemplateToken>>            parsedTemplates            = Collections.emptyMap();
+    private Set<String>                                tagPropagationEdges        = Collections.emptySet();
+    private Map<String, List<AtlasNamespaceAttribute>> namespaceAttributes      = Collections.emptyMap();
 
     public AtlasEntityType(AtlasEntityDef entityDef) {
         super(entityDef);
@@ -140,6 +143,7 @@ public class AtlasEntityType extends AtlasStructType {
         this.typeAndAllSubTypes     = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
         this.relationshipAttributes = new HashMap<>(); // this will be populated in resolveReferencesPhase3()
         this.tagPropagationEdges    = new HashSet<>(); // this will be populated in resolveReferencesPhase2()
+        this.namespaceAttributes    = new HashMap<>(); // this will be populated in resolveReferences(), from AtlasNamespaceType
 
         this.typeAndAllSubTypes.add(this.getTypeName());
 
@@ -259,6 +263,7 @@ public class AtlasEntityType extends AtlasStructType {
         relationshipAttributes     = Collections.unmodifiableMap(relationshipAttributes);
         ownedRefAttributes         = Collections.unmodifiableList(ownedRefAttributes);
         tagPropagationEdges        = Collections.unmodifiableSet(tagPropagationEdges);
+        namespaceAttributes        = Collections.unmodifiableMap(namespaceAttributes);
 
         entityDef.setSubTypes(subTypes);
 
@@ -361,6 +366,14 @@ public class AtlasEntityType extends AtlasStructType {
     public String[] getTagPropagationEdgesArray() {
         return CollectionUtils.isNotEmpty(tagPropagationEdges) ? tagPropagationEdges.toArray(new String[tagPropagationEdges.size()]) : null;
     }
+ 
+    public Map<String, List<AtlasNamespaceAttribute>> getNamespaceAttributes() {
+        return namespaceAttributes;
+    }
+
+    public List<AtlasNamespaceAttribute> getNamespaceAttributes(String nsName) {
+        return namespaceAttributes.get(nsName);
+    }
 
     public Map<String,List<TemplateToken>> getParsedTemplates() { return parsedTemplates; }
 
@@ -452,6 +465,19 @@ public class AtlasEntityType extends AtlasStructType {
         return relationshipAttributes.containsKey(attributeName);
     }
 
+    public void addNamespaceAttribute(AtlasNamespaceAttribute attribute) {
+        String                        nsName     = attribute.getDefinedInType().getTypeName();
+        List<AtlasNamespaceAttribute> attributes = namespaceAttributes.get(nsName);
+
+        if (attributes == null) {
+            attributes = new ArrayList<>();
+
+            namespaceAttributes.put(nsName, attributes);
+        }
+
+        attributes.add(attribute);
+    }
+
     public String getQualifiedAttributeName(String attrName) throws AtlasBaseException {
         AtlasAttribute ret = getAttribute(attrName);
 
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java b/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
new file mode 100644
index 0000000..a141d4a
--- /dev/null
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
@@ -0,0 +1,184 @@
+/**
+ * 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.instance.AtlasStruct;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
+import org.apache.commons.collections.CollectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.*;
+
+
+public class AtlasNamespaceType extends AtlasStructType {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasNamespaceType.class);
+
+    private final AtlasNamespaceDef namespaceDef;
+
+
+    public AtlasNamespaceType(AtlasNamespaceDef namespaceDef) {
+        super(namespaceDef);
+
+        this.namespaceDef = namespaceDef;
+    }
+
+    @Override
+    public boolean isValidValue(Object o) {
+        return true; // there is no runtime instance for Namespaces, so return true
+    }
+
+    @Override
+    public AtlasStruct createDefaultValue() {
+        return null;  // there is no runtime instance for Namespaces, so return null
+    }
+
+    @Override
+    public Object getNormalizedValue(Object a) {
+        return null;  // there is no runtime instance for Namespaces, so return null
+    }
+
+    public AtlasNamespaceDef getNamespaceDef() {
+        return namespaceDef;
+    }
+
+    @Override
+    void resolveReferences(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+        super.resolveReferences(typeRegistry);
+
+        Map<String, AtlasNamespaceAttribute> a = new HashMap<>();
+
+        for (AtlasAttribute attribute : super.allAttributes.values()) {
+            AtlasAttributeDef attributeDef = attribute.getAttributeDef();
+            String            attrName     = attribute.getName();
+            AtlasType         attrType     = attribute.getAttributeType();
+
+            if (attrType instanceof AtlasArrayType) {
+                attrType = ((AtlasArrayType) attrType).getElementType();
+            } else if (attrType instanceof AtlasMapType) {
+                attrType = ((AtlasMapType) attrType).getValueType();
+            }
+
+            // check if attribute type is not struct/classification/entity/namespace
+            if (attrType instanceof AtlasStructType) {
+                throw new AtlasBaseException(AtlasErrorCode.NAMESPACE_DEF_ATTRIBUTE_TYPE_INVALID, getTypeName(), attrName);
+            }
+
+            if (!attributeDef.getIsOptional()) {
+                throw new AtlasBaseException(AtlasErrorCode.NAMESPACE_DEF_MANDATORY_ATTRIBUTE_NOT_ALLOWED, getTypeName(), attrName);
+            }
+
+            if (attributeDef.getIsUnique()) {
+                throw new AtlasBaseException(AtlasErrorCode.NAMESPACE_DEF_UNIQUE_ATTRIBUTE_NOT_ALLOWED, getTypeName(), attrName);
+            }
+
+            Set<String>          entityTypeNames = attribute.getOptionSet(ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+            Set<AtlasEntityType> entityTypes     = new HashSet<>();
+
+            if (CollectionUtils.isNotEmpty(entityTypeNames)) {
+                for (String entityTypeName : entityTypeNames) {
+                    AtlasEntityType entityType = typeRegistry.getEntityTypeByName(entityTypeName);
+
+                    if (entityType == null) {
+                        throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, entityTypeName);
+                    }
+
+                    entityTypes.add(entityType);
+                }
+            } else {
+                throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, attributeDef.getName(), "options." + ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+            }
+
+            AtlasNamespaceAttribute nsAttribute;
+            if (attribute.getAttributeType() instanceof AtlasBuiltInTypes.AtlasStringType) {
+                Integer maxStringLength = attribute.getOptionInt(ATTR_MAX_STRING_LENGTH);
+                if (maxStringLength == null) {
+                    throw new AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE, attributeDef.getName(), "options." + ATTR_MAX_STRING_LENGTH);
+                }
+
+                String validPattern = attribute.getOptionString(ATTR_VALID_PATTERN);
+                nsAttribute = new AtlasNamespaceAttribute(attribute, entityTypes, maxStringLength, validPattern);
+            } else {
+                nsAttribute = new AtlasNamespaceAttribute(attribute, entityTypes);
+            }
+
+            a.put(attrName, nsAttribute);
+        }
+
+        super.allAttributes = Collections.unmodifiableMap(a);
+    }
+
+    @Override
+    void resolveReferencesPhase2(AtlasTypeRegistry typeRegistry) throws AtlasBaseException {
+        super.resolveReferencesPhase2(typeRegistry);
+
+        for (AtlasAttribute attribute : super.allAttributes.values()) {
+            AtlasNamespaceAttribute nsAttribute = (AtlasNamespaceAttribute) attribute;
+            Set<AtlasEntityType>    entityTypes = nsAttribute.getApplicableEntityTypes();
+
+            if (CollectionUtils.isNotEmpty(entityTypes)) {
+                for (AtlasEntityType entityType : entityTypes) {
+                    entityType.addNamespaceAttribute(nsAttribute);
+                }
+            }
+        }
+    }
+
+    public static class AtlasNamespaceAttribute extends AtlasAttribute {
+        private final Set<AtlasEntityType> applicableEntityTypes;
+        private final int maxStringLength;
+        private final String validPattern;
+
+        public AtlasNamespaceAttribute(AtlasAttribute attribute, Set<AtlasEntityType> applicableEntityTypes) {
+            super(attribute);
+            this.maxStringLength = 0;
+            this.validPattern = null;
+            this.applicableEntityTypes = applicableEntityTypes;
+        }
+
+        public AtlasNamespaceAttribute(AtlasAttribute attribute, Set<AtlasEntityType> applicableEntityTypes,
+                                       int maxStringLength, String validPattern) {
+            super(attribute);
+            this.maxStringLength = maxStringLength;
+            this.validPattern = validPattern;
+            this.applicableEntityTypes = applicableEntityTypes;
+        }
+
+        @Override
+        public AtlasNamespaceType getDefinedInType() {
+            return (AtlasNamespaceType) super.getDefinedInType();
+        }
+
+        public Set<AtlasEntityType> getApplicableEntityTypes() {
+            return applicableEntityTypes;
+        }
+
+        public String getValidPattern() {
+            return validPattern;
+        }
+
+        public int getMaxStringLength() {
+            return maxStringLength;
+        }
+    }
+}
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 3475ce6..6bd3a11 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasStructType.java
@@ -112,6 +112,10 @@ public class AtlasStructType extends AtlasType {
                 throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_TYPE_INVALID, getTypeName(), attributeDef.getName());
             }
 
+            if (attrType instanceof AtlasNamespaceType) {
+                throw new AtlasBaseException(AtlasErrorCode.ATTRIBUTE_TYPE_INVALID, getTypeName(), attributeDef.getName());
+            }
+
             a.put(attributeDef.getName(), attribute);
         }
 
@@ -794,6 +798,26 @@ public class AtlasStructType extends AtlasType {
             this(definedInType, attrDef, attributeType, null, null);
         }
 
+        public AtlasAttribute(AtlasAttribute other) {
+            this.definedInType             = other.definedInType;
+            this.attributeType             = other.attributeType;
+            this.attributeDef              = other.attributeDef;
+            this.qualifiedName             = other.qualifiedName;
+            this.vertexPropertyName        = other.vertexPropertyName;
+            this.vertexUniquePropertyName  = other.vertexUniquePropertyName;
+            this.isOwnedRef                = other.isOwnedRef;
+            this.isObjectRef               = other.isObjectRef;
+            this.inverseRefAttributeName   = other.inverseRefAttributeName;
+            this.inverseRefAttribute       = other.inverseRefAttribute;
+            this.relationshipName          = other.relationshipName;
+            this.relationshipEdgeLabel     = other.relationshipEdgeLabel;
+            this.relationshipEdgeDirection = other.relationshipEdgeDirection;
+            this.isLegacyAttribute         = other.isLegacyAttribute;
+            this.indexFieldName            = other.indexFieldName;
+            this.isDynAttribute            = false;
+            this.isDynAttributeEvalTrigger = false;
+        }
+
         public AtlasStructType getDefinedInType() { return definedInType; }
 
         public AtlasStructDef getDefinedInDef() { return definedInType.getStructDef(); }
@@ -860,6 +884,27 @@ public class AtlasStructType extends AtlasType {
 
         public void setIsDynAttributeEvalTrigger(boolean isDynAttributeEvalTrigger) { this.isDynAttributeEvalTrigger = isDynAttributeEvalTrigger; }
 
+        public Set<String> getOptionSet(String optionName) {
+            String      strValue = attributeDef.getOption(optionName);
+            Set<String> ret      = StringUtils.isBlank(strValue) ? null : AtlasType.fromJson(strValue, Set.class);
+
+            return ret;
+        }
+
+        public Integer getOptionInt(String optionName) {
+            String  strValue = attributeDef.getOption(optionName);
+            Integer ret      = StringUtils.isBlank(strValue) ? null : Integer.parseInt(strValue);
+
+            return ret;
+        }
+
+        public String getOptionString(String optionName) {
+            String  strValue = attributeDef.getOption(optionName);
+            String ret      = StringUtils.isBlank(strValue) ? null : strValue;
+
+            return ret;
+        }
+
         public static String getEdgeLabel(String property) {
             return "__" + property;
         }
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 b071dc9..97e27d0 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -23,6 +23,7 @@ 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.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
@@ -192,6 +193,15 @@ public class AtlasTypeRegistry {
         return registryData.classificationDefs.getTypeByName(name);
     }
 
+    public Collection<AtlasNamespaceType> getAllNamespaceTypes() {
+        return registryData.namespaceDefs.getAllTypes();
+    }
+
+    public Collection<AtlasNamespaceDef> getAllNamespaceDefs() {
+        return registryData.namespaceDefs.getAll();
+    }
+
+
     public Collection<AtlasRelationshipDef> getAllRelationshipDefs() { return registryData.relationshipDefs.getAll(); }
 
     public Collection<AtlasEntityDef> getAllEntityDefs() { return registryData.entityDefs.getAll(); }
@@ -217,6 +227,15 @@ public class AtlasTypeRegistry {
     public AtlasRelationshipDef getRelationshipDefByName(String name) {
         return registryData.relationshipDefs.getTypeDefByName(name);
     }
+
+    public AtlasNamespaceDef getNamespaceDefByGuid(String guid) {
+        return registryData.namespaceDefs.getTypeDefByGuid(guid);
+    }
+
+    public AtlasNamespaceDef getNamespaceDefByName(String name) {
+        return registryData.namespaceDefs.getTypeDefByName(name);
+    }
+
     public AtlasRelationshipType getRelationshipTypeByName(String name) { return registryData.relationshipDefs.getTypeByName(name); }
 
     public AtlasTransientTypeRegistry lockTypeRegistryForUpdate() throws AtlasBaseException {
@@ -271,6 +290,7 @@ public class AtlasTypeRegistry {
         final TypeDefCache<AtlasClassificationDef, AtlasClassificationType>   classificationDefs;
         final TypeDefCache<AtlasEntityDef, AtlasEntityType>                   entityDefs;
         final TypeDefCache<AtlasRelationshipDef, AtlasRelationshipType>       relationshipDefs;
+        final TypeDefCache<AtlasNamespaceDef, AtlasNamespaceType>             namespaceDefs;
         final TypeDefCache<? extends AtlasBaseTypeDef, ? extends AtlasType>[] allDefCaches;
 
         RegistryData() {
@@ -280,7 +300,9 @@ public class AtlasTypeRegistry {
             classificationDefs = new TypeDefCache<>(allTypes);
             entityDefs         = new TypeDefCache<>(allTypes);
             relationshipDefs   = new TypeDefCache<>(allTypes);
-            allDefCaches       = new TypeDefCache[] { enumDefs, structDefs, classificationDefs, entityDefs, relationshipDefs };
+            namespaceDefs      = new TypeDefCache<>(allTypes);
+            allDefCaches       = new TypeDefCache[] { enumDefs, structDefs, classificationDefs, entityDefs,
+                    relationshipDefs, namespaceDefs };
 
             init();
         }
@@ -339,6 +361,7 @@ public class AtlasTypeRegistry {
                 classificationDefs.updateGuid(typeName, guid);
                 entityDefs.updateGuid(typeName, guid);
                 relationshipDefs.updateGuid(typeName, guid);
+                namespaceDefs.updateGuid(typeName, guid);
             }
         }
 
@@ -349,6 +372,7 @@ public class AtlasTypeRegistry {
                 classificationDefs.removeTypeDefByGuid(guid);
                 entityDefs.removeTypeDefByGuid(guid);
                 relationshipDefs.removeTypeDefByGuid(guid);
+                namespaceDefs.removeTypeDefByGuid(guid);
             }
         }
 
@@ -359,6 +383,7 @@ public class AtlasTypeRegistry {
                 classificationDefs.removeTypeDefByName(typeName);
                 entityDefs.removeTypeDefByName(typeName);
                 relationshipDefs.removeTypeDefByName(typeName);
+                namespaceDefs.removeTypeDefByName(typeName);
             }
         }
 
@@ -369,7 +394,7 @@ public class AtlasTypeRegistry {
             classificationDefs.clear();
             entityDefs.clear();
             relationshipDefs.clear();
-
+            namespaceDefs.clear();
             init();
         }
     }
@@ -388,6 +413,7 @@ public class AtlasTypeRegistry {
             addTypesWithNoRefResolve(parent.getAllClassificationDefs());
             addTypesWithNoRefResolve(parent.getAllEntityDefs());
             addTypesWithNoRefResolve(parent.getAllRelationshipDefs());
+            addTypesWithNoRefResolve(parent.getAllNamespaceDefs());
 
             addedTypes.clear();
             updatedTypes.clear();
@@ -467,6 +493,7 @@ public class AtlasTypeRegistry {
                 addTypesWithNoRefResolve(typesDef.getClassificationDefs());
                 addTypesWithNoRefResolve(typesDef.getEntityDefs());
                 addTypesWithNoRefResolve(typesDef.getRelationshipDefs());
+                addTypesWithNoRefResolve(typesDef.getNamespaceDefs());
             }
 
             resolveReferences();
@@ -567,6 +594,7 @@ public class AtlasTypeRegistry {
                 updateTypesWithNoRefResolve(typesDef.getClassificationDefs());
                 updateTypesWithNoRefResolve(typesDef.getEntityDefs());
                 updateTypesWithNoRefResolve(typesDef.getRelationshipDefs());
+                updateTypesWithNoRefResolve(typesDef.getNamespaceDefs());
             }
 
             if (LOG.isDebugEnabled()) {
@@ -581,6 +609,7 @@ public class AtlasTypeRegistry {
                 removeTypesWithNoRefResolve(typesDef.getClassificationDefs());
                 removeTypesWithNoRefResolve(typesDef.getEntityDefs());
                 removeTypesWithNoRefResolve(typesDef.getRelationshipDefs());
+                removeTypesWithNoRefResolve(typesDef.getNamespaceDefs());
             }
 
             resolveReferences();
@@ -615,6 +644,9 @@ public class AtlasTypeRegistry {
                 case RELATIONSHIP:
                     registryData.relationshipDefs.removeTypeDefByName(typeDef.getName());
                     break;
+                case NAMESPACE:
+                    registryData.namespaceDefs.removeTypeDefByName(typeDef.getName());
+                    break;
             }
             deletedTypes.add(typeDef);
         }
@@ -636,6 +668,9 @@ public class AtlasTypeRegistry {
                 case RELATIONSHIP:
                     registryData.relationshipDefs.removeTypeDefByGuid(typeDef.getGuid());
                     break;
+                case NAMESPACE:
+                    registryData.namespaceDefs.removeTypeDefByGuid(typeDef.getGuid());
+                    break;
             }
             deletedTypes.add(typeDef);
         }
@@ -722,6 +757,9 @@ public class AtlasTypeRegistry {
                     AtlasRelationshipDef relationshipDef = (AtlasRelationshipDef) typeDef;
 
                     registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
+                } else if (typeDef.getClass().equals(AtlasNamespaceDef.class)) {
+                    AtlasNamespaceDef namespaceDef = (AtlasNamespaceDef) typeDef;
+                    registryData.namespaceDefs.addType(namespaceDef, new AtlasNamespaceType(namespaceDef));
                 }
 
                 addedTypes.add(typeDef);
@@ -801,6 +839,11 @@ public class AtlasTypeRegistry {
 
                     registryData.relationshipDefs.removeTypeDefByGuid(guid);
                     registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
+                } else if (typeDef.getClass().equals(AtlasNamespaceDef.class)) {
+                    AtlasNamespaceDef namespaceDef = (AtlasNamespaceDef) typeDef;
+
+                    registryData.namespaceDefs.removeTypeDefByGuid(guid);
+                    registryData.namespaceDefs.addType(namespaceDef, new AtlasNamespaceType(namespaceDef));
                 }
 
                 updatedTypes.add(typeDef);
@@ -843,6 +886,11 @@ public class AtlasTypeRegistry {
 
                     registryData.relationshipDefs.removeTypeDefByName(name);
                     registryData.relationshipDefs.addType(relationshipDef, new AtlasRelationshipType(relationshipDef));
+                } else if (typeDef.getClass().equals(AtlasNamespaceDef.class)) {
+                    AtlasNamespaceDef namespaceDef = (AtlasNamespaceDef) typeDef;
+
+                    registryData.namespaceDefs.removeTypeDefByName(name);
+                    registryData.namespaceDefs.addType(namespaceDef, new AtlasNamespaceType(namespaceDef));
                 }
 
                 updatedTypes.add(typeDef);
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 0883d54..5b115b5 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeUtil.java
@@ -28,6 +28,7 @@ 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.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
@@ -315,6 +316,15 @@ public class AtlasTypeUtil {
         return new AtlasTypesDef(enums, structs, traits, classes, relations);
     }
 
+    public static AtlasTypesDef getTypesDef(List<AtlasEnumDef> enums,
+                                            List<AtlasStructDef> structs,
+                                            List<AtlasClassificationDef> traits,
+                                            List<AtlasEntityDef> classes,
+                                            List<AtlasRelationshipDef> relations,
+                                            List<AtlasNamespaceDef> namespaces) {
+        return new AtlasTypesDef(enums, structs, traits, classes, relations, namespaces);
+    }
+
     public static List<AtlasTypeDefHeader> toTypeDefHeader(AtlasTypesDef typesDef) {
         List<AtlasTypeDefHeader> headerList = new LinkedList<>();
         if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
diff --git a/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java b/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
index dba2d88..d57a484 100644
--- a/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
+++ b/intg/src/main/java/org/apache/atlas/typesystem/types/DataTypes.java
@@ -30,6 +30,7 @@ public class DataTypes {
         STRUCT,
         TRAIT,
         CLASS,
-        RELATIONSHIP
+        RELATIONSHIP,
+        NAMESPACE
     }
 }
\ No newline at end of file
diff --git a/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java b/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java
index 02613b5..32ed6ee 100755
--- a/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java
+++ b/intg/src/test/java/org/apache/atlas/TestRelationshipUtilsV2.java
@@ -27,10 +27,12 @@ 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.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasType;
 import org.apache.commons.lang.ArrayUtils;
 import org.apache.commons.lang.StringUtils;
 
@@ -38,6 +40,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.*;
 
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
 import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.BOTH;
 import static org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags.ONE_TO_TWO;
 import static org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory.AGGREGATION;
@@ -141,11 +144,25 @@ public final class TestRelationshipUtilsV2 {
                                                         new AtlasRelationshipEndDef(PERSON_TYPE, "sibling", SINGLE),
                                                         new AtlasRelationshipEndDef(PERSON_TYPE, "sibling", SINGLE));
 
+        AtlasStructDef.AtlasAttributeDef nsAttr1 = new AtlasStructDef.AtlasAttributeDef("attr1", "int");
+        AtlasStructDef.AtlasAttributeDef nsAttr2 = new AtlasStructDef.AtlasAttributeDef("attr2", "int");
+
+        nsAttr1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(DEPARTMENT_TYPE)));
+        nsAttr1.setIsOptional(true);
+        nsAttr1.setIsUnique(false);
+
+        nsAttr2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(DEPARTMENT_TYPE)));
+        nsAttr2.setIsOptional(true);
+        nsAttr2.setIsUnique(false);
+
+        AtlasNamespaceDef namespaceDef = new AtlasNamespaceDef("test_namespace", "test_description", DEFAULT_VERSION, Arrays.asList(nsAttr1, nsAttr2));
+
         return new AtlasTypesDef(Collections.singletonList(orgLevelType),
                                  Collections.singletonList(addressType),
                                  Collections.singletonList(securityClearanceType),
                                  Arrays.asList(personType, employeeType, departmentType, managerType),
-                                 Arrays.asList(employeeDepartmentType, employeeManagerType, employeeMentorsType, employeeFriendsType, personSiblingType));
+                                 Arrays.asList(employeeDepartmentType, employeeManagerType, employeeMentorsType, employeeFriendsType, personSiblingType),
+                                 Collections.singletonList(namespaceDef));
     }
 
     public static AtlasEntitiesWithExtInfo getDepartmentEmployeeInstances() {
@@ -278,7 +295,7 @@ public final class TestRelationshipUtilsV2 {
                                                         new AtlasRelationshipEndDef(TYPE_A, "mapToB", SET));
 
         return new AtlasTypesDef(Collections.<AtlasEnumDef>emptyList(), Collections.<AtlasStructDef>emptyList(), Collections.<AtlasClassificationDef>emptyList(),  Arrays.asList(aType, bType),
-                                 Arrays.asList(relationshipType1, relationshipType2, relationshipType3, relationshipType4));
+                                 Arrays.asList(relationshipType1, relationshipType2, relationshipType3, relationshipType4), Collections.<AtlasNamespaceDef>emptyList());
     }
 
     private static List<AtlasEnumElementDef> getOrgLevelElements() {
diff --git a/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasNamespaceDef.java b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasNamespaceDef.java
new file mode 100644
index 0000000..8867774
--- /dev/null
+++ b/intg/src/test/java/org/apache/atlas/model/typedef/TestAtlasNamespaceDef.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.model.typedef;
+
+import org.apache.atlas.type.AtlasType;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+
+public class TestAtlasNamespaceDef {
+
+    @Test
+    public void namespaceDefSerDes() {
+        AtlasNamespaceDef namespaceDef = new AtlasNamespaceDef("test_namespace", "test_description", null);
+        String jsonString = AtlasType.toJson(namespaceDef);
+
+        AtlasNamespaceDef namespaceDef1 = AtlasType.fromJson(jsonString, AtlasNamespaceDef.class);
+        assertEquals(namespaceDef, namespaceDef1,
+                "Incorrect serialization/deserialization of AtlasNamespaceDef");
+    }
+
+    @Test
+    public void namespaceDefEquality() {
+        AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+        AtlasNamespaceDef namespaceDef2 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+        assertEquals(namespaceDef1, namespaceDef2, "Namespaces should be equal because the name of the" +
+                "namespace is same");
+    }
+
+    @Test
+    public void namespaceDefUnequality() {
+        AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+        AtlasNamespaceDef namespaceDef2 = new AtlasNamespaceDef("test_namespace1", "test_description", null);
+        assertNotEquals(namespaceDef1, namespaceDef2, "Namespaces should not be equal since they have a" +
+                "different name");
+    }
+
+    @Test
+    public void namespaceDefWithNamespaceAttributes() {
+        AtlasNamespaceDef                namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+        AtlasStructDef.AtlasAttributeDef nsAttr1       = new AtlasStructDef.AtlasAttributeDef("attr1", "int");
+        AtlasStructDef.AtlasAttributeDef nsAttr2       = new AtlasStructDef.AtlasAttributeDef("attr2", "int");
+
+        nsAttr1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+        nsAttr2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+
+        namespaceDef1.setAttributeDefs(Arrays.asList(nsAttr1, nsAttr2));
+        assertEquals(namespaceDef1.getAttributeDefs().size(), 2);
+    }
+
+    @Test
+    public void namespaceDefWithNamespaceAttributesHavingCardinality() {
+        AtlasNamespaceDef                namespaceDef1 = new AtlasNamespaceDef("test_namespace", "test_description", null);
+        AtlasStructDef.AtlasAttributeDef nsAttr1       = new AtlasStructDef.AtlasAttributeDef("attr1", "int");
+        AtlasStructDef.AtlasAttributeDef nsAttr2       = new AtlasStructDef.AtlasAttributeDef("attr2", "int");
+
+        nsAttr1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+        nsAttr2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+        nsAttr2.setCardinality(AtlasStructDef.AtlasAttributeDef.Cardinality.SET);
+
+        namespaceDef1.setAttributeDefs(Arrays.asList(nsAttr1, nsAttr2));
+        assertEquals(namespaceDef1.getAttributeDefs().size(), 2);
+    }
+}
\ No newline at end of file
diff --git a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
index f96e6a6..7f4fc04 100755
--- a/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
+++ b/repository/src/main/java/org/apache/atlas/repository/graph/GraphBackedSearchIndexer.java
@@ -33,6 +33,7 @@ import org.apache.atlas.model.TypeCategory;
 import org.apache.atlas.model.typedef.AtlasBaseTypeDef;
 import org.apache.atlas.model.typedef.AtlasEntityDef;
 import org.apache.atlas.model.typedef.AtlasEnumDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.repository.Constants;
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
index 6016723..82a2d31 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportService.java
@@ -347,6 +347,7 @@ public class ExportService {
         final Set<String>                     structTypes         = new HashSet<>();
         final Set<String>                     enumTypes           = new HashSet<>();
         final Set<String>                     relationshipTypes   = new HashSet<>();
+        final Set<String>                     namespaceTypes     = new HashSet<>();
         final AtlasExportResult               result;
         private final ZipSink                 sink;
 
diff --git a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
index 5bad615..b553352 100644
--- a/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
+++ b/repository/src/main/java/org/apache/atlas/repository/impexp/ExportTypeProcessor.java
@@ -28,6 +28,7 @@ import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasEnumType;
 import org.apache.atlas.type.AtlasMapType;
+import org.apache.atlas.type.AtlasNamespaceType;
 import org.apache.atlas.type.AtlasRelationshipType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasType;
@@ -103,12 +104,14 @@ class ExportTypeProcessor {
             addEntityType((AtlasEntityType)type, context);
         } else if (type instanceof AtlasClassificationType) {
             addClassificationType((AtlasClassificationType)type, context);
+        } else if (type instanceof AtlasRelationshipType) {
+            addRelationshipType(type.getTypeName(), context);
+        } else if (type instanceof AtlasNamespaceType) {
+            addNamespaceType((AtlasNamespaceType) type, context);
         } else if (type instanceof AtlasStructType) {
             addStructType((AtlasStructType)type, context);
         } else if (type instanceof AtlasEnumType) {
             addEnumType((AtlasEnumType)type, context);
-        } else if (type instanceof AtlasRelationshipType) {
-            addRelationshipType(type.getTypeName(), context);
         }
     }
 
@@ -169,6 +172,14 @@ class ExportTypeProcessor {
         }
     }
 
+    private void addNamespaceType(AtlasNamespaceType namespaceType, ExportService.ExportContext context) {
+        if (!context.namespaceTypes.contains(namespaceType.getTypeName())) {
+            context.namespaceTypes.add(namespaceType.getTypeName());
+
+            addAttributeTypes(namespaceType, context);
+        }
+    }
+
     private void addAttributeTypes(AtlasStructType structType, ExportService.ExportContext context) {
         for (AtlasStructDef.AtlasAttributeDef attributeDef : structType.getStructDef().getAttributeDefs()) {
             addType(attributeDef.getTypeName(), context);
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
index 08b00e7..2a602c8 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
@@ -34,13 +34,13 @@ 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.AtlasEnumDef.AtlasEnumElementDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory;
 import org.apache.atlas.model.typedef.AtlasRelationshipEndDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
-import org.apache.atlas.repository.Constants;
 import org.apache.atlas.repository.graph.GraphBackedSearchIndexer;
 import org.apache.atlas.repository.graphdb.AtlasGraph;
 import org.apache.atlas.repository.patches.AtlasPatchRegistry;
@@ -55,7 +55,6 @@ import org.apache.commons.collections.MapUtils;
 import org.apache.commons.configuration.Configuration;
 import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
-import org.apache.jute.Index;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.core.annotation.Order;
@@ -253,6 +252,14 @@ public class AtlasTypeDefStoreInitializer implements ActiveStateChangeHandler {
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+            for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+                if (!typeRegistry.isRegisteredType(namespaceDef.getName())) {
+                    typesToCreate.getNamespaceDefs().add(namespaceDef);
+                }
+            }
+        }
+
         return typesToCreate;
     }
 
@@ -337,6 +344,20 @@ public class AtlasTypeDefStoreInitializer implements ActiveStateChangeHandler {
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+            for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+                AtlasNamespaceDef oldNamespaceDef = typeRegistry.getNamespaceDefByName(namespaceDef.getName());
+
+                if (oldNamespaceDef == null) {
+                    continue;
+                }
+
+                if (updateTypeAttributes(oldNamespaceDef, namespaceDef, checkTypeVersion)) {
+                    typesToUpdate.getNamespaceDefs().add(namespaceDef);
+                }
+            }
+        }
+
         return typesToUpdate;
     }
 
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 b04f188..e1ef849 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
@@ -79,6 +79,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
 
     protected abstract AtlasDefStore<AtlasRelationshipDef> getRelationshipDefStore(AtlasTypeRegistry typeRegistry);
 
+    protected abstract AtlasDefStore<AtlasNamespaceDef> getNamespaceDefStore(AtlasTypeRegistry typeRegistry);
+
     public AtlasTypeRegistry getTypeRegistry() { return typeRegistry; }
 
     @Override
@@ -97,7 +99,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
                     getStructDefStore(ttr).getAll(),
                     getClassificationDefStore(ttr).getAll(),
                     getEntityDefStore(ttr).getAll(),
-                    getRelationshipDefStore(ttr).getAll());
+                    getRelationshipDefStore(ttr).getAll(),
+                    getNamespaceDefStore(ttr).getAll());
 
             rectifyTypeErrorsIfAny(typesDef);
 
@@ -194,6 +197,28 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
     }
 
     @Override
+    public AtlasNamespaceDef getNamespaceDefByName(String name) throws AtlasBaseException {
+        AtlasNamespaceDef ret = typeRegistry.getNamespaceDefByName(name);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasNamespaceDef getNamespaceDefByGuid(String guid) throws AtlasBaseException {
+        AtlasNamespaceDef ret = typeRegistry.getNamespaceDefByGuid(guid);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        return ret;
+    }
+
+    @Override
     @GraphTransaction
     public AtlasStructDef updateStructDefByName(String name, AtlasStructDef structDef) throws AtlasBaseException {
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -325,12 +350,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
     @GraphTransaction
     public AtlasTypesDef createTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classifications={}, entities={}, relationships={})",
+            LOG.debug("==> AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classifications={}, entities={}, relationships={}, namespaces={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
                     CollectionUtils.size(typesDef.getEntityDefs()),
-                    CollectionUtils.size(typesDef.getRelationshipDefs()));
+                    CollectionUtils.size(typesDef.getRelationshipDefs()),
+                    CollectionUtils.size(typesDef.getNamespaceDefs()));
         }
 
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -346,12 +372,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
+            LOG.debug("<== AtlasTypeDefGraphStore.createTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={}, namespaces={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
                     CollectionUtils.size(typesDef.getEntityDefs()),
-                    CollectionUtils.size(typesDef.getRelationshipDefs()));
+                    CollectionUtils.size(typesDef.getRelationshipDefs()),
+                    CollectionUtils.size(typesDef.getNamespaceDefs()));
         }
 
         return ret;
@@ -429,12 +456,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
     @GraphTransaction
     public AtlasTypesDef updateTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships{})",
+            LOG.debug("==> AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships{}, namespaceDefs={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
                     CollectionUtils.size(typesDef.getEntityDefs()),
-                    CollectionUtils.size(typesDef.getRelationshipDefs()));
+                    CollectionUtils.size(typesDef.getRelationshipDefs()),
+                    CollectionUtils.size(typesDef.getNamespaceDefs()));
         }
 
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -459,12 +487,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
         }
 
         if (LOG.isDebugEnabled()) {
-            LOG.debug("<== AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
+            LOG.debug("<== AtlasTypeDefGraphStore.updateTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={}, namespaceDefs={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
                     CollectionUtils.size(typesDef.getEntityDefs()),
-                    CollectionUtils.size(typesDef.getRelationshipDefs()));
+                    CollectionUtils.size(typesDef.getRelationshipDefs()),
+                    CollectionUtils.size(typesDef.getNamespaceDefs()));
         }
 
         return ret;
@@ -475,12 +504,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
     @GraphTransaction
     public void deleteTypesDef(AtlasTypesDef typesDef) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
-            LOG.debug("==> AtlasTypeDefGraphStore.deleteTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={})",
+            LOG.debug("==> AtlasTypeDefGraphStore.deleteTypesDef(enums={}, structs={}, classfications={}, entities={}, relationships={}, namespaceDefs={})",
                     CollectionUtils.size(typesDef.getEnumDefs()),
                     CollectionUtils.size(typesDef.getStructDefs()),
                     CollectionUtils.size(typesDef.getClassificationDefs()),
                     CollectionUtils.size(typesDef.getEntityDefs()),
-                    CollectionUtils.size(typesDef.getRelationshipDefs()));
+                    CollectionUtils.size(typesDef.getRelationshipDefs()),
+                    CollectionUtils.size(typesDef.getNamespaceDefs()));
         }
 
         AtlasTransientTypeRegistry ttr = lockTypeRegistryAndReleasePostCommit();
@@ -490,6 +520,7 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
         AtlasDefStore<AtlasClassificationDef> classifiDefStore      = getClassificationDefStore(ttr);
         AtlasDefStore<AtlasEntityDef>         entityDefStore        = getEntityDefStore(ttr);
         AtlasDefStore<AtlasRelationshipDef>   relationshipDefStore  = getRelationshipDefStore(ttr);
+        AtlasDefStore<AtlasNamespaceDef>      namespaceDefStore     = getNamespaceDefStore(ttr);
 
         List<AtlasVertex> preDeleteStructDefs   = new ArrayList<>();
         List<AtlasVertex> preDeleteClassifiDefs = new ArrayList<>();
@@ -599,6 +630,16 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+            for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+                if (StringUtils.isNotBlank(namespaceDef.getGuid())) {
+                    namespaceDefStore.deleteByGuid(namespaceDef.getGuid(), null);
+                } else {
+                    namespaceDefStore.deleteByName(namespaceDef.getName(), null);
+                }
+            }
+        }
+
         // Remove all from
         ttr.removeTypesDef(typesDef);
 
@@ -631,6 +672,8 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             typesDef.setEnumDefs(Collections.singletonList((AtlasEnumDef) baseTypeDef));
         } else if (baseTypeDef instanceof AtlasRelationshipDef) {
             typesDef.setRelationshipDefs(Collections.singletonList((AtlasRelationshipDef) baseTypeDef));
+        } else if (baseTypeDef instanceof AtlasNamespaceDef) {
+            typesDef.setNamespaceDefs(Collections.singletonList((AtlasNamespaceDef) baseTypeDef));
         } else if (baseTypeDef instanceof AtlasStructDef) {
             typesDef.setStructDefs(Collections.singletonList((AtlasStructDef) baseTypeDef));
         }
@@ -673,6 +716,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             }
         }
 
+        for(AtlasNamespaceType namespaceType : typeRegistry.getAllNamespaceTypes()) {
+            if (searchPredicates.evaluate(namespaceType)) {
+                typesDef.getNamespaceDefs().add(namespaceType.getNamespaceDef());
+            }
+        }
+
         return typesDef;
     }
 
@@ -712,6 +761,9 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             case RELATIONSHIP:
                 ret = ((AtlasRelationshipType) type).getRelationshipDef();
                 break;
+            case NAMESPACE:
+                ret = ((AtlasNamespaceType) type).getNamespaceDef();
+                break;
             case PRIMITIVE:
             case OBJECT_ID_TYPE:
             case ARRAY:
@@ -838,11 +890,13 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
         AtlasDefStore<AtlasClassificationDef> classifiDefStore      = getClassificationDefStore(ttr);
         AtlasDefStore<AtlasEntityDef>         entityDefStore        = getEntityDefStore(ttr);
         AtlasDefStore<AtlasRelationshipDef>   relationshipDefStore  = getRelationshipDefStore(ttr);
+        AtlasDefStore<AtlasNamespaceDef>      nameSpaceDefStore     = getNamespaceDefStore(ttr);
 
-        List<AtlasVertex> preCreateStructDefs   = new ArrayList<>();
-        List<AtlasVertex> preCreateClassifiDefs = new ArrayList<>();
-        List<AtlasVertex> preCreateEntityDefs   = new ArrayList<>();
+        List<AtlasVertex> preCreateStructDefs         = new ArrayList<>();
+        List<AtlasVertex> preCreateClassifiDefs       = new ArrayList<>();
+        List<AtlasVertex> preCreateEntityDefs         = new ArrayList<>();
         List<AtlasVertex> preCreateRelationshipDefs   = new ArrayList<>();
+        List<AtlasVertex> preCreateNamespaceDefs      = new ArrayList<>();
 
         // for enumerations run the create
         if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
@@ -880,6 +934,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+            for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+                preCreateNamespaceDefs.add(nameSpaceDefStore.preCreate(namespaceDef));
+            }
+        }
+
         if (CollectionUtils.isNotEmpty(typesDef.getStructDefs())) {
             int i = 0;
             for (AtlasStructDef structDef : typesDef.getStructDefs()) {
@@ -927,17 +987,30 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+            int i = 0;
+            for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+                AtlasNamespaceDef createdDef = nameSpaceDefStore.create(namespaceDef, preCreateNamespaceDefs.get(i));
+
+                ttr.updateGuid(createdDef.getName(), createdDef.getGuid());
+
+                ret.getNamespaceDefs().add(createdDef);
+                i++;
+            }
+        }
+
         return ret;
     }
 
     private AtlasTypesDef updateGraphStore(AtlasTypesDef typesDef, AtlasTransientTypeRegistry ttr) throws AtlasBaseException {
         AtlasTypesDef ret = new AtlasTypesDef();
 
-        AtlasDefStore<AtlasEnumDef>           enumDefStore     = getEnumDefStore(ttr);
-        AtlasDefStore<AtlasStructDef>         structDefStore   = getStructDefStore(ttr);
-        AtlasDefStore<AtlasClassificationDef> classifiDefStore = getClassificationDefStore(ttr);
-        AtlasDefStore<AtlasEntityDef>         entityDefStore   = getEntityDefStore(ttr);
-        AtlasDefStore<AtlasRelationshipDef>   relationDefStore = getRelationshipDefStore(ttr);
+        AtlasDefStore<AtlasEnumDef>           enumDefStore      = getEnumDefStore(ttr);
+        AtlasDefStore<AtlasStructDef>         structDefStore    = getStructDefStore(ttr);
+        AtlasDefStore<AtlasClassificationDef> classifiDefStore  = getClassificationDefStore(ttr);
+        AtlasDefStore<AtlasEntityDef>         entityDefStore    = getEntityDefStore(ttr);
+        AtlasDefStore<AtlasRelationshipDef>   relationDefStore  = getRelationshipDefStore(ttr);
+        AtlasDefStore<AtlasNamespaceDef>      nameSpaceDefStore = getNamespaceDefStore(ttr);
 
         if (CollectionUtils.isNotEmpty(typesDef.getEnumDefs())) {
             for (AtlasEnumDef enumDef : typesDef.getEnumDefs()) {
@@ -969,6 +1042,12 @@ public abstract class AtlasTypeDefGraphStore implements AtlasTypeDefStore {
             }
         }
 
+        if (CollectionUtils.isNotEmpty(typesDef.getNamespaceDefs())) {
+            for (AtlasNamespaceDef namespaceDef : typesDef.getNamespaceDefs()) {
+                ret.getNamespaceDefs().add(nameSpaceDefStore.update(namespaceDef));
+            }
+        }
+
         return ret;
     }
 
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2.java
new file mode 100644
index 0000000..eaaf6bb
--- /dev/null
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2.java
@@ -0,0 +1,347 @@
+/**
+ * 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.v2;
+
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.authorize.AtlasAuthorizationUtils;
+import org.apache.atlas.authorize.AtlasPrivilege;
+import org.apache.atlas.authorize.AtlasTypeAccessRequest;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.TypeCategory;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.repository.Constants;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.type.AtlasNamespaceType;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.apache.atlas.typesystem.types.DataTypes;
+import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.inject.Inject;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
+
+public class AtlasNamespaceDefStoreV2 extends AtlasAbstractDefStoreV2<AtlasNamespaceDef> {
+    private static final Logger LOG = LoggerFactory.getLogger(AtlasNamespaceDefStoreV2.class);
+
+    @Inject
+    public AtlasNamespaceDefStoreV2(AtlasTypeDefGraphStoreV2 typeDefStore, AtlasTypeRegistry typeRegistry) {
+        super(typeDefStore, typeRegistry);
+    }
+
+    @Override
+    public AtlasVertex preCreate(AtlasNamespaceDef namespaceDef) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.preCreate({})", namespaceDef);
+        }
+
+        validateType(namespaceDef);
+
+        AtlasType type = typeRegistry.getType(namespaceDef.getName());
+
+        if (type.getTypeCategory() != TypeCategory.NAMESPACE) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, namespaceDef.getName(),
+                    DataTypes.TypeCategory.NAMESPACE.name());
+        }
+
+        AtlasVertex ret = typeDefStore.findTypeVertexByName(namespaceDef.getName());
+
+        if (ret != null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_ALREADY_EXISTS, namespaceDef.getName());
+        }
+
+        ret = typeDefStore.createTypeVertex(namespaceDef);
+
+        updateVertexPreCreate(namespaceDef, (AtlasNamespaceType) type, ret);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.preCreate({}): {}", namespaceDef, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasNamespaceDef create(AtlasNamespaceDef namespaceDef, AtlasVertex preCreateResult) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.create({}, {})", namespaceDef, preCreateResult);
+        }
+
+        AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_CREATE, namespaceDef), "create namespace-def ", namespaceDef.getName());
+
+        AtlasVertex vertex = (preCreateResult == null) ? preCreate(namespaceDef) : preCreateResult;
+
+        AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.create({}, {}): {}", namespaceDef, preCreateResult, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public List<AtlasNamespaceDef> getAll() throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDef.getAll()");
+        }
+
+        List<AtlasNamespaceDef> ret = new ArrayList<>();
+
+        Iterator<AtlasVertex> vertices = typeDefStore.findTypeVerticesByCategory(DataTypes.TypeCategory.NAMESPACE);
+        while (vertices.hasNext()) {
+            ret.add(toNamespaceDef(vertices.next()));
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.getAll(): count={}", ret.size());
+        }
+        return ret;
+    }
+
+    @Override
+    public AtlasNamespaceDef getByName(String name) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.getByName({})", name);
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, DataTypes.TypeCategory.NAMESPACE);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        vertex.getProperty(Constants.TYPE_CATEGORY_PROPERTY_KEY, String.class);
+
+        AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.getByName({}): {}", name, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasNamespaceDef getByGuid(String guid) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.getByGuid({})", guid);
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, DataTypes.TypeCategory.NAMESPACE);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.getByGuid({}): {}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasNamespaceDef update(AtlasNamespaceDef typeDef) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.update({})", typeDef);
+        }
+
+        validateType(typeDef);
+
+        AtlasNamespaceDef ret = StringUtils.isNotBlank(typeDef.getGuid()) ? updateByGuid(typeDef.getGuid(), typeDef)
+                : updateByName(typeDef.getName(), typeDef);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.update({}): {}", typeDef, ret);
+        }
+
+        return ret;
+    }
+
+    @Override
+    public AtlasNamespaceDef updateByName(String name, AtlasNamespaceDef typeDef) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.updateByName({}, {})", name, typeDef);
+        }
+
+        AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByName(name);
+
+        AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update namespace-def ", name);
+
+        validateType(typeDef);
+
+        AtlasType type = typeRegistry.getType(typeDef.getName());
+
+        if (type.getTypeCategory() != TypeCategory.NAMESPACE) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, typeDef.getName(), DataTypes.TypeCategory.NAMESPACE.name());
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByNameAndCategory(name, DataTypes.TypeCategory.NAMESPACE);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+
+        updateVertexPreUpdate(typeDef, (AtlasNamespaceType)type, vertex);
+
+        AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.updateByName({}, {}): {}", name, typeDef, ret);
+        }
+
+        return ret;
+    }
+
+    public AtlasNamespaceDef updateByGuid(String guid, AtlasNamespaceDef typeDef) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.updateByGuid({})", guid);
+        }
+
+        AtlasNamespaceDef existingDef   = typeRegistry.getNamespaceDefByGuid(guid);
+
+        AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_UPDATE, existingDef), "update namespace-def ", (existingDef != null ? existingDef.getName() : guid));
+
+        validateType(typeDef);
+
+        AtlasType type = typeRegistry.getTypeByGuid(guid);
+
+        if (type.getTypeCategory() != org.apache.atlas.model.TypeCategory.NAMESPACE) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_MATCH_FAILED, typeDef.getName(), DataTypes.TypeCategory.NAMESPACE.name());
+        }
+
+        AtlasVertex vertex = typeDefStore.findTypeVertexByGuidAndCategory(guid, DataTypes.TypeCategory.NAMESPACE);
+
+        if (vertex == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        updateVertexPreUpdate(typeDef, (AtlasNamespaceType)type, vertex);
+
+        AtlasNamespaceDef ret = toNamespaceDef(vertex);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.updateByGuid({}): {}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    public AtlasVertex preDeleteByName(String name) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.preDeleteByName({})", name);
+        }
+
+        AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByName(name);
+
+        AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete namespace-def ", name);
+
+        AtlasVertex ret = typeDefStore.findTypeVertexByNameAndCategory(name, DataTypes.TypeCategory.NAMESPACE);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_NAME_NOT_FOUND, name);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.preDeleteByName({}): {}", name, ret);
+        }
+
+        return ret;
+    }
+
+    public AtlasVertex preDeleteByGuid(String guid) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> AtlasNamespaceDefStoreV2.preDeleteByGuid({})", guid);
+        }
+
+        AtlasNamespaceDef existingDef = typeRegistry.getNamespaceDefByGuid(guid);
+
+        AtlasAuthorizationUtils.verifyAccess(new AtlasTypeAccessRequest(AtlasPrivilege.TYPE_DELETE, existingDef), "delete namespace-def ", (existingDef != null ? existingDef.getName() : guid));
+
+        AtlasVertex ret = typeDefStore.findTypeVertexByGuidAndCategory(guid, DataTypes.TypeCategory.NAMESPACE);
+
+        if (ret == null) {
+            throw new AtlasBaseException(AtlasErrorCode.TYPE_GUID_NOT_FOUND, guid);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== AtlasNamespaceDefStoreV2.preDeleteByGuid({}): ret={}", guid, ret);
+        }
+
+        return ret;
+    }
+
+    private void updateVertexPreCreate(AtlasNamespaceDef namespaceDef, AtlasNamespaceType namespaceType,
+                                      AtlasVertex vertex) throws AtlasBaseException {
+        AtlasStructDefStoreV2.updateVertexPreCreate(namespaceDef, namespaceType, vertex, typeDefStore);
+    }
+
+    private void updateVertexPreUpdate(AtlasNamespaceDef namespaceDef, AtlasNamespaceType namespaceType,
+                                       AtlasVertex vertex) throws AtlasBaseException {
+        // Load up current struct definition for matching attributes
+        AtlasNamespaceDef currentNamespaceDef = toNamespaceDef(vertex);
+
+        // Check to verify that in an update call we only allow addition of new entity types, not deletion of existing
+        // entity types
+        if (CollectionUtils.isNotEmpty(namespaceDef.getAttributeDefs())) {
+            for (AtlasStructDef.AtlasAttributeDef attributeDef : namespaceDef.getAttributeDefs()) {
+                String updatedApplicableEntityTypesString = attributeDef.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+                Set<String> updatedApplicableEntityTypes = StringUtils.isBlank(updatedApplicableEntityTypesString) ? null : AtlasType.fromJson(updatedApplicableEntityTypesString, Set.class);
+
+                AtlasStructDef.AtlasAttributeDef existingAttribute = currentNamespaceDef.getAttribute(attributeDef.getName());
+                if (existingAttribute != null) {
+                    String existingApplicableEntityTypesString = existingAttribute.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES);
+                    Set<String> existingApplicableEntityTypes = StringUtils.isBlank(existingApplicableEntityTypesString) ? null : AtlasType.fromJson(existingApplicableEntityTypesString, Set.class);
+
+                    if (existingApplicableEntityTypes != null) {
+                        if (!updatedApplicableEntityTypes.containsAll(existingApplicableEntityTypes)) {
+                            throw new AtlasBaseException(AtlasErrorCode.APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED,
+                                    attributeDef.getName(), namespaceDef.getName());
+                        }
+                    }
+                }
+            }
+        }
+
+        AtlasStructDefStoreV2.updateVertexPreUpdate(namespaceDef, namespaceType, vertex, typeDefStore);
+    }
+
+    private AtlasNamespaceDef toNamespaceDef(AtlasVertex vertex) throws AtlasBaseException {
+        AtlasNamespaceDef ret = null;
+
+        if (vertex != null && typeDefStore.isTypeVertex(vertex, DataTypes.TypeCategory.NAMESPACE)) {
+            ret = new AtlasNamespaceDef();
+
+            AtlasStructDefStoreV2.toStructDef(vertex, ret, typeDefStore);
+        }
+
+        return ret;
+    }
+}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java
index a5ccfb5..afdfba9 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasTypeDefGraphStoreV2.java
@@ -19,17 +19,6 @@ package org.apache.atlas.repository.store.graph.v2;
 
 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.v2.AtlasGraphUtilsV2.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.RequestContext;
 import org.apache.atlas.annotation.GraphTransaction;
@@ -37,8 +26,12 @@ import org.apache.atlas.exception.AtlasBaseException;
 import org.apache.atlas.listener.TypeDefChangeListener;
 import org.apache.atlas.model.typedef.*;
 import org.apache.atlas.repository.Constants;
-import org.apache.atlas.repository.graphdb.*;
-import org.apache.atlas.repository.store.graph.*;
+import org.apache.atlas.repository.graphdb.AtlasEdge;
+import org.apache.atlas.repository.graphdb.AtlasEdgeDirection;
+import org.apache.atlas.repository.graphdb.AtlasGraph;
+import org.apache.atlas.repository.graphdb.AtlasVertex;
+import org.apache.atlas.repository.store.graph.AtlasDefStore;
+import org.apache.atlas.repository.store.graph.AtlasTypeDefGraphStore;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
 import org.apache.atlas.typesystem.types.DataTypes.TypeCategory;
@@ -50,6 +43,16 @@ import org.springframework.stereotype.Component;
 
 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.v2.AtlasGraphUtilsV2.VERTEX_TYPE;
 
 
 /**
@@ -97,6 +100,10 @@ public class AtlasTypeDefGraphStoreV2 extends AtlasTypeDefGraphStore {
         return new AtlasRelationshipDefStoreV2(this, typeRegistry);
     }
 
+    @Override
+    protected AtlasDefStore<AtlasNamespaceDef> getNamespaceDefStore(AtlasTypeRegistry typeRegistry) {
+        return new AtlasNamespaceDefStoreV2(this, typeRegistry);
+    }
 
     @Override
     @GraphTransaction
@@ -490,6 +497,9 @@ public class AtlasTypeDefGraphStoreV2 extends AtlasTypeDefGraphStore {
 
             case RELATIONSHIP:
                 return TypeCategory.RELATIONSHIP;
+
+            case NAMESPACE:
+                return TypeCategory.NAMESPACE;
         }
 
         return null;
diff --git a/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2Test.java b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2Test.java
new file mode 100644
index 0000000..1d6534e
--- /dev/null
+++ b/repository/src/test/java/org/apache/atlas/repository/store/graph/v2/AtlasNamespaceDefStoreV2Test.java
@@ -0,0 +1,319 @@
+/**
+ * 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.v2;
+
+import com.google.inject.Inject;
+import org.apache.atlas.AtlasErrorCode;
+import org.apache.atlas.TestModules;
+import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
+import org.apache.atlas.model.typedef.AtlasStructDef;
+import org.apache.atlas.model.typedef.AtlasTypesDef;
+import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasNamespaceType;
+import org.apache.atlas.type.AtlasType;
+import org.apache.atlas.type.AtlasTypeRegistry;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.util.*;
+
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
+import static org.apache.atlas.repository.impexp.ZipFileResourceTestUtils.*;
+
+/* Please note that for these tests, since the typeRegistry can be injected only once,
+ * any new tests should make sure that they flush the type registry at the end of the test.
+ * testNG does not provide a way to execute a method after each test has completed the run, hence
+ * we have to manually make sure that the flushTypeRegistry method is invoked.
+ */
+@Guice(modules = TestModules.TestOnlyModule.class)
+public class AtlasNamespaceDefStoreV2Test {
+
+    @Inject
+    AtlasTypeRegistry typeRegistry;
+
+    @Inject
+    private AtlasTypeDefGraphStoreV2 typeDefStore;
+
+    private AtlasTypesDef typesDefs;
+
+    private static int randomCount;
+    private static final String TEST_NAMESPACE = "test_namespace";
+    private String namespaceName;
+    @BeforeClass
+    public void setup() throws IOException, AtlasBaseException {
+        loadBaseModel(typeDefStore, typeRegistry);
+        loadFsModel(typeDefStore, typeRegistry);
+        loadHiveModel(typeDefStore, typeRegistry);
+
+        typesDefs = new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+
+        namespaceName = TEST_NAMESPACE;
+
+        randomCount = 1;
+    }
+
+    @BeforeMethod
+    public void setTypeDefs() {
+        typesDefs = new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+        randomCount++;
+        namespaceName = TEST_NAMESPACE + randomCount;
+    }
+
+    @Test
+    public void createNamespaceTypeDef() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+        Assert.assertEquals(typeRegistry.getAllNamespaceDefs().size(), 1);
+        AtlasEntityType entityType = typeRegistry.getEntityTypeByName("hive_table");
+        Map<String, List<AtlasNamespaceType.AtlasNamespaceAttribute>> m1 = entityType.getNamespaceAttributes();
+        Assert.assertEquals(m1.get(namespaceName).size(), 2);
+    }
+
+    @Test
+    public void deleteNamespaceTypeDefs() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+        for (AtlasNamespaceDef atlasNamespaceDef : typesDefs.getNamespaceDefs()) {
+            if (atlasNamespaceDef.getName().equals(namespaceName)) {
+                typesDefs = new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(), Collections.emptyList(),
+                        Collections.emptyList());
+                typesDefs.setNamespaceDefs(Arrays.asList(atlasNamespaceDef));
+                typeDefStore.deleteTypesDef(typesDefs);
+            }
+        }
+
+        for (AtlasNamespaceDef namespaceDef : typeRegistry.getAllNamespaceDefs()) {
+            Assert.assertNotEquals(namespaceDef.getName(), namespaceName);
+        }
+    }
+
+    @Test
+    public void updateNamespaceTypeDefs() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+        AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+        Assert.assertNotNull(namespaceDef);
+
+        addNamespaceAttribute(namespaceDef, "test_namespace_attribute3", Collections.singleton("hive_table"),
+                String.format("array<%s>", "string"), AtlasStructDef.AtlasAttributeDef.Cardinality.LIST);
+
+        updateNamespaceTypeDefs(namespaceDef);
+        typeDefStore.updateTypesDef(typesDefs);
+        AtlasEntityType entityType = typeRegistry.getEntityTypeByName("hive_table");
+        Map<String, List<AtlasNamespaceType.AtlasNamespaceAttribute>> m1 = entityType.getNamespaceAttributes();
+        Assert.assertEquals(m1.get(namespaceName).size(), 3);
+    }
+
+    /**
+     * Test to verify that we cannot delete attribute defs from a namespace definition
+     * @throws AtlasBaseException
+     */
+    @Test
+    public void updateTypeDefsWithoutApplicableEntityTypes() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+        AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+        Assert.assertNotNull(namespaceDef);
+
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef = namespaceDef.getAttributeDefs().iterator().next();
+        namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef));
+
+        AtlasTypesDef existingTypeDefs = typesDefs;
+
+        try {
+            typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef));
+            typeDefStore.updateTypesDef(typesDefs);
+        } catch (AtlasBaseException e) {
+            Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.ATTRIBUTE_DELETION_NOT_SUPPORTED);
+        } finally {
+            typesDefs = existingTypeDefs;
+        }
+    }
+
+    @Test
+    public void updateTypeDefsDeleteApplicableEntityTypes() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+        AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+        Assert.assertNotNull(namespaceDef);
+
+        Iterator<AtlasStructDef.AtlasAttributeDef> it = namespaceDef.getAttributeDefs().iterator();
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef = it.next();
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef2 = it.next();
+
+        namespaceAttributeDef.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.emptySet()));
+
+        namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef, namespaceAttributeDef2));
+
+        AtlasTypesDef existingTypeDefs = typesDefs;
+
+        try {
+            typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef));
+            typeDefStore.updateTypesDef(typesDefs);
+        } catch (AtlasBaseException e) {
+            Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE);
+        } finally {
+            typesDefs = existingTypeDefs;
+        }
+    }
+
+    /**
+     * Test to verify that we cannot have an empty applicable entity types in an attribute definition
+     * @throws AtlasBaseException
+     */
+    @Test
+    public void createNsAttrDefWithoutApplicableEntityTypes() {
+        AtlasTypesDef existingTypeDefs = typesDefs;
+
+        try {
+            typesDefs.setNamespaceDefs(Arrays.asList(createNamespaceDef2(namespaceName)));
+            typeDefStore.updateTypesDef(typesDefs);
+        } catch (AtlasBaseException e) {
+            Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE);
+        } finally {
+            typesDefs = existingTypeDefs;
+        }
+    }
+
+    @Test
+    public void updateNsAttrDefDeleteApplicableEntityTypes() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+
+        AtlasNamespaceDef namespaceDef = findNamespaceDef(namespaceName);
+        Assert.assertNotNull(namespaceDef);
+
+        Iterator<AtlasStructDef.AtlasAttributeDef> it = namespaceDef.getAttributeDefs().iterator();
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef = it.next();
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef2 = it.next();
+
+        namespaceAttributeDef.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton("hive_table")));
+
+        namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef, namespaceAttributeDef2));
+
+        AtlasTypesDef existingTypeDefs = typesDefs;
+
+        try {
+            typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef));
+            typeDefStore.updateTypesDef(typesDefs);
+        } catch (AtlasBaseException e) {
+            Assert.assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED);
+        } finally {
+            typesDefs = existingTypeDefs;
+        }
+    }
+
+    @Test
+    public void updateNsAttrDefAddApplicableEntityTypes() throws AtlasBaseException {
+        createNamespaceTypes(namespaceName);
+
+        AtlasNamespaceDef                namespaceDef           = findNamespaceDef(namespaceName);
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef1 = namespaceDef.getAttributeDefs().get(0);
+        AtlasStructDef.AtlasAttributeDef namespaceAttributeDef2 = namespaceDef.getAttributeDefs().get(1);
+        Set<String>                      applicableEntityTypes  = AtlasType.fromJson(namespaceAttributeDef1.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES), Set.class);
+
+        if (applicableEntityTypes == null) {
+            applicableEntityTypes = new HashSet<>();
+        }
+
+        applicableEntityTypes.add("hive_column");
+        namespaceAttributeDef1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(applicableEntityTypes));
+        namespaceDef.setAttributeDefs(Arrays.asList(namespaceAttributeDef1, namespaceAttributeDef2));
+
+        updateNamespaceTypeDefs(namespaceDef);
+
+        typeDefStore.updateTypesDef(typesDefs);
+
+        namespaceDef = findNamespaceDef(namespaceName);
+        namespaceAttributeDef1 = namespaceDef.getAttributeDefs().get(0);
+
+        applicableEntityTypes  = AtlasType.fromJson(namespaceAttributeDef1.getOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES), Set.class);
+
+        Assert.assertEquals(applicableEntityTypes == null ? 0 : applicableEntityTypes.size(), 3);
+    }
+
+    @Test
+    public void validateMaxStringLengthForStringTypes() throws AtlasBaseException {
+        AtlasTypesDef existingTypeDefs = typesDefs;
+        AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef(namespaceName, "test_description", null);
+        addNamespaceAttribute(namespaceDef1, "test_namespace_attribute1", new HashSet<>(Arrays.asList("hive_table", "fs_path")), "string",
+                AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        typesDefs.setNamespaceDefs(Arrays.asList(namespaceDef1));
+        try {
+            typeDefStore.createTypesDef(typesDefs);
+        } catch (AtlasBaseException exception) {
+            Assert.assertEquals(exception.getAtlasErrorCode(), AtlasErrorCode.MISSING_MANDATORY_ATTRIBUTE);
+        } finally {
+            typesDefs = existingTypeDefs;
+        }
+    }
+
+    private AtlasNamespaceDef createNamespaceDef(String namespaceName) {
+        AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef(namespaceName, "test_description", null);
+        addNamespaceAttribute(namespaceDef1, "test_namespace_attribute1", new HashSet<>(Arrays.asList("hive_table", "fs_path")), "int",
+                AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        addNamespaceAttribute(namespaceDef1, "test_namespace_attribute2", Collections.singleton("hive_table"), "int",
+                AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        return namespaceDef1;
+    }
+
+    private AtlasNamespaceDef createNamespaceDef2(String namespaceName) {
+        AtlasNamespaceDef namespaceDef1 = new AtlasNamespaceDef(namespaceName, "test_description", null);
+        addNamespaceAttribute(namespaceDef1, "test_namespace_attribute1", Collections.emptySet(), "int",
+                AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        addNamespaceAttribute(namespaceDef1, "test_namespace_attribute2", Collections.singleton("hive_table"), "int",
+                AtlasStructDef.AtlasAttributeDef.Cardinality.SINGLE);
+        return namespaceDef1;
+    }
+
+    private void createNamespaceTypes(String namespaceName) throws AtlasBaseException {
+        List<AtlasNamespaceDef> namespaceDefs = new ArrayList(typesDefs.getNamespaceDefs());
+        namespaceDefs.add(createNamespaceDef(namespaceName));
+        typesDefs.setNamespaceDefs(namespaceDefs);
+        typeDefStore.createTypesDef(typesDefs);
+    }
+
+    private void addNamespaceAttribute(AtlasNamespaceDef namespaceDef, String name, Set<String> applicableEntityTypes,
+                                       String typeName, AtlasStructDef.AtlasAttributeDef.Cardinality cardinality) {
+        AtlasStructDef.AtlasAttributeDef attributeDef = new AtlasStructDef.AtlasAttributeDef(name, typeName);
+
+        attributeDef.setCardinality(cardinality);
+        attributeDef.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(applicableEntityTypes));
+        attributeDef.setIsOptional(true);
+        attributeDef.setIsUnique(false);
+
+        namespaceDef.addAttribute(attributeDef);
+    }
+
+    private AtlasNamespaceDef findNamespaceDef(String namespaceName) {
+        for (AtlasNamespaceDef atlasNamespaceDef : typesDefs.getNamespaceDefs()) {
+            if (atlasNamespaceDef.getName().equals(namespaceName)) {
+                return atlasNamespaceDef;
+            }
+        }
+
+        return null;
+    }
+
+    private void updateNamespaceTypeDefs(AtlasNamespaceDef atlasNamespaceDef) {
+        for (int i = 0; i < typesDefs.getNamespaceDefs().size(); i++) {
+            if (typesDefs.getNamespaceDefs().get(i).getName().equals(namespaceName)) {
+                typesDefs.getNamespaceDefs().set(i, atlasNamespaceDef);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
index 6cd0ee3..72f5bef 100755
--- a/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
+++ b/webapp/src/main/java/org/apache/atlas/examples/QuickStartV2.java
@@ -19,7 +19,6 @@
 package org.apache.atlas.examples;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.ImmutableMap;
 import com.sun.jersey.core.util.MultivaluedMapImpl;
 import org.apache.atlas.ApplicationProperties;
 import org.apache.atlas.AtlasClientV2;
@@ -40,10 +39,12 @@ import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageDirection;
 import org.apache.atlas.model.lineage.AtlasLineageInfo.LineageRelation;
 import org.apache.atlas.model.typedef.AtlasClassificationDef;
 import org.apache.atlas.model.typedef.AtlasEntityDef;
+import org.apache.atlas.model.typedef.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
-import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
+import org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef;
 import org.apache.atlas.model.typedef.AtlasTypesDef;
-import org.apache.atlas.repository.Constants;
+import org.apache.atlas.model.typedef.AtlasRelationshipDef.PropagateTags;
+import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeUtil;
 import org.apache.atlas.utils.AuthenticationUtil;
 import org.apache.commons.collections.CollectionUtils;
@@ -55,6 +56,7 @@ import java.util.*;
 
 import static java.util.Arrays.asList;
 import static org.apache.atlas.AtlasClient.REFERENCEABLE_ATTRIBUTE_NAME;
+import static org.apache.atlas.model.typedef.AtlasNamespaceDef.ATTR_OPTION_APPLICABLE_ENTITY_TYPES;
 import static org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory.AGGREGATION;
 import static org.apache.atlas.model.typedef.AtlasRelationshipDef.RelationshipCategory.COMPOSITION;
 import static org.apache.atlas.model.typedef.AtlasStructDef.AtlasAttributeDef.Cardinality.SET;
@@ -316,7 +318,25 @@ public class QuickStartV2 {
         List<AtlasRelationshipDef>   relationshipDefs   = asList(tableDatabaseTypeDef, viewDatabaseTypeDef, viewTablesTypeDef, tableColumnsTypeDef, tableStorageDescTypeDef, processProcessExecutionTypeDef);
         List<AtlasClassificationDef> classificationDefs = asList(dimClassifDef, factClassifDef, piiClassifDef, metricClassifDef, etlClassifDef, jdbcClassifDef, logClassifDef);
 
-        return new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), classificationDefs, entityDefs, relationshipDefs);
+        // Namespace definitions
+        AtlasAttributeDef nsAttrDef1 = new AtlasAttributeDef("attr1", "int");
+        AtlasAttributeDef nsAttrDef2 = new AtlasAttributeDef("attr2", "int");
+
+        nsAttrDef1.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(TABLE_TYPE)));
+        nsAttrDef1.setIsOptional(true);
+        nsAttrDef1.setIsUnique(false);
+
+        nsAttrDef2.setOption(ATTR_OPTION_APPLICABLE_ENTITY_TYPES, AtlasType.toJson(Collections.singleton(TABLE_TYPE)));
+        nsAttrDef2.setIsOptional(true);
+        nsAttrDef2.setIsUnique(false);
+
+        AtlasNamespaceDef testNamespaceDef = new AtlasNamespaceDef("test_namespace", "test_description", VERSION_1);
+
+        testNamespaceDef.setAttributeDefs(Arrays.asList(nsAttrDef1, nsAttrDef2));
+
+        List<AtlasNamespaceDef> namespaceDefs  = asList(testNamespaceDef);
+
+        return new AtlasTypesDef(Collections.emptyList(), Collections.emptyList(), classificationDefs, entityDefs, relationshipDefs, namespaceDefs);
     }
 
     void createEntities() throws Exception {
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 fb56fad..e7cf62d 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
@@ -23,6 +23,7 @@ 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.AtlasNamespaceDef;
 import org.apache.atlas.model.typedef.AtlasRelationshipDef;
 import org.apache.atlas.model.typedef.AtlasStructDef;
 import org.apache.atlas.model.typedef.AtlasTypeDefHeader;
@@ -317,6 +318,43 @@ public class TypesREST {
 
         return ret;
     }
+
+    /**
+     * Get the namespace definition for the given guid
+     * @param guid namespace guid
+     * @return namespace definition
+     * @throws AtlasBaseException
+     * @HTTP 200 On successful lookup of the the namespace definition by it's guid
+     * @HTTP 404 On Failed lookup for the given guid
+     */
+    @GET
+    @Path("/namespacedef/guid/{guid}")
+    public AtlasNamespaceDef getNamespaceDefByGuid(@PathParam("guid") String guid) throws AtlasBaseException {
+        Servlets.validateQueryParamLength("guid", guid);
+
+        AtlasNamespaceDef ret = typeDefStore.getNamespaceDefByGuid(guid);
+
+        return ret;
+    }
+
+    /**
+     * Get the namespace definition by it's name (unique)
+     * @param name namespace name
+     * @return namespace definition
+     * @throws AtlasBaseException
+     * @HTTP 200 On successful lookup of the the namespace definition by it's name
+     * @HTTP 404 On Failed lookup for the given name
+     */
+    @GET
+    @Path("/namespacedef/name/{name}")
+    public AtlasNamespaceDef getNamespaceDefByName(@PathParam("name") String name) throws AtlasBaseException {
+        Servlets.validateQueryParamLength("name", name);
+
+        AtlasNamespaceDef ret = typeDefStore.getNamespaceDefByName(name);
+
+        return ret;
+    }
+
     /* Bulk API operation */
 
     /**