MINOR - Rules per Entity endpoint (#23109)

(cherry picked from commit ae76182e3efd00429c7b354714fd4f72b2a5cec5)
This commit is contained in:
Pere Miquel Brull 2025-08-28 09:49:51 +02:00 committed by OpenMetadata Release Bot
parent 3678346a10
commit 7cfff762c4
2 changed files with 117 additions and 0 deletions

View File

@ -36,11 +36,13 @@ import lombok.extern.slf4j.Slf4j;
import org.openmetadata.common.utils.CommonUtil;
import org.openmetadata.schema.api.search.SearchSettings;
import org.openmetadata.schema.auth.EmailRequest;
import org.openmetadata.schema.configuration.EntityRulesSettings;
import org.openmetadata.schema.settings.Settings;
import org.openmetadata.schema.settings.SettingsType;
import org.openmetadata.schema.system.ValidationResponse;
import org.openmetadata.schema.type.Include;
import org.openmetadata.schema.type.MetadataOperation;
import org.openmetadata.schema.type.SemanticsRule;
import org.openmetadata.schema.util.EntitiesCount;
import org.openmetadata.schema.util.ServicesCount;
import org.openmetadata.schema.utils.JsonUtils;
@ -192,6 +194,41 @@ public class SystemResource {
return systemRepository.getConfigWithKey(name);
}
@GET
@Path("/settings/entityRulesSettings/{entityType}")
@Operation(
operationId = "getEntityRulesSetting",
summary = "Get a setting for an entity type",
description = "Get the list of available entity rules settings for a given entity type",
responses = {
@ApiResponse(
responseCode = "200",
description = "Settings",
content =
@Content(
mediaType = "application/json",
schema = @Schema(implementation = Settings.class)))
})
public List<SemanticsRule> getEntityRulesSettingByType(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Entity Type", schema = @Schema(type = "string"))
@PathParam("entityType")
String entityType) {
return SettingsCache.getSetting(SettingsType.ENTITY_RULES_SETTINGS, EntityRulesSettings.class)
.getEntitySemantics()
.stream()
.filter(SemanticsRule::getEnabled)
.filter(
rule ->
rule.getEntityType() == null || rule.getEntityType().equalsIgnoreCase(entityType))
.filter(
rule ->
nullOrEmpty(rule.getIgnoredEntities())
|| !rule.getIgnoredEntities().contains(entityType))
.toList();
}
@GET
@Path("/search/nlq")
@Operation(

View File

@ -8,6 +8,7 @@ import static org.junit.jupiter.api.Assertions.fail;
import static org.openmetadata.service.util.TestUtils.ADMIN_AUTH_HEADERS;
import static org.openmetadata.service.util.TestUtils.TEST_AUTH_HEADERS;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.dropwizard.configuration.ConfigurationException;
import io.dropwizard.configuration.FileConfigurationSourceProvider;
@ -71,6 +72,7 @@ import org.openmetadata.schema.settings.Settings;
import org.openmetadata.schema.settings.SettingsType;
import org.openmetadata.schema.system.ValidationResponse;
import org.openmetadata.schema.type.ColumnDataType;
import org.openmetadata.schema.type.SemanticsRule;
import org.openmetadata.schema.util.EntitiesCount;
import org.openmetadata.schema.util.ServicesCount;
import org.openmetadata.schema.utils.JsonUtils;
@ -95,6 +97,7 @@ import org.openmetadata.service.resources.storages.ContainerResourceTest;
import org.openmetadata.service.resources.teams.TeamResourceTest;
import org.openmetadata.service.resources.teams.UserResourceTest;
import org.openmetadata.service.resources.topics.TopicResourceTest;
import org.openmetadata.service.security.SecurityUtil;
import org.openmetadata.service.util.TestUtils;
@Slf4j
@ -1018,6 +1021,83 @@ class SystemResourceTest extends OpenMetadataApplicationTest {
"The test entity type should not be added to allowedFields");
}
@Test
void testGetEntityRulesSettingByType() throws HttpResponseException {
// Test table entity type - should include only enabled rules applicable to tables
List<SemanticsRule> tableRules = getEntityRules("table");
assertFalse(tableRules.isEmpty(), "Table rules should not be empty");
// Should contain general enabled rules
assertTrue(
tableRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Users or Single Team Ownership")),
"Should contain general ownership rule");
assertTrue(
tableRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Domains are not allowed")),
"Should contain domains rule");
// Should NOT contain disabled rules (even if they are table-specific)
assertFalse(
tableRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Data Products are not allowed")),
"Should not contain disabled data products rule");
assertFalse(
tableRules.stream()
.anyMatch(rule -> rule.getName().equals("Tables can only have a single Glossary Term")),
"Should not contain disabled table-specific glossary term rule");
// Test dashboard entity type - should only get general enabled rules
List<SemanticsRule> dashboardRules = getEntityRules("dashboard");
assertFalse(dashboardRules.isEmpty(), "Dashboard rules should not be empty");
// Should contain general enabled rules
assertTrue(
dashboardRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Users or Single Team Ownership")),
"Dashboard should get ownership rule");
assertTrue(
dashboardRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Domains are not allowed")),
"Dashboard should get domains rule");
// Test team entity type - should get rules but exclude those that ignore team
List<SemanticsRule> teamRules = getEntityRules("team");
assertFalse(teamRules.isEmpty(), "Team rules should not be empty");
// Should contain general ownership rule
assertTrue(
teamRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Users or Single Team Ownership")),
"Team should get ownership rule");
// Should NOT contain domains rule since team is in ignoredEntities
assertFalse(
teamRules.stream()
.anyMatch(rule -> rule.getName().equals("Multiple Domains are not allowed")),
"Team should not get domains rule as it's in ignored entities");
}
private static List<SemanticsRule> getEntityRules(String entityType)
throws HttpResponseException {
ObjectMapper objectMapper = Jackson.newObjectMapper();
WebTarget target = getResource("system/settings/entityRulesSettings/" + entityType);
Response response = SecurityUtil.addHeaders(target, ADMIN_AUTH_HEADERS).get();
String responseString = response.readEntity(String.class);
try {
return objectMapper.readValue(responseString, new TypeReference<List<SemanticsRule>>() {});
} catch (Exception e) {
throw new HttpResponseException(
500, "Failed to parse " + entityType + " response: " + e.getMessage());
}
}
private static ValidationResponse getValidation() throws HttpResponseException {
WebTarget target = getResource("system/status");
return TestUtils.get(target, ValidationResponse.class, ADMIN_AUTH_HEADERS);