Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEAT Fix Issues in Glosary #14197

Merged
merged 17 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import org.jdbi.v3.sqlobject.transaction.Transaction;
import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.EntityInterface;
import org.openmetadata.schema.type.ApiStatus;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.TagLabel;
Expand All @@ -47,7 +48,6 @@
import org.openmetadata.schema.type.csv.CsvFile;
import org.openmetadata.schema.type.csv.CsvHeader;
import org.openmetadata.schema.type.csv.CsvImportResult;
import org.openmetadata.schema.type.csv.CsvImportResult.Status;
import org.openmetadata.service.Entity;
import org.openmetadata.service.jdbi3.EntityRepository;
import org.openmetadata.service.util.EntityUtil;
Expand Down Expand Up @@ -413,7 +413,7 @@ public static String invalidBoolean(int field, String fieldValue) {
}

private void documentFailure(String error) {
importResult.withStatus(Status.ABORTED);
importResult.withStatus(ApiStatus.ABORTED);
importResult.withAbortReason(error);
}

Expand All @@ -435,11 +435,11 @@ protected void importFailure(CSVPrinter printer, String failedReason, CSVRecord
}

private void setFinalStatus() {
Status status = Status.FAILURE;
ApiStatus status = ApiStatus.FAILURE;
harshach marked this conversation as resolved.
Show resolved Hide resolved
if (importResult.getNumberOfRowsPassed().equals(importResult.getNumberOfRowsProcessed())) {
status = Status.SUCCESS;
status = ApiStatus.SUCCESS;
} else if (importResult.getNumberOfRowsPassed() > 1) {
status = Status.PARTIAL_SUCCESS;
status = ApiStatus.PARTIAL_SUCCESS;
}
importResult.setStatus(status);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import static org.openmetadata.common.utils.CommonUtil.listOf;
import static org.openmetadata.common.utils.CommonUtil.listOrEmpty;
import static org.openmetadata.service.resources.tags.TagLabelUtil.addDerivedTags;
import static org.openmetadata.service.util.EntityUtil.getFlattenedEntityField;

import com.fasterxml.jackson.annotation.JsonPropertyOrder;
Expand Down Expand Up @@ -539,11 +540,15 @@ public static <T extends FieldInterface> void populateEntityFieldTags(
List<T> flattenedFields = getFlattenedEntityField(fields);

// Fetch All tags belonging to Prefix
Map<String, List<TagLabel>> allTags = repository.getTagsByPrefix(fqnPrefix);
Map<String, List<TagLabel>> allTags = repository.getTagsByPrefix(fqnPrefix, ".%");
for (T c : listOrEmpty(flattenedFields)) {
if (setTags) {
List<TagLabel> columnTag = allTags.get(FullyQualifiedName.buildHash(c.getFullyQualifiedName()));
c.setTags(columnTag == null ? new ArrayList<>() : columnTag);
if (columnTag == null) {
c.setTags(new ArrayList<>());
} else {
c.setTags(addDerivedTags(columnTag));
}
} else {
c.setTags(c.getTags());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2195,9 +2195,11 @@ default List<TagLabel> getTags(String targetFQN) {
return tags;
}

default Map<String, List<TagLabel>> getTagsByPrefix(String targetFQNPrefix) {
default Map<String, List<TagLabel>> getTagsByPrefix(
String targetFQNPrefix, String postfix, boolean requiresFqnHash) {
String fqnHash = requiresFqnHash ? FullyQualifiedName.buildHash(targetFQNPrefix) : targetFQNPrefix;
Map<String, List<TagLabel>> resultSet = new LinkedHashMap<>();
List<Pair<String, TagLabel>> tags = getTagsInternalByPrefix(targetFQNPrefix);
List<Pair<String, TagLabel>> tags = getTagsInternalByPrefix(fqnHash, postfix);
tags.forEach(
pair -> {
String targetHash = pair.getLeft();
Expand Down Expand Up @@ -2234,7 +2236,7 @@ default Map<String, List<TagLabel>> getTagsByPrefix(String targetFQNPrefix) {
+ " ON ta.fqnHash = tu.tagFQNHash "
+ " WHERE tu.source = 0 "
+ ") AS combined_data "
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, '.%')",
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, :postfix)",
connectionType = MYSQL)
@ConnectionAwareSqlQuery(
value =
Expand All @@ -2250,10 +2252,11 @@ default Map<String, List<TagLabel>> getTagsByPrefix(String targetFQNPrefix) {
+ " JOIN tag_usage AS tu ON ta.fqnHash = tu.tagFQNHash "
+ " WHERE tu.source = 0 "
+ ") AS combined_data "
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, '.%')",
+ "WHERE combined_data.targetFQNHash LIKE CONCAT(:targetFQNHashPrefix, :postfix)",
connectionType = POSTGRES)
@RegisterRowMapper(TagLabelRowMapperWithTargetFqnHash.class)
List<Pair<String, TagLabel>> getTagsInternalByPrefix(@BindFQN("targetFQNHashPrefix") String targetFQNHashPrefix);
List<Pair<String, TagLabel>> getTagsInternalByPrefix(
@Bind("targetFQNHashPrefix") String targetFQNHashPrefix, @Bind("postfix") String postfix);

@SqlQuery("SELECT * FROM tag_usage")
@Deprecated(since = "Release 1.1")
Expand All @@ -2269,6 +2272,11 @@ default Map<String, List<TagLabel>> getTagsByPrefix(String targetFQNPrefix) {
@SqlUpdate("DELETE FROM tag_usage where targetFQNHash = :targetFQNHash")
void deleteTagsByTarget(@BindFQN("targetFQNHash") String targetFQNHash);

@SqlUpdate(
"DELETE FROM tag_usage where tagFQNHash = :tagFqnHash AND targetFQNHash LIKE CONCAT(:targetFQNHash, '%')")
void deleteTagsByTagAndTargetEntity(
@BindFQN("tagFqnHash") String tagFqnHash, @BindFQN("targetFQNHash") String targetFQNHash);

@SqlUpdate("DELETE FROM tag_usage where tagFQNHash = :tagFQNHash AND source = :source")
void deleteTagLabels(@Bind("source") int source, @BindFQN("tagFQNHash") String tagFQNHash);

Expand Down Expand Up @@ -2333,6 +2341,15 @@ void renameInternal(
@SqlUpdate("<update>")
void updateTagPrefixInternal(@Define("update") String update);

@SqlQuery(
"select * from tag_usage where targetFQNHash in (select targetFQNHash FROM tag_usage where tagFQNHash = :tagFQNHash) and tagFQNHash != :tagFQNHash")
@RegisterRowMapper(TagLabelMapper.class)
List<TagLabel> getEntityTagsFromTag(@BindFQN("tagFQNHash") String tagFQNHash);

@SqlQuery("select targetFQNHash FROM tag_usage where tagFQNHash = :tagFQNHash")
@RegisterRowMapper(TagLabelMapper.class)
List<String> getTargetFQNHashForTag(@BindFQN("tagFQNHash") String tagFQNHash);

class TagLabelMapper implements RowMapper<TagLabel> {
@Override
public TagLabel map(ResultSet r, StatementContext ctx) throws SQLException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@
import static org.openmetadata.service.Entity.getEntityFields;
import static org.openmetadata.service.exception.CatalogExceptionMessage.csvNotSupported;
import static org.openmetadata.service.exception.CatalogExceptionMessage.entityNotFound;
import static org.openmetadata.service.resources.tags.TagLabelUtil.addDerivedTags;
import static org.openmetadata.service.resources.tags.TagLabelUtil.checkMutuallyExclusive;
import static org.openmetadata.service.util.EntityUtil.compareTagLabel;
import static org.openmetadata.service.util.EntityUtil.entityReferenceMatch;
import static org.openmetadata.service.util.EntityUtil.fieldAdded;
Expand Down Expand Up @@ -69,7 +71,6 @@
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
Expand Down Expand Up @@ -1227,31 +1228,6 @@ public Object getExtension(T entity) {
return objectNode;
}

/** Validate given list of tags and add derived tags to it */
public final List<TagLabel> addDerivedTags(List<TagLabel> tagLabels) {
if (nullOrEmpty(tagLabels)) {
return tagLabels;
}

List<TagLabel> updatedTagLabels = new ArrayList<>();
EntityUtil.mergeTags(updatedTagLabels, tagLabels);
for (TagLabel tagLabel : tagLabels) {
EntityUtil.mergeTags(updatedTagLabels, getDerivedTags(tagLabel));
}
updatedTagLabels.sort(compareTagLabel);
return updatedTagLabels;
}

/** Get tags associated with a given set of tags */
private List<TagLabel> getDerivedTags(TagLabel tagLabel) {
if (tagLabel.getSource() == TagLabel.TagSource.GLOSSARY) { // Related tags are only supported for Glossary
List<TagLabel> derivedTags = daoCollection.tagUsageDAO().getTags(tagLabel.getTagFQN());
derivedTags.forEach(tag -> tag.setLabelType(TagLabel.LabelType.DERIVED));
return derivedTags;
}
return Collections.emptyList();
}

protected void applyColumnTags(List<Column> columns) {
// Add column level tags by adding tag to column relationship
for (Column column : columns) {
Expand All @@ -1274,26 +1250,18 @@ protected void applyTags(T entity) {
public void applyTags(List<TagLabel> tagLabels, String targetFQN) {
for (TagLabel tagLabel : listOrEmpty(tagLabels)) {
// Apply tagLabel to targetFQN that identifies an entity or field
daoCollection
.tagUsageDAO()
.applyTag(
tagLabel.getSource().ordinal(),
tagLabel.getTagFQN(),
tagLabel.getTagFQN(),
targetFQN,
tagLabel.getLabelType().ordinal(),
tagLabel.getState().ordinal());
}
}

void checkMutuallyExclusive(List<TagLabel> tagLabels) {
Map<String, TagLabel> map = new HashMap<>();
for (TagLabel tagLabel : listOrEmpty(tagLabels)) {
// When two tags have the same parent that is mutuallyExclusive, then throw an error
String parentFqn = FullyQualifiedName.getParentFQN(tagLabel.getTagFQN());
TagLabel stored = map.put(parentFqn, tagLabel);
if (stored != null && TagLabelUtil.mutuallyExclusive(tagLabel)) {
throw new IllegalArgumentException(CatalogExceptionMessage.mutuallyExclusiveLabels(tagLabel, stored));
boolean isTagDerived = tagLabel.getLabelType().equals(TagLabel.LabelType.DERIVED);
// Derived Tags should not create Relationships, and needs to be built on the during Read
if (!isTagDerived) {
daoCollection
.tagUsageDAO()
.applyTag(
tagLabel.getSource().ordinal(),
tagLabel.getTagFQN(),
tagLabel.getTagFQN(),
targetFQN,
tagLabel.getLabelType().ordinal(),
tagLabel.getState().ordinal());
}
}
}
Expand All @@ -1303,11 +1271,16 @@ protected List<TagLabel> getTags(T entity) {
}

protected List<TagLabel> getTags(String fqn) {
return !supportsTags ? null : daoCollection.tagUsageDAO().getTags(fqn);
if (!supportsTags) {
return null;
}

// Populate Glossary Tags on Read
return addDerivedTags(daoCollection.tagUsageDAO().getTags(fqn));
}

public Map<String, List<TagLabel>> getTagsByPrefix(String prefix) {
return !supportsTags ? null : daoCollection.tagUsageDAO().getTagsByPrefix(prefix);
public Map<String, List<TagLabel>> getTagsByPrefix(String prefix, String postfix) {
return !supportsTags ? null : daoCollection.tagUsageDAO().getTagsByPrefix(prefix, postfix, true);
}

protected List<EntityReference> getFollowers(T entity) {
Expand Down
Loading
Loading