- Encode Entity fqn

This commit is contained in:
Mohit Yadav 2025-02-27 01:01:28 +05:30 committed by mohitdeuex
parent f818b587ac
commit c5f4d49333
7 changed files with 57 additions and 24 deletions

View File

@ -14,6 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EntityUtil.encodeEntityFqn;
import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
@ -61,11 +62,12 @@ public class EmailMessageDecorator implements MessageDecorator<EmailMessage> {
@Override @Override
public String getEntityUrl(String prefix, String fqn, String additionalParams) { public String getEntityUrl(String prefix, String fqn, String additionalParams) {
String encodedFqn = encodeEntityFqn(fqn);
return String.format( return String.format(
"<a href='%s/%s/%s%s'>%s</a>", "<a href='%s/%s/%s%s'>%s</a>",
getSmtpSettings().getOpenMetadataUrl(), getSmtpSettings().getOpenMetadataUrl(),
prefix, prefix,
fqn.trim(), encodedFqn,
nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams), nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams),
fqn.trim()); fqn.trim());
} }

View File

@ -14,6 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EntityUtil.encodeEntityFqn;
import org.openmetadata.schema.type.ChangeEvent; import org.openmetadata.schema.type.ChangeEvent;
import org.openmetadata.service.formatter.util.FeedMessage; import org.openmetadata.service.formatter.util.FeedMessage;
@ -57,11 +58,12 @@ public class FeedMessageDecorator implements MessageDecorator<FeedMessage> {
@Override @Override
public String getEntityUrl(String prefix, String fqn, String additionalParams) { public String getEntityUrl(String prefix, String fqn, String additionalParams) {
String encodedFqn = encodeEntityFqn(fqn);
return String.format( return String.format(
"[%s](/%s/%s%s)", "[%s](/%s/%s%s)",
fqn,
prefix,
fqn.trim(), fqn.trim(),
prefix,
encodedFqn,
nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams)); nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams));
} }

View File

@ -14,6 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EntityUtil.encodeEntityFqn;
import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
@ -76,11 +77,12 @@ public class GChatMessageDecorator implements MessageDecorator<GChatMessage> {
@Override @Override
public String getEntityUrl(String prefix, String fqn, String additionalParams) { public String getEntityUrl(String prefix, String fqn, String additionalParams) {
String encodedFqn = encodeEntityFqn(fqn);
return String.format( return String.format(
"<%s/%s/%s%s|%s>", "<%s/%s/%s%s|%s>",
getSmtpSettings().getOpenMetadataUrl(), getSmtpSettings().getOpenMetadataUrl(),
prefix, prefix,
fqn.trim().replace(" ", "%20"), encodedFqn,
nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams), nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams),
fqn.trim()); fqn.trim());
} }

View File

@ -14,6 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EntityUtil.encodeEntityFqn;
import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import java.util.ArrayList; import java.util.ArrayList;
@ -81,11 +82,13 @@ public class MSTeamsMessageDecorator implements MessageDecorator<TeamsMessage> {
@Override @Override
public String getEntityUrl(String prefix, String fqn, String additionalParams) { public String getEntityUrl(String prefix, String fqn, String additionalParams) {
String encodedFqn = encodeEntityFqn(fqn);
return String.format( return String.format(
"[%s](/%s/%s%s)", "[%s](%s/%s/%s%s)",
fqn.trim(), fqn.trim(),
getSmtpSettings().getOpenMetadataUrl(), getSmtpSettings().getOpenMetadataUrl(),
prefix, prefix,
encodedFqn,
nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams)); nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams));
} }

View File

@ -33,6 +33,7 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; import java.util.Optional;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bitbucket.cowwoc.diffmatchpatch.DiffMatchPatch; import org.bitbucket.cowwoc.diffmatchpatch.DiffMatchPatch;
import org.openmetadata.common.utils.CommonUtil; import org.openmetadata.common.utils.CommonUtil;
@ -48,8 +49,11 @@ import org.openmetadata.service.jdbi3.TestCaseRepository;
import org.openmetadata.service.resources.feeds.MessageParser; import org.openmetadata.service.resources.feeds.MessageParser;
import org.openmetadata.service.util.EntityUtil; import org.openmetadata.service.util.EntityUtil;
import org.openmetadata.service.util.FeedUtils; import org.openmetadata.service.util.FeedUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public interface MessageDecorator<T> { public interface MessageDecorator<T> {
Logger LOG = LoggerFactory.getLogger(MessageDecorator.class);
String CONNECTION_TEST_DESCRIPTION = String CONNECTION_TEST_DESCRIPTION =
"This is a test message, receiving this message confirms that you have successfully configured OpenMetadata to receive alerts."; "This is a test message, receiving this message confirms that you have successfully configured OpenMetadata to receive alerts.";
@ -85,34 +89,40 @@ public interface MessageDecorator<T> {
T buildTestMessage(); T buildTestMessage();
@SneakyThrows
default String buildEntityUrl(String entityType, EntityInterface entityInterface) { default String buildEntityUrl(String entityType, EntityInterface entityInterface) {
String fqn = resolveFullyQualifiedName(entityType, entityInterface); String fqn = resolveFullyQualifiedName(entityType, entityInterface);
String entityUrl = "";
switch (entityType) { switch (entityType) {
case Entity.TEST_CASE: case Entity.TEST_CASE:
if (entityInterface instanceof TestCase testCase) { if (entityInterface instanceof TestCase testCase) {
return getEntityUrl( entityUrl =
getEntityUrl(
"incident-manager", testCase.getFullyQualifiedName(), "test-case-results"); "incident-manager", testCase.getFullyQualifiedName(), "test-case-results");
} }
break; break;
case Entity.GLOSSARY_TERM: case Entity.GLOSSARY_TERM:
return getEntityUrl(Entity.GLOSSARY, fqn, ""); entityUrl = getEntityUrl(Entity.GLOSSARY, fqn, "");
break;
case Entity.TAG: case Entity.TAG:
return getEntityUrl("tags", fqn.split("\\.")[0], ""); entityUrl = getEntityUrl("tags", fqn.split("\\.")[0], "");
break;
case Entity.INGESTION_PIPELINE: case Entity.INGESTION_PIPELINE:
return getIngestionPipelineUrl(this, entityType, entityInterface); entityUrl = getIngestionPipelineUrl(this, entityType, entityInterface);
break;
default: default:
return getEntityUrl(entityType, fqn, ""); entityUrl = getEntityUrl(entityType, fqn, "");
} }
// Fallback in case of no match LOG.debug("buildEntityUrl for Alert: {}", entityUrl);
return getEntityUrl(entityType, fqn, ""); return entityUrl;
} }
@SneakyThrows
default String buildThreadUrl( default String buildThreadUrl(
ThreadType threadType, String entityType, EntityInterface entityInterface) { ThreadType threadType, String entityType, EntityInterface entityInterface) {
@ -120,30 +130,34 @@ public interface MessageDecorator<T> {
threadType.equals(ThreadType.Task) ? "activity_feed/tasks" : "activity_feed/all"; threadType.equals(ThreadType.Task) ? "activity_feed/tasks" : "activity_feed/all";
String fqn = resolveFullyQualifiedName(entityType, entityInterface); String fqn = resolveFullyQualifiedName(entityType, entityInterface);
String entityUrl = "";
switch (entityType) { switch (entityType) {
case Entity.TEST_CASE: case Entity.TEST_CASE:
if (entityInterface instanceof TestCase) { if (entityInterface instanceof TestCase) {
TestCase testCase = (TestCase) entityInterface; TestCase testCase = (TestCase) entityInterface;
return getEntityUrl("incident-manager", testCase.getFullyQualifiedName(), "issues"); entityUrl = getEntityUrl("incident-manager", testCase.getFullyQualifiedName(), "issues");
} }
break; break;
case Entity.GLOSSARY_TERM: case Entity.GLOSSARY_TERM:
return getEntityUrl(Entity.GLOSSARY, fqn, activeTab); entityUrl = getEntityUrl(Entity.GLOSSARY, fqn, activeTab);
break;
case Entity.TAG: case Entity.TAG:
return getEntityUrl("tags", fqn.split("\\.")[0], ""); entityUrl = getEntityUrl("tags", fqn.split("\\.")[0], "");
break;
case Entity.INGESTION_PIPELINE: case Entity.INGESTION_PIPELINE:
return getIngestionPipelineUrl(this, entityType, entityInterface); entityUrl = getIngestionPipelineUrl(this, entityType, entityInterface);
break;
default: default:
return getEntityUrl(entityType, fqn, activeTab); entityUrl = getEntityUrl(entityType, fqn, activeTab);
} }
// Fallback in case of no match // Fallback in case of no match
return getEntityUrl(entityType, fqn, activeTab); LOG.debug("buildThreadUrl for Alert: {}", entityUrl);
return entityUrl;
} }
// Helper function to resolve FQN if null or empty // Helper function to resolve FQN if null or empty

View File

@ -14,6 +14,7 @@
package org.openmetadata.service.formatter.decorators; package org.openmetadata.service.formatter.decorators;
import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty; import static org.openmetadata.common.utils.CommonUtil.nullOrEmpty;
import static org.openmetadata.service.util.EntityUtil.encodeEntityFqn;
import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings; import static org.openmetadata.service.util.email.EmailUtil.getSmtpSettings;
import com.slack.api.model.block.Blocks; import com.slack.api.model.block.Blocks;
@ -77,14 +78,17 @@ public class SlackMessageDecorator implements MessageDecorator<SlackMessage> {
return "~"; return "~";
} }
@Override
public String getEntityUrl(String prefix, String fqn, String additionalParams) { public String getEntityUrl(String prefix, String fqn, String additionalParams) {
String encodedFqn = encodeEntityFqn(fqn);
return String.format( return String.format(
"<%s/%s/%s%s|%s>", "<%s/%s/%s%s|%s>",
getSmtpSettings().getOpenMetadataUrl(), getSmtpSettings().getOpenMetadataUrl(),
prefix, prefix,
fqn.trim().replaceAll(" ", "%20"), encodedFqn, // Use encoded FQN in the URL
nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams), nullOrEmpty(additionalParams) ? "" : String.format("/%s", additionalParams),
fqn.trim()); fqn.trim() // Display text remains unencoded
);
} }
@Override @Override

View File

@ -21,6 +21,8 @@ import static org.openmetadata.service.jdbi3.RoleRepository.DOMAIN_ONLY_ACCESS_R
import static org.openmetadata.service.security.DefaultAuthorizer.getSubjectContext; import static org.openmetadata.service.security.DefaultAuthorizer.getSubjectContext;
import java.io.IOException; import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.time.LocalDate; import java.time.LocalDate;
import java.util.ArrayList; import java.util.ArrayList;
@ -702,4 +704,8 @@ public final class EntityUtil {
} }
} }
} }
public static String encodeEntityFqn(String fqn) {
return URLEncoder.encode(fqn.trim(), StandardCharsets.UTF_8).replace("+", "%20");
}
} }