Commit 66f8ae16 by apoorvnaik

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

Change-Id: I4cddcfe76eabcf7ee705b60848521158bb33a8a5
parent 801db28b
......@@ -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}");
......
......@@ -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;
}
......
......@@ -29,13 +29,13 @@ import java.util.Objects;
public abstract class AtlasGlossaryBaseObject extends AtlasBaseModelObject {
// Core attributes
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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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 (StringUtils.isEmpty(updatedCategoryAnchor.getGlossaryGuid())) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_NEW_ANCHOR_GUID);
} else {
if (DEBUG_ENABLED) {
LOG.debug("Creating new category anchor, category = {}, glossary = {}", existing.getGuid(), updatedCategory.getAnchor().getDisplayText());
LOG.debug("Creating new category anchor, category = {}, glossary = {}", storeObject.getGuid(), updatedCategory.getAnchor().getGlossaryGuid());
}
// Derive the qualifiedName
String anchorGlossaryGuid = updatedCategory.getAnchor().getGlossaryGuid();
createRelationship(defineCategoryAnchorRelation(anchorGlossaryGuid, existing.getGuid()));
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()));
}
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)) {
processParentRemoval(storeObject, updatedCategory, existingParent, impactedCategories);
}
break;
}
}
private void processNewParent(AtlasGlossaryCategory storeObject, AtlasRelatedCategoryHeader newParent, Map<String, AtlasGlossaryCategory> impactedCategories) throws AtlasBaseException {
if (DEBUG_ENABLED) {
LOG.debug("Removing category parent, category = {}, parent = {}", existing.getGuid(), existingParent.getDisplayText());
LOG.debug("Creating new parent, category = {}, parent = {}", storeObject.getGuid(), newParent.getDisplayText());
}
relationshipStore.deleteById(existingParent.getRelationGuid());
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());
}
break;
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 updatedCategory, AtlasGlossaryCategory existing, RelationshipOperation op) throws AtlasBaseException {
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);
}
}
}
......@@ -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)) {
if (StringUtils.isEmpty(glossaryTerm.getDisplayName())) {
throw new AtlasBaseException(AtlasErrorCode.GLOSSARY_TERM_QUALIFIED_NAME_CANT_BE_DERIVED);
} else {
glossaryTerm.setQualifiedName(displayName + "@" + glossaryName);
}
}
// 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);
// Re save the categories in case any qualifiedName change has occurred
dataAccess.save(impactedCategories.values());
// Attempt relation creation
glossaryCategoryUtils.processCategoryRelations(glossaryCategory, saved, GlossaryUtils.RelationshipOperation.CREATE);
saved = dataAccess.load(glossaryCategory);
// 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());
......
......@@ -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));
}
}
}
......
......@@ -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);
......
......@@ -314,7 +314,12 @@ public class GlossaryServiceTest {
List<AtlasGlossaryCategory> categories = glossaryService.createCategories(Arrays.asList(accountCategory, mortgageCategory));
accountCategory.setGuid(categories.get(0).getGuid());
assertNotNull(accountCategory.getParentCategory());
assertEquals(accountCategory.getParentCategory().getCategoryGuid(), customerCategory.getGuid());
assertTrue(accountCategory.getQualifiedName().endsWith(customerCategory.getQualifiedName()));
mortgageCategory.setGuid(categories.get(1).getGuid());
assertNull(mortgageCategory.getParentCategory());
} catch (AtlasBaseException e) {
fail("Category creation should've succeeded", e);
}
......@@ -395,11 +400,51 @@ public class GlossaryServiceTest {
public void testDeleteGlossary() {
try {
glossaryService.deleteGlossary(bankGlossary.getGuid());
// Fetch deleted glossary
try {
glossaryService.getGlossary(bankGlossary.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
// Fetch delete terms
try {
glossaryService.getTerm(fixedRateMortgage.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
try {
glossaryService.getTerm(adjustableRateMortgage.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
try {
glossaryService.getTerm(savingsAccount.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
try {
glossaryService.getTerm(checkingAccount.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
// Fetch deleted categories
try {
glossaryService.getCategory(customerCategory.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
try {
glossaryService.getCategory(accountCategory.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
try {
glossaryService.getCategory(mortgageCategory.getGuid());
} catch (AtlasBaseException e) {
assertEquals(e.getAtlasErrorCode(), AtlasErrorCode.INSTANCE_GUID_NOT_FOUND);
}
} catch (AtlasBaseException e) {
fail("Glossary delete should've succeeded", e);
}
......@@ -460,11 +505,22 @@ public class GlossaryServiceTest {
// Unlink children
try {
AtlasGlossaryCategory category = glossaryService.getCategory(customerCategory.getGuid());
category.setChildrenCategories(null);
category = glossaryService.updateCategory(category);
assertNotNull(category);
assertNull(category.getChildrenCategories());
customerCategory = glossaryService.getCategory(customerCategory.getGuid());
customerCategory.setChildrenCategories(null);
customerCategory = glossaryService.updateCategory(customerCategory);
assertNotNull(customerCategory);
assertNull(customerCategory.getChildrenCategories());
accountCategory = glossaryService.getCategory(accountCategory.getGuid());
assertNull(accountCategory.getParentCategory());
assertTrue(accountCategory.getQualifiedName().endsWith(bankGlossary.getQualifiedName()));
mortgageCategory = glossaryService.getCategory(mortgageCategory.getGuid());
assertNull(mortgageCategory.getParentCategory());
assertTrue(mortgageCategory.getQualifiedName().endsWith(bankGlossary.getQualifiedName()));
} catch (AtlasBaseException e) {
fail("Customer category fetch should've succeeded");
}
......@@ -519,16 +575,27 @@ public class GlossaryServiceTest {
try {
customerCategory = glossaryService.getCategory(customerCategory.getGuid());
mortgageCategory = glossaryService.getCategory(mortgageCategory.getGuid());
accountCategory = glossaryService.getCategory(accountCategory.getGuid());
} catch (AtlasBaseException e) {
fail("Category fetch for migration should've succeeded");
}
customerCategory.setAnchor(newGlossaryHeader);
customerCategory.setChildrenCategories(null);
mortgageCategory.setAnchor(newGlossaryHeader);
accountCategory.setAnchor(newGlossaryHeader);
try {
customerCategory = glossaryService.updateCategory(customerCategory);
assertTrue(CollectionUtils.isEmpty(customerCategory.getChildrenCategories()));
mortgageCategory = glossaryService.updateCategory(mortgageCategory);
accountCategory = glossaryService.updateCategory(accountCategory);
assertTrue(customerCategory.getQualifiedName().endsWith(creditUnionGlossary.getQualifiedName()));
assertEquals(customerCategory.getAnchor().getGlossaryGuid(), newGlossaryHeader.getGlossaryGuid());
assertTrue(accountCategory.getQualifiedName().endsWith(creditUnionGlossary.getQualifiedName()));
assertEquals(accountCategory.getAnchor().getGlossaryGuid(), newGlossaryHeader.getGlossaryGuid());
assertTrue(mortgageCategory.getQualifiedName().endsWith(creditUnionGlossary.getQualifiedName()));
assertEquals(mortgageCategory.getAnchor().getGlossaryGuid(), newGlossaryHeader.getGlossaryGuid());
} catch (AtlasBaseException e) {
fail("Category anchor change should've succeeded");
}
......@@ -536,10 +603,50 @@ public class GlossaryServiceTest {
try {
List<AtlasRelatedCategoryHeader> categories = glossaryService.getGlossaryCategoriesHeaders(creditUnionGlossary.getGuid(), 0, 5, SortOrder.ASCENDING);
assertNotNull(categories);
assertEquals(categories.size(), 1);
assertEquals(categories.size(), 3);
} catch (AtlasBaseException e) {
fail("Category migration should've succeeded", e);
}
// Move the entire hierarchy back to the original glossary
AtlasRelatedCategoryHeader child1 = new AtlasRelatedCategoryHeader();
child1.setCategoryGuid(accountCategory.getGuid());
AtlasRelatedCategoryHeader child2 = new AtlasRelatedCategoryHeader();
child2.setCategoryGuid(mortgageCategory.getGuid());
customerCategory.addChild(child1);
customerCategory.addChild(child2);
try {
customerCategory = glossaryService.updateCategory(customerCategory);
assertTrue(CollectionUtils.isNotEmpty(customerCategory.getChildrenCategories()));
} catch (AtlasBaseException e) {
fail("Children addition to Category should've succeeded");
}
customerCategory.setAnchor(newGlossaryHeader);
newGlossaryHeader.setGlossaryGuid(bankGlossary.getGuid());
try {
customerCategory = glossaryService.getCategory(customerCategory.getGuid());
assertTrue(CollectionUtils.isNotEmpty(customerCategory.getChildrenCategories()));
} catch (AtlasBaseException e) {
fail("Category fetch should've succeeded");
}
try {
accountCategory = glossaryService.getCategory(accountCategory.getGuid());
assertEquals(accountCategory.getAnchor().getGlossaryGuid(), customerCategory.getAnchor().getGlossaryGuid());
} catch (AtlasBaseException e) {
fail("Category fetch should've succeeded");
}
try {
mortgageCategory = glossaryService.getCategory(mortgageCategory.getGuid());
assertEquals(mortgageCategory.getAnchor().getGlossaryGuid(), customerCategory.getAnchor().getGlossaryGuid());
} catch (AtlasBaseException e) {
fail("Category fetch should've succeeded");
}
}
@Test(groups = "Glossary.UPDATE", dependsOnGroups = "Glossary.CREATE")
......@@ -689,6 +796,12 @@ public class GlossaryServiceTest {
} catch (AtlasBaseException e) {
fail("Term update should've succeeded", e);
}
try {
entityStore.deleteById(relatedObjectId.getGuid());
} catch (AtlasBaseException e) {
fail("Entity delete should've succeeded");
}
}
@Test(groups = "Glossary.UPDATE", dependsOnGroups = "Glossary.CREATE")
......
......@@ -394,7 +394,7 @@ public class GlossaryREST {
try {
glossary.setAttribute(entry.getKey(), entry.getValue());
} catch (IllegalArgumentException e) {
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARTIAL_UPDATE_ATTR, "Glossary", entry.getKey());
throw new AtlasBaseException(AtlasErrorCode.INVALID_PARTIAL_UPDATE_ATTR, entry.getKey(), "Glossary");
}
}
return glossaryService.updateGlossary(glossary);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment