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