Skip to content
Draft
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 @@ -27,10 +27,13 @@
import org.openmetadata.it.util.SdkClients;
import org.openmetadata.it.util.TestNamespace;
import org.openmetadata.schema.api.policies.CreatePolicy;
import org.openmetadata.schema.api.teams.CreateRole;
import org.openmetadata.schema.entity.policies.Policy;
import org.openmetadata.schema.entity.policies.accessControl.Rule;
import org.openmetadata.schema.entity.policies.accessControl.Rule.Effect;
import org.openmetadata.schema.entity.teams.Role;
import org.openmetadata.schema.type.EntityHistory;
import org.openmetadata.schema.type.EntityReference;
import org.openmetadata.schema.type.MetadataOperation;
import org.openmetadata.sdk.client.OpenMetadataClient;
import org.openmetadata.sdk.models.ListParams;
Expand Down Expand Up @@ -352,6 +355,68 @@ void test_listPolicies(TestNamespace ns) {
assertTrue(response.getData().size() >= 3);
}

/**
* Verifies bulk policy listing includes associated roles when requested via fields parameter.
* Addresses bug where fetchAndSetRoles used wrong parameter order in findFromBatch call.
*/
@Test
void test_bulkGetPoliciesReturnsRolesField(TestNamespace ns) {
OpenMetadataClient apiClient = SdkClients.adminClient();

String uniquePolicyName = ns.prefix("bulk_roles_test_policy");
String uniqueRoleName = ns.prefix("bulk_roles_test_role");

Policy newPolicy =
apiClient
.policies()
.create(
new CreatePolicy()
.withName(uniquePolicyName)
.withRules(List.of(createBasicRule("testRule")))
.withDescription("Testing roles in bulk response"));

Role newRole =
apiClient
.roles()
.create(
new CreateRole()
.withName(uniqueRoleName)
.withPolicies(List.of(newPolicy.getFullyQualifiedName()))
.withDescription("Role linked to test policy"));

UUID policyUuid = newPolicy.getId();
UUID roleUuid = newRole.getId();

try {
Policy directFetch = apiClient.policies().get(policyUuid.toString(), "roles");
List<EntityReference> directRoles = directFetch.getRoles();
assertNotNull(directRoles);
assertTrue(
directRoles.stream().anyMatch(ref -> ref.getId().equals(roleUuid)),
"Direct fetch must include the role");

ListParams queryParams = new ListParams();
queryParams.setFields("roles");
queryParams.setLimit(200);

ListResponse<Policy> allPolicies = apiClient.policies().list(queryParams);
Policy bulkFetchedPolicy =
allPolicies.getData().stream()
.filter(pol -> pol.getId().equals(policyUuid))
.findFirst()
.orElseThrow(() -> new AssertionError("Policy missing from bulk response"));

List<EntityReference> bulkRoles = bulkFetchedPolicy.getRoles();
assertNotNull(bulkRoles, "Roles field must be present in bulk response");
assertTrue(
bulkRoles.stream().anyMatch(ref -> ref.getId().equals(roleUuid)),
"Bulk response must contain the associated role - this validates the bug fix");
} finally {
apiClient.roles().delete(roleUuid.toString());
apiClient.policies().delete(policyUuid.toString(), java.util.Map.of("hardDelete", "true"));
}
}

@Test
void test_createPolicyWithSpecificResource(TestNamespace ns) {
OpenMetadataClient client = SdkClients.adminClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,19 @@ private void fetchAndSetTeams(List<Policy> policies) {
List<String> policyIds =
policies.stream().map(Policy::getId).map(UUID::toString).distinct().toList();

// Bulk fetch teams
// Bulk fetch teams - relationship is Team HAS Policy (Team=from, Policy=to)
List<CollectionDAO.EntityRelationshipObject> teamRecords =
daoCollection
.relationshipDAO()
.findFromBatch(policyIds, Relationship.HAS.ordinal(), POLICY, Entity.TEAM);
.findFromBatch(policyIds, Relationship.HAS.ordinal(), Entity.TEAM, POLICY);

// Create a map of policy ID to team references
Map<UUID, List<EntityReference>> policyToTeams = new HashMap<>();
for (CollectionDAO.EntityRelationshipObject record : teamRecords) {
UUID policyId = UUID.fromString(record.getFromId());
UUID policyId = UUID.fromString(record.getToId());
EntityReference teamRef =
Entity.getEntityReferenceById(
Entity.TEAM, UUID.fromString(record.getToId()), Include.ALL);
Entity.TEAM, UUID.fromString(record.getFromId()), Include.ALL);
policyToTeams.computeIfAbsent(policyId, k -> new ArrayList<>()).add(teamRef);
}

Expand All @@ -120,19 +120,19 @@ private void fetchAndSetRoles(List<Policy> policies) {
List<String> policyIds =
policies.stream().map(Policy::getId).map(UUID::toString).distinct().toList();

// Bulk fetch roles
// Bulk fetch roles - relationship is Role HAS Policy (Role=from, Policy=to)
List<CollectionDAO.EntityRelationshipObject> roleRecords =
daoCollection
.relationshipDAO()
.findFromBatch(policyIds, Relationship.HAS.ordinal(), POLICY, Entity.ROLE);
.findFromBatch(policyIds, Relationship.HAS.ordinal(), Entity.ROLE, POLICY);

// Create a map of policy ID to role references
Map<UUID, List<EntityReference>> policyToRoles = new HashMap<>();
for (CollectionDAO.EntityRelationshipObject record : roleRecords) {
UUID policyId = UUID.fromString(record.getFromId());
UUID policyId = UUID.fromString(record.getToId());
EntityReference roleRef =
Entity.getEntityReferenceById(
Entity.ROLE, UUID.fromString(record.getToId()), Include.ALL);
Entity.ROLE, UUID.fromString(record.getFromId()), Include.ALL);
policyToRoles.computeIfAbsent(policyId, k -> new ArrayList<>()).add(roleRef);
}

Expand Down