mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-09-02 21:53:30 +00:00
Improvement : Teams api to update and remove users (#18729)
This commit is contained in:
parent
026f39c5c7
commit
e8031bcc0e
@ -279,6 +279,11 @@ public final class CatalogExceptionMessage {
|
|||||||
"Team of type %s can't own entities. Only Team of type Group can own entities.", teamType);
|
"Team of type %s can't own entities. Only Team of type Group can own entities.", teamType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String invalidTeamUpdateUsers(TeamType teamType) {
|
||||||
|
return String.format(
|
||||||
|
"Team is of type %s. Users can be updated only in team of type Group.", teamType);
|
||||||
|
}
|
||||||
|
|
||||||
public static String invalidOwnerType(String entityType) {
|
public static String invalidOwnerType(String entityType) {
|
||||||
return String.format(
|
return String.format(
|
||||||
"Entity of type %s can't be the owner. Only Team of type Group or a User can own entities.",
|
"Entity of type %s can't be the owner. Only Team of type Group or a User can own entities.",
|
||||||
|
@ -847,6 +847,13 @@ public interface CollectionDAO {
|
|||||||
bulkInsertTo(insertToRelationship);
|
bulkInsertTo(insertToRelationship);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default void bulkRemoveToRelationship(
|
||||||
|
UUID fromId, List<UUID> toIds, String fromEntity, String toEntity, int relation) {
|
||||||
|
|
||||||
|
List<String> toIdsAsString = toIds.stream().map(UUID::toString).toList();
|
||||||
|
bulkRemoveTo(fromId, toIdsAsString, fromEntity, toEntity, relation);
|
||||||
|
}
|
||||||
|
|
||||||
@ConnectionAwareSqlUpdate(
|
@ConnectionAwareSqlUpdate(
|
||||||
value =
|
value =
|
||||||
"INSERT INTO entity_relationship(fromId, toId, fromEntity, toEntity, relation, json) "
|
"INSERT INTO entity_relationship(fromId, toId, fromEntity, toEntity, relation, json) "
|
||||||
@ -882,6 +889,18 @@ public interface CollectionDAO {
|
|||||||
propertyNames = {"fromId", "toId", "fromEntity", "toEntity", "relation"})
|
propertyNames = {"fromId", "toId", "fromEntity", "toEntity", "relation"})
|
||||||
List<EntityRelationshipObject> values);
|
List<EntityRelationshipObject> values);
|
||||||
|
|
||||||
|
@SqlUpdate(
|
||||||
|
value =
|
||||||
|
"DELETE FROM entity_relationship WHERE fromId = :fromId "
|
||||||
|
+ "AND fromEntity = :fromEntity AND toId IN (<toIds>) "
|
||||||
|
+ "AND toEntity = :toEntity AND relation = :relation")
|
||||||
|
void bulkRemoveTo(
|
||||||
|
@BindUUID("fromId") UUID fromId,
|
||||||
|
@BindList("toIds") List<String> toIds,
|
||||||
|
@Bind("fromEntity") String fromEntity,
|
||||||
|
@Bind("toEntity") String toEntity,
|
||||||
|
@Bind("relation") int relation);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Find to operations
|
// Find to operations
|
||||||
//
|
//
|
||||||
|
@ -1835,6 +1835,14 @@ public abstract class EntityRepository<T extends EntityInterface> {
|
|||||||
.bulkInsertToRelationship(fromId, toId, fromEntity, toEntity, relationship.ordinal());
|
.bulkInsertToRelationship(fromId, toId, fromEntity, toEntity, relationship.ordinal());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
public final void bulkRemoveToRelationship(
|
||||||
|
UUID fromId, List<UUID> toId, String fromEntity, String toEntity, Relationship relationship) {
|
||||||
|
daoCollection
|
||||||
|
.relationshipDAO()
|
||||||
|
.bulkRemoveToRelationship(fromId, toId, fromEntity, toEntity, relationship.ordinal());
|
||||||
|
}
|
||||||
|
|
||||||
public final List<EntityReference> findBoth(
|
public final List<EntityReference> findBoth(
|
||||||
UUID entity1, String entityType1, Relationship relationship, String entity2) {
|
UUID entity1, String entityType1, Relationship relationship, String entity2) {
|
||||||
// Find bidirectional relationship
|
// Find bidirectional relationship
|
||||||
|
@ -24,6 +24,7 @@ import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.DEPARTMENT;
|
|||||||
import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.DIVISION;
|
import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.DIVISION;
|
||||||
import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.GROUP;
|
import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.GROUP;
|
||||||
import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.ORGANIZATION;
|
import static org.openmetadata.schema.api.teams.CreateTeam.TeamType.ORGANIZATION;
|
||||||
|
import static org.openmetadata.schema.type.EventType.ENTITY_FIELDS_CHANGED;
|
||||||
import static org.openmetadata.schema.type.Include.ALL;
|
import static org.openmetadata.schema.type.Include.ALL;
|
||||||
import static org.openmetadata.schema.type.Include.NON_DELETED;
|
import static org.openmetadata.schema.type.Include.NON_DELETED;
|
||||||
import static org.openmetadata.service.Entity.ADMIN_USER_NAME;
|
import static org.openmetadata.service.Entity.ADMIN_USER_NAME;
|
||||||
@ -41,6 +42,7 @@ import static org.openmetadata.service.exception.CatalogExceptionMessage.UNEXPEC
|
|||||||
import static org.openmetadata.service.exception.CatalogExceptionMessage.invalidChild;
|
import static org.openmetadata.service.exception.CatalogExceptionMessage.invalidChild;
|
||||||
import static org.openmetadata.service.exception.CatalogExceptionMessage.invalidParent;
|
import static org.openmetadata.service.exception.CatalogExceptionMessage.invalidParent;
|
||||||
import static org.openmetadata.service.exception.CatalogExceptionMessage.invalidParentCount;
|
import static org.openmetadata.service.exception.CatalogExceptionMessage.invalidParentCount;
|
||||||
|
import static org.openmetadata.service.util.EntityUtil.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -50,20 +52,26 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.csv.CSVPrinter;
|
import org.apache.commons.csv.CSVPrinter;
|
||||||
import org.apache.commons.csv.CSVRecord;
|
import org.apache.commons.csv.CSVRecord;
|
||||||
import org.jdbi.v3.sqlobject.transaction.Transaction;
|
import org.jdbi.v3.sqlobject.transaction.Transaction;
|
||||||
import org.openmetadata.common.utils.CommonUtil;
|
import org.openmetadata.common.utils.CommonUtil;
|
||||||
import org.openmetadata.csv.EntityCsv;
|
import org.openmetadata.csv.EntityCsv;
|
||||||
|
import org.openmetadata.schema.api.teams.CreateTeam;
|
||||||
import org.openmetadata.schema.api.teams.CreateTeam.TeamType;
|
import org.openmetadata.schema.api.teams.CreateTeam.TeamType;
|
||||||
import org.openmetadata.schema.entity.teams.Team;
|
import org.openmetadata.schema.entity.teams.Team;
|
||||||
import org.openmetadata.schema.entity.teams.TeamHierarchy;
|
import org.openmetadata.schema.entity.teams.TeamHierarchy;
|
||||||
|
import org.openmetadata.schema.type.ChangeDescription;
|
||||||
|
import org.openmetadata.schema.type.ChangeEvent;
|
||||||
import org.openmetadata.schema.type.EntityReference;
|
import org.openmetadata.schema.type.EntityReference;
|
||||||
|
import org.openmetadata.schema.type.EventType;
|
||||||
import org.openmetadata.schema.type.Include;
|
import org.openmetadata.schema.type.Include;
|
||||||
import org.openmetadata.schema.type.Relationship;
|
import org.openmetadata.schema.type.Relationship;
|
||||||
import org.openmetadata.schema.type.api.BulkAssets;
|
import org.openmetadata.schema.type.api.BulkAssets;
|
||||||
@ -74,17 +82,20 @@ import org.openmetadata.schema.type.csv.CsvFile;
|
|||||||
import org.openmetadata.schema.type.csv.CsvHeader;
|
import org.openmetadata.schema.type.csv.CsvHeader;
|
||||||
import org.openmetadata.schema.type.csv.CsvImportResult;
|
import org.openmetadata.schema.type.csv.CsvImportResult;
|
||||||
import org.openmetadata.service.Entity;
|
import org.openmetadata.service.Entity;
|
||||||
|
import org.openmetadata.service.exception.CatalogExceptionMessage;
|
||||||
import org.openmetadata.service.exception.EntityNotFoundException;
|
import org.openmetadata.service.exception.EntityNotFoundException;
|
||||||
import org.openmetadata.service.jdbi3.CollectionDAO.EntityRelationshipRecord;
|
import org.openmetadata.service.jdbi3.CollectionDAO.EntityRelationshipRecord;
|
||||||
import org.openmetadata.service.resources.teams.TeamResource;
|
import org.openmetadata.service.resources.teams.TeamResource;
|
||||||
import org.openmetadata.service.security.policyevaluator.SubjectContext;
|
import org.openmetadata.service.security.policyevaluator.SubjectContext;
|
||||||
import org.openmetadata.service.util.EntityUtil;
|
import org.openmetadata.service.util.EntityUtil;
|
||||||
import org.openmetadata.service.util.EntityUtil.Fields;
|
import org.openmetadata.service.util.EntityUtil.Fields;
|
||||||
|
import org.openmetadata.service.util.RestUtil;
|
||||||
import org.openmetadata.service.util.ResultList;
|
import org.openmetadata.service.util.ResultList;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TeamRepository extends EntityRepository<Team> {
|
public class TeamRepository extends EntityRepository<Team> {
|
||||||
static final String PARENTS_FIELD = "parents";
|
static final String PARENTS_FIELD = "parents";
|
||||||
|
static final String USERS_FIELD = "users";
|
||||||
static final String TEAM_UPDATE_FIELDS =
|
static final String TEAM_UPDATE_FIELDS =
|
||||||
"profile,users,defaultRoles,parents,children,policies,teamType,email,domains";
|
"profile,users,defaultRoles,parents,children,policies,teamType,email,domains";
|
||||||
static final String TEAM_PATCH_FIELDS =
|
static final String TEAM_PATCH_FIELDS =
|
||||||
@ -607,6 +618,111 @@ public class TeamRepository extends EntityRepository<Team> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Transaction
|
||||||
|
public RestUtil.PutResponse<Team> updateTeamUsers(
|
||||||
|
String updatedBy, UUID teamId, List<EntityReference> updatedUsers) {
|
||||||
|
|
||||||
|
if (updatedUsers == null) {
|
||||||
|
throw new IllegalArgumentException("Users list cannot be null");
|
||||||
|
}
|
||||||
|
|
||||||
|
Team team = Entity.getEntity(Entity.TEAM, teamId, USERS_FIELD, Include.NON_DELETED);
|
||||||
|
if (!team.getTeamType().equals(CreateTeam.TeamType.GROUP)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
CatalogExceptionMessage.invalidTeamUpdateUsers(team.getTeamType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<EntityReference> currentUsers = team.getUsers();
|
||||||
|
|
||||||
|
Set<UUID> oldUserIds =
|
||||||
|
currentUsers.stream().map(EntityReference::getId).collect(Collectors.toSet());
|
||||||
|
Set<UUID> updatedUserIds =
|
||||||
|
updatedUsers.stream().map(EntityReference::getId).collect(Collectors.toSet());
|
||||||
|
List<EntityReference> addedUsers =
|
||||||
|
updatedUsers.stream()
|
||||||
|
.filter(user -> !oldUserIds.contains(user.getId()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Optional.of(addedUsers).ifPresent(this::validateUsers);
|
||||||
|
|
||||||
|
List<UUID> addedUserIds =
|
||||||
|
updatedUsers.stream()
|
||||||
|
.map(EntityReference::getId)
|
||||||
|
.filter(id -> !oldUserIds.contains(id))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<UUID> removedUserIds =
|
||||||
|
currentUsers.stream()
|
||||||
|
.map(EntityReference::getId)
|
||||||
|
.filter(id -> !updatedUserIds.contains(id))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
Optional.of(addedUserIds)
|
||||||
|
.filter(ids -> !ids.isEmpty())
|
||||||
|
.ifPresent(
|
||||||
|
ids -> bulkAddToRelationship(teamId, ids, Entity.TEAM, Entity.USER, Relationship.HAS));
|
||||||
|
|
||||||
|
Optional.of(removedUserIds)
|
||||||
|
.filter(ids -> !ids.isEmpty())
|
||||||
|
.ifPresent(
|
||||||
|
ids ->
|
||||||
|
bulkRemoveToRelationship(teamId, ids, Entity.TEAM, Entity.USER, Relationship.HAS));
|
||||||
|
|
||||||
|
setFieldsInternal(team, new EntityUtil.Fields(allowedFields, USERS_FIELD));
|
||||||
|
ChangeDescription change = new ChangeDescription().withPreviousVersion(team.getVersion());
|
||||||
|
fieldAdded(change, USERS_FIELD, updatedUsers);
|
||||||
|
|
||||||
|
ChangeEvent changeEvent =
|
||||||
|
new ChangeEvent()
|
||||||
|
.withId(UUID.randomUUID())
|
||||||
|
.withEntity(team)
|
||||||
|
.withChangeDescription(change)
|
||||||
|
.withEventType(EventType.ENTITY_UPDATED)
|
||||||
|
.withEntityType(entityType)
|
||||||
|
.withEntityId(teamId)
|
||||||
|
.withEntityFullyQualifiedName(team.getFullyQualifiedName())
|
||||||
|
.withUserName(updatedBy)
|
||||||
|
.withTimestamp(System.currentTimeMillis())
|
||||||
|
.withCurrentVersion(team.getVersion())
|
||||||
|
.withPreviousVersion(change.getPreviousVersion());
|
||||||
|
team.setChangeDescription(change);
|
||||||
|
|
||||||
|
return new RestUtil.PutResponse<>(Response.Status.OK, changeEvent, ENTITY_FIELDS_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final RestUtil.PutResponse<Team> deleteTeamUser(
|
||||||
|
String updatedBy, UUID teamId, UUID userId) {
|
||||||
|
Team team = find(teamId, NON_DELETED);
|
||||||
|
if (!team.getTeamType().equals(CreateTeam.TeamType.GROUP)) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
CatalogExceptionMessage.invalidTeamUpdateUsers(team.getTeamType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate user
|
||||||
|
EntityReference user = Entity.getEntityReferenceById(Entity.USER, userId, NON_DELETED);
|
||||||
|
|
||||||
|
deleteRelationship(teamId, Entity.TEAM, userId, Entity.USER, Relationship.HAS);
|
||||||
|
|
||||||
|
ChangeDescription change = new ChangeDescription().withPreviousVersion(team.getVersion());
|
||||||
|
fieldDeleted(change, USERS_FIELD, List.of(user));
|
||||||
|
|
||||||
|
ChangeEvent changeEvent =
|
||||||
|
new ChangeEvent()
|
||||||
|
.withId(UUID.randomUUID())
|
||||||
|
.withEntity(team)
|
||||||
|
.withChangeDescription(change)
|
||||||
|
.withEventType(EventType.ENTITY_UPDATED)
|
||||||
|
.withEntityFullyQualifiedName(team.getFullyQualifiedName())
|
||||||
|
.withEntityType(entityType)
|
||||||
|
.withEntityId(teamId)
|
||||||
|
.withUserName(updatedBy)
|
||||||
|
.withTimestamp(System.currentTimeMillis())
|
||||||
|
.withCurrentVersion(team.getVersion())
|
||||||
|
.withPreviousVersion(change.getPreviousVersion());
|
||||||
|
|
||||||
|
return new RestUtil.PutResponse<>(Response.Status.OK, changeEvent, ENTITY_FIELDS_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
public void initOrganization() {
|
public void initOrganization() {
|
||||||
organization = findByNameOrNull(ORGANIZATION_NAME, ALL);
|
organization = findByNameOrNull(ORGANIZATION_NAME, ALL);
|
||||||
if (organization == null) {
|
if (organization == null) {
|
||||||
|
@ -57,6 +57,7 @@ import org.openmetadata.schema.entity.teams.Team;
|
|||||||
import org.openmetadata.schema.entity.teams.TeamHierarchy;
|
import org.openmetadata.schema.entity.teams.TeamHierarchy;
|
||||||
import org.openmetadata.schema.type.ChangeEvent;
|
import org.openmetadata.schema.type.ChangeEvent;
|
||||||
import org.openmetadata.schema.type.EntityHistory;
|
import org.openmetadata.schema.type.EntityHistory;
|
||||||
|
import org.openmetadata.schema.type.EntityReference;
|
||||||
import org.openmetadata.schema.type.Include;
|
import org.openmetadata.schema.type.Include;
|
||||||
import org.openmetadata.schema.type.MetadataOperation;
|
import org.openmetadata.schema.type.MetadataOperation;
|
||||||
import org.openmetadata.schema.type.api.BulkAssets;
|
import org.openmetadata.schema.type.api.BulkAssets;
|
||||||
@ -71,6 +72,7 @@ import org.openmetadata.service.limits.Limits;
|
|||||||
import org.openmetadata.service.resources.Collection;
|
import org.openmetadata.service.resources.Collection;
|
||||||
import org.openmetadata.service.resources.EntityResource;
|
import org.openmetadata.service.resources.EntityResource;
|
||||||
import org.openmetadata.service.security.Authorizer;
|
import org.openmetadata.service.security.Authorizer;
|
||||||
|
import org.openmetadata.service.security.policyevaluator.OperationContext;
|
||||||
import org.openmetadata.service.util.CSVExportResponse;
|
import org.openmetadata.service.util.CSVExportResponse;
|
||||||
import org.openmetadata.service.util.EntityUtil;
|
import org.openmetadata.service.util.EntityUtil;
|
||||||
import org.openmetadata.service.util.JsonUtils;
|
import org.openmetadata.service.util.JsonUtils;
|
||||||
@ -666,6 +668,69 @@ public class TeamResource extends EntityResource<Team, TeamRepository> {
|
|||||||
return importCsvInternal(securityContext, name, csv, dryRun);
|
return importCsvInternal(securityContext, name, csv, dryRun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("/{teamId}/users")
|
||||||
|
@Operation(
|
||||||
|
operationId = "updateTeamUsers",
|
||||||
|
summary = "Update team users",
|
||||||
|
description =
|
||||||
|
"Update the list of users for a team. Replaces existing users with the provided list.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "Updated team users",
|
||||||
|
content = @Content(mediaType = "application/json")),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Team not found")
|
||||||
|
})
|
||||||
|
public Response updateTeamUsers(
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext,
|
||||||
|
@PathParam("teamId") UUID teamId,
|
||||||
|
List<EntityReference> users) {
|
||||||
|
|
||||||
|
OperationContext operationContext =
|
||||||
|
new OperationContext(entityType, MetadataOperation.EDIT_ALL);
|
||||||
|
authorizer.authorize(securityContext, operationContext, getResourceContextById(teamId));
|
||||||
|
return repository
|
||||||
|
.updateTeamUsers(securityContext.getUserPrincipal().getName(), teamId, users)
|
||||||
|
.toResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
@Path("/{teamId}/users/{userId}")
|
||||||
|
@Operation(
|
||||||
|
operationId = "deleteTeamUser",
|
||||||
|
summary = "Remove a user from a team",
|
||||||
|
description = "Remove the user identified by `userId` from the team identified by `teamId`.",
|
||||||
|
responses = {
|
||||||
|
@ApiResponse(
|
||||||
|
responseCode = "200",
|
||||||
|
description = "User removed from team",
|
||||||
|
content =
|
||||||
|
@Content(
|
||||||
|
mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = ChangeEvent.class))),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Team or user not found")
|
||||||
|
})
|
||||||
|
public Response deleteTeamUser(
|
||||||
|
@Context UriInfo uriInfo,
|
||||||
|
@Context SecurityContext securityContext,
|
||||||
|
@Parameter(description = "Id of the team", schema = @Schema(type = "UUID"))
|
||||||
|
@PathParam("teamId")
|
||||||
|
UUID teamId,
|
||||||
|
@Parameter(description = "Id of the user being removed", schema = @Schema(type = "string"))
|
||||||
|
@PathParam("userId")
|
||||||
|
String userId) {
|
||||||
|
|
||||||
|
OperationContext operationContext =
|
||||||
|
new OperationContext(entityType, MetadataOperation.EDIT_ALL);
|
||||||
|
authorizer.authorize(securityContext, operationContext, getResourceContextById(teamId));
|
||||||
|
return repository
|
||||||
|
.deleteTeamUser(
|
||||||
|
securityContext.getUserPrincipal().getName(), teamId, UUID.fromString(userId))
|
||||||
|
.toResponse();
|
||||||
|
}
|
||||||
|
|
||||||
@PUT
|
@PUT
|
||||||
@Path("/name/{name}/importAsync")
|
@Path("/name/{name}/importAsync")
|
||||||
@Consumes(MediaType.TEXT_PLAIN)
|
@Consumes(MediaType.TEXT_PLAIN)
|
||||||
|
@ -72,6 +72,7 @@ import java.util.UUID;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import javax.ws.rs.client.WebTarget;
|
import javax.ws.rs.client.WebTarget;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.http.client.HttpResponseException;
|
import org.apache.http.client.HttpResponseException;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -93,7 +94,9 @@ import org.openmetadata.schema.entity.teams.TeamHierarchy;
|
|||||||
import org.openmetadata.schema.entity.teams.User;
|
import org.openmetadata.schema.entity.teams.User;
|
||||||
import org.openmetadata.schema.type.ApiStatus;
|
import org.openmetadata.schema.type.ApiStatus;
|
||||||
import org.openmetadata.schema.type.ChangeDescription;
|
import org.openmetadata.schema.type.ChangeDescription;
|
||||||
|
import org.openmetadata.schema.type.ChangeEvent;
|
||||||
import org.openmetadata.schema.type.EntityReference;
|
import org.openmetadata.schema.type.EntityReference;
|
||||||
|
import org.openmetadata.schema.type.EventType;
|
||||||
import org.openmetadata.schema.type.ImageList;
|
import org.openmetadata.schema.type.ImageList;
|
||||||
import org.openmetadata.schema.type.Include;
|
import org.openmetadata.schema.type.Include;
|
||||||
import org.openmetadata.schema.type.MetadataOperation;
|
import org.openmetadata.schema.type.MetadataOperation;
|
||||||
@ -932,6 +935,86 @@ public class TeamResourceTest extends EntityResourceTest<Team, CreateTeam> {
|
|||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void put_addDeleteTeamUser_200(TestInfo test) throws IOException {
|
||||||
|
// Create a team of type GROUP
|
||||||
|
TeamResourceTest teamResourceTest = new TeamResourceTest();
|
||||||
|
Team team =
|
||||||
|
teamResourceTest.createEntity(teamResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS);
|
||||||
|
UUID teamId = team.getId();
|
||||||
|
|
||||||
|
// Add user to the team
|
||||||
|
UserResourceTest userResourceTest = new UserResourceTest();
|
||||||
|
User user1 =
|
||||||
|
userResourceTest.createEntity(userResourceTest.createRequest(test, 1), ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
User user2 =
|
||||||
|
userResourceTest.createEntity(userResourceTest.createRequest(test, 2), ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
addAndCheckTeamUser(
|
||||||
|
teamId,
|
||||||
|
List.of(user1.getEntityReference(), user2.getEntityReference()),
|
||||||
|
OK,
|
||||||
|
2,
|
||||||
|
ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
CreateTeam createDepartmentTeam =
|
||||||
|
createRequest(test)
|
||||||
|
.withDomains(List.of(DOMAIN.getFullyQualifiedName()))
|
||||||
|
.withTeamType(DEPARTMENT);
|
||||||
|
Team departmentTeam = createEntity(createDepartmentTeam, ADMIN_AUTH_HEADERS);
|
||||||
|
|
||||||
|
// Add user only for GROUP type team
|
||||||
|
assertResponse(
|
||||||
|
() ->
|
||||||
|
addAndCheckTeamUser(
|
||||||
|
departmentTeam.getId(),
|
||||||
|
List.of(user1.getEntityReference(), user2.getEntityReference()),
|
||||||
|
OK,
|
||||||
|
0,
|
||||||
|
ADMIN_AUTH_HEADERS),
|
||||||
|
BAD_REQUEST,
|
||||||
|
CatalogExceptionMessage.invalidTeamUpdateUsers(departmentTeam.getTeamType()));
|
||||||
|
|
||||||
|
deleteAndCheckTeamUser(teamId, user1.getId(), 1, ADMIN_AUTH_HEADERS);
|
||||||
|
deleteAndCheckTeamUser(teamId, user2.getId(), 0, ADMIN_AUTH_HEADERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAndCheckTeamUser(
|
||||||
|
UUID teamId,
|
||||||
|
List<EntityReference> users,
|
||||||
|
Response.Status status,
|
||||||
|
int expectedUserCount,
|
||||||
|
Map<String, String> authHeaders)
|
||||||
|
throws IOException {
|
||||||
|
WebTarget target = getResource("teams/" + teamId + "/users");
|
||||||
|
ChangeEvent event = TestUtils.put(target, users, ChangeEvent.class, status, authHeaders);
|
||||||
|
Team team = getEntity(teamId, authHeaders);
|
||||||
|
validateEntityReferences(team.getUsers());
|
||||||
|
assertEquals(expectedUserCount, team.getUsers().size());
|
||||||
|
validateChangeEvents(
|
||||||
|
team,
|
||||||
|
event.getTimestamp(),
|
||||||
|
EventType.ENTITY_UPDATED,
|
||||||
|
event.getChangeDescription(),
|
||||||
|
authHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteAndCheckTeamUser(
|
||||||
|
UUID teamId, UUID userId, int expectedUserCount, Map<String, String> authHeaders)
|
||||||
|
throws IOException {
|
||||||
|
WebTarget target = getResource("teams/" + teamId + "/users/" + userId);
|
||||||
|
ChangeEvent change = TestUtils.delete(target, ChangeEvent.class, authHeaders);
|
||||||
|
Team team = getEntity(teamId, authHeaders);
|
||||||
|
assertEquals(expectedUserCount, team.getUsers().size());
|
||||||
|
validateChangeEvents(
|
||||||
|
team,
|
||||||
|
change.getTimestamp(),
|
||||||
|
EventType.ENTITY_UPDATED,
|
||||||
|
change.getChangeDescription(),
|
||||||
|
authHeaders);
|
||||||
|
}
|
||||||
|
|
||||||
private static void validateTeam(
|
private static void validateTeam(
|
||||||
Team team,
|
Team team,
|
||||||
String expectedDescription,
|
String expectedDescription,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user