Skip to content

Commit

Permalink
apache#4873 support list group
Browse files Browse the repository at this point in the history
  • Loading branch information
LiuQhahah committed Sep 25, 2024
1 parent 7f2f3c9 commit eb8cba6
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,15 @@ public Group getGroup(String group) throws NoSuchGroupException, NoSuchMetalakeE
return getMetalake().getGroup(group);
}


public Group[] listGroups(){
return getMetalake().listGroups();
}

public String[] listGroupNames(){
return getMetalake().listGroupNames();
}

/**
* Gets a Role.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import org.apache.gravitino.dto.responses.DropResponse;
import org.apache.gravitino.dto.responses.EntityListResponse;
import org.apache.gravitino.dto.responses.ErrorResponse;
import org.apache.gravitino.dto.responses.GroupListResponse;
import org.apache.gravitino.dto.responses.GroupResponse;
import org.apache.gravitino.dto.responses.NameListResponse;
import org.apache.gravitino.dto.responses.OwnerResponse;
Expand Down Expand Up @@ -582,6 +583,43 @@ public Group getGroup(String group) throws NoSuchGroupException, NoSuchMetalakeE
return resp.getGroup();
}


/**
* Lists the groups
*
* @return The Group list
*/
public Group[] listGroups() {
Map<String,String> params = new HashMap<>();
GroupListResponse resp =
restClient.get(
String.format(API_METALAKES_GROUPS_PATH,name(),BLANK_PLACE_HOLDER),
params,
GroupListResponse.class,
Collections.emptyMap(),
ErrorHandlers.groupErrorHandler()
);
resp.validate();
return resp.getGroups();
}

/**
* Lists the group names
*
* @return The Group Name List
*/
public String[] listGroupNames(){
NameListResponse resp = restClient.get(
String.format(API_METALAKES_GROUPS_PATH,name(),
BLANK_PLACE_HOLDER),
NameListResponse.class,
Collections.emptyMap(),
ErrorHandlers.groupErrorHandler()
);
resp.validate();
return resp.getNames();
}

/**
* Gets a Role.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.apache.hc.core5.http.HttpStatus.SC_SERVER_ERROR;

import com.fasterxml.jackson.core.JsonProcessingException;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.gravitino.authorization.Group;
import org.apache.gravitino.authorization.User;
import org.apache.gravitino.dto.AuditDTO;
Expand All @@ -33,15 +37,18 @@
import org.apache.gravitino.dto.requests.GroupAddRequest;
import org.apache.gravitino.dto.requests.UserAddRequest;
import org.apache.gravitino.dto.responses.ErrorResponse;
import org.apache.gravitino.dto.responses.GroupListResponse;
import org.apache.gravitino.dto.responses.GroupResponse;
import org.apache.gravitino.dto.responses.MetalakeResponse;
import org.apache.gravitino.dto.responses.NameListResponse;
import org.apache.gravitino.dto.responses.RemoveResponse;
import org.apache.gravitino.dto.responses.UserResponse;
import org.apache.gravitino.exceptions.GroupAlreadyExistsException;
import org.apache.gravitino.exceptions.NoSuchGroupException;
import org.apache.gravitino.exceptions.NoSuchMetalakeException;
import org.apache.gravitino.exceptions.NoSuchUserException;
import org.apache.gravitino.exceptions.UserAlreadyExistsException;
import org.apache.hadoop.security.Groups;
import org.apache.hc.core5.http.HttpStatus;
import org.apache.hc.core5.http.Method;
import org.junit.jupiter.api.Assertions;
Expand Down Expand Up @@ -273,6 +280,55 @@ public void testRemoveGroups() throws Exception {
Assertions.assertThrows(RuntimeException.class, () -> gravitinoClient.removeGroup(groupName));
}


@Test
public void testListGroupNames() throws JsonProcessingException {
String groupPath = withSlash(String.format(API_METALAKES_GROUPS_PATH,metalakeName,""));
NameListResponse listResponse = new NameListResponse(new String[] {"group1","group2"});
buildMockResource(Method.GET,groupPath,null,listResponse,SC_OK);
Assertions.assertArrayEquals(new String[]{"group1","group2"},gravitinoClient.listGroupNames());
ErrorResponse errRespNoMetaLake = ErrorResponse.notFound(NoSuchMetalakeException.class.getSimpleName(),"metalake not found");
buildMockResource(Method.GET,groupPath,null,errRespNoMetaLake,SC_NOT_FOUND);
Exception ex = Assertions.assertThrows(
NoSuchMetalakeException.class,()->{
gravitinoClient.listGroupNames();
}
);
Assertions.assertEquals("metalake not found",ex.getMessage());

// Test RuntimeException
ErrorResponse errResp = ErrorResponse.internalError("internal error");
buildMockResource(Method.GET,groupPath,null,errResp,SC_SERVER_ERROR);

Assertions.assertThrows(RuntimeException.class,()->gravitinoClient.listGroupNames());
}

@Test
public void testListGroups() throws JsonProcessingException {
String groupPath = withSlash(String.format(API_METALAKES_GROUPS_PATH,metalakeName,""));
GroupDTO group1 = mockGroupDTO("group1");
GroupDTO group2 = mockGroupDTO("group2");
GroupDTO group3 = mockGroupDTO("group3");
Map<String,String> params = new HashMap<>();
GroupListResponse listResponse = new GroupListResponse(new GroupDTO[]{group1,group2,group3});
buildMockResource(Method.GET,groupPath,params,null,listResponse,SC_OK);

Group[] groups = gravitinoClient.listGroups();
Assertions.assertEquals(3,groups.length);
assertGroup(group1,groups[0]);
assertGroup(group2,groups[1]);
assertGroup(group3,groups[2]);
ErrorResponse errResNoMetaLake = ErrorResponse.notFound(NoSuchMetalakeException.class.getSimpleName(),"metalake not found");
buildMockResource(Method.GET,groupPath,params,null,errResNoMetaLake,SC_NOT_FOUND);
Exception ex = Assertions.assertThrows(NoSuchMetalakeException.class,()-> gravitinoClient.listGroups());
Assertions.assertEquals("metalake not found",ex.getMessage());
// Test RuntimeException
ErrorResponse errResp = ErrorResponse.internalError("internal error");
buildMockResource(Method.GET,groupPath,params,null,errResp,SC_SERVER_ERROR);
Assertions.assertThrows(RuntimeException.class,()->gravitinoClient.listGroups());
}


private UserDTO mockUserDTO(String name) {
return UserDTO.builder()
.withName(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,12 @@

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.gravitino.Configs;
import org.apache.gravitino.auth.AuthConstants;
import org.apache.gravitino.authorization.Group;
Expand Down Expand Up @@ -97,8 +101,21 @@ void testManageGroups() {
// Get a not-existed group
Assertions.assertThrows(NoSuchGroupException.class, () -> metalake.getGroup("not-existed"));


// List groups
String anotherGroups = "group2#456";
metalake.addGroup(anotherGroups);
String[] groupNames = metalake.listGroupNames();
Arrays.sort(groupNames);
Assertions.assertEquals(Lists.newArrayList(groupName,anotherGroups),Arrays.asList(groupNames));




Assertions.assertTrue(metalake.removeGroup(groupName));
Assertions.assertTrue(metalake.removeGroup(anotherGroups));
Assertions.assertFalse(metalake.removeGroup(groupName));
Assertions.assertFalse(metalake.removeGroup(anotherGroups));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,14 @@ public static GroupDTO toDTO(Group group) {
.build();
}


public static GroupDTO[] toDTOs(Group[] groups){
if (ArrayUtils.isEmpty(groups)){
return new GroupDTO[0];
}
return Arrays.stream(groups).map(DTOConverters::toDTO).toArray(GroupDTO[]::new);
}

/**
* Converts a role implementation to a RoleDTO.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,9 @@ Group getGroup(String metalake, String group)
*
* @return The list of groups
*/
Group[] listGroup(Namespace namespace);
Group[] listGroup(String metalake);

String[] listGroupNames(String metalake);

/**
* Grant roles to a user.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,13 @@ public Group getGroup(String metalake, String group)
}

@Override
public Group[] listGroup(Namespace namespace) {
return userGroupManager.listGroups(namespace);
public Group[] listGroup(String metalake) {
return userGroupManager.listGroups(metalake);
}

@Override
public String[] listGroupNames(String metalake) {
return userGroupManager.listGroupNames(metalake);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
import com.google.common.collect.Lists;
import java.io.IOException;
import java.time.Instant;
import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import org.apache.gravitino.Entity;
import org.apache.gravitino.Entity.EntityType;
import org.apache.gravitino.EntityAlreadyExistsException;
import org.apache.gravitino.EntityStore;
import org.apache.gravitino.Field;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.Namespace;
import org.apache.gravitino.exceptions.GroupAlreadyExistsException;
Expand All @@ -39,6 +42,7 @@
import org.apache.gravitino.meta.UserEntity;
import org.apache.gravitino.storage.IdGenerator;
import org.apache.gravitino.utils.PrincipalUtils;
import org.glassfish.jersey.internal.guava.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -182,14 +186,20 @@ private void checkMetalakeExists(NameIdentifier ident) throws NoSuchMetalakeExce
}
}

Group[] listGroups(Namespace namespace) {
NameIdentifier groupIdent = NameIdentifier.of(namespace.levels());
checkMetalakeExists(groupIdent);
Group[] listGroups(String metalake) {
AuthorizationUtils.checkMetalakeExists(metalake);
Namespace namespace = AuthorizationUtils.ofGroupNamespace(metalake);

try {
return store.list(namespace, GroupEntity.class, EntityType.GROUP).toArray(new Group[0]);
} catch (Exception ioe) {
LOG.error("Listing Groups failed due to storage issues.", ioe);
throw new RuntimeException(ioe);
}
}

String[] listGroupNames(String metalake){
return Arrays.stream(listGroups(metalake)).map(Group::name).toArray(String[]::new);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,16 @@ public Group getGroup(String metalake, String group)
}

@Override
public Group[] listGroup(Namespace namespace) {
return dispatcher.listGroup(namespace);
public Group[] listGroup(String metalake) {
return dispatcher.listGroup(metalake);
}

@Override
public String[] listGroupNames(String metalake) {
return dispatcher.listGroupNames(metalake);
}


@Override
public User grantRolesToUser(String metalake, List<String> roles, String user)
throws NoSuchUserException, NoSuchRoleException, NoSuchMetalakeException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ public <E extends Entity & HasIdentifier> List<E> list(
return (List<E>) TopicMetaService.getInstance().listTopicsByNamespace(namespace);
case TAG:
return (List<E>) TagMetaService.getInstance().listTagsByNamespace(namespace);
case GROUP:
return (List<E>) GroupMetaService.getInstance().listGroupsByNamespace(namespace);
default:
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for list operation", entityType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@ public String selectGroupIdBySchemaIdAndName(
+ " AND deleted_at = 0";
}

public String listGroupsByMetalakeId(@Param("metalakeId") Long metalakeId){
return "SELECT group_id as groupId, group_name as groupName, metalake_id as metalakeId,"
+ " audit_info as auditInfo, current_version as currentVersion, last_version as lastVersion,"
+ " deleted_at as deletedAt FROM " + GROUP_TABLE_NAME + " WHERE metalake_id = #{metalakeId}"
+ " AND deleted_at = 0";
}

public String selectGroupMetaByMetalakeIdAndName(
@Param("metalakeId") Long metalakeId, @Param("groupName") String name) {
return "SELECT group_id as groupId, group_name as groupName,"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.apache.gravitino.storage.relational.mapper;

import java.util.List;
import org.apache.gravitino.authorization.Group;
import org.apache.gravitino.storage.relational.po.GroupPO;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
Expand Down Expand Up @@ -51,6 +52,12 @@ Long selectGroupIdBySchemaIdAndName(
GroupPO selectGroupMetaByMetalakeIdAndName(
@Param("metalakeId") Long metalakeId, @Param("groupName") String name);

@SelectProvider(
type = GroupMetaSQLProviderFactory.class,
method = "listGroupsByMetalakeId")
List<GroupPO> selectGroupsMetaByMetalakeId(@Param("metalakeId") Long metalakeId);


@InsertProvider(type = GroupMetaSQLProviderFactory.class, method = "insertGroupMeta")
void insertGroupMeta(@Param("groupMeta") GroupPO groupPO);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public static String updateGroupMeta(
public static String listGroupsByRoleId(@Param("roleId") Long roleId) {
return getProvider().listGroupsByRoleId(roleId);
}
public static String listGroupsByMetalake(@Param("metalakeId")Long metalakeId){

return getProvider().listGroupsByMetalakeId(metalakeId);
}

public static String deleteGroupMetasByLegacyTimeline(
@Param("legacyTimeline") Long legacyTimeline, @Param("limit") int limit) {
Expand Down
Loading

0 comments on commit eb8cba6

Please sign in to comment.