Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#2851] feat(core): Add relational backend for Group Entity #3031

Merged
merged 39 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
bf74cf6
fix: conflict
lw-yang Apr 9, 2024
0d11446
fix: spotlessApply
lw-yang Apr 9, 2024
dc06f1c
fix: conflict
lw-yang Apr 9, 2024
23d09ca
Merge branch 'main' into issue-2705
lw-yang Apr 9, 2024
47c4298
Merge branch 'main' into issue-2705
lw-yang Apr 9, 2024
981771a
fix: conflict
lw-yang Apr 15, 2024
a51b619
fix: checkSQLException
lw-yang Apr 15, 2024
dceb555
Merge branch 'main' into issue-2705
lw-yang Apr 16, 2024
1830d52
fix: role_meta table
lw-yang Apr 16, 2024
7c9246f
fix: h2 role_meta
lw-yang Apr 16, 2024
2d454af
fix: conflict
lw-yang Apr 18, 2024
121b9c2
fix: conflict
lw-yang Apr 18, 2024
8f0e383
fix: user meta
lw-yang Apr 18, 2024
d17137b
fix: user meta
lw-yang Apr 19, 2024
c15ce31
fix: update audit
lw-yang Apr 19, 2024
a01f1dc
fix: licence
lw-yang Apr 19, 2024
2a1384d
Merge branch 'issue-2705' into issue-2851
lw-yang Apr 19, 2024
db74108
fix: group meta
lw-yang Apr 19, 2024
f8d79c5
Merge branch 'main' into issue-2851
lw-yang Apr 19, 2024
7f7fb6f
Merge branch 'main' into issue-2705
lw-yang Apr 19, 2024
53c5011
fix: 1. delete user when delete metalake without cascade.
lw-yang Apr 19, 2024
3a3c571
Merge branch 'main' into issue-2705
lw-yang Apr 19, 2024
86f98ef
Merge branch 'issue-2705' into issue-2851
lw-yang Apr 19, 2024
1871fa7
fix: polish
lw-yang Apr 19, 2024
20e6f61
fix: spotlessApply
lw-yang Apr 19, 2024
d186d6c
fix: test
lw-yang Apr 19, 2024
fc3a415
fix: polish
lw-yang Apr 19, 2024
0238185
fix: optimize
lw-yang Apr 19, 2024
295be70
Merge branch 'issue-2705' into issue-2851
lw-yang Apr 19, 2024
738dd19
fix: optimize
lw-yang Apr 19, 2024
90b800b
fix: not update user twice
lw-yang Apr 20, 2024
4932872
Merge branch 'issue-2705' into issue-2851
lw-yang Apr 20, 2024
9cab387
fix: polish
lw-yang Apr 20, 2024
e08bfc4
Merge branch 'main' into issue-2851
lw-yang Apr 20, 2024
5a9d57a
fix: conflict
lw-yang Apr 20, 2024
fa4b9d8
fix: spotlessApply
lw-yang Apr 20, 2024
888ad47
fix: polish
lw-yang Apr 22, 2024
505a7e8
Merge branch 'main' into issue-2851
lw-yang Apr 22, 2024
81d4606
fix: optimize
lw-yang Apr 22, 2024
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 @@ -20,6 +20,7 @@
import com.datastrato.gravitino.meta.BaseMetalake;
import com.datastrato.gravitino.meta.CatalogEntity;
import com.datastrato.gravitino.meta.FilesetEntity;
import com.datastrato.gravitino.meta.GroupEntity;
import com.datastrato.gravitino.meta.RoleEntity;
import com.datastrato.gravitino.meta.SchemaEntity;
import com.datastrato.gravitino.meta.TableEntity;
Expand All @@ -28,6 +29,7 @@
import com.datastrato.gravitino.storage.relational.converters.SQLExceptionConverterFactory;
import com.datastrato.gravitino.storage.relational.service.CatalogMetaService;
import com.datastrato.gravitino.storage.relational.service.FilesetMetaService;
import com.datastrato.gravitino.storage.relational.service.GroupMetaService;
import com.datastrato.gravitino.storage.relational.service.MetalakeMetaService;
import com.datastrato.gravitino.storage.relational.service.RoleMetaService;
import com.datastrato.gravitino.storage.relational.service.SchemaMetaService;
Expand Down Expand Up @@ -109,6 +111,8 @@ public <E extends Entity & HasIdentifier> void insert(E e, boolean overwritten)
UserMetaService.getInstance().insertUser((UserEntity) e, overwritten);
} else if (e instanceof RoleEntity) {
RoleMetaService.getInstance().insertRole((RoleEntity) e, overwritten);
} else if (e instanceof GroupEntity) {
GroupMetaService.getInstance().insertGroup((GroupEntity) e, overwritten);
} else {
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for insert operation", e.getClass());
Expand All @@ -134,6 +138,8 @@ public <E extends Entity & HasIdentifier> E update(
return (E) TopicMetaService.getInstance().updateTopic(ident, updater);
case USER:
return (E) UserMetaService.getInstance().updateUser(ident, updater);
case GROUP:
return (E) GroupMetaService.getInstance().updateGroup(ident, updater);
default:
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for update operation", entityType);
Expand All @@ -158,6 +164,8 @@ public <E extends Entity & HasIdentifier> E get(
return (E) TopicMetaService.getInstance().getTopicByIdentifier(ident);
case USER:
return (E) UserMetaService.getInstance().getUserByIdentifier(ident);
case GROUP:
return (E) GroupMetaService.getInstance().getGroupByIdentifier(ident);
default:
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for get operation", entityType);
Expand All @@ -181,6 +189,8 @@ public boolean delete(NameIdentifier ident, Entity.EntityType entityType, boolea
return TopicMetaService.getInstance().deleteTopic(ident);
case USER:
return UserMetaService.getInstance().deleteUser(ident);
case GROUP:
return GroupMetaService.getInstance().deleteGroup(ident);
default:
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for delete operation", entityType);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/

package com.datastrato.gravitino.storage.relational.mapper;

import com.datastrato.gravitino.storage.relational.po.GroupPO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

/**
* A MyBatis Mapper for table meta operation SQLs.
*
* <p>This interface class is a specification defined by MyBatis. It requires this interface class
* to identify the corresponding SQLs for execution. We can write SQLs in an additional XML file, or
* write SQLs with annotations in this interface Mapper. See: <a
* href="https://mybatis.org/mybatis-3/getting-started.html"></a>
*/
public interface GroupMetaMapper {
String TABLE_NAME = "group_meta";

@Select(
"SELECT group_id as groupId FROM "
+ TABLE_NAME
+ " WHERE metalake_id = #{metalakeId} AND group_name = #{groupName}"
+ " AND deleted_at = 0")
Long selectGroupIdBySchemaIdAndName(
@Param("metalakeId") Long metalakeId, @Param("groupName") String name);

@Select(
"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 "
+ TABLE_NAME
+ " WHERE metalake_id = #{metalakeId} AND group_name = #{groupName}"
+ " AND deleted_at = 0")
GroupPO selectGroupMetaByMetalakeIdAndName(
@Param("metalakeId") Long metalakeId, @Param("groupName") String name);

@Insert(
"INSERT INTO "
+ TABLE_NAME
+ "(group_id, group_name,"
+ " metalake_id, audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES("
+ " #{groupMeta.groupId},"
+ " #{groupMeta.groupName},"
+ " #{groupMeta.metalakeId},"
+ " #{groupMeta.auditInfo},"
+ " #{groupMeta.currentVersion},"
+ " #{groupMeta.lastVersion},"
+ " #{groupMeta.deletedAt}"
+ " )")
void insertGroupMeta(@Param("groupMeta") GroupPO groupPO);

@Insert(
"INSERT INTO "
+ TABLE_NAME
+ "(group_id, group_name,"
+ "metalake_id, audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES("
+ " #{groupMeta.groupId},"
+ " #{groupMeta.groupName},"
+ " #{groupMeta.metalakeId},"
+ " #{groupMeta.auditInfo},"
+ " #{groupMeta.currentVersion},"
+ " #{groupMeta.lastVersion},"
+ " #{groupMeta.deletedAt}"
+ " )"
+ " ON DUPLICATE KEY UPDATE"
+ " group_name = #{groupMeta.groupName},"
+ " metalake_id = #{groupMeta.metalakeId},"
+ " audit_info = #{groupMeta.auditInfo},"
+ " current_version = #{groupMeta.currentVersion},"
+ " last_version = #{groupMeta.lastVersion},"
+ " deleted_at = #{groupMeta.deletedAt}")
void insertGroupMetaOnDuplicateKeyUpdate(@Param("groupMeta") GroupPO groupPO);

@Update(
"UPDATE "
+ TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE group_id = #{groupId} AND deleted_at = 0")
void softDeleteGroupMetaByGroupId(@Param("groupId") Long groupId);

@Update(
"UPDATE "
+ TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE metalake_id = #{metalakeId} AND deleted_at = 0")
void softDeleteGroupMetasByMetalakeId(@Param("metalakeId") Long metalakeId);

@Update(
"UPDATE "
+ TABLE_NAME
+ " SET group_name = #{newGroupMeta.groupName},"
+ " metalake_id = #{newGroupMeta.metalakeId},"
+ " audit_info = #{newGroupMeta.auditInfo},"
+ " current_version = #{newGroupMeta.currentVersion},"
+ " last_version = #{newGroupMeta.lastVersion},"
+ " deleted_at = #{newGroupMeta.deletedAt}"
+ " WHERE group_id = #{oldGroupMeta.groupId}"
+ " AND group_name = #{oldGroupMeta.groupName}"
+ " AND metalake_id = #{oldGroupMeta.metalakeId}"
+ " AND audit_info = #{oldGroupMeta.auditInfo}"
+ " AND current_version = #{oldGroupMeta.currentVersion}"
+ " AND last_version = #{oldGroupMeta.lastVersion}"
+ " AND deleted_at = 0")
Integer updateGroupMeta(
@Param("newGroupMeta") GroupPO newGroupPO, @Param("oldGroupMeta") GroupPO oldGroupPO);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/

package com.datastrato.gravitino.storage.relational.mapper;

import com.datastrato.gravitino.storage.relational.po.GroupRoleRelPO;
import java.util.List;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;

/**
* A MyBatis Mapper for table meta operation SQLs.
*
* <p>This interface class is a specification defined by MyBatis. It requires this interface class
* to identify the corresponding SQLs for execution. We can write SQLs in an additional XML file, or
* write SQLs with annotations in this interface Mapper. See: <a
* href="https://mybatis.org/mybatis-3/getting-started.html"></a>
*/
public interface GroupRoleRelMapper {
String RELATION_TABLE_NAME = "group_role_rel";
String GROUP_TABLE_NAME = "group_meta";

@Insert({
"<script>",
"INSERT INTO "
+ RELATION_TABLE_NAME
+ "(group_id, role_id,"
+ " audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES ",
"<foreach collection='groupRoleRels' item='item' separator=','>",
"(#{item.groupId},"
+ " #{item.roleId},"
+ " #{item.auditInfo},"
+ " #{item.currentVersion},"
+ " #{item.lastVersion},"
+ " #{item.deletedAt})",
"</foreach>",
"</script>"
})
void batchInsertGroupRoleRel(@Param("groupRoleRels") List<GroupRoleRelPO> groupRoleRelPOS);

@Insert({
"<script>",
"INSERT INTO "
+ RELATION_TABLE_NAME
+ "(group_id, role_id,"
+ " audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES ",
"<foreach collection='groupRoleRels' item='item' separator=','>",
"(#{item.groupId},"
+ " #{item.roleId},"
+ " #{item.auditInfo},"
+ " #{item.currentVersion},"
+ " #{item.lastVersion},"
+ " #{item.deletedAt})",
"</foreach>",
" ON DUPLICATE KEY UPDATE"
+ " group_id = VALUES(group_id),"
+ " role_id = VALUES(role_id),"
+ " audit_info = VALUES(audit_info),"
+ " current_version = VALUES(current_version),"
+ " last_version = VALUES(last_version),"
+ " deleted_at = VALUES(deleted_at)",
"</script>"
})
void batchInsertGroupRoleRelOnDuplicateKeyUpdate(
@Param("groupRoleRels") List<GroupRoleRelPO> groupRoleRelPOS);

@Update(
"UPDATE "
+ RELATION_TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE group_id = #{groupId} AND deleted_at = 0")
void softDeleteGroupRoleRelByGroupId(@Param("groupId") Long groupId);

@Update({
"<script>",
"UPDATE "
+ RELATION_TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE group_id = #{groupId} AND role_id in (",
"<foreach collection='roleIds' item='roleId' separator=','>",
"#{roleId}",
"</foreach>",
") " + "AND deleted_at = 0",
"</script>"
})
void softDeleteGroupRoleRelByGroupAndRoles(
@Param("groupId") Long groupId, @Param("roleIds") List<Long> roleIds);

@Update(
"UPDATE "
+ RELATION_TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE group_id IN (SELECT group_id FROM "
+ GROUP_TABLE_NAME
+ " WHERE metalake_id = #{metalakeId} AND deleted_at = 0)"
+ " AND deleted_at = 0")
void softDeleteGroupRoleRelByMetalakeId(Long metalakeId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
*/
public interface RoleMetaMapper {
String ROLE_TABLE_NAME = "role_meta";
String RELATION_TABLE_NAME = "user_role_rel";
String USER_RELATION_TABLE_NAME = "user_role_rel";
String GROUP_RELATION_TABLE_NAME = "group_role_rel";

@Select(
"SELECT role_id as roleId FROM "
Expand All @@ -40,12 +41,27 @@ Long selectRoleIdByMetalakeIdAndName(
+ " FROM "
+ ROLE_TABLE_NAME
+ " ro JOIN "
+ RELATION_TABLE_NAME
+ USER_RELATION_TABLE_NAME
+ " re ON ro.role_id = re.role_id"
+ " WHERE re.user_id = #{userId}"
+ " AND ro.deleted_at = 0 AND re.deleted_at = 0")
List<RolePO> listRolesByUserId(@Param("userId") Long userId);

@Select(
"SELECT ro.role_id as roleId, ro.role_name as roleName,"
+ " ro.metalake_id as metalakeId, ro.properties as properties,"
+ " ro.securable_object as securableObject, ro.privileges as privileges,"
+ " ro.audit_info as auditInfo, ro.current_version as currentVersion,"
+ " ro.last_version as lastVersion, ro.deleted_at as deletedAt"
+ " FROM "
+ ROLE_TABLE_NAME
+ " ro JOIN "
+ GROUP_RELATION_TABLE_NAME
+ " ge ON ro.role_id = ge.role_id"
+ " WHERE ge.group_id = #{groupId}"
+ " AND ro.deleted_at = 0 AND ge.deleted_at = 0")
List<RolePO> listRolesByGroupId(Long groupId);

@Insert(
"INSERT INTO "
+ ROLE_TABLE_NAME
Expand Down
Loading
Loading