mirror of
				https://github.com/open-metadata/OpenMetadata.git
				synced 2025-11-04 12:36:23 +00:00 
			
		
		
		
	MINOR - Rules per Entity endpoint (#23109)
This commit is contained in:
		
							parent
							
								
									8c028b81c0
								
							
						
					
					
						commit
						ae76182e3e
					
				@ -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(
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user