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

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

commit e621788c55368a11c4fe8fa28f2b4caa626b1511
Author: Mandar Ambawane <mandar.ambaw...@freestoneinfotech.com>
AuthorDate: Thu Feb 6 14:45:49 2020 +0530

    ATLAS-3534: enhancements to support add/update/delete namespace-attributes 
on entities
    
    Signed-off-by: Madhan Neethiraj <mad...@apache.org>
    (cherry picked from commit d3a08b6eabcc50536c468db2d1328df54ee27fce)
---
 .../org/apache/atlas/repository/Constants.java     |   3 +-
 .../main/java/org/apache/atlas/AtlasErrorCode.java |  41 +++---
 .../apache/atlas/model/instance/AtlasEntity.java   |  56 +++++++-
 .../org/apache/atlas/type/AtlasNamespaceType.java  |  17 +--
 .../org/apache/atlas/type/AtlasTypeRegistry.java   |   1 +
 .../repository/store/graph/AtlasEntityStore.java   |  17 +++
 .../store/graph/v2/AtlasEntityStoreV2.java         | 122 ++++++++++++++++-
 .../store/graph/v2/EntityGraphMapper.java          | 146 ++++++++++++++++++++-
 .../store/graph/v2/EntityGraphRetriever.java       |  23 ++++
 .../java/org/apache/atlas/web/rest/EntityREST.java |  73 +++++++++++
 10 files changed, 455 insertions(+), 44 deletions(-)

diff --git a/common/src/main/java/org/apache/atlas/repository/Constants.java 
b/common/src/main/java/org/apache/atlas/repository/Constants.java
index 0b28243..7c0fd56 100644
--- a/common/src/main/java/org/apache/atlas/repository/Constants.java
+++ b/common/src/main/java/org/apache/atlas/repository/Constants.java
@@ -88,14 +88,13 @@ public final class Constants {
     public static final String VERSION_PROPERTY_KEY                 = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "version");
     public static final String STATE_PROPERTY_KEY                   = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "state");
     public static final String CREATED_BY_KEY                       = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "createdBy");
+    public static final String MODIFIED_BY_KEY                      = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "modifiedBy");
     public static final String CLASSIFICATION_TEXT_KEY              = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "classificationsText");
     public static final String CLASSIFICATION_NAMES_KEY             = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "classificationNames");
     public static final String PROPAGATED_CLASSIFICATION_NAMES_KEY  = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + 
"propagatedClassificationNames");
     public static final String CUSTOM_ATTRIBUTES_PROPERTY_KEY       = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "customAttributes");
     public static final String LABELS_PROPERTY_KEY                  = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "labels");
 
-    public static final String MODIFIED_BY_KEY                      = 
encodePropertyKey(INTERNAL_PROPERTY_KEY_PREFIX + "modifiedBy");
-
     /**
      * Patch vertices property keys.
      */
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java 
b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 2054513..1670bda 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -147,25 +147,28 @@ public enum AtlasErrorCode {
     ATTRIBUTE_TYPE_INVALID(400, "ATLAS-400-00-081", "{0}.{1}: invalid 
attribute type. Attribute cannot be of type classification"),
     MISSING_CATEGORY_DISPLAY_NAME(400, "ATLAS-400-00-082", "Category name is 
empty/null"),
     INVALID_DISPLAY_NAME(400, "ATLAS-400-00-083", "name cannot contain 
following special chars ('@', '.')"),
-    TERM_HAS_ENTITY_ASSOCIATION(400, "ATLAS-400-00-086", "Term (guid={0}) 
can't be deleted as it has been assigned to {1} entities."),
-    INVALID_TIMEBOUNDRY_TIMEZONE(400, "ATLAS-400-00-87A", "Invalid timezone 
{0}"),
-    INVALID_TIMEBOUNDRY_START_TIME(400, "ATLAS-400-00-87B", "Invalid startTime 
{0}"),
-    INVALID_TIMEBOUNDRY_END_TIME(400, "ATLAS-400-00-87C", "Invalid endTime 
{0}"),
-    INVALID_TIMEBOUNDRY_DATERANGE(400, "ATLAS-400-00-87D", "Invalid dateRange: 
startTime {0} must be before endTime {1}"),
-    PROPAGATED_CLASSIFICATION_REMOVAL_NOT_SUPPORTED(400, "ATLAS-400-00-87E", 
"Removal of classification {0}, which is propagated from entity {1}, is not 
supported"),
-    IMPORT_ATTEMPTING_EMPTY_ZIP(400, "ATLAS-400-00-87F", "Attempting to import 
empty ZIP file."),
-    PATCH_MISSING_RELATIONSHIP_LABEL(400, "ATLAS-400-00-88", "{0} - must 
include relationship label for type {1}"),
-    INVALID_CUSTOM_ATTRIBUTE_KEY_LENGTH(400, "ATLAS-400-00-89", "Invalid key: 
{0} in custom attribute, key size should not be greater than 50"),
-    INVALID_CUSTOM_ATTRIBUTE_KEY_CHARACTERS(400, "ATLAS-400-00-90", "Invalid 
key: {0} in custom attribute, key should only contain alphanumeric characters, 
'_' or '-'"),
-    INVALID_CUSTOM_ATTRIBUTE_VALUE(400, "ATLAS-400-00-9A", "Invalid value: {0} 
in custom attribute, value length is greater than {1}"),
-    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"),
+    TERM_HAS_ENTITY_ASSOCIATION(400, "ATLAS-400-00-084", "Term (guid={0}) 
can't be deleted as it has been assigned to {1} entities."),
+    INVALID_TIMEBOUNDRY_TIMEZONE(400, "ATLAS-400-00-085", "Invalid timezone 
{0}"),
+    INVALID_TIMEBOUNDRY_START_TIME(400, "ATLAS-400-00-086", "Invalid startTime 
{0}"),
+    INVALID_TIMEBOUNDRY_END_TIME(400, "ATLAS-400-00-087", "Invalid endTime 
{0}"),
+    INVALID_TIMEBOUNDRY_DATERANGE(400, "ATLAS-400-00-088", "Invalid dateRange: 
startTime {0} must be before endTime {1}"),
+    PROPAGATED_CLASSIFICATION_REMOVAL_NOT_SUPPORTED(400, "ATLAS-400-00-089", 
"Removal of classification {0}, which is propagated from entity {1}, is not 
supported"),
+    IMPORT_ATTEMPTING_EMPTY_ZIP(400, "ATLAS-400-00-08A", "Attempting to import 
empty ZIP file."),
+    PATCH_MISSING_RELATIONSHIP_LABEL(400, "ATLAS-400-00-08B", "{0} - must 
include relationship label for type {1}"),
+    INVALID_CUSTOM_ATTRIBUTE_KEY_LENGTH(400, "ATLAS-400-00-08C", "Invalid key: 
{0} in custom attribute, key size should not be greater than 50"),
+    INVALID_CUSTOM_ATTRIBUTE_KEY_CHARACTERS(400, "ATLAS-400-00-08D", "Invalid 
key: {0} in custom attribute, key should only contain alphanumeric characters, 
'_' or '-'"),
+    INVALID_CUSTOM_ATTRIBUTE_VALUE(400, "ATLAS-400-00-08E", "Invalid value: 
{0} in custom attribute, value length is greater than {1}"),
+    INVALID_LABEL_LENGTH(400, "ATLAS-400-00-08F", "Invalid label: {0}, label 
size should not be greater than {1}"),
+    INVALID_LABEL_CHARACTERS(400, "ATLAS-400-00-090", "Invalid label: {0}, 
label should contain alphanumeric characters, '_' or '-'"),
+    INVALID_PROPAGATION_TYPE(400, "ATLAS-400-00-091", "Invalid propagation {0} 
for relationship-type={1}. Default value is {2}"),
+    DUPLICATE_NAMESPACE_ATTRIBUTE(400, "ATLAS-400-00-092", "Duplicate 
Namespace Attributes: {0} not allowed within the same namespace: {1}"),
+    APPLICABLE_ENTITY_TYPES_DELETION_NOT_SUPPORTED(400, "ATLAS-400-00-093", 
"Cannot remove applicableEntityTypes in Attribute Def: {0}, defined in 
namespace: {1}"),
+    NAMESPACE_DEF_MANDATORY_ATTRIBUTE_NOT_ALLOWED(400, "ATLAS-400-00-094", 
"{0}.{1} : namespaces can not have mandatory attribute"),
+    NAMESPACE_DEF_UNIQUE_ATTRIBUTE_NOT_ALLOWED(400, "ATLAS-400-00-095", 
"{0}.{1} : namespaces can not have unique attribute"),
+    NAMESPACE_DEF_ATTRIBUTE_TYPE_INVALID(400, "ATLAS-400-00-096", "{0}.{1}: 
invalid attribute type. Namespace attribute cannot be of type 
entity/classification/struct/namespace"),
+    INVALID_NAMESPACE_NAME_FOR_ENTITY_TYPE(400, "ATLAS-400-00-097", "Invalid 
Namespace: {0} specified for entity, applicable namespaces: {1}"),
+    NAMESPACE_ATTRIBUTE_DOES_NOT_EXIST(400, "ATLAS-400-00-098", "Namespace 
attribute does not exist  in entity: {0}"),
+    NAMESPACE_ATTRIBUTE_ALREADY_EXISTS(400, "ATLAS-400-00-099", "Namespace 
attribute already exists in entity: {0}"),
 
     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/instance/AtlasEntity.java 
b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
index 1b033b9..2e2e4ee 100644
--- a/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
+++ b/intg/src/main/java/org/apache/atlas/model/instance/AtlasEntity.java
@@ -89,11 +89,12 @@ public class AtlasEntity extends AtlasStruct implements 
Serializable {
     private Date    updateTime     = null;
     private Long    version        = 0L;
 
-    private Map<String, Object>             relationshipAttributes;
-    private List<AtlasClassification>       classifications;
-    private List<AtlasTermAssignmentHeader> meanings;
-    private Map<String, String>             customAttributes;
-    private Set<String>                     labels;
+    private Map<String, Object>              relationshipAttributes;
+    private List<AtlasClassification>        classifications;
+    private List<AtlasTermAssignmentHeader>  meanings;
+    private Map<String, String>              customAttributes;
+    private Map<String, Map<String, Object>> namespaceAttributes;
+    private Set<String>                      labels;
 
     @JsonIgnore
     private static AtomicLong s_nextId = new AtomicLong(System.nanoTime());
@@ -217,6 +218,7 @@ public class AtlasEntity extends AtlasStruct implements 
Serializable {
             setRelationshipAttributes(other.getRelationshipAttributes());
             setMeanings(other.getMeanings());
             setCustomAttributes(other.getCustomAttributes());
+            setNamespaceAttributes(other.getNamespaceAttributes());
             setLabels(other.getLabels());
         }
     }
@@ -348,6 +350,41 @@ public class AtlasEntity extends AtlasStruct implements 
Serializable {
         this.customAttributes = customAttributes;
     }
 
+    public Map<String, Map<String, Object>> getNamespaceAttributes() {
+        return namespaceAttributes;
+    }
+
+    public void setNamespaceAttributes(Map<String, Map<String, Object>> 
namespaceAttributes) {
+        this.namespaceAttributes = namespaceAttributes;
+    }
+
+    public void setNamespaceAttribute(String nsName, String nsAttrName, Object 
nsValue) {
+        Map<String, Map<String, Object>> namespaceAttributes = 
this.namespaceAttributes;
+
+        if (namespaceAttributes == null) {
+            namespaceAttributes = new HashMap<>();
+
+            this.namespaceAttributes = namespaceAttributes;
+        }
+
+        Map<String, Object> namespaceAttributeMap = 
namespaceAttributes.get(nsName);
+
+        if (namespaceAttributeMap == null) {
+            namespaceAttributeMap = new HashMap<>();
+
+            namespaceAttributes.put(nsName, namespaceAttributeMap);
+        }
+
+        namespaceAttributeMap.put(nsAttrName, nsValue);
+    }
+
+    public Object getNamespaceAttribute(String nsName, String nsAttrName) {
+        Map<String, Map<String, Object>> namespaceAttributes   = 
this.namespaceAttributes;
+        Map<String, Object>              namespaceAttributeMap = 
namespaceAttributes == null ? null : namespaceAttributes.get(nsName);
+
+        return namespaceAttributeMap == null ? null : 
namespaceAttributeMap.get(nsAttrName);
+    }
+
     public Set<String> getLabels() {
         return labels;
     }
@@ -404,6 +441,7 @@ public class AtlasEntity extends AtlasStruct implements 
Serializable {
         setClassifications(null);
         setMeanings(null);
         setCustomAttributes(null);
+        setNamespaceAttributes(null);
         setLabels(null);
     }
 
@@ -442,6 +480,9 @@ public class AtlasEntity extends AtlasStruct implements 
Serializable {
         sb.append(", customAttributes=[");
         dumpObjects(customAttributes, sb);
         sb.append("]");
+        sb.append(", namespaceAttributes=[");
+        dumpObjects(namespaceAttributes, sb);
+        sb.append("]");
         sb.append(", labels=[");
         dumpObjects(labels, sb);
         sb.append("]");
@@ -470,14 +511,15 @@ public class AtlasEntity extends AtlasStruct implements 
Serializable {
                 Objects.equals(version, that.version) &&
                 Objects.equals(relationshipAttributes, 
that.relationshipAttributes) &&
                 Objects.equals(customAttributes, that.customAttributes) &&
+                Objects.equals(namespaceAttributes, that.namespaceAttributes) 
&&
                 Objects.equals(labels, that.labels) &&
                 Objects.equals(classifications, that.classifications);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(super.hashCode(), guid, homeId, isProxy, 
isIncomplete, provenanceType, status, createdBy,
-                updatedBy, createTime, updateTime, version, 
relationshipAttributes, classifications, customAttributes, labels);
+        return Objects.hash(super.hashCode(), guid, homeId, isProxy, 
isIncomplete, provenanceType, status, createdBy, updatedBy,
+                createTime, updateTime, version, relationshipAttributes, 
classifications, customAttributes, namespaceAttributes, labels);
     }
 
     @Override
diff --git a/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java 
b/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
index a141d4a..cfbf2b1 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasNamespaceType.java
@@ -146,21 +146,22 @@ public class AtlasNamespaceType extends AtlasStructType {
 
     public static class AtlasNamespaceAttribute extends AtlasAttribute {
         private final Set<AtlasEntityType> applicableEntityTypes;
-        private final int maxStringLength;
-        private final String validPattern;
+        private final int                  maxStringLength;
+        private final String               validPattern;
 
         public AtlasNamespaceAttribute(AtlasAttribute attribute, 
Set<AtlasEntityType> applicableEntityTypes) {
             super(attribute);
-            this.maxStringLength = 0;
-            this.validPattern = null;
+
+            this.maxStringLength       = 0;
+            this.validPattern          = null;
             this.applicableEntityTypes = applicableEntityTypes;
         }
 
-        public AtlasNamespaceAttribute(AtlasAttribute attribute, 
Set<AtlasEntityType> applicableEntityTypes,
-                                       int maxStringLength, String 
validPattern) {
+        public AtlasNamespaceAttribute(AtlasAttribute attribute, 
Set<AtlasEntityType> applicableEntityTypes, int maxStringLength, String 
validPattern) {
             super(attribute);
-            this.maxStringLength = maxStringLength;
-            this.validPattern = validPattern;
+
+            this.maxStringLength       = maxStringLength;
+            this.validPattern          = validPattern;
             this.applicableEntityTypes = applicableEntityTypes;
         }
 
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 97e27d0..5b7cbee 100644
--- a/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
+++ b/intg/src/main/java/org/apache/atlas/type/AtlasTypeRegistry.java
@@ -201,6 +201,7 @@ public class AtlasTypeRegistry {
         return registryData.namespaceDefs.getAll();
     }
 
+    public AtlasNamespaceType getNamespaceTypeByName(String name) { return 
registryData.namespaceDefs.getTypeByName(name); }
 
     public Collection<AtlasRelationshipDef> getAllRelationshipDefs() { return 
registryData.relationshipDefs.getAll(); }
 
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
index 928c70d..39ea3f8 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/AtlasEntityStore.java
@@ -248,6 +248,23 @@ public interface AtlasEntityStore {
     void setLabels(String guid, Set<String> labels) throws AtlasBaseException;
 
     /**
+     *
+     * @param guid
+     * @param namespaceAttributes
+     * @param isOverwrite
+     * @throws AtlasBaseException
+     */
+    void addOrUpdateNamespaceAttributes(String guid, Map<String, Map<String, 
Object>> namespaceAttributes, boolean isOverwrite) throws AtlasBaseException;
+
+    /**
+     *
+     * @param guid
+     * @param namespaceAttributes
+     * @throws AtlasBaseException
+     */
+    void removeNamespaceAttributes(String guid, Map<String, Map<String, 
Object>> namespaceAttributes) throws AtlasBaseException;
+
+    /**
      * Remove given labels, if labels is null/empty, no labels will be 
removed. If any labels in
      * labels set are non-existing labels, they will be ignored, only existing 
labels will be removed.
      */
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
index 25284e9..f511e2f 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/AtlasEntityStoreV2.java
@@ -47,6 +47,7 @@ import 
org.apache.atlas.repository.store.graph.v1.DeleteHandlerDelegate;
 import org.apache.atlas.store.DeleteType;
 import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
+import org.apache.atlas.type.AtlasNamespaceType.AtlasNamespaceAttribute;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
 import org.apache.atlas.type.AtlasType;
 import org.apache.atlas.type.AtlasTypeRegistry;
@@ -74,6 +75,7 @@ import static java.lang.Boolean.FALSE;
 import static 
org.apache.atlas.model.instance.EntityMutations.EntityOperation.*;
 import static org.apache.atlas.repository.Constants.IS_INCOMPLETE_PROPERTY_KEY;
 import static 
org.apache.atlas.repository.graph.GraphHelper.getCustomAttributes;
+import static org.apache.atlas.repository.graph.GraphHelper.getTypeName;
 import static org.apache.atlas.repository.graph.GraphHelper.isEntityIncomplete;
 import static 
org.apache.atlas.repository.store.graph.v2.EntityGraphMapper.validateLabels;
 
@@ -318,13 +320,13 @@ public class AtlasEntityStoreV2 implements 
AtlasEntityStore {
     @Override
     @GraphTransaction
     public EntityMutationResponse createOrUpdate(EntityStream entityStream, 
boolean isPartialUpdate) throws AtlasBaseException {
-        return createOrUpdate(entityStream, isPartialUpdate, false);
+        return createOrUpdate(entityStream, isPartialUpdate, false, false);
     }
 
     @Override
     @GraphTransaction(logRollback = false)
     public EntityMutationResponse createOrUpdateForImport(EntityStream 
entityStream) throws AtlasBaseException {
-        return createOrUpdate(entityStream, false, true);
+        return createOrUpdate(entityStream, false, true, true);
     }
 
     @Override
@@ -356,7 +358,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore 
{
 
         entity.setGuid(guid);
 
-        return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), 
isPartialUpdate, false);
+        return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), 
isPartialUpdate, false, false);
     }
 
     @Override
@@ -378,7 +380,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore 
{
 
         AtlasAuthorizationUtils.verifyAccess(new 
AtlasEntityAccessRequest(typeRegistry, AtlasPrivilege.ENTITY_UPDATE, new 
AtlasEntityHeader(entity)), "update entity ByUniqueAttributes");
 
-        return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), true, 
false);
+        return createOrUpdate(new AtlasEntityStream(updatedEntityInfo), true, 
false, false);
     }
 
     @Override
@@ -429,7 +431,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore 
{
                 throw new 
AtlasBaseException(AtlasErrorCode.ATTRIBUTE_UPDATE_NOT_SUPPORTED, attrName, 
attrType.getTypeName());
         }
 
-        return createOrUpdate(new AtlasEntityStream(updateEntity), true, 
false);
+        return createOrUpdate(new AtlasEntityStream(updateEntity), true, 
false, false);
     }
 
     @Override
@@ -823,6 +825,66 @@ public class AtlasEntityStoreV2 implements 
AtlasEntityStore {
 
     @Override
     @GraphTransaction
+    public void addOrUpdateNamespaceAttributes(String guid, Map<String, 
Map<String, Object>> entityNamespaces, boolean isOverwrite) throws 
AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> addOrUpdateNamespaceAttributes(guid={}, 
entityNamespaces={}, isOverwrite={})", guid, entityNamespaces, isOverwrite);
+        }
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, 
"guid is null/empty");
+        }
+
+        AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
+
+        if (entityVertex == null) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+
+        String          typeName   = getTypeName(entityVertex);
+        AtlasEntityType entityType = 
typeRegistry.getEntityTypeByName(typeName);
+
+        validateNamespaceAttributes(entityVertex, entityType, 
entityNamespaces, isOverwrite);
+
+        if (isOverwrite) {
+            entityGraphMapper.setNamespaceAttributes(entityVertex, entityType, 
entityNamespaces);
+        } else {
+            entityGraphMapper.addOrUpdateNamespaceAttributes(entityVertex, 
entityType, entityNamespaces);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== addOrUpdateNamespaceAttributes(guid={}, 
entityNamespaces={}, isOverwrite={})", guid, entityNamespaces, isOverwrite);
+        }
+    }
+
+    @Override
+    @GraphTransaction
+    public void removeNamespaceAttributes(String guid, Map<String, Map<String, 
Object>> entityNamespaces) throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> removeNamespaceAttributes(guid={}, 
entityNamespaces={})", guid, entityNamespaces);
+        }
+
+        if (StringUtils.isEmpty(guid)) {
+            throw new AtlasBaseException(AtlasErrorCode.INVALID_PARAMETERS, 
"guid is null/empty");
+        }
+
+        AtlasVertex entityVertex = AtlasGraphUtilsV2.findByGuid(guid);
+
+        if (entityVertex == null) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_GUID_NOT_FOUND, guid);
+        }
+
+        String          typeName   = getTypeName(entityVertex);
+        AtlasEntityType entityType = 
typeRegistry.getEntityTypeByName(typeName);
+
+        entityGraphMapper.removeNamespaceAttributes(entityVertex, entityType, 
entityNamespaces);
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== removeNamespaceAttributes(guid={}, 
entityNamespaces={})", guid, entityNamespaces);
+        }
+    }
+
+    @Override
+    @GraphTransaction
     public void setLabels(String guid, Set<String> labels) throws 
AtlasBaseException {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> setLabels()");
@@ -899,7 +961,7 @@ public class AtlasEntityStoreV2 implements AtlasEntityStore 
{
         }
     }
 
-    private EntityMutationResponse createOrUpdate(EntityStream entityStream, 
boolean isPartialUpdate, boolean replaceClassifications) throws 
AtlasBaseException {
+    private EntityMutationResponse createOrUpdate(EntityStream entityStream, 
boolean isPartialUpdate, boolean replaceClassifications, boolean 
replaceNamespaceAttributes) throws AtlasBaseException {
         if (LOG.isDebugEnabled()) {
             LOG.debug("==> createOrUpdate()");
         }
@@ -1040,7 +1102,7 @@ public class AtlasEntityStoreV2 implements 
AtlasEntityStore {
                 
RequestContext.get().endMetricRecord(checkForUnchangedEntities);
             }
 
-            EntityMutationResponse ret = 
entityGraphMapper.mapAttributesAndClassifications(context, isPartialUpdate, 
replaceClassifications);
+            EntityMutationResponse ret = 
entityGraphMapper.mapAttributesAndClassifications(context, isPartialUpdate, 
replaceClassifications, replaceNamespaceAttributes);
 
             ret.setGuidAssignments(context.getGuidAssignments());
 
@@ -1311,4 +1373,50 @@ public class AtlasEntityStoreV2 implements 
AtlasEntityStore {
             }
         }
     }
+
+    private void validateNamespaceAttributes(AtlasVertex entityVertex, 
AtlasEntityType entityType, Map<String, Map<String, Object>> entityNamespaces, 
boolean isOverwrite) throws AtlasBaseException {
+        List<String> messages = new ArrayList<>();
+
+        Map<String, List<AtlasNamespaceAttribute>> entityTypeNamespaces = 
entityType.getNamespaceAttributes();
+
+        for (String nsName : entityNamespaces.keySet()) {
+            if (!entityNamespaces.containsKey(nsName)) {
+                messages.add(nsName + ": invalid namespace for entity type " + 
entityType.getTypeName());
+
+                continue;
+            }
+
+            List<AtlasNamespaceAttribute> entityTypeNsAttributes = 
entityTypeNamespaces.get(nsName);
+            Map<String, Object>           entityNsAttributes     = 
entityNamespaces.get(nsName);
+
+            for (AtlasNamespaceAttribute nsAttribute : entityTypeNsAttributes) 
{
+                AtlasType attrType  = nsAttribute.getAttributeType();
+                String    attrName  = nsAttribute.getName();
+                Object    attrValue = entityNsAttributes.get(attrName);
+                String    fieldName = entityType.getTypeName() + "." + nsName 
+ "." + attrName;
+
+                if (attrValue != null) {
+                    attrType.validateValue(attrValue, fieldName, messages);
+                } else if (!nsAttribute.getAttributeDef().getIsOptional()) {
+                    final boolean isAttrValuePresent;
+
+                    if (isOverwrite) {
+                        isAttrValuePresent = false;
+                    } else {
+                        Object existingValue = 
AtlasGraphUtilsV2.getEncodedProperty(entityVertex, 
nsAttribute.getVertexPropertyName(), Object.class);
+
+                        isAttrValuePresent = existingValue != null;
+                    }
+
+                    if (!isAttrValuePresent) {
+                        messages.add(fieldName + ": mandatory namespace 
attribute value missing in type " + entityType.getTypeName());
+                    }
+                }
+            }
+        }
+
+        if (!messages.isEmpty()) {
+            throw new 
AtlasBaseException(AtlasErrorCode.INSTANCE_CRUD_INVALID_PARAMS, messages);
+        }
+    }
 }
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
index 3d42d1f..113325d 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphMapper.java
@@ -53,6 +53,7 @@ import org.apache.atlas.type.AtlasBuiltInTypes;
 import org.apache.atlas.type.AtlasClassificationType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasMapType;
+import org.apache.atlas.type.AtlasNamespaceType.AtlasNamespaceAttribute;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
 import 
org.apache.atlas.type.AtlasStructType.AtlasAttribute.AtlasRelationshipEdgeDirection;
@@ -253,7 +254,7 @@ public class EntityGraphMapper {
         }
     }
 
-    public EntityMutationResponse 
mapAttributesAndClassifications(EntityMutationContext context, final boolean 
isPartialUpdate, final boolean replaceClassifications) throws 
AtlasBaseException {
+    public EntityMutationResponse 
mapAttributesAndClassifications(EntityMutationContext context, final boolean 
isPartialUpdate, final boolean replaceClassifications, boolean 
replaceNamespaceAttributes) throws AtlasBaseException {
         MetricRecorder metric = 
RequestContext.get().startMetricRecord("mapAttributesAndClassifications");
 
         EntityMutationResponse resp       = new EntityMutationResponse();
@@ -275,6 +276,8 @@ public class EntityGraphMapper {
                 resp.addEntity(CREATE, constructHeader(createdEntity, 
entityType, vertex));
                 addClassifications(context, guid, 
createdEntity.getClassifications());
 
+                addOrUpdateNamespaceAttributes(vertex, entityType, 
createdEntity.getNamespaceAttributes());
+
                 reqContext.cache(createdEntity);
             }
         }
@@ -300,6 +303,10 @@ public class EntityGraphMapper {
                     addClassifications(context, guid, 
updatedEntity.getClassifications());
                 }
 
+                if (replaceNamespaceAttributes) {
+                    setNamespaceAttributes(vertex, entityType, 
updatedEntity.getNamespaceAttributes());
+                }
+
                 reqContext.cache(updatedEntity);
             }
         }
@@ -412,6 +419,143 @@ public class EntityGraphMapper {
         return ret;
     }
 
+    /*
+     * reset/overwrite namespace attributes of the entity with given values
+     */
+    public void setNamespaceAttributes(AtlasVertex entityVertex, 
AtlasEntityType entityType, Map<String, Map<String, Object>> entityNamespaces) 
throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> setNamespaceAttributes(entityVertex={}, 
entityType={}, entityNamespaces={}", entityVertex, entityType.getTypeName(), 
entityNamespaces);
+        }
+
+        Map<String, List<AtlasNamespaceAttribute>> entityTypeNamespaces = 
entityType.getNamespaceAttributes();
+
+        for (Map.Entry<String, List<AtlasNamespaceAttribute>> entry : 
entityTypeNamespaces.entrySet()) {
+            String                        nsName                 = 
entry.getKey();
+            List<AtlasNamespaceAttribute> entityTypeNsAttributes = 
entry.getValue();
+            Map<String, Object>           entityNsAttributes     = 
MapUtils.isEmpty(entityNamespaces) ? null : entityNamespaces.get(nsName);
+
+            for (AtlasNamespaceAttribute nsAttribute : entityTypeNsAttributes) 
{
+                String nsAttrName          = nsAttribute.getName();
+                Object nsAttrExistingValue = 
entityVertex.getProperty(nsAttribute.getVertexPropertyName(), Object.class);
+                Object nsAttrNewValue      = 
MapUtils.isEmpty(entityNsAttributes) ? null : 
entityNsAttributes.get(nsAttrName);
+
+                if (nsAttrExistingValue == null) {
+                    if (nsAttrNewValue != null) {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("setNamespaceAttributes(): adding 
{}.{}={}", nsName, nsAttribute.getName(), nsAttrNewValue);
+                        }
+
+                        mapAttribute(nsAttribute, nsAttrNewValue, 
entityVertex, CREATE, new EntityMutationContext());
+                    }
+                } else {
+                    if (nsAttrNewValue != null) {
+                        if (!Objects.equals(nsAttrExistingValue, 
nsAttrNewValue)) {
+                            if (LOG.isDebugEnabled()) {
+                                LOG.debug("setNamespaceAttributes(): updating 
{}.{}={}", nsName, nsAttribute.getName(), nsAttrNewValue);
+                            }
+
+                            mapAttribute(nsAttribute, nsAttrNewValue, 
entityVertex, UPDATE, new EntityMutationContext());
+                        }
+                    } else {
+                        if (LOG.isDebugEnabled()) {
+                            LOG.debug("setNamespaceAttributes(): removing 
{}.{}", nsName, nsAttribute.getName());
+                        }
+
+                        
entityVertex.removeProperty(nsAttribute.getVertexPropertyName());
+                    }
+                }
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== setNamespaceAttributes(entityVertex={}, 
entityType={}, entityNamespaces={}", entityVertex, entityType.getTypeName(), 
entityNamespaces);
+        }
+    }
+
+    /*
+     * add or update the given namespace attributes on the entity
+     */
+    public void addOrUpdateNamespaceAttributes(AtlasVertex entityVertex, 
AtlasEntityType entityType, Map<String, Map<String, Object>> entityNamespaces) 
throws AtlasBaseException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> addOrUpdateNamespaceAttributes(entityVertex={}, 
entityType={}, entityNamespaces={}", entityVertex, entityType.getTypeName(), 
entityNamespaces);
+        }
+
+        Map<String, List<AtlasNamespaceAttribute>> entityTypeNamespaces = 
entityType.getNamespaceAttributes();
+
+        if (MapUtils.isNotEmpty(entityTypeNamespaces) && 
MapUtils.isNotEmpty(entityNamespaces)) {
+            for (Map.Entry<String, List<AtlasNamespaceAttribute>> entry : 
entityTypeNamespaces.entrySet()) {
+                String                        nsName                 = 
entry.getKey();
+                List<AtlasNamespaceAttribute> entityTypeNsAttributes = 
entry.getValue();
+                Map<String, Object>           entityNsAttributes     = 
entityNamespaces.get(nsName);
+
+                if (MapUtils.isEmpty(entityNsAttributes)) {
+                    continue;
+                }
+
+                for (AtlasNamespaceAttribute nsAttribute : 
entityTypeNsAttributes) {
+                    String nsAttrName = nsAttribute.getName();
+
+                    if (!entityNsAttributes.containsKey(nsAttrName)) {
+                        continue;
+                    }
+
+                    Object nsAttrValue   = entityNsAttributes.get(nsAttrName);
+                    Object existingValue = 
AtlasGraphUtilsV2.getEncodedProperty(entityVertex, 
nsAttribute.getVertexPropertyName(), Object.class);
+
+                    if (existingValue == null) {
+                        if (nsAttrValue != null) {
+                            mapAttribute(nsAttribute, nsAttrValue, 
entityVertex, CREATE, new EntityMutationContext());
+                        }
+                    } else {
+                        if (!Objects.equals(existingValue, nsAttrValue)) {
+                            mapAttribute(nsAttribute, nsAttrValue, 
entityVertex, UPDATE, new EntityMutationContext());
+                        }
+                    }
+                }
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== addOrUpdateNamespaceAttributes(entityVertex={}, 
entityType={}, entityNamespaces={}", entityVertex, entityType.getTypeName(), 
entityNamespaces);
+        }
+    }
+
+    /*
+     * remove the given namespace attributes from the entity
+     */
+    public void removeNamespaceAttributes(AtlasVertex entityVertex, 
AtlasEntityType entityType, Map<String, Map<String, Object>> entityNamespaces) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> removeNamespaceAttributes(entityVertex={}, 
entityType={}, entityNamespaces={}", entityVertex, entityType.getTypeName(), 
entityNamespaces);
+        }
+
+        Map<String, List<AtlasNamespaceAttribute>> entityTypeNamespaces = 
entityType.getNamespaceAttributes();
+
+        if (MapUtils.isNotEmpty(entityTypeNamespaces) && 
MapUtils.isNotEmpty(entityNamespaces)) {
+            for (Map.Entry<String, List<AtlasNamespaceAttribute>> entry : 
entityTypeNamespaces.entrySet()) {
+                String                        nsName                 = 
entry.getKey();
+                List<AtlasNamespaceAttribute> entityTypeNsAttributes = 
entry.getValue();
+
+                if (!entityNamespaces.containsKey(nsName)) { // nothing to 
remove for this namespace
+                    continue;
+                }
+
+                Map<String, Object> entityNsAttributes = 
entityNamespaces.get(nsName);
+
+                for (AtlasNamespaceAttribute nsAttribute : 
entityTypeNsAttributes) {
+                    // if (entityNsAttributes is empty) remove all attributes 
in this namespace
+                    // else remove the attribute only if its given in 
entityNsAttributes
+                    if (MapUtils.isEmpty(entityNsAttributes) || 
entityNsAttributes.containsKey(nsAttribute.getName())) {
+                        
entityVertex.removeProperty(nsAttribute.getVertexPropertyName());
+                    }
+                }
+            }
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("<== removeNamespaceAttributes(entityVertex={}, 
entityType={}, entityNamespaces={}", entityVertex, entityType.getTypeName(), 
entityNamespaces);
+        }
+    }
+
     private AtlasVertex createStructVertex(AtlasStruct struct) {
         return createStructVertex(struct.getTypeName());
     }
diff --git 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
index dc4c399..55c1cac 100644
--- 
a/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
+++ 
b/repository/src/main/java/org/apache/atlas/repository/store/graph/v2/EntityGraphRetriever.java
@@ -48,6 +48,7 @@ import org.apache.atlas.type.AtlasArrayType;
 import org.apache.atlas.type.AtlasBuiltInTypes.AtlasObjectIdType;
 import org.apache.atlas.type.AtlasEntityType;
 import org.apache.atlas.type.AtlasMapType;
+import org.apache.atlas.type.AtlasNamespaceType.AtlasNamespaceAttribute;
 import org.apache.atlas.type.AtlasRelationshipType;
 import org.apache.atlas.type.AtlasStructType;
 import org.apache.atlas.type.AtlasStructType.AtlasAttribute;
@@ -586,6 +587,8 @@ public class EntityGraphRetriever {
 
             mapSystemAttributes(entityVertex, entity);
 
+            mapNamespaceAttributes(entityVertex, entity);
+
             mapAttributes(entityVertex, entity, entityExtInfo, isMinExtInfo, 
includeReferences);
 
             if (!ignoreRelationshipAttr) { // only map when really needed
@@ -761,6 +764,26 @@ public class EntityGraphRetriever {
         }
     }
 
+    private void mapNamespaceAttributes(AtlasVertex entityVertex, AtlasEntity 
entity) throws AtlasBaseException {
+        AtlasEntityType                            entityType           = 
typeRegistry.getEntityTypeByName(entity.getTypeName());
+        Map<String, List<AtlasNamespaceAttribute>> entityTypeNamespaces = 
entityType != null ? entityType.getNamespaceAttributes() : null;
+
+        if (MapUtils.isNotEmpty(entityTypeNamespaces)) {
+            for (Map.Entry<String, List<AtlasNamespaceAttribute>> entry : 
entityTypeNamespaces.entrySet()) {
+                String                        nsName       = entry.getKey();
+                List<AtlasNamespaceAttribute> nsAttributes = entry.getValue();
+
+                for (AtlasNamespaceAttribute nsAttribute : nsAttributes) {
+                    Object nsAttrValue = mapVertexToAttribute(entityVertex, 
nsAttribute, null, false, false);
+
+                    if (nsAttrValue != null) {
+                        entity.setNamespaceAttribute(nsName, 
nsAttribute.getName(), nsAttrValue);
+                    }
+                }
+            }
+        }
+    }
+
     public List<AtlasClassification> getAllClassifications(AtlasVertex 
entityVertex) throws AtlasBaseException {
         List<AtlasClassification> ret   = new ArrayList<>();
         Iterable                  edges = 
entityVertex.query().direction(AtlasEdgeDirection.OUT).label(CLASSIFICATION_LABEL).edges();
diff --git a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java 
b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
index 6845121..fcf7189 100644
--- a/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
+++ b/webapp/src/main/java/org/apache/atlas/web/rest/EntityREST.java
@@ -64,6 +64,7 @@ import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -855,6 +856,78 @@ public class EntityREST {
         }
     }
 
+    @POST
+    @Path("/guid/{guid}/namespaces")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    public void addOrUpdateNamespaceAttributes(@PathParam("guid") final String 
guid, @QueryParam("isOverwrite") @DefaultValue("false") boolean isOverwrite, 
Map<String, Map<String, Object>> entityNamespaces) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"EntityREST.addOrUpdateNamespaceAttributes(" + guid + ", isOverwrite=" + 
isOverwrite + ")");
+            }
+
+            entitiesStore.addOrUpdateNamespaceAttributes(guid, 
entityNamespaces, isOverwrite);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    @DELETE
+    @Path("/guid/{guid}/namespaces")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    public void removeNamespaceAttributes(@PathParam("guid") final String 
guid, Map<String, Map<String, Object>> entityNamespaces) throws 
AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"EntityREST.removeNamespaceAttributes(" + guid + ")");
+            }
+
+            entitiesStore.removeNamespaceAttributes(guid, entityNamespaces);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    @POST
+    @Path("/guid/{guid}/namespace/{namespace}")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    public void addOrUpdateNamespaceAttributes(@PathParam("guid") final String 
guid, @PathParam("namespace") final String namespace, Map<String, Object> 
entityNsAttributes) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"EntityREST.addOrUpdateNamespaceAttributes(" + guid + ", " + namespace + ")");
+            }
+
+            entitiesStore.addOrUpdateNamespaceAttributes(guid, 
Collections.singletonMap(namespace, entityNsAttributes), false);
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
+    @DELETE
+    @Path("/guid/{guid}/namespace/{namespace}")
+    @Produces(Servlets.JSON_MEDIA_TYPE)
+    @Consumes(Servlets.JSON_MEDIA_TYPE)
+    public void removeNamespaceAttributes(@PathParam("guid") final String 
guid, @PathParam("namespace") final String namespace, Map<String, Object> 
entityNsAttributes) throws AtlasBaseException {
+        AtlasPerfTracer perf = null;
+
+        try {
+            if (AtlasPerfTracer.isPerfTraceEnabled(PERF_LOG)) {
+                perf = AtlasPerfTracer.getPerfTracer(PERF_LOG, 
"EntityREST.removeNamespaceAttributes(" + guid + ", " + namespace + ")");
+            }
+
+            entitiesStore.removeNamespaceAttributes(guid, 
Collections.singletonMap(namespace, entityNsAttributes));
+        } finally {
+            AtlasPerfTracer.log(perf);
+        }
+    }
+
     /**
      * Set labels to a given entity
      * @param guid - Unique entity identifier

Reply via email to