ATLAS-2679: Update qualifiedName category hierarchy corresponding to any change 
to category

Change-Id: I4cddcfe76eabcf7ee705b60848521158bb33a8a5
(cherry picked from commit 66f8ae16045b79d8839ee2088fc5cc64ffa2fa5d)


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

Branch: refs/heads/branch-1.0
Commit: 65e3a1147d0babc73361be518bf282713e13f2f7
Parents: 562550c
Author: apoorvnaik <[email protected]>
Authored: Thu May 10 16:09:12 2018 -0700
Committer: Madhan Neethiraj <[email protected]>
Committed: Tue May 15 22:10:26 2018 -0700

----------------------------------------------------------------------
 .../java/org/apache/atlas/AtlasErrorCode.java   |   3 +-
 .../atlas/model/glossary/AtlasGlossary.java     |   7 +-
 .../model/glossary/AtlasGlossaryBaseObject.java |  14 +-
 .../model/glossary/AtlasGlossaryCategory.java   |   6 -
 .../atlas/model/glossary/AtlasGlossaryTerm.java |   2 -
 .../atlas/glossary/GlossaryCategoryUtils.java   | 293 +++++++++++++------
 .../apache/atlas/glossary/GlossaryService.java  | 184 ++++++------
 .../atlas/glossary/GlossaryTermUtils.java       | 108 ++++---
 .../apache/atlas/glossary/GlossaryUtils.java    |  23 ++
 .../atlas/glossary/GlossaryServiceTest.java     | 129 +++++++-
 .../org/apache/atlas/web/rest/GlossaryREST.java |   2 +-
 11 files changed, 522 insertions(+), 249 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
----------------------------------------------------------------------
diff --git a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java 
b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
index 7cf3fd1..3a60978 100644
--- a/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
+++ b/intg/src/main/java/org/apache/atlas/AtlasErrorCode.java
@@ -26,6 +26,7 @@ import java.util.Arrays;
 
 public enum AtlasErrorCode {
     NO_SEARCH_RESULTS(204, "ATLAS-204-00-001", "Given search filter {0} did 
not yield any results"),
+    DATA_ACCESS_SAVE_FAILED(204, "ATLAS-204-00-002", "Save failed: {0} has no 
updates"),
 
     UNKNOWN_TYPE(400, "ATLAS-400-00-001", "Unknown type {0} for {1}.{2}"),
     CIRCULAR_REFERENCE(400, "ATLAS-400-00-002", "{0}: invalid supertypes - 
circular reference back to self {1}"),
@@ -144,6 +145,7 @@ public enum AtlasErrorCode {
     INVALID_CHILD_CATEGORY_DIFFERENT_GLOSSARY(400, "ATLAS-400-00-07F", 
"Invalid child category relationship: Child category (guid = {0}) belongs to 
different glossary"),
     INVALID_TERM_DISSOCIATION(400, "ATLAS-400-00-080", "Given term (guid={0}) 
is not associated to entity(guid={1})"),
     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 
displayName is empty/null"),
 
     UNAUTHORIZED_ACCESS(403, "ATLAS-403-00-001", "{0} is not authorized to 
perform {1}"),
 
@@ -196,7 +198,6 @@ public enum AtlasErrorCode {
     SQOOP_HOOK(500, "ATLAS-500-00-00F", "SqoopHook: {0}"),
     HIVE_HOOK(500, "ATLAS-500-00-010", "HiveHook: {0}"),
     HIVE_HOOK_METASTORE_BRIDGE(500, "ATLAS-500-00-011", 
"HiveHookMetaStoreBridge: {0}"),
-    DATA_ACCESS_SAVE_FAILED(500, "ATLAS-500-00-012", "Save failed: {0}"),
     DATA_ACCESS_LOAD_FAILED(500, "ATLAS-500-00-013", "Load failed: {0}"),
     ENTITY_NOTIFICATION_FAILED(500, "ATLAS-500-00-014", "Notification failed 
for operation: {0} : {1}");
 

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
index b99817c..ccd0b90 100644
--- a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossary.java
@@ -146,12 +146,10 @@ public class AtlasGlossary extends 
AtlasGlossaryBaseObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
-        sb.append("language='").append(language).append('\'');
+        sb.append(", language='").append(language).append('\'');
         sb.append(", usage='").append(usage).append('\'');
         sb.append(", terms=").append(terms);
         sb.append(", categories=").append(categories);
-        sb.append('}');
 
         return sb;
     }
@@ -234,11 +232,8 @@ public class AtlasGlossary extends AtlasGlossaryBaseObject 
{
 
         @Override
         public StringBuilder toString(StringBuilder sb) {
-            sb.append("{");
-            super.toString(sb);
             sb.append(", termInfo=").append(termInfo);
             sb.append(", categoryInfo=").append(categoryInfo);
-            sb.append('}');
 
             return sb;
         }

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
index 556362f..959d347 100644
--- 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
+++ 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryBaseObject.java
@@ -29,13 +29,13 @@ import java.util.Objects;
 public abstract class AtlasGlossaryBaseObject extends AtlasBaseModelObject {
 
     // Core attributes
-    protected      String     displayName;
-    protected      String     shortDescription;
-    protected      String     longDescription;
+    private   String qualifiedName;
+    protected String displayName;
+    protected String shortDescription;
+    protected String longDescription;
 
     // Classifications
     protected List<AtlasClassification> classifications;
-    private   String                    qualifiedName;
 
     public AtlasGlossaryBaseObject() {
     }
@@ -129,13 +129,11 @@ public abstract class AtlasGlossaryBaseObject extends 
AtlasBaseModelObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
-        sb.append("displayName='").append(displayName).append('\'');
+        sb.append(", qualifiedName='").append(qualifiedName).append('\'');
+        sb.append(", displayName='").append(displayName).append('\'');
         sb.append(", 
shortDescription='").append(shortDescription).append('\'');
         sb.append(", longDescription='").append(longDescription).append('\'');
         sb.append(", classifications=").append(classifications);
-        sb.append(", qualifiedName='").append(qualifiedName).append('\'');
-        sb.append('}');
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
index 043eaa5..9fcca5d 100644
--- 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
+++ 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryCategory.java
@@ -138,16 +138,10 @@ public class AtlasGlossaryCategory extends 
AtlasGlossaryBaseObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
-        sb.append("displayName='").append(getDisplayName()).append('\'');
-        sb.append(", 
shortDescription='").append(getShortDescription()).append('\'');
-        sb.append(", 
longDescription='").append(getLongDescription()).append('\'');
         sb.append(", anchor=").append(anchor);
         sb.append(", parentCategory=").append(parentCategory);
         sb.append(", childrenCategories=").append(childrenCategories);
         sb.append(", terms=").append(terms);
-        sb.append(", classifications=").append(getClassifications());
-        sb.append('}');
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
----------------------------------------------------------------------
diff --git 
a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java 
b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
index 7b4543b..daf6c7b 100644
--- a/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
+++ b/intg/src/main/java/org/apache/atlas/model/glossary/AtlasGlossaryTerm.java
@@ -376,7 +376,6 @@ public class AtlasGlossaryTerm extends 
AtlasGlossaryBaseObject {
 
     @Override
     protected StringBuilder toString(final StringBuilder sb) {
-        sb.append("{");
         sb.append("examples=").append(examples);
         sb.append(", abbreviation='").append(abbreviation).append('\'');
         sb.append(", usage='").append(usage).append('\'');
@@ -396,7 +395,6 @@ public class AtlasGlossaryTerm extends 
AtlasGlossaryBaseObject {
         sb.append(", classifies=").append(classifies);
         sb.append(", validValues=").append(validValues);
         sb.append(", validValuesFor=").append(validValuesFor);
-        sb.append('}');
 
         return sb;
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java 
b/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
index e1b30c4..42cdef8 100644
--- 
a/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
+++ 
b/repository/src/main/java/org/apache/atlas/glossary/GlossaryCategoryUtils.java
@@ -19,7 +19,9 @@ package org.apache.atlas.glossary;
 
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.glossary.AtlasGlossary;
 import org.apache.atlas.model.glossary.AtlasGlossaryCategory;
+import org.apache.atlas.model.glossary.relations.AtlasGlossaryHeader;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedCategoryHeader;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
 import org.apache.atlas.model.instance.AtlasObjectId;
@@ -51,68 +53,103 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         super(relationshipStore, typeRegistry, dataAccess);
     }
 
-    public void processCategoryRelations(AtlasGlossaryCategory 
updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) 
throws AtlasBaseException {
+    public Map<String, AtlasGlossaryCategory> 
processCategoryRelations(AtlasGlossaryCategory storeObject, 
AtlasGlossaryCategory updatedCategory, RelationshipOperation op) throws 
AtlasBaseException {
         if (DEBUG_ENABLED) {
-            LOG.debug("==> GlossaryCategoryUtils.processCategoryRelations({}, 
{}, {})", updatedCategory, existing, op);
+            LOG.debug("==> GlossaryCategoryUtils.processCategoryRelations({}, 
{}, {})", storeObject, updatedCategory, op);
         }
-        processCategoryAnchor(updatedCategory, existing, op);
-        processParentCategory(updatedCategory, existing, op);
-        processCategoryChildren(updatedCategory, existing, op);
-        processAssociatedTerms(updatedCategory, existing, op);
+        Map<String, AtlasGlossaryCategory> impactedCategories = new 
HashMap<>();
+
+        processCategoryAnchor(storeObject, updatedCategory, op, 
impactedCategories);
+        processParentCategory(storeObject, updatedCategory, op, 
impactedCategories);
+        processCategoryChildren(storeObject, updatedCategory, op, 
impactedCategories);
+        processAssociatedTerms(storeObject, updatedCategory, op);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryCategoryUtils.processCategoryRelations()");
+            LOG.debug("<== GlossaryCategoryUtils.processCategoryRelations(): 
{}", impactedCategories);
         }
+
+        return impactedCategories;
     }
 
-    private void processCategoryAnchor(AtlasGlossaryCategory updatedCategory, 
AtlasGlossaryCategory existing, RelationshipOperation op) throws 
AtlasBaseException {
+    private void processCategoryAnchor(AtlasGlossaryCategory storeObject, 
AtlasGlossaryCategory updatedCategory,
+                                       RelationshipOperation op, Map<String, 
AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
         if (Objects.isNull(updatedCategory.getAnchor()) && op != 
RelationshipOperation.DELETE) {
             throw new 
AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
         }
 
+        AtlasGlossaryHeader existingAnchor        = storeObject.getAnchor();
+        AtlasGlossaryHeader updatedCategoryAnchor = 
updatedCategory.getAnchor();
+
         switch (op) {
             case CREATE:
-                if (DEBUG_ENABLED) {
-                    LOG.debug("Creating new category anchor, category = {}, 
glossary = {}", existing.getGuid(), 
updatedCategory.getAnchor().getDisplayText());
+                if 
(StringUtils.isEmpty(updatedCategoryAnchor.getGlossaryGuid())) {
+                    throw new 
AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
+                } else {
+                    if (DEBUG_ENABLED) {
+                        LOG.debug("Creating new category anchor, category = 
{}, glossary = {}", storeObject.getGuid(), 
updatedCategory.getAnchor().getGlossaryGuid());
+                    }
+
+                    // Derive the qualifiedName
+                    String anchorGlossaryGuid = 
updatedCategory.getAnchor().getGlossaryGuid();
+                    AtlasGlossary glossary = 
dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName()+ 
"@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", 
storeObject.getQualifiedName());
+                    }
+
+                    
createRelationship(defineCategoryAnchorRelation(anchorGlossaryGuid, 
storeObject.getGuid()));
                 }
-                String anchorGlossaryGuid = 
updatedCategory.getAnchor().getGlossaryGuid();
-                
createRelationship(defineCategoryAnchorRelation(anchorGlossaryGuid, 
existing.getGuid()));
                 break;
             case UPDATE:
-                if (!Objects.equals(updatedCategory.getAnchor(), 
existing.getAnchor())) {
+                if (!Objects.equals(existingAnchor, updatedCategoryAnchor)) {
                     if 
(Objects.isNull(updatedCategory.getAnchor().getGlossaryGuid())) {
                         throw new 
AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
                     }
 
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Updating category anchor, category = {}, 
currAnchor = {}, newAnchor = {}", existing.getGuid(),
-                                  existing.getAnchor().getDisplayText(), 
updatedCategory.getAnchor().getDisplayText());
+                        LOG.debug("Updating category anchor, currAnchor = {}, 
newAnchor = {} and category = {}",
+                                  storeObject.getAnchor().getGlossaryGuid(),
+                                  
updatedCategory.getAnchor().getGlossaryGuid(),
+                                  storeObject.getGuid());
+                    }
+                    
relationshipStore.deleteById(storeObject.getAnchor().getRelationGuid());
+
+                    // Derive the qualifiedName when anchor changes
+                    String        anchorGlossaryGuid = 
updatedCategory.getAnchor().getGlossaryGuid();
+                    AtlasGlossary glossary           = 
dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName()+ 
"@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", 
storeObject.getQualifiedName());
                     }
-                    
relationshipStore.deleteById(existing.getAnchor().getRelationGuid());
-                    
createRelationship(defineCategoryAnchorRelation(updatedCategory.getAnchor().getGlossaryGuid(),
 existing.getGuid()));
+
+                    
createRelationship(defineCategoryAnchorRelation(updatedCategory.getAnchor().getGlossaryGuid(),
 storeObject.getGuid()));
+
+                    // Anchor changed, qualifiedName of children needs an 
update
+                    updateChildCategories(storeObject, 
storeObject.getChildrenCategories(), impactedCategories, false);
                 }
                 break;
             case DELETE:
-                if (Objects.nonNull(existing.getAnchor())) {
+                if (Objects.nonNull(storeObject.getAnchor())) {
                     if (DEBUG_ENABLED) {
                         LOG.debug("Deleting category anchor");
                     }
-                    
relationshipStore.deleteById(existing.getAnchor().getRelationGuid());
+                    
relationshipStore.deleteById(storeObject.getAnchor().getRelationGuid());
                 }
                 break;
         }
     }
 
-    private void processParentCategory(AtlasGlossaryCategory updatedCategory, 
AtlasGlossaryCategory existing, RelationshipOperation op) throws 
AtlasBaseException {
+    private void processParentCategory(AtlasGlossaryCategory storeObject, 
AtlasGlossaryCategory updatedCategory,
+                                       RelationshipOperation op, Map<String, 
AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
         AtlasRelatedCategoryHeader newParent      = 
updatedCategory.getParentCategory();
-        AtlasRelatedCategoryHeader existingParent = 
existing.getParentCategory();
+        AtlasRelatedCategoryHeader existingParent = 
storeObject.getParentCategory();
+
         switch (op) {
             case CREATE:
                 if (Objects.nonNull(newParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new parent, category = {}, parent 
= {}", existing.getGuid(), newParent.getDisplayText());
-                    }
-                    createRelationship(defineCategoryHierarchyLink(newParent, 
existing.getGuid()));
+                    processNewParent(storeObject, newParent, 
impactedCategories);
                 }
                 break;
             case UPDATE:
@@ -124,18 +161,12 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                 }
 
                 if (Objects.isNull(existingParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new parent, category = {}, parent 
= {}", existing.getGuid(), newParent.getDisplayText());
-                    }
-                    createRelationship(defineCategoryHierarchyLink(newParent, 
existing.getGuid()));
+                    processNewParent(storeObject, newParent, 
impactedCategories);
                 } else if (Objects.isNull(newParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Removing category parent, category = {}, 
parent = {}", existing.getGuid(), existingParent.getDisplayText());
-                    }
-                    
relationshipStore.deleteById(existingParent.getRelationGuid());
+                    processParentRemoval(storeObject, updatedCategory, 
existingParent, impactedCategories);
                 } else {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Updating category parent, category = {}, 
currParent = {}, newParent = {}", existing.getGuid(), 
existingParent.getDisplayText(), newParent.getDisplayText());
+                        LOG.debug("Updating category parent, category = {}, 
currParent = {}, newParent = {}", storeObject.getGuid(), 
existingParent.getDisplayText(), newParent.getDisplayText());
                     }
                     AtlasRelationship parentRelationship = 
relationshipStore.getById(existingParent.getRelationGuid());
                     if 
(existingParent.getCategoryGuid().equals(newParent.getCategoryGuid())) {
@@ -144,48 +175,83 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                     } else {
                         // Delete link to existing parent and link to new 
parent
                         
relationshipStore.deleteById(parentRelationship.getGuid());
-                        
createRelationship(defineCategoryHierarchyLink(newParent, existing.getGuid()));
+                        
createRelationship(defineCategoryHierarchyLink(newParent, 
storeObject.getGuid()));
                     }
                 }
                 break;
             case DELETE:
                 if (Objects.nonNull(existingParent)) {
-                    if (DEBUG_ENABLED) {
-                        LOG.debug("Removing category parent, category = {}, 
parent = {}", existing.getGuid(), existingParent.getDisplayText());
-                    }
-                    
relationshipStore.deleteById(existingParent.getRelationGuid());
+                    processParentRemoval(storeObject, updatedCategory, 
existingParent, impactedCategories);
                 }
                 break;
         }
     }
 
-    private void processAssociatedTerms(AtlasGlossaryCategory updatedCategory, 
AtlasGlossaryCategory existing, RelationshipOperation op) throws 
AtlasBaseException {
+    private void processNewParent(AtlasGlossaryCategory storeObject, 
AtlasRelatedCategoryHeader newParent, Map<String, AtlasGlossaryCategory> 
impactedCategories) throws AtlasBaseException {
+        if (DEBUG_ENABLED) {
+            LOG.debug("Creating new parent, category = {}, parent = {}", 
storeObject.getGuid(), newParent.getDisplayText());
+        }
+        createRelationship(defineCategoryHierarchyLink(newParent, 
storeObject.getGuid()));
+
+        // New parent added, qualifiedName needs recomputation
+        // Derive the qualifiedName of the Glossary
+        AtlasGlossaryCategory parentCategory = 
dataAccess.load(getAtlasGlossaryCategorySkeleton(newParent.getCategoryGuid()));
+        storeObject.setQualifiedName(storeObject.getDisplayName() + "." + 
parentCategory.getQualifiedName());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Derived qualifiedName = {}", 
storeObject.getQualifiedName());
+        }
+
+        updateChildCategories(storeObject, 
storeObject.getChildrenCategories(), impactedCategories, false);
+    }
+
+    private void processParentRemoval(AtlasGlossaryCategory storeObject, 
AtlasGlossaryCategory updatedCategory, AtlasRelatedCategoryHeader 
existingParent, Map<String, AtlasGlossaryCategory> impactedCategories) throws 
AtlasBaseException {
+        if (DEBUG_ENABLED) {
+            LOG.debug("Removing category parent, category = {}, parent = {}", 
storeObject.getGuid(), existingParent.getDisplayText());
+        }
+        relationshipStore.deleteById(existingParent.getRelationGuid());
+
+        // Parent deleted, qualifiedName needs recomputation
+
+        // Derive the qualifiedName of the Glossary
+        String        anchorGlossaryGuid = 
updatedCategory.getAnchor().getGlossaryGuid();
+        AtlasGlossary glossary           = 
dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+        storeObject.setQualifiedName(storeObject.getDisplayName() + "@" + 
glossary.getQualifiedName());
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Derived qualifiedName = {}", 
storeObject.getQualifiedName());
+        }
+
+        updateChildCategories(storeObject, 
storeObject.getChildrenCategories(), impactedCategories, false);
+    }
+
+    private void processAssociatedTerms(AtlasGlossaryCategory storeObject, 
AtlasGlossaryCategory updatedCategory, RelationshipOperation op) throws 
AtlasBaseException {
         Map<String, AtlasRelatedTermHeader> newTerms      = 
getTerms(updatedCategory);
-        Map<String, AtlasRelatedTermHeader> existingTerms = getTerms(existing);
+        Map<String, AtlasRelatedTermHeader> existingTerms = 
getTerms(storeObject);
 
         switch (op) {
             case CREATE:
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating term relation with category = {}, 
terms = {}", existing.getDisplayName(),
+                    LOG.debug("Creating term relation with category = {}, 
terms = {}", storeObject.getDisplayName(),
                               Objects.nonNull(newTerms) ? newTerms.size() : 
"none");
                 }
-                createTermCategorizationRelationships(existing, 
newTerms.values());
+                createTermCategorizationRelationships(storeObject, 
newTerms.values());
                 break;
             case UPDATE:
                 if (MapUtils.isEmpty(existingTerms)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating term relation with category = {}, 
terms = {}", existing.getDisplayName(),
+                        LOG.debug("Creating term relation with category = {}, 
terms = {}", storeObject.getDisplayName(),
                                   Objects.nonNull(newTerms) ? newTerms.size() 
: "none");
                     }
-                    createTermCategorizationRelationships(existing, 
newTerms.values());
+                    createTermCategorizationRelationships(storeObject, 
newTerms.values());
                     break;
                 }
 
                 if (MapUtils.isEmpty(newTerms)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Deleting term relation with category = {}, 
terms = {}", existing.getDisplayName(), existingTerms.size());
+                        LOG.debug("Deleting term relation with category = {}, 
terms = {}", storeObject.getDisplayName(), existingTerms.size());
                     }
-                    deleteTermCategorizationRelationships(existing, 
existingTerms.values());
+                    deleteTermCategorizationRelationships(storeObject, 
existingTerms.values());
                     break;
                 }
 
@@ -194,24 +260,24 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                                                                .stream()
                                                                .filter(t -> 
!existingTerms.containsKey(t.getTermGuid()))
                                                                
.collect(Collectors.toSet());
-                createTermCategorizationRelationships(existing, toCreate);
+                createTermCategorizationRelationships(storeObject, toCreate);
 
                 Set<AtlasRelatedTermHeader> toUpdate = newTerms
                                                                .values()
                                                                .stream()
                                                                .filter(t -> 
updatedExistingTermRelation(existingTerms, t))
                                                                
.collect(Collectors.toSet());
-                updateTermCategorizationRelationships(existing, toUpdate);
+                updateTermCategorizationRelationships(storeObject, toUpdate);
 
                 Set<AtlasRelatedTermHeader> toDelete = existingTerms
                                                                .values()
                                                                .stream()
                                                                .filter(t -> 
!newTerms.containsKey(t.getTermGuid()))
                                                                
.collect(Collectors.toSet());
-                deleteTermCategorizationRelationships(existing, toDelete);
+                deleteTermCategorizationRelationships(storeObject, toDelete);
                 break;
             case DELETE:
-                deleteTermCategorizationRelationships(existing, 
existingTerms.values());
+                deleteTermCategorizationRelationships(storeObject, 
existingTerms.values());
                 break;
         }
     }
@@ -220,7 +286,7 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         return Objects.nonNull(term.getRelationGuid()) && 
!existingTerms.get(term.getTermGuid()).equals(term);
     }
 
-    private Map<String, AtlasRelatedTermHeader> getTerms(final 
AtlasGlossaryCategory category) {
+    private Map<String, AtlasRelatedTermHeader> getTerms(AtlasGlossaryCategory 
category) {
         if (Objects.nonNull(category.getTerms())) {
             Map<String, AtlasRelatedTermHeader> map = new HashMap<>();
             for (AtlasRelatedTermHeader t : category.getTerms()) {
@@ -236,9 +302,9 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         else return Collections.emptyMap();
     }
 
-    private void createTermCategorizationRelationships(AtlasGlossaryCategory 
existing, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void createTermCategorizationRelationships(AtlasGlossaryCategory 
storeObject, Collection<AtlasRelatedTermHeader> terms) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
-            Set<AtlasRelatedTermHeader> existingTerms = existing.getTerms();
+            Set<AtlasRelatedTermHeader> existingTerms = storeObject.getTerms();
             for (AtlasRelatedTermHeader term : terms) {
                 if (Objects.isNull(term.getTermGuid())) {
                     throw new 
AtlasBaseException(AtlasErrorCode.MISSING_TERM_ID_FOR_CATEGORIZATION);
@@ -250,19 +316,19 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                         continue;
                     }
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating relation between category = {} and 
term = {}", existing.getGuid(), term.getDisplayText());
+                        LOG.debug("Creating relation between category = {} and 
term = {}", storeObject.getGuid(), term.getDisplayText());
                     }
-                    
createRelationship(defineCategorizedTerm(existing.getGuid(), term));
+                    
createRelationship(defineCategorizedTerm(storeObject.getGuid(), term));
                 }
             }
         }
     }
 
-    private void updateTermCategorizationRelationships(AtlasGlossaryCategory 
existing, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void updateTermCategorizationRelationships(AtlasGlossaryCategory 
storeObject, Collection<AtlasRelatedTermHeader> terms) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             for (AtlasRelatedTermHeader term : terms) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Updating term relation with category = {}, term 
= {}", existing.getDisplayName(), term.getDisplayText());
+                    LOG.debug("Updating term relation with category = {}, term 
= {}", storeObject.getDisplayName(), term.getDisplayText());
                 }
                 AtlasRelationship relationship = 
relationshipStore.getById(term.getRelationGuid());
                 updateRelationshipAttributes(relationship, term);
@@ -271,44 +337,53 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
-    private void deleteTermCategorizationRelationships(AtlasGlossaryCategory 
existing, Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void deleteTermCategorizationRelationships(AtlasGlossaryCategory 
storeObject, Collection<AtlasRelatedTermHeader> terms) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             for (AtlasRelatedTermHeader term : terms) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating term relation with category = {}, 
terms = {}", existing.getDisplayName(), term.getDisplayText());
+                    LOG.debug("Creating term relation with category = {}, 
terms = {}", storeObject.getDisplayName(), term.getDisplayText());
                 }
                 relationshipStore.deleteById(term.getRelationGuid());
             }
         }
     }
 
-    private void processCategoryChildren(AtlasGlossaryCategory 
updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) 
throws AtlasBaseException {
+    private void processCategoryChildren(AtlasGlossaryCategory storeObject, 
AtlasGlossaryCategory updatedCategory, RelationshipOperation op, Map<String, 
AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
         Map<String, AtlasRelatedCategoryHeader> newChildren      = 
getChildren(updatedCategory);
-        Map<String, AtlasRelatedCategoryHeader> existingChildren = 
getChildren(existing);
+        Map<String, AtlasRelatedCategoryHeader> existingChildren = 
getChildren(storeObject);
         switch (op) {
             case CREATE:
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating new children, category = {}, children 
= {}", existing.getDisplayName(),
+                    LOG.debug("Creating new children, category = {}, children 
= {}", storeObject.getDisplayName(),
                               Objects.nonNull(newChildren) ? 
newChildren.size() : "none");
                 }
-                createCategoryRelationships(existing, newChildren.values());
+                createCategoryRelationships(storeObject, newChildren.values());
+
+                // New children added, qualifiedName needs recomputation
+                updateChildCategories(storeObject, newChildren.values(), 
impactedCategories, false);
                 break;
             case UPDATE:
                 // Create new children
                 if (MapUtils.isEmpty(existingChildren)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new children, category = {}, 
children = {}", existing.getDisplayName(),
+                        LOG.debug("Creating new children, category = {}, 
children = {}", storeObject.getDisplayName(),
                                   Objects.nonNull(newChildren) ? 
newChildren.size() : "none");
                     }
-                    createCategoryRelationships(existing, 
newChildren.values());
+                    createCategoryRelationships(storeObject, 
newChildren.values());
+
+                    // New children added, qualifiedName needs recomputation
+                    updateChildCategories(storeObject, newChildren.values(), 
impactedCategories, false);
                     break;
                 }
                 // Delete current children
                 if (MapUtils.isEmpty(newChildren)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Deleting children, category = {}, children 
= {}", existing.getDisplayName(), existingChildren.size());
+                        LOG.debug("Deleting children, category = {}, children 
= {}", storeObject.getDisplayName(), existingChildren.size());
                     }
-                    deleteCategoryRelationships(existing, 
existingChildren.values());
+                    deleteCategoryRelationships(storeObject, 
existingChildren.values());
+
+                    // Re-compute the qualifiedName for all children
+                    updateChildCategories(storeObject, 
existingChildren.values(), impactedCategories, true);
                     break;
                 }
 
@@ -317,24 +392,26 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                                                                    .stream()
                                                                    .filter(c 
-> !existingChildren.containsKey(c.getCategoryGuid()))
                                                                    
.collect(Collectors.toSet());
-                createCategoryRelationships(existing, toCreate);
+                createCategoryRelationships(storeObject, toCreate);
+                // New children added, qualifiedName needs recomputation
+                updateChildCategories(storeObject, toCreate, 
impactedCategories, false);
 
                 Set<AtlasRelatedCategoryHeader> toUpdate = newChildren
                                                                    .values()
                                                                    .stream()
                                                                    .filter(c 
-> updatedExistingCategoryRelation(existingChildren, c))
                                                                    
.collect(Collectors.toSet());
-                updateCategoryRelationships(existing, toUpdate);
+                updateCategoryRelationships(storeObject, toUpdate);
 
                 Set<AtlasRelatedCategoryHeader> toDelete = existingChildren
                                                                    .values()
                                                                    .stream()
                                                                    .filter(c 
-> !newChildren.containsKey(c.getCategoryGuid()))
                                                                    
.collect(Collectors.toSet());
-                deleteCategoryRelationships(existing, toDelete);
+                deleteCategoryRelationships(storeObject, toDelete);
                 break;
             case DELETE:
-                deleteCategoryRelationships(existing, 
existingChildren.values());
+                deleteCategoryRelationships(storeObject, 
existingChildren.values());
                 break;
         }
     }
@@ -343,7 +420,7 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         return Objects.nonNull(header.getRelationGuid()) && 
!header.equals(existingChildren.get(header.getCategoryGuid()));
     }
 
-    private Map<String, AtlasRelatedCategoryHeader> getChildren(final 
AtlasGlossaryCategory category) {
+    private Map<String, AtlasRelatedCategoryHeader> 
getChildren(AtlasGlossaryCategory category) {
         if (Objects.nonNull(category.getChildrenCategories())) {
             Map<String, AtlasRelatedCategoryHeader> map = new HashMap<>();
             for (AtlasRelatedCategoryHeader c : 
category.getChildrenCategories()) {
@@ -357,9 +434,9 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         else return Collections.emptyMap();
     }
 
-    private void createCategoryRelationships(AtlasGlossaryCategory existing, 
Collection<AtlasRelatedCategoryHeader> newChildren) throws AtlasBaseException {
+    private void createCategoryRelationships(AtlasGlossaryCategory 
storeObject, Collection<AtlasRelatedCategoryHeader> newChildren) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(newChildren)) {
-            Set<AtlasRelatedCategoryHeader> existingChildren = 
existing.getChildrenCategories();
+            Set<AtlasRelatedCategoryHeader> existingChildren = 
storeObject.getChildrenCategories();
             for (AtlasRelatedCategoryHeader child : newChildren) {
                 if (Objects.nonNull(existingChildren) && 
existingChildren.contains(child)) {
                     if (DEBUG_ENABLED) {
@@ -376,11 +453,11 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
                 childCategory.setGuid(child.getCategoryGuid());
                 childCategory = dataAccess.load(childCategory);
 
-                if (StringUtils.equals(existing.getAnchor().getGlossaryGuid(), 
childCategory.getAnchor().getGlossaryGuid())) {
+                if 
(StringUtils.equals(storeObject.getAnchor().getGlossaryGuid(), 
childCategory.getAnchor().getGlossaryGuid())) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new child, category = {}, child = 
{}", existing.getDisplayName(), child.getDisplayText());
+                        LOG.debug("Creating new child, category = {}, child = 
{}", storeObject.getDisplayName(), child.getDisplayText());
                     }
-                    
createRelationship(defineCategoryHierarchyLink(existing.getGuid(), child));
+                    
createRelationship(defineCategoryHierarchyLink(storeObject.getGuid(), child));
                 } else {
                     throw new 
AtlasBaseException(AtlasErrorCode.INVALID_CHILD_CATEGORY_DIFFERENT_GLOSSARY, 
child.getCategoryGuid());
                 }
@@ -389,11 +466,11 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
-    private void updateCategoryRelationships(AtlasGlossaryCategory existing, 
Collection<AtlasRelatedCategoryHeader> toUpdate) throws AtlasBaseException {
+    private void updateCategoryRelationships(AtlasGlossaryCategory 
storeObject, Collection<AtlasRelatedCategoryHeader> toUpdate) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(toUpdate)) {
             for (AtlasRelatedCategoryHeader categoryHeader : toUpdate) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Updating child, category = {}, child = {}", 
existing.getDisplayName(), categoryHeader.getDisplayText());
+                    LOG.debug("Updating child, category = {}, child = {}", 
storeObject.getDisplayName(), categoryHeader.getDisplayText());
                 }
                 AtlasRelationship childRelationship = 
relationshipStore.getById(categoryHeader.getRelationGuid());
                 updateRelationshipAttributes(childRelationship, 
categoryHeader);
@@ -402,11 +479,11 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
-    private void deleteCategoryRelationships(AtlasGlossaryCategory existing, 
Collection<AtlasRelatedCategoryHeader> existingChildren) throws 
AtlasBaseException {
+    private void deleteCategoryRelationships(AtlasGlossaryCategory 
storeObject, Collection<AtlasRelatedCategoryHeader> existingChildren) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(existingChildren)) {
             for (AtlasRelatedCategoryHeader child : existingChildren) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Deleting child, category = {}, child = {}", 
existing.getDisplayName(), child.getDisplayText());
+                    LOG.debug("Deleting child, category = {}, child = {}", 
storeObject.getDisplayName(), child.getDisplayText());
                 }
                 relationshipStore.deleteById(child.getRelationGuid());
             }
@@ -453,4 +530,56 @@ public class GlossaryCategoryUtils extends GlossaryUtils {
         }
     }
 
+    private void updateChildCategories(AtlasGlossaryCategory parentCategory, 
Collection<AtlasRelatedCategoryHeader> childCategories, Map<String, 
AtlasGlossaryCategory> impactedCategories, boolean isParentRemoved) throws 
AtlasBaseException {
+        if (CollectionUtils.isEmpty(childCategories)) {
+            return;
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Recomputing qualifiedName for {} children of 
category(guid={}, qualifiedName={})", childCategories.size(), 
parentCategory.getGuid(), parentCategory.getQualifiedName());
+        }
+
+        String parentAnchorGuid = parentCategory.getAnchor().getGlossaryGuid();
+
+        for (AtlasRelatedCategoryHeader childCategoryHeader : childCategories) 
{
+            AtlasGlossaryCategory child           = 
dataAccess.load(getAtlasGlossaryCategorySkeleton(childCategoryHeader.getCategoryGuid()));
+            String                qualifiedName   = child.getDisplayName() + 
".";
+            String                childAnchorGuid = 
child.getAnchor().getGlossaryGuid();
+            if (isParentRemoved) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Parent removed, deriving qualifiedName using 
Glossary");
+                }
+                AtlasGlossary glossary = 
dataAccess.load(getGlossarySkeleton(childAnchorGuid));
+                qualifiedName += glossary.getQualifiedName();
+                child.setParentCategory(null);
+            } else {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Using parent to derive qualifiedName");
+                }
+                qualifiedName += parentCategory.getQualifiedName();
+            }
+            child.setQualifiedName(qualifiedName);
+
+            if (!StringUtils.equals(childAnchorGuid, parentAnchorGuid)){
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Child anchor guid({}) doesn't match parent 
anchor guid({}). Updating child anchor", childAnchorGuid, parentAnchorGuid);
+                }
+                // Remove old glossary relation
+                
relationshipStore.deleteById(child.getAnchor().getRelationGuid());
+                // Link to new glossary
+                
createRelationship(defineCategoryAnchorRelation(parentAnchorGuid, 
child.getGuid()));
+                // Update the child's anchor GUID
+                child.getAnchor().setGlossaryGuid(parentAnchorGuid);
+            }
+
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Derived qualifiedName = {}", qualifiedName);
+            }
+
+            // Collect all affected/impacted categories in this accumulator. 
All impacted categories will be saved as a part of post processing
+            impactedCategories.put(child.getGuid(), child);
+            updateChildCategories(child, child.getChildrenCategories(), 
impactedCategories, false);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java 
b/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
index e63c519..bc9fe2a 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryService.java
@@ -50,6 +50,10 @@ import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
+import static 
org.apache.atlas.glossary.GlossaryUtils.getAtlasGlossaryCategorySkeleton;
+import static 
org.apache.atlas.glossary.GlossaryUtils.getAtlasGlossaryTermSkeleton;
+import static org.apache.atlas.glossary.GlossaryUtils.getGlossarySkeleton;
+
 @Service
 public class GlossaryService {
     private static final Logger  LOG           = 
LoggerFactory.getLogger(GlossaryService.class);
@@ -91,7 +95,7 @@ public class GlossaryService {
         List<AtlasGlossary> ret;
         List<String>        guidsToLoad = paginationHelper.getPaginatedList();
         if (CollectionUtils.isNotEmpty(guidsToLoad)) {
-            ret = 
guidsToLoad.stream().map(GlossaryService::getGlossarySkeleton).collect(Collectors.toList());
+            ret = 
guidsToLoad.stream().map(GlossaryUtils::getGlossarySkeleton).collect(Collectors.toList());
             Iterable<AtlasGlossary> glossaries = dataAccess.load(ret);
             ret.clear();
 
@@ -139,13 +143,13 @@ public class GlossaryService {
             throw new 
AtlasBaseException(AtlasErrorCode.GLOSSARY_ALREADY_EXISTS, 
atlasGlossary.getQualifiedName());
         }
 
-        AtlasGlossary saved = dataAccess.save(atlasGlossary);
+        AtlasGlossary storeObject = dataAccess.save(atlasGlossary);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.createGlossary() : {}", saved);
+            LOG.debug("<== GlossaryService.createGlossary() : {}", 
storeObject);
         }
 
-        return saved;
+        return storeObject;
     }
 
     /**
@@ -238,20 +242,20 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, 
"DisplayName can't be null/empty");
         }
 
-        AtlasGlossary ret = dataAccess.load(atlasGlossary);
+        AtlasGlossary storeObject = dataAccess.load(atlasGlossary);
 
-        if (!ret.equals(atlasGlossary)) {
-            atlasGlossary.setGuid(ret.getGuid());
-            atlasGlossary.setQualifiedName(ret.getQualifiedName());
+        if (!storeObject.equals(atlasGlossary)) {
+            atlasGlossary.setGuid(storeObject.getGuid());
+            atlasGlossary.setQualifiedName(storeObject.getQualifiedName());
 
-            ret = dataAccess.save(atlasGlossary);
-            setInfoForRelations(ret);
+            storeObject = dataAccess.save(atlasGlossary);
+            setInfoForRelations(storeObject);
         }
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.updateGlossary() : {}", ret);
+            LOG.debug("<== GlossaryService.updateGlossary() : {}", 
storeObject);
         }
-        return ret;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -263,13 +267,13 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, 
"glossaryGuid is null/empty");
         }
 
-        AtlasGlossary existing = 
dataAccess.load(getGlossarySkeleton(glossaryGuid));
+        AtlasGlossary storeObject = 
dataAccess.load(getGlossarySkeleton(glossaryGuid));
 
-        Set<AtlasRelatedTermHeader> terms = existing.getTerms();
-        deleteTerms(existing, terms);
+        Set<AtlasRelatedTermHeader> terms = storeObject.getTerms();
+        deleteTerms(storeObject, terms);
 
-        Set<AtlasRelatedCategoryHeader> categories = existing.getCategories();
-        deleteCategories(existing, categories);
+        Set<AtlasRelatedCategoryHeader> categories = 
storeObject.getCategories();
+        deleteCategories(storeObject, categories);
 
         // Once all relations are deleted, then delete the Glossary
         dataAccess.delete(glossaryGuid);
@@ -314,31 +318,26 @@ public class GlossaryService {
         if (Objects.isNull(glossaryTerm.getAnchor())) {
             throw new 
AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
         }
-        if (StringUtils.isEmpty(glossaryTerm.getQualifiedName())) {
-            String displayName  = glossaryTerm.getDisplayName();
-            String glossaryName = glossaryTerm.getAnchor().getDisplayText();
-            if (StringUtils.isEmpty(displayName) || 
StringUtils.isEmpty(glossaryName)) {
-                throw new 
AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_QUALIFIED_NAME_CANT_BE_DERIVED);
-            } else {
-                glossaryTerm.setQualifiedName(displayName + "@" + 
glossaryName);
-            }
+        if (StringUtils.isEmpty(glossaryTerm.getDisplayName())) {
+            throw new 
AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_QUALIFIED_NAME_CANT_BE_DERIVED);
         }
 
+        // This might fail for the case when the term's qualifiedName has been 
updated and the duplicate request comes in with old name
         if (termExists(glossaryTerm)) {
             throw new 
AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_ALREADY_EXISTS, 
glossaryTerm.getQualifiedName());
         }
 
-        AtlasGlossaryTerm existing = dataAccess.save(glossaryTerm);
-        glossaryTermUtils.processTermRelations(glossaryTerm, existing, 
GlossaryUtils.RelationshipOperation.CREATE);
+        AtlasGlossaryTerm storeObject = dataAccess.save(glossaryTerm);
+        glossaryTermUtils.processTermRelations(storeObject, glossaryTerm, 
GlossaryUtils.RelationshipOperation.CREATE);
 
         // Re-load term after handling relations
-        existing = dataAccess.load(glossaryTerm);
-        setInfoForRelations(existing);
+        storeObject = dataAccess.load(glossaryTerm);
+        setInfoForRelations(storeObject);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.create() : {}", existing);
+            LOG.debug("<== GlossaryService.create() : {}", storeObject);
         }
-        return existing;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -378,28 +377,29 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, 
"DisplayName can't be null/empty");
         }
 
-        AtlasGlossaryTerm existing = dataAccess.load(atlasGlossaryTerm);
-        AtlasGlossaryTerm updated  = atlasGlossaryTerm;
-        if (!existing.equals(updated)) {
+        AtlasGlossaryTerm storeObject = dataAccess.load(atlasGlossaryTerm);
+        if (!storeObject.equals(atlasGlossaryTerm)) {
             try {
-                updated.setGuid(existing.getGuid());
-                updated.setQualifiedName(existing.getQualifiedName());
+                atlasGlossaryTerm.setGuid(storeObject.getGuid());
+                
atlasGlossaryTerm.setQualifiedName(storeObject.getQualifiedName());
 
-                atlasGlossaryTerm = dataAccess.save(updated);
+                storeObject = dataAccess.save(atlasGlossaryTerm);
             } catch (AtlasBaseException e) {
                 LOG.debug("Glossary term had no immediate attr updates. 
Exception: {}", e.getMessage());
             } finally {
-                glossaryTermUtils.processTermRelations(atlasGlossaryTerm, 
existing, GlossaryUtils.RelationshipOperation.UPDATE);
+                glossaryTermUtils.processTermRelations(storeObject, 
atlasGlossaryTerm, GlossaryUtils.RelationshipOperation.UPDATE);
             }
 
         }
 
-        updated = dataAccess.load(atlasGlossaryTerm);
-        setInfoForRelations(updated);
+        storeObject = dataAccess.load(atlasGlossaryTerm);
+        setInfoForRelations(storeObject);
+
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.updateTerm() : {}", updated);
+            LOG.debug("<== GlossaryService.updateTerm() : {}", storeObject);
         }
-        return updated;
+
+        return storeObject;
     }
 
     @GraphTransaction
@@ -411,13 +411,13 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "termGuid 
is null/empty");
         }
 
-        AtlasGlossaryTerm existing = 
dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid));
+        AtlasGlossaryTerm storeObject = 
dataAccess.load(getAtlasGlossaryTermSkeleton(termGuid));
 
         // Remove term from Glossary
-        glossaryTermUtils.processTermRelations(existing, existing, 
GlossaryUtils.RelationshipOperation.DELETE);
+        glossaryTermUtils.processTermRelations(storeObject, storeObject, 
GlossaryUtils.RelationshipOperation.DELETE);
 
         // Remove term associations with Entities
-        glossaryTermUtils.processTermDissociation(existing, 
existing.getAssignedEntities());
+        glossaryTermUtils.processTermDissociation(storeObject, 
storeObject.getAssignedEntities());
 
         // Now delete the term
         dataAccess.delete(termGuid);
@@ -489,33 +489,39 @@ public class GlossaryService {
         if (Objects.isNull(glossaryCategory.getAnchor())) {
             throw new 
AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
         }
-        if (StringUtils.isEmpty(glossaryCategory.getQualifiedName())) {
-            String displayName  = glossaryCategory.getDisplayName();
-            String glossaryName = 
glossaryCategory.getAnchor().getDisplayText();
-            if (StringUtils.isEmpty(displayName) || 
StringUtils.isEmpty(glossaryName)) {
-                throw new 
AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_QUALIFIED_NAME_CANT_BE_DERIVED);
-            } else {
-                glossaryCategory.setQualifiedName(displayName + "@" + 
glossaryName);
-            }
+        if (Objects.isNull(glossaryCategory.getDisplayName())) {
+            throw new 
AtlasBaseException(AtlasErrorCode.MISSING_CATEGORY_DISPLAY_NAME);
         }
 
+        // This might fail for the case when the category's qualifiedName has 
been updated during a hierarchy change
+        // and the duplicate request comes in with old name
         if (categoryExists(glossaryCategory)) {
             throw new 
AtlasBaseException(AtlasErrorCode.GLOSSARY_CATEGORY_ALREADY_EXISTS, 
glossaryCategory.getQualifiedName());
         }
 
-        AtlasGlossaryCategory saved = dataAccess.save(glossaryCategory);
+        AtlasGlossaryCategory storeObject = dataAccess.save(glossaryCategory);
+
+        // Attempt relation creation and gather all impacted categories
+        Map<String, AtlasGlossaryCategory> impactedCategories = 
glossaryCategoryUtils.processCategoryRelations(storeObject, glossaryCategory, 
GlossaryUtils.RelationshipOperation.CREATE);
 
-        // Attempt relation creation
-        glossaryCategoryUtils.processCategoryRelations(glossaryCategory, 
saved, GlossaryUtils.RelationshipOperation.CREATE);
-        saved = dataAccess.load(glossaryCategory);
+        // Re save the categories in case any qualifiedName change has occurred
+        dataAccess.save(impactedCategories.values());
+
+        // Since the current category is also affected, we need to update 
qualifiedName and save again
+        if (!StringUtils.equals(glossaryCategory.getQualifiedName(), 
storeObject.getQualifiedName())) {
+            glossaryCategory.setQualifiedName(storeObject.getQualifiedName());
+            storeObject = dataAccess.save(glossaryCategory);
+        } else {
+            storeObject = dataAccess.load(glossaryCategory);
+        }
 
-        setInfoForRelations(saved);
+        setInfoForRelations(storeObject);
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.createCategory() : {}", saved);
+            LOG.debug("<== GlossaryService.createCategory() : {}", 
storeObject);
         }
 
-        return saved;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -552,30 +558,36 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, 
"DisplayName can't be null/empty");
         }
 
-        AtlasGlossaryCategory existing = dataAccess.load(glossaryCategory);
-        AtlasGlossaryCategory ret      = glossaryCategory;
+        AtlasGlossaryCategory storeObject = dataAccess.load(glossaryCategory);
 
-        if (!existing.equals(glossaryCategory)) {
+        if (!storeObject.equals(glossaryCategory)) {
             try {
-                glossaryCategory.setGuid(existing.getGuid());
-                glossaryCategory.setQualifiedName(existing.getQualifiedName());
+                glossaryCategory.setGuid(storeObject.getGuid());
+                
glossaryCategory.setQualifiedName(storeObject.getQualifiedName());
 
-                ret = dataAccess.save(glossaryCategory);
+                storeObject = dataAccess.save(glossaryCategory);
             } catch (AtlasBaseException e) {
                 LOG.debug("No immediate attribute update. Exception: {}", 
e.getMessage());
             } finally {
-                
glossaryCategoryUtils.processCategoryRelations(glossaryCategory, existing, 
GlossaryUtils.RelationshipOperation.UPDATE);
+                Map<String, AtlasGlossaryCategory> impactedCategories = 
glossaryCategoryUtils.processCategoryRelations(storeObject, glossaryCategory, 
GlossaryUtils.RelationshipOperation.UPDATE);
+                dataAccess.save(impactedCategories.values());
+                // Since the current category is also affected, we need to 
update qualifiedName and save again
+                if (!StringUtils.equals(glossaryCategory.getQualifiedName(), 
storeObject.getQualifiedName())){
+                    
glossaryCategory.setQualifiedName(storeObject.getQualifiedName());
+                    storeObject = dataAccess.save(glossaryCategory);
+                } else {
+                    storeObject = dataAccess.load(glossaryCategory);
+                }
             }
         }
 
         if (DEBUG_ENABLED) {
-            LOG.debug("<== GlossaryService.updateCategory() : {}", ret);
+            LOG.debug("<== GlossaryService.updateCategory() : {}", 
storeObject);
         }
-        ret = dataAccess.load(glossaryCategory);
 
-        setInfoForRelations(ret);
+        setInfoForRelations(storeObject);
 
-        return ret;
+        return storeObject;
     }
 
     @GraphTransaction
@@ -587,10 +599,10 @@ public class GlossaryService {
             throw new AtlasBaseException(AtlasErrorCode.BAD_REQUEST, "Category 
guid is null/empty");
         }
 
-        AtlasGlossaryCategory existing = 
dataAccess.load(getAtlasGlossaryCategorySkeleton(categoryGuid));
+        AtlasGlossaryCategory storeObject = 
dataAccess.load(getAtlasGlossaryCategorySkeleton(categoryGuid));
 
         // Delete all relations
-        glossaryCategoryUtils.processCategoryRelations(existing, existing, 
GlossaryUtils.RelationshipOperation.DELETE);
+        glossaryCategoryUtils.processCategoryRelations(storeObject, 
storeObject, GlossaryUtils.RelationshipOperation.DELETE);
 
         // Now delete the category
         dataAccess.delete(categoryGuid);
@@ -825,12 +837,6 @@ public class GlossaryService {
         return ret;
     }
 
-    private static AtlasGlossary getGlossarySkeleton(String glossaryGuid) {
-        AtlasGlossary glossary = new AtlasGlossary();
-        glossary.setGuid(glossaryGuid);
-        return glossary;
-    }
-
     private boolean glossaryExists(AtlasGlossary atlasGlossary) {
         AtlasVertex vertex = 
AtlasGraphUtilsV1.findByUniqueAttributes(atlasTypeRegistry.getEntityTypeByName(GlossaryUtils.ATLAS_GLOSSARY_TYPENAME),
 new HashMap<String, Object>() {{
             put(QUALIFIED_NAME_ATTR, atlasGlossary.getQualifiedName());
@@ -852,10 +858,10 @@ public class GlossaryService {
         return Objects.nonNull(vertex);
     }
 
-    private void deleteCategories(final AtlasGlossary existing, final 
Collection<AtlasRelatedCategoryHeader> categories) throws AtlasBaseException {
+    private void deleteCategories(final AtlasGlossary storeObject, final 
Collection<AtlasRelatedCategoryHeader> categories) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(categories)) {
             if (DEBUG_ENABLED) {
-                LOG.debug("Deleting categories within glossary guid = {}", 
existing.getGuid());
+                LOG.debug("Deleting categories within glossary guid = {}", 
storeObject.getGuid());
             }
             for (AtlasRelatedCategoryHeader category : categories) {
                 // Delete category
@@ -864,10 +870,10 @@ public class GlossaryService {
         }
     }
 
-    private void deleteTerms(final AtlasGlossary existing, final 
Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
+    private void deleteTerms(final AtlasGlossary storeObject, final 
Collection<AtlasRelatedTermHeader> terms) throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             if (DEBUG_ENABLED) {
-                LOG.debug("Deleting terms within glossary guid = {}", 
existing.getGuid());
+                LOG.debug("Deleting terms within glossary guid = {}", 
storeObject.getGuid());
             }
             for (AtlasRelatedTermHeader term : terms) {
                 // Delete the term
@@ -876,18 +882,6 @@ public class GlossaryService {
         }
     }
 
-    private AtlasGlossaryTerm getAtlasGlossaryTermSkeleton(final String 
termGuid) {
-        AtlasGlossaryTerm glossaryTerm = new AtlasGlossaryTerm();
-        glossaryTerm.setGuid(termGuid);
-        return glossaryTerm;
-    }
-
-    private AtlasGlossaryCategory getAtlasGlossaryCategorySkeleton(final 
String categoryGuid) {
-        AtlasGlossaryCategory glossaryCategory = new AtlasGlossaryCategory();
-        glossaryCategory.setGuid(categoryGuid);
-        return glossaryCategory;
-    }
-
     private void setInfoForRelations(final AtlasGlossary ret) throws 
AtlasBaseException {
         if (Objects.nonNull(ret.getTerms())) {
             setInfoForTerms(ret.getTerms());

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java 
b/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
index 6977369..2c38d31 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryTermUtils.java
@@ -19,6 +19,7 @@ package org.apache.atlas.glossary;
 
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.glossary.AtlasGlossary;
 import org.apache.atlas.model.glossary.AtlasGlossaryTerm;
 import org.apache.atlas.model.glossary.relations.AtlasGlossaryHeader;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
@@ -53,14 +54,14 @@ public class GlossaryTermUtils extends GlossaryUtils {
         super(relationshipStore, typeRegistry, dataAccess);
     }
 
-    public void processTermRelations(AtlasGlossaryTerm updatedTerm, 
AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException 
{
+    public void processTermRelations(AtlasGlossaryTerm storeObject, 
AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws 
AtlasBaseException {
         if (DEBUG_ENABLED) {
-            LOG.debug("==> GlossaryTermUtils.processTermRelations({}, {}, 
{})", updatedTerm, existing, op);
+            LOG.debug("==> GlossaryTermUtils.processTermRelations({}, {}, 
{})", storeObject, updatedTerm, op);
         }
 
-        processTermAnchor(updatedTerm, existing, op);
-        processRelatedTerms(updatedTerm, existing, op);
-        processAssociatedCategories(updatedTerm, existing, op);
+        processTermAnchor(storeObject, updatedTerm, op);
+        processRelatedTerms(storeObject, updatedTerm, op);
+        processAssociatedCategories(storeObject, updatedTerm, op);
 
         if (DEBUG_ENABLED) {
             LOG.debug("<== GlossaryTermUtils.processTermRelations()");
@@ -130,12 +131,16 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private boolean isRelationshipGuidSame(final AtlasRelatedObjectId 
existing, final AtlasRelatedObjectId relatedObjectId) {
-        return StringUtils.equals(relatedObjectId.getRelationshipGuid(), 
existing.getRelationshipGuid());
+    private boolean isRelationshipGuidSame(AtlasRelatedObjectId storeObject, 
AtlasRelatedObjectId relatedObjectId) {
+        return StringUtils.equals(relatedObjectId.getRelationshipGuid(), 
storeObject.getRelationshipGuid());
     }
 
-    private void processTermAnchor(AtlasGlossaryTerm updatedTerm, 
AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException 
{
-        AtlasGlossaryHeader existingAnchor    = existing.getAnchor();
+    private void processTermAnchor(AtlasGlossaryTerm storeObject, 
AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws 
AtlasBaseException {
+        if (Objects.isNull(updatedTerm.getAnchor()) && op != 
RelationshipOperation.DELETE) {
+            throw new 
AtlasBaseException(AtlasErrorCode.MISSING_MANDATORY_ANCHOR);
+        }
+
+        AtlasGlossaryHeader existingAnchor    = storeObject.getAnchor();
         AtlasGlossaryHeader updatedTermAnchor = updatedTerm.getAnchor();
 
         switch (op) {
@@ -144,9 +149,19 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     throw new 
AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
                 } else {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating relation between glossary = {} and 
term = {}", updatedTermAnchor.getGlossaryGuid(), existing.getDisplayName());
+                        LOG.debug("Creating new term anchor, category = {}, 
glossary = {}", storeObject.getGuid(), 
updatedTerm.getAnchor().getGlossaryGuid());
+                    }
+
+                    // Derive the qualifiedName
+                    String        anchorGlossaryGuid = 
updatedTermAnchor.getGlossaryGuid();
+                    AtlasGlossary glossary           = 
dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName() 
+ "@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", 
storeObject.getQualifiedName());
                     }
-                    
createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(),
 existing.getGuid()));
+
+                    
createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(),
 storeObject.getGuid()));
                 }
                 break;
             case UPDATE:
@@ -156,10 +171,23 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     }
 
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Updating relation between glossary = {} and 
term = {}", updatedTermAnchor.getGlossaryGuid(), existing.getDisplayName());
+                        LOG.debug("Updating term anchor, currAnchor = {}, 
newAnchor = {} and term = {}",
+                                  existingAnchor.getGlossaryGuid(),
+                                  updatedTermAnchor.getGlossaryGuid(),
+                                  storeObject.getDisplayName());
                     }
                     
relationshipStore.deleteById(existingAnchor.getRelationGuid());
-                    
createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(),
 existing.getGuid()));
+
+                    // Derive the qualifiedName when anchor changes
+                    String        anchorGlossaryGuid = 
updatedTermAnchor.getGlossaryGuid();
+                    AtlasGlossary glossary           = 
dataAccess.load(getGlossarySkeleton(anchorGlossaryGuid));
+                    storeObject.setQualifiedName(storeObject.getDisplayName() 
+ "@" + glossary.getQualifiedName());
+
+                    if (LOG.isDebugEnabled()) {
+                        LOG.debug("Derived qualifiedName = {}", 
storeObject.getQualifiedName());
+                    }
+
+                    
createRelationship(defineTermAnchorRelation(updatedTermAnchor.getGlossaryGuid(),
 storeObject.getGuid()));
                 }
                 break;
             case DELETE:
@@ -173,9 +201,9 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private void processRelatedTerms(AtlasGlossaryTerm updatedTerm, 
AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException 
{
+    private void processRelatedTerms(AtlasGlossaryTerm storeObject, 
AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws 
AtlasBaseException {
         Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> 
newRelatedTerms      = updatedTerm.getRelatedTerms();
-        Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> 
existingRelatedTerms = existing.getRelatedTerms();
+        Map<AtlasGlossaryTerm.Relation, Set<AtlasRelatedTermHeader>> 
existingRelatedTerms = storeObject.getRelatedTerms();
         switch (op) {
             case CREATE:
                 for (Map.Entry<AtlasGlossaryTerm.Relation, 
Set<AtlasRelatedTermHeader>> entry : newRelatedTerms.entrySet()) {
@@ -183,10 +211,10 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     Set<AtlasRelatedTermHeader> terms    = entry.getValue();
                     if (Objects.nonNull(terms)) {
                         if (DEBUG_ENABLED) {
-                            LOG.debug("{} relation {} for term = {}", op, 
relation, existing.getGuid());
+                            LOG.debug("{} relation {} for term = {}", op, 
relation, storeObject.getGuid());
                             LOG.debug("Related Term count = {}", terms.size());
                         }
-                        createTermRelationships(existing, relation, terms);
+                        createTermRelationships(storeObject, relation, terms);
                     }
                 }
                 break;
@@ -201,7 +229,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                             LOG.debug("Creating new term relations, relation = 
{}, terms = {}", relation,
                                       Objects.nonNull(newTermHeaders) ? 
newTermHeaders.size() : "none");
                         }
-                        createTermRelationships(existing, relation, 
newTermHeaders.values());
+                        createTermRelationships(storeObject, relation, 
newTermHeaders.values());
                         continue;
                     }
 
@@ -230,7 +258,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                                                                    .filter(t 
-> !newTermHeaders.containsKey(t.getTermGuid()))
                                                                    
.collect(Collectors.toSet());
 
-                    createTermRelationships(existing, relation, toCreate);
+                    createTermRelationships(storeObject, relation, toCreate);
                     updateTermRelationships(relation, toUpdate);
                     deleteTermRelationships(relation, toDelete);
 
@@ -265,33 +293,33 @@ public class GlossaryTermUtils extends GlossaryUtils {
         return Objects.nonNull(header.getRelationGuid()) && 
!header.equals(existingTermHeaders.get(header.getTermGuid()));
     }
 
-    private void processAssociatedCategories(AtlasGlossaryTerm updatedTerm, 
AtlasGlossaryTerm existing, RelationshipOperation op) throws AtlasBaseException 
{
+    private void processAssociatedCategories(AtlasGlossaryTerm storeObject, 
AtlasGlossaryTerm updatedTerm, RelationshipOperation op) throws 
AtlasBaseException {
         Map<String, AtlasTermCategorizationHeader> newCategories      = 
getAssociatedCategories(updatedTerm);
-        Map<String, AtlasTermCategorizationHeader> existingCategories = 
getAssociatedCategories(existing);
+        Map<String, AtlasTermCategorizationHeader> existingCategories = 
getAssociatedCategories(storeObject);
         switch (op) {
             case CREATE:
                 if (Objects.nonNull(newCategories)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new term categorization, term = 
{}, categories = {}", existing.getGuid(), newCategories.size());
+                        LOG.debug("Creating new term categorization, term = 
{}, categories = {}", storeObject.getGuid(), newCategories.size());
                     }
-                    createTermCategorizationRelationships(existing, 
newCategories.values());
+                    createTermCategorizationRelationships(storeObject, 
newCategories.values());
                 }
                 break;
             case UPDATE:
                 // If no existing categories are present then create all 
existing ones
                 if (MapUtils.isEmpty(existingCategories)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Creating new term categorization, term = 
{}, categories = {}", existing.getGuid(),
+                        LOG.debug("Creating new term categorization, term = 
{}, categories = {}", storeObject.getGuid(),
                                   Objects.nonNull(newCategories) ? 
newCategories.size() : "none");
                     }
-                    createTermCategorizationRelationships(existing, 
newCategories.values());
+                    createTermCategorizationRelationships(storeObject, 
newCategories.values());
                     break;
                 }
 
                 // If no new categories are present then delete all existing 
ones
                 if (MapUtils.isEmpty(newCategories)) {
                     if (DEBUG_ENABLED) {
-                        LOG.debug("Deleting term categorization, term = {}, 
categories = {}", existing.getGuid(), existingCategories.size());
+                        LOG.debug("Deleting term categorization, term = {}, 
categories = {}", storeObject.getGuid(), existingCategories.size());
                     }
                     
deleteCategorizationRelationship(existingCategories.values());
                     break;
@@ -302,13 +330,13 @@ public class GlossaryTermUtils extends GlossaryUtils {
                                                                       .stream()
                                                                       
.filter(c -> !existingCategories.containsKey(c.getCategoryGuid()))
                                                                       
.collect(Collectors.toSet());
-                createTermCategorizationRelationships(existing, toCreate);
+                createTermCategorizationRelationships(storeObject, toCreate);
                 Set<AtlasTermCategorizationHeader> toUpdate = newCategories
                                                                       .values()
                                                                       .stream()
                                                                       
.filter(c -> updatedExistingCategorizationRelation(existingCategories, c))
                                                                       
.collect(Collectors.toSet());
-                updateTermCategorizationRelationships(existing, toUpdate);
+                updateTermCategorizationRelationships(storeObject, toUpdate);
                 Set<AtlasTermCategorizationHeader> toDelete = 
existingCategories
                                                                       .values()
                                                                       .stream()
@@ -326,7 +354,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
         return Objects.nonNull(header.getRelationGuid()) && 
!header.equals(existingCategories.get(header.getCategoryGuid()));
     }
 
-    private Map<String, AtlasTermCategorizationHeader> 
getAssociatedCategories(final AtlasGlossaryTerm term) {
+    private Map<String, AtlasTermCategorizationHeader> 
getAssociatedCategories(AtlasGlossaryTerm term) {
         if (Objects.nonNull(term.getCategories())) {
             Map<String, AtlasTermCategorizationHeader> map = new HashMap<>();
             for (AtlasTermCategorizationHeader c : term.getCategories()) {
@@ -341,9 +369,9 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private void createTermCategorizationRelationships(AtlasGlossaryTerm 
existing, Collection<AtlasTermCategorizationHeader> categories) throws 
AtlasBaseException {
+    private void createTermCategorizationRelationships(AtlasGlossaryTerm 
storeObject, Collection<AtlasTermCategorizationHeader> categories) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(categories)) {
-            Set<AtlasTermCategorizationHeader> existingCategories = 
existing.getCategories();
+            Set<AtlasTermCategorizationHeader> existingCategories = 
storeObject.getCategories();
             for (AtlasTermCategorizationHeader categorizationHeader : 
categories) {
                 if (Objects.nonNull(existingCategories) && 
existingCategories.contains(categorizationHeader)) {
                     if (DEBUG_ENABLED) {
@@ -352,18 +380,18 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     continue;
                 }
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Creating relation between term = {} and 
category = {}", existing.getGuid(), categorizationHeader.getDisplayText());
+                    LOG.debug("Creating relation between term = {} and 
category = {}", storeObject.getGuid(), categorizationHeader.getDisplayText());
                 }
-                createRelationship(defineCategorizedTerm(categorizationHeader, 
existing.getGuid()));
+                createRelationship(defineCategorizedTerm(categorizationHeader, 
storeObject.getGuid()));
             }
         }
     }
 
-    private void updateTermCategorizationRelationships(AtlasGlossaryTerm 
existing, Collection<AtlasTermCategorizationHeader> toUpdate) throws 
AtlasBaseException {
+    private void updateTermCategorizationRelationships(AtlasGlossaryTerm 
storeObject, Collection<AtlasTermCategorizationHeader> toUpdate) throws 
AtlasBaseException {
         if (CollectionUtils.isNotEmpty(toUpdate)) {
             for (AtlasTermCategorizationHeader categorizationHeader : 
toUpdate) {
                 if (DEBUG_ENABLED) {
-                    LOG.debug("Updating relation between term = {} and 
category = {}", existing.getGuid(), categorizationHeader.getDisplayText());
+                    LOG.debug("Updating relation between term = {} and 
category = {}", storeObject.getGuid(), categorizationHeader.getDisplayText());
                 }
                 AtlasRelationship relationship = 
relationshipStore.getById(categorizationHeader.getRelationGuid());
                 updateRelationshipAttributes(relationship, 
categorizationHeader);
@@ -383,12 +411,12 @@ public class GlossaryTermUtils extends GlossaryUtils {
         }
     }
 
-    private void createTermRelationships(AtlasGlossaryTerm existing, 
AtlasGlossaryTerm.Relation relation, Collection<AtlasRelatedTermHeader> terms) 
throws AtlasBaseException {
+    private void createTermRelationships(AtlasGlossaryTerm storeObject, 
AtlasGlossaryTerm.Relation relation, Collection<AtlasRelatedTermHeader> terms) 
throws AtlasBaseException {
         if (CollectionUtils.isNotEmpty(terms)) {
             Map<String, AtlasRelatedTermHeader> existingRelations;
-            if (Objects.nonNull(existing.getRelatedTerms()) && 
Objects.nonNull(existing.getRelatedTerms().get(relation))) {
+            if (Objects.nonNull(storeObject.getRelatedTerms()) && 
Objects.nonNull(storeObject.getRelatedTerms().get(relation))) {
                 Map<String, AtlasRelatedTermHeader> map = new HashMap<>();
-                for (AtlasRelatedTermHeader t : 
existing.getRelatedTerms().get(relation)) {
+                for (AtlasRelatedTermHeader t : 
storeObject.getRelatedTerms().get(relation)) {
                     AtlasRelatedTermHeader header = map.get(t.getTermGuid());
                     if (header == null || 
(StringUtils.isEmpty(header.getRelationGuid()) && 
StringUtils.isNotEmpty(t.getRelationGuid()))) {
                         map.put(t.getTermGuid(), t);
@@ -406,7 +434,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     continue;
                 }
 
-                if (existing.getGuid().equals(term.getTermGuid())) {
+                if (storeObject.getGuid().equals(term.getTermGuid())) {
                     throw new 
AtlasBaseException(AtlasErrorCode.INVALID_TERM_RELATION_TO_SELF);
                 }
 
@@ -414,7 +442,7 @@ public class GlossaryTermUtils extends GlossaryUtils {
                     LOG.debug("Creating new term relation = {}, terms = {}", 
relation, term.getDisplayText());
                 }
 
-                createRelationship(defineTermRelation(relation, 
existing.getGuid(), term));
+                createRelationship(defineTermRelation(relation, 
storeObject.getGuid(), term));
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/atlas/blob/65e3a114/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
----------------------------------------------------------------------
diff --git 
a/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java 
b/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
index e320144..cec4c23 100644
--- a/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
+++ b/repository/src/main/java/org/apache/atlas/glossary/GlossaryUtils.java
@@ -19,6 +19,9 @@ package org.apache.atlas.glossary;
 
 import org.apache.atlas.AtlasErrorCode;
 import org.apache.atlas.exception.AtlasBaseException;
+import org.apache.atlas.model.glossary.AtlasGlossary;
+import org.apache.atlas.model.glossary.AtlasGlossaryCategory;
+import org.apache.atlas.model.glossary.AtlasGlossaryTerm;
 import org.apache.atlas.model.glossary.relations.AtlasRelatedTermHeader;
 import org.apache.atlas.model.instance.AtlasRelationship;
 import org.apache.atlas.repository.ogm.DataAccess;
@@ -64,6 +67,26 @@ public abstract class GlossaryUtils {
         this.dataAccess = dataAccess;
     }
 
+    public static AtlasGlossary getGlossarySkeleton(String glossaryGuid) {
+        AtlasGlossary glossary = new AtlasGlossary();
+        glossary.setGuid(glossaryGuid);
+        return glossary;
+    }
+
+    public static AtlasGlossaryTerm getAtlasGlossaryTermSkeleton(final String 
termGuid) {
+        AtlasGlossaryTerm glossaryTerm = new AtlasGlossaryTerm();
+        glossaryTerm.setGuid(termGuid);
+        return glossaryTerm;
+    }
+
+    public static AtlasGlossaryCategory getAtlasGlossaryCategorySkeleton(final 
String categoryGuid) {
+        AtlasGlossaryCategory glossaryCategory = new AtlasGlossaryCategory();
+        glossaryCategory.setGuid(categoryGuid);
+        return glossaryCategory;
+    }
+
+
+
     protected void createRelationship(AtlasRelationship relationship) throws 
AtlasBaseException {
         try {
             relationshipStore.create(relationship);

Reply via email to