mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-12-29 16:39:04 +00:00
parent
ea8cf999ad
commit
6a0b89c27e
@ -1090,7 +1090,7 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
||||
|
||||
/** Remove owner relationship for a given entity */
|
||||
private void removeOwner(T entity, EntityReference owner) {
|
||||
if (owner != null && owner.getId() != null) {
|
||||
if (EntityUtil.getId(owner) != null) {
|
||||
LOG.info("Removing owner {}:{} for entity {}", owner.getType(), owner.getId(), entity.getId());
|
||||
deleteRelationship(owner.getId(), owner.getType(), entity.getId(), entityType, Relationship.OWNS);
|
||||
}
|
||||
|
||||
@ -18,7 +18,10 @@ package org.openmetadata.service.jdbi3;
|
||||
|
||||
import static org.openmetadata.common.utils.CommonUtil.listOrEmpty;
|
||||
import static org.openmetadata.schema.type.Include.ALL;
|
||||
import static org.openmetadata.service.Entity.GLOSSARY;
|
||||
import static org.openmetadata.service.Entity.GLOSSARY_TERM;
|
||||
import static org.openmetadata.service.util.EntityUtil.entityReferenceMatch;
|
||||
import static org.openmetadata.service.util.EntityUtil.getId;
|
||||
import static org.openmetadata.service.util.EntityUtil.stringMatch;
|
||||
import static org.openmetadata.service.util.EntityUtil.termReferenceMatch;
|
||||
|
||||
@ -26,6 +29,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.openmetadata.schema.api.data.TermReference;
|
||||
@ -40,7 +44,6 @@ import org.openmetadata.schema.type.TagLabel.TagSource;
|
||||
import org.openmetadata.service.Entity;
|
||||
import org.openmetadata.service.exception.CatalogExceptionMessage;
|
||||
import org.openmetadata.service.jdbi3.CollectionDAO.EntityRelationshipRecord;
|
||||
import org.openmetadata.service.jdbi3.EntityRepository.EntityUpdater;
|
||||
import org.openmetadata.service.resources.glossary.GlossaryTermResource;
|
||||
import org.openmetadata.service.util.EntityUtil;
|
||||
import org.openmetadata.service.util.EntityUtil.Fields;
|
||||
@ -99,14 +102,14 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
|
||||
@Override
|
||||
public void prepare(GlossaryTerm entity) throws IOException {
|
||||
validateHierarchy(entity);
|
||||
|
||||
// Validate glossary
|
||||
Fields glossaryFields = Entity.getFields(Entity.GLOSSARY, "reviewers");
|
||||
Fields glossaryFields = Entity.getFields(GLOSSARY, "reviewers");
|
||||
Glossary glossary = Entity.getEntity(entity.getGlossary(), glossaryFields, Include.NON_DELETED);
|
||||
entity.setGlossary(glossary.getEntityReference());
|
||||
|
||||
// If reviewers is not set in the glossary term, then carry it from the glossary
|
||||
System.out.println("XXX reviewers " + entity.getReviewers());
|
||||
System.out.println("XXX glossary reviewers " + glossary.getReviewers());
|
||||
entity.setReviewers(entity.getReviewers() == null ? glossary.getReviewers() : entity.getReviewers());
|
||||
|
||||
// Validate parent term
|
||||
@ -152,11 +155,8 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
|
||||
@Override
|
||||
public void storeRelationships(GlossaryTerm entity) {
|
||||
addRelationship(
|
||||
entity.getGlossary().getId(), entity.getId(), Entity.GLOSSARY, GLOSSARY_TERM, Relationship.CONTAINS);
|
||||
if (entity.getParent() != null) {
|
||||
addRelationship(entity.getParent().getId(), entity.getId(), GLOSSARY_TERM, GLOSSARY_TERM, Relationship.CONTAINS);
|
||||
}
|
||||
addGlossaryRelationship(entity);
|
||||
addParentRelationship(entity);
|
||||
for (EntityReference relTerm : listOrEmpty(entity.getRelatedTerms())) {
|
||||
// Make this bidirectional relationship
|
||||
addRelationship(entity.getId(), relTerm.getId(), GLOSSARY_TERM, GLOSSARY_TERM, Relationship.RELATED_TO, true);
|
||||
@ -170,8 +170,8 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
|
||||
@Override
|
||||
public void restorePatchAttributes(GlossaryTerm original, GlossaryTerm updated) {
|
||||
// Patch can't update Children, Glossary, or Parent
|
||||
updated.withChildren(original.getChildren()).withGlossary(original.getGlossary()).withParent(original.getParent());
|
||||
// Patch can't update Children
|
||||
updated.withChildren(original.getChildren());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -186,7 +186,7 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
}
|
||||
|
||||
protected EntityReference getGlossary(GlossaryTerm term) throws IOException {
|
||||
return getFromEntityRef(term.getId(), Relationship.CONTAINS, Entity.GLOSSARY, true);
|
||||
return getFromEntityRef(term.getId(), Relationship.CONTAINS, GLOSSARY, true);
|
||||
}
|
||||
|
||||
public EntityReference getGlossary(String id) throws IOException {
|
||||
@ -204,6 +204,49 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
daoCollection.tagUsageDAO().deleteTagLabels(TagSource.GLOSSARY.ordinal(), entity.getFullyQualifiedName());
|
||||
}
|
||||
|
||||
private void addGlossaryRelationship(GlossaryTerm term) {
|
||||
addRelationship(term.getGlossary().getId(), term.getId(), GLOSSARY, GLOSSARY_TERM, Relationship.CONTAINS);
|
||||
}
|
||||
|
||||
private void deleteGlossaryRelationship(GlossaryTerm term) {
|
||||
deleteRelationship(term.getGlossary().getId(), GLOSSARY, term.getId(), GLOSSARY_TERM, Relationship.CONTAINS);
|
||||
}
|
||||
|
||||
private void updateGlossaryRelationship(GlossaryTerm orig, GlossaryTerm updated) {
|
||||
deleteGlossaryRelationship(orig);
|
||||
addGlossaryRelationship(updated);
|
||||
}
|
||||
|
||||
private void addParentRelationship(GlossaryTerm term) {
|
||||
if (term.getParent() != null) {
|
||||
addRelationship(term.getParent().getId(), term.getId(), GLOSSARY_TERM, GLOSSARY_TERM, Relationship.CONTAINS);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteParentRelationship(GlossaryTerm term) {
|
||||
if (term.getParent() != null) {
|
||||
deleteRelationship(term.getParent().getId(), GLOSSARY_TERM, term.getId(), GLOSSARY_TERM, Relationship.CONTAINS);
|
||||
}
|
||||
}
|
||||
|
||||
private void updateParentRelationship(GlossaryTerm orig, GlossaryTerm updated) {
|
||||
deleteParentRelationship(orig);
|
||||
addParentRelationship(updated);
|
||||
}
|
||||
|
||||
private void validateHierarchy(GlossaryTerm term) {
|
||||
// The glossary and the parent term must belong to the same hierachy
|
||||
if (term.getParent() == null) {
|
||||
return; // Parent is the root of the glossary
|
||||
}
|
||||
if (!term.getParent().getFullyQualifiedName().startsWith(term.getGlossary().getFullyQualifiedName())) {
|
||||
throw new IllegalArgumentException(
|
||||
String.format(
|
||||
"Invalid hierarchy - parent [%s] does not belong to glossary[%s]",
|
||||
term.getParent().getFullyQualifiedName(), term.getGlossary().getFullyQualifiedName()));
|
||||
}
|
||||
}
|
||||
|
||||
/** Handles entity updated from PUT and POST operation. */
|
||||
public class GlossaryTermUpdater extends EntityUpdater {
|
||||
public GlossaryTermUpdater(GlossaryTerm original, GlossaryTerm updated, Operation operation) {
|
||||
@ -218,6 +261,7 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
updateRelatedTerms(original, updated);
|
||||
updateReviewers(original, updated);
|
||||
updateName(original, updated);
|
||||
updateParent(original, updated);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -293,5 +337,27 @@ public class GlossaryTermRepository extends EntityRepository<GlossaryTerm> {
|
||||
recordChange("name", original.getName(), updated.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateParent(GlossaryTerm original, GlossaryTerm updated) throws JsonProcessingException {
|
||||
// Can't change parent and glossary both at the same time
|
||||
UUID oldParentId = getId(original.getParent());
|
||||
UUID newParentId = getId(updated.getParent());
|
||||
boolean parentChanged = !Objects.equals(oldParentId, newParentId);
|
||||
|
||||
UUID oldGlossaryId = getId(original.getGlossary());
|
||||
UUID newGlossaryId = getId(updated.getGlossary());
|
||||
boolean glossaryChanged = !Objects.equals(oldGlossaryId, newGlossaryId);
|
||||
|
||||
daoCollection.glossaryTermDAO().updateFqn(original.getFullyQualifiedName(), updated.getFullyQualifiedName());
|
||||
daoCollection.tagUsageDAO().rename(original.getFullyQualifiedName(), updated.getFullyQualifiedName());
|
||||
if (glossaryChanged) {
|
||||
updateGlossaryRelationship(original, updated);
|
||||
recordChange("glossary", original.getGlossary(), updated.getGlossary(), true, entityReferenceMatch);
|
||||
}
|
||||
if (parentChanged) {
|
||||
updateParentRelationship(original, updated);
|
||||
recordChange("parent", original.getParent(), updated.getParent(), true, entityReferenceMatch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ import static org.openmetadata.service.Entity.FIELD_OWNER;
|
||||
import static org.openmetadata.service.Entity.LOCATION;
|
||||
import static org.openmetadata.service.Entity.POLICY;
|
||||
import static org.openmetadata.service.util.EntityUtil.entityReferenceMatch;
|
||||
import static org.openmetadata.service.util.EntityUtil.getId;
|
||||
import static org.openmetadata.service.util.EntityUtil.getRuleField;
|
||||
import static org.openmetadata.service.util.EntityUtil.ruleMatch;
|
||||
|
||||
@ -92,7 +93,7 @@ public class PolicyRepository extends EntityRepository<Policy> {
|
||||
/** Generate EntityReference for a given Policy's Location. * */
|
||||
@Transaction
|
||||
private EntityReference getLocationReference(Policy policy) throws IOException {
|
||||
if (policy == null || policy.getLocation() == null || policy.getLocation().getId() == null) {
|
||||
if (policy == null || getId(policy.getLocation()) == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -163,7 +164,7 @@ public class PolicyRepository extends EntityRepository<Policy> {
|
||||
}
|
||||
|
||||
private void setLocation(Policy policy, EntityReference location) {
|
||||
if (location == null || location.getId() == null) {
|
||||
if (getId(location) == null) {
|
||||
return;
|
||||
}
|
||||
addRelationship(policy.getId(), policy.getLocation().getId(), POLICY, Entity.LOCATION, Relationship.APPLIED_TO);
|
||||
@ -184,12 +185,12 @@ public class PolicyRepository extends EntityRepository<Policy> {
|
||||
|
||||
private void updateLocation(Policy origPolicy, Policy updatedPolicy) throws IOException {
|
||||
// remove original Policy --> Location relationship if exists.
|
||||
if (origPolicy.getLocation() != null && origPolicy.getLocation().getId() != null) {
|
||||
if (getId(origPolicy.getLocation()) != null) {
|
||||
deleteRelationship(
|
||||
origPolicy.getId(), POLICY, origPolicy.getLocation().getId(), Entity.LOCATION, Relationship.APPLIED_TO);
|
||||
}
|
||||
// insert updated Policy --> Location relationship.
|
||||
if (updatedPolicy.getLocation() != null && updatedPolicy.getLocation().getId() != null) {
|
||||
if (getId(updatedPolicy.getLocation()) != null) {
|
||||
addRelationship(
|
||||
updatedPolicy.getId(),
|
||||
updatedPolicy.getLocation().getId(),
|
||||
|
||||
@ -460,4 +460,20 @@ public final class EntityUtil {
|
||||
public static MetadataOperation createOrUpdateOperation(ResourceContext resourceContext) throws IOException {
|
||||
return resourceContext.getEntity() == null ? MetadataOperation.CREATE : MetadataOperation.EDIT_ALL;
|
||||
}
|
||||
|
||||
public static UUID getId(EntityReference ref) {
|
||||
return ref == null ? null : ref.getId();
|
||||
}
|
||||
|
||||
public static String getFqn(EntityReference ref) {
|
||||
return ref == null ? null : ref.getFullyQualifiedName();
|
||||
}
|
||||
|
||||
public static String getFqn(EntityInterface entity) {
|
||||
return entity == null ? null : entity.getFullyQualifiedName();
|
||||
}
|
||||
|
||||
public static EntityReference getEntityReference(EntityInterface entity) {
|
||||
return entity == null ? null : entity.getEntityReference();
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,8 @@ import static org.openmetadata.schema.type.ProviderType.SYSTEM;
|
||||
import static org.openmetadata.service.util.EntityUtil.fieldAdded;
|
||||
import static org.openmetadata.service.util.EntityUtil.fieldDeleted;
|
||||
import static org.openmetadata.service.util.EntityUtil.fieldUpdated;
|
||||
import static org.openmetadata.service.util.EntityUtil.getEntityReference;
|
||||
import static org.openmetadata.service.util.EntityUtil.getFqn;
|
||||
import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.service.util.TestUtils.UpdateType.MINOR_UPDATE;
|
||||
import static org.openmetadata.service.util.TestUtils.assertListNull;
|
||||
@ -36,6 +38,7 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.ws.rs.core.Response.Status;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.http.client.HttpResponseException;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
@ -65,6 +68,7 @@ import org.openmetadata.service.util.JsonUtils;
|
||||
import org.openmetadata.service.util.TestUtils;
|
||||
import org.openmetadata.service.util.TestUtils.UpdateType;
|
||||
|
||||
@Slf4j
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class GlossaryResourceTest extends EntityResourceTest<Glossary, CreateGlossary> {
|
||||
public GlossaryResourceTest() {
|
||||
@ -203,6 +207,102 @@ public class GlossaryResourceTest extends EntityResourceTest<Glossary, CreateGlo
|
||||
assertTagPrefixAbsent(table.getColumns().get(0).getTags(), "renameGlossary");
|
||||
}
|
||||
|
||||
@Test
|
||||
void patch_moveGlossaryTerm(TestInfo test) throws IOException {
|
||||
//
|
||||
// These test move a glossary term to different parts of the glossary hierarchy and to different glossaries
|
||||
//
|
||||
|
||||
// Create glossary with the following hierarchy
|
||||
// -> t1 -> t11 -> t111
|
||||
// g -> t12 -> t121
|
||||
// -> t2 -> t21 -> t211
|
||||
//
|
||||
// h -> h1 -> h11 -> h111
|
||||
Glossary g = createEntity(createRequest("changeParent_g"), ADMIN_AUTH_HEADERS);
|
||||
Glossary h = createEntity(createRequest("changeParent_h"), ADMIN_AUTH_HEADERS);
|
||||
|
||||
GlossaryTermResourceTest glossaryTermResourceTest = new GlossaryTermResourceTest();
|
||||
GlossaryTerm t1 = createGlossaryTerm(glossaryTermResourceTest, g, null, "t1");
|
||||
GlossaryTerm t11 = createGlossaryTerm(glossaryTermResourceTest, g, t1, "t11");
|
||||
GlossaryTerm t111 = createGlossaryTerm(glossaryTermResourceTest, g, t11, "t111");
|
||||
GlossaryTerm t12 = createGlossaryTerm(glossaryTermResourceTest, g, t1, "t12");
|
||||
GlossaryTerm t121 = createGlossaryTerm(glossaryTermResourceTest, g, t12, "t121");
|
||||
GlossaryTerm t13 = createGlossaryTerm(glossaryTermResourceTest, g, t1, "t13");
|
||||
GlossaryTerm t131 = createGlossaryTerm(glossaryTermResourceTest, g, t13, "t131");
|
||||
GlossaryTerm t2 = createGlossaryTerm(glossaryTermResourceTest, g, null, "t2");
|
||||
GlossaryTerm t21 = createGlossaryTerm(glossaryTermResourceTest, g, t2, "t21");
|
||||
GlossaryTerm t211 = createGlossaryTerm(glossaryTermResourceTest, g, t21, "t211");
|
||||
GlossaryTerm h1 = createGlossaryTerm(glossaryTermResourceTest, h, null, "h1");
|
||||
GlossaryTerm h11 = createGlossaryTerm(glossaryTermResourceTest, h, h1, "h11");
|
||||
GlossaryTerm h111 = createGlossaryTerm(glossaryTermResourceTest, h, h11, "h111");
|
||||
|
||||
// Create a table with all the terms as tag labels
|
||||
TableResourceTest tableResourceTest = new TableResourceTest();
|
||||
List<TagLabel> tagLabels = toTagLabels(t1, t11, t111, t12, t121, t13, t131, t2, t21, t211, h1, h11, h111);
|
||||
Column column = new Column().withName("c1").withDataType(ColumnDataType.INT).withTags(tagLabels);
|
||||
CreateTable createTable =
|
||||
tableResourceTest.createRequest(getEntityName(test)).withTags(tagLabels).withColumns(CommonUtil.listOf(column));
|
||||
Table table = tableResourceTest.createEntity(createTable, ADMIN_AUTH_HEADERS);
|
||||
|
||||
Object[][] scenarios = {
|
||||
// { glossaryTerm being moved, parent/glossary to move to, [... parent/glossary to move to] }
|
||||
// Leaf node t111 is moved in these tests
|
||||
{t111, g, t1, t11},
|
||||
{t111, t2, t21, t211}, // Diff hierarchy and glossary
|
||||
{t111, h, h1, h11, h111}, // Diff hierarchy and diff glossary
|
||||
|
||||
// Middle node t11 is moved in these tests
|
||||
{t11, g, t1}, // Same hierarchy and glossary
|
||||
{t11, t2, t21, t211}, // Diff hierarchy and same glossary
|
||||
{t11, h, h1, h11, h111}, // Diff hierarchy and diff glossary
|
||||
|
||||
// Top node t1 is moved in these tests
|
||||
{t1, g}, // Same hierarchy and glossary
|
||||
{t1, t2, t21, t211}, // Diff hierarchy and same glossary
|
||||
{t1, h, h1, h11, h111} // Diff hierarchy and diff glossary
|
||||
};
|
||||
|
||||
for (int i = 0; i < scenarios.length; i++) {
|
||||
GlossaryTerm termToMove = (GlossaryTerm) scenarios[i][0];
|
||||
|
||||
// Moving to another glossary term as parent
|
||||
for (int j = 1; j < scenarios[i].length; j++) {
|
||||
GlossaryTerm updatedTerm;
|
||||
|
||||
EntityReference newGlossary;
|
||||
EntityReference newParent;
|
||||
if (scenarios[i][j] instanceof Glossary) { // Moving to root of another glossary
|
||||
newGlossary = ((Glossary) scenarios[i][j]).getEntityReference();
|
||||
newParent = null;
|
||||
} else { // Moving to another glossary term as parent
|
||||
GlossaryTerm newParentTerm = (GlossaryTerm) scenarios[i][j];
|
||||
newGlossary = newParentTerm.getGlossary();
|
||||
newParent = newParentTerm.getEntityReference();
|
||||
}
|
||||
LOG.info(
|
||||
"Scenario iteration [{}, {}] move {} from glossary{} parent {} to glossary {} and parent {}",
|
||||
i,
|
||||
j,
|
||||
getFqn(termToMove),
|
||||
getFqn(termToMove.getGlossary()),
|
||||
getFqn(termToMove.getParent()),
|
||||
getFqn(newParent),
|
||||
getFqn(newGlossary));
|
||||
updatedTerm = moveGlossaryTermAndBack(newGlossary, newParent, termToMove, table);
|
||||
copyGlossaryTerm(updatedTerm, termToMove);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyGlossaryTerm(GlossaryTerm from, GlossaryTerm to) {
|
||||
to.withGlossary(from.getGlossary())
|
||||
.withParent(from.getParent())
|
||||
.withFullyQualifiedName(from.getFullyQualifiedName())
|
||||
.withChangeDescription(from.getChangeDescription())
|
||||
.withVersion(from.getVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CreateGlossary createRequest(String name) {
|
||||
return new CreateGlossary().withName(name).withDescription("d");
|
||||
@ -270,7 +370,7 @@ public class GlossaryResourceTest extends EntityResourceTest<Glossary, CreateGlo
|
||||
.withName(name)
|
||||
.withDescription("d")
|
||||
.withGlossary(glossary.getEntityReference())
|
||||
.withParent(parent == null ? null : parent.getEntityReference())
|
||||
.withParent(getEntityReference(parent))
|
||||
.withProvider(provider);
|
||||
return resource.createEntity(create, ADMIN_AUTH_HEADERS);
|
||||
}
|
||||
@ -304,9 +404,44 @@ public class GlossaryResourceTest extends EntityResourceTest<Glossary, CreateGlo
|
||||
}
|
||||
}
|
||||
|
||||
/** Change the parent of a glossary term to another glossary term then move it back to the previous hierarchy */
|
||||
private GlossaryTerm moveGlossaryTermAndBack(
|
||||
EntityReference newGlossary, EntityReference newParent, GlossaryTerm term, Table table) throws IOException {
|
||||
EntityReference previousParent = term.getParent();
|
||||
EntityReference previousGlossary = term.getGlossary();
|
||||
|
||||
// Change the parent to new parent
|
||||
GlossaryTerm updatedTerm = moveGlossaryTerm(newGlossary, newParent, term, table);
|
||||
// Change the parent back to old parent
|
||||
return moveGlossaryTerm(previousGlossary, previousParent, updatedTerm, table);
|
||||
}
|
||||
|
||||
private GlossaryTerm moveGlossaryTerm(
|
||||
EntityReference newGlossary, EntityReference newParent, GlossaryTerm term, Table table) throws IOException {
|
||||
GlossaryTermResourceTest glossaryTermResourceTest = new GlossaryTermResourceTest();
|
||||
String previousTermFqn = term.getFullyQualifiedName();
|
||||
|
||||
// Update the parent
|
||||
GlossaryTerm updatedTerm = glossaryTermResourceTest.moveGlossaryTerm(newGlossary, newParent, term);
|
||||
assertTagLabelsChanged(table, previousTermFqn, updatedTerm.getFullyQualifiedName());
|
||||
return updatedTerm;
|
||||
}
|
||||
|
||||
private void assertTagPrefixAbsent(List<TagLabel> labels, String prefix) {
|
||||
for (TagLabel tag : labels) {
|
||||
assertFalse(tag.getTagFQN().startsWith(prefix), tag.getTagFQN());
|
||||
}
|
||||
}
|
||||
|
||||
private void assertTagLabelsChanged(Table table, String previousTermFqn, String newTermFqn)
|
||||
throws HttpResponseException {
|
||||
TableResourceTest tableResourceTest = new TableResourceTest();
|
||||
table = tableResourceTest.getEntity(table.getId(), "columns,tags", ADMIN_AUTH_HEADERS);
|
||||
|
||||
// Ensure the previous term is no longer used as tags due tag label renaming
|
||||
if (!previousTermFqn.equals(newTermFqn)) { // Old and new parent are different
|
||||
assertTagPrefixAbsent(table.getTags(), previousTermFqn);
|
||||
assertTagPrefixAbsent(table.getColumns().get(0).getTags(), previousTermFqn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +32,11 @@ import static org.openmetadata.service.resources.databases.TableResourceTest.get
|
||||
import static org.openmetadata.service.util.EntityUtil.fieldAdded;
|
||||
import static org.openmetadata.service.util.EntityUtil.fieldDeleted;
|
||||
import static org.openmetadata.service.util.EntityUtil.fieldUpdated;
|
||||
import static org.openmetadata.service.util.EntityUtil.getEntityReference;
|
||||
import static org.openmetadata.service.util.EntityUtil.getId;
|
||||
import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS;
|
||||
import static org.openmetadata.service.util.TestUtils.UpdateType.MINOR_UPDATE;
|
||||
import static org.openmetadata.service.util.TestUtils.UpdateType.NO_CHANGE;
|
||||
import static org.openmetadata.service.util.TestUtils.assertListNotEmpty;
|
||||
import static org.openmetadata.service.util.TestUtils.assertListNotNull;
|
||||
import static org.openmetadata.service.util.TestUtils.assertListNull;
|
||||
@ -47,6 +50,7 @@ import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.apache.http.client.HttpResponseException;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
import org.junit.jupiter.api.Order;
|
||||
@ -73,6 +77,7 @@ import org.openmetadata.service.util.FullyQualifiedName;
|
||||
import org.openmetadata.service.util.JsonUtils;
|
||||
import org.openmetadata.service.util.ResultList;
|
||||
import org.openmetadata.service.util.TestUtils;
|
||||
import org.openmetadata.service.util.TestUtils.UpdateType;
|
||||
|
||||
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
|
||||
public class GlossaryTermResourceTest extends EntityResourceTest<GlossaryTerm, CreateGlossaryTerm> {
|
||||
@ -333,7 +338,7 @@ public class GlossaryTermResourceTest extends EntityResourceTest<GlossaryTerm, C
|
||||
public GlossaryTerm createTerm(
|
||||
Glossary glossary, GlossaryTerm parent, String termName, List<EntityReference> reviewers) throws IOException {
|
||||
EntityReference glossaryRef = glossary.getEntityReference();
|
||||
EntityReference parentRef = parent != null ? parent.getEntityReference() : null;
|
||||
EntityReference parentRef = getEntityReference(parent);
|
||||
CreateGlossaryTerm createGlossaryTerm =
|
||||
createRequest(termName, "", "", null).withGlossary(glossaryRef).withParent(parentRef).withReviewers(reviewers);
|
||||
return createAndCheckEntity(createGlossaryTerm, ADMIN_AUTH_HEADERS);
|
||||
@ -434,29 +439,29 @@ public class GlossaryTermResourceTest extends EntityResourceTest<GlossaryTerm, C
|
||||
}
|
||||
switch (fieldName) {
|
||||
case "reviewers":
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<EntityReference> expectedRefs = (List<EntityReference>) expected;
|
||||
List<EntityReference> actualRefs = JsonUtils.readObjects(actual.toString(), EntityReference.class);
|
||||
assertEntityReferences(expectedRefs, actualRefs);
|
||||
break;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<EntityReference> expectedRefs = (List<EntityReference>) expected;
|
||||
List<EntityReference> actualRefs = JsonUtils.readObjects(actual.toString(), EntityReference.class);
|
||||
assertEntityReferences(expectedRefs, actualRefs);
|
||||
break;
|
||||
case "parent":
|
||||
case "glossary":
|
||||
EntityReference expectedRef = (EntityReference) expected;
|
||||
EntityReference actualRef = JsonUtils.readValue(actual.toString(), EntityReference.class);
|
||||
assertEquals(expectedRef.getId(), actualRef.getId());
|
||||
break;
|
||||
case "synonyms":
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> expectedRefs = (List<String>) expected;
|
||||
List<String> actualRefs = JsonUtils.readObjects(actual.toString(), String.class);
|
||||
assertStrings(expectedRefs, actualRefs);
|
||||
break;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<String> expectedStrings = (List<String>) expected;
|
||||
List<String> actualStrings = JsonUtils.readObjects(actual.toString(), String.class);
|
||||
assertStrings(expectedStrings, actualStrings);
|
||||
break;
|
||||
case "references":
|
||||
{
|
||||
@SuppressWarnings("unchecked")
|
||||
List<TermReference> expectedRefs = (List<TermReference>) expected;
|
||||
List<TermReference> actualRefs = JsonUtils.readObjects(actual.toString(), TermReference.class);
|
||||
assertTermReferences(expectedRefs, actualRefs);
|
||||
break;
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
List<TermReference> expectedTermRefs = (List<TermReference>) expected;
|
||||
List<TermReference> actualTermRefs = JsonUtils.readObjects(actual.toString(), TermReference.class);
|
||||
assertTermReferences(expectedTermRefs, actualTermRefs);
|
||||
break;
|
||||
case "status":
|
||||
Status expectedStatus = (Status) expected;
|
||||
Status actualStatus = Status.fromValue(actual.toString());
|
||||
@ -491,4 +496,53 @@ public class GlossaryTermResourceTest extends EntityResourceTest<GlossaryTerm, C
|
||||
assertTrue(child.getFullyQualifiedName().startsWith(getTerm.getFullyQualifiedName()));
|
||||
}
|
||||
}
|
||||
|
||||
public GlossaryTerm moveGlossaryTerm(EntityReference newGlossary, EntityReference newParent, GlossaryTerm term)
|
||||
throws IOException {
|
||||
EntityReference oldGlossary = term.getGlossary();
|
||||
EntityReference oldParent = term.getParent();
|
||||
String json = JsonUtils.pojoToJson(term);
|
||||
ChangeDescription change = getChangeDescription(term.getVersion());
|
||||
|
||||
// Changes description for glossary term parent change
|
||||
UpdateType update = MINOR_UPDATE;
|
||||
if (newParent == null && oldParent != null) {
|
||||
fieldDeleted(change, "parent", oldParent);
|
||||
} else if (oldParent == null && newParent != null) {
|
||||
fieldAdded(change, "parent", newParent);
|
||||
} else if (Objects.equals(getId(newParent), getId(oldParent))) {
|
||||
update = NO_CHANGE;
|
||||
} else {
|
||||
fieldUpdated(change, "parent", oldParent, newParent);
|
||||
}
|
||||
|
||||
// Changes description for glossary change for glossary term
|
||||
if (!newGlossary.getId().equals(oldGlossary.getId())) {
|
||||
update = MINOR_UPDATE;
|
||||
fieldUpdated(change, "glossary", oldGlossary, newGlossary);
|
||||
}
|
||||
String parentFQN = newParent == null ? newGlossary.getFullyQualifiedName() : newParent.getFullyQualifiedName();
|
||||
term.setFullyQualifiedName(FullyQualifiedName.add(parentFQN, term.getName()));
|
||||
term.setParent(newParent);
|
||||
term.setGlossary(newGlossary);
|
||||
term = patchEntityAndCheck(term, json, ADMIN_AUTH_HEADERS, update, change);
|
||||
assertChildrenFqnChanged(term);
|
||||
return term;
|
||||
}
|
||||
|
||||
public void assertChildrenFqnChanged(GlossaryTerm term) throws HttpResponseException {
|
||||
// GET the glossary term and check all the children are renamed
|
||||
GlossaryTerm newTerm = getEntity(term.getId(), ADMIN_AUTH_HEADERS);
|
||||
for (EntityReference ref : newTerm.getChildren()) {
|
||||
assertTrue(ref.getFullyQualifiedName().startsWith(newTerm.getFullyQualifiedName()));
|
||||
}
|
||||
|
||||
// List children glossary terms with this term as the parent and ensure rename
|
||||
Map<String, String> queryParams = new HashMap<>();
|
||||
queryParams.put("parent", term.getId().toString());
|
||||
List<GlossaryTerm> children = listEntities(queryParams, ADMIN_AUTH_HEADERS).getData();
|
||||
for (GlossaryTerm child : listOrEmpty(children)) {
|
||||
assertTrue(child.getFullyQualifiedName().startsWith(newTerm.getFullyQualifiedName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user