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

[#2705] feat(core): Add the relational backend for User Entity #2850

Merged
merged 24 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from 11 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 @@ -6,6 +6,7 @@

import com.datastrato.gravitino.Namespace;
import com.datastrato.gravitino.meta.UserEntity;
import com.google.common.collect.Lists;
import java.util.Collection;

public class UserEntitySerDe implements ProtoSerDe<UserEntity, User> {
Expand All @@ -32,7 +33,8 @@ public UserEntity deserialize(User user, Namespace namespace) {
.withId(user.getId())
.withName(user.getName())
.withNamespace(namespace)
.withAuditInfo(new AuditInfoSerDe().deserialize(user.getAuditInfo(), namespace));
.withAuditInfo(new AuditInfoSerDe().deserialize(user.getAuditInfo(), namespace))
.withRoles(Lists.newArrayList());

if (user.getRolesCount() > 0) {
builder.withRoles(user.getRolesList());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
import com.datastrato.gravitino.meta.SchemaEntity;
import com.datastrato.gravitino.meta.TableEntity;
import com.datastrato.gravitino.meta.TopicEntity;
import com.datastrato.gravitino.meta.UserEntity;
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.MetalakeMetaService;
import com.datastrato.gravitino.storage.relational.service.SchemaMetaService;
import com.datastrato.gravitino.storage.relational.service.TableMetaService;
import com.datastrato.gravitino.storage.relational.service.TopicMetaService;
import com.datastrato.gravitino.storage.relational.service.UserMetaService;
import com.datastrato.gravitino.storage.relational.session.SqlSessionFactoryHelper;
import java.io.IOException;
import java.util.List;
Expand Down Expand Up @@ -95,6 +97,8 @@ public <E extends Entity & HasIdentifier> void insert(E e, boolean overwritten)
FilesetMetaService.getInstance().insertFileset((FilesetEntity) e, overwritten);
} else if (e instanceof TopicEntity) {
TopicMetaService.getInstance().insertTopic((TopicEntity) e, overwritten);
} else if (e instanceof UserEntity) {
UserMetaService.getInstance().insertUser((UserEntity) e, overwritten);
} else {
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for insert operation", e.getClass());
Expand Down Expand Up @@ -140,6 +144,8 @@ public <E extends Entity & HasIdentifier> E get(
return (E) FilesetMetaService.getInstance().getFilesetByIdentifier(ident);
case TOPIC:
return (E) TopicMetaService.getInstance().getTopicByIdentifier(ident);
case USER:
return (E) UserMetaService.getInstance().getUserByIdentifier(ident);
default:
throw new UnsupportedEntityTypeException(
"Unsupported entity type: %s for get operation", entityType);
Expand All @@ -161,6 +167,8 @@ public boolean delete(NameIdentifier ident, Entity.EntityType entityType, boolea
return FilesetMetaService.getInstance().deleteFileset(ident);
case TOPIC:
return TopicMetaService.getInstance().deleteTopic(ident);
case USER:
return UserMetaService.getInstance().deleteUser(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,42 @@
/*
* Copyright 2024 Datastrato Pvt Ltd.
* This software is licensed under the Apache License version 2.
*/

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

import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

/**
* 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 RoleMetaMapper {
String ROLE_TABLE_NAME = "role_meta";
String RELATION_TABLE_NAME = "user_role_rel";

@Select(
"SELECT role_id as roleId FROM "
+ ROLE_TABLE_NAME
+ " WHERE metalake_id = #{metalakeId} AND role_name = #{roleName}"
+ " AND deleted_at = 0")
Long selectRoleIdByMetalakeIdAndName(
@Param("metalakeId") Long metalakeId, @Param("roleName") String name);

@Select(
"SELECT ro.role_name as roleName"
+ " FROM "
+ ROLE_TABLE_NAME
+ " ro JOIN "
+ 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<String> listRoleNameByUserId(@Param("userId") Long userId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/*
* 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.UserPO;
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 UserMetaMapper {
String TABLE_NAME = "user_meta";

@Select(
"SELECT user_id as userId FROM "
+ TABLE_NAME
+ " WHERE metalake_id = #{metalakeId} AND user_name = #{userName}"
+ " AND deleted_at = 0")
Long selectUserIdBySchemaIdAndName(
@Param("metalakeId") Long metalakeId, @Param("userName") String name);

@Select(
"SELECT user_id as userId, user_name as userName,"
+ " 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 user_name = #{userName}"
+ " AND deleted_at = 0")
UserPO selectUserMetaByMetalakeIdAndName(
@Param("metalakeId") Long metalakeId, @Param("userName") String name);

@Insert(
"INSERT INTO "
+ TABLE_NAME
+ "(user_id, user_name,"
+ " metalake_id, audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES("
+ " #{userMeta.userId},"
+ " #{userMeta.userName},"
+ " #{userMeta.metalakeId},"
+ " #{userMeta.auditInfo},"
+ " #{userMeta.currentVersion},"
+ " #{userMeta.lastVersion},"
+ " #{userMeta.deletedAt}"
+ " )")
void insertUserMeta(@Param("userMeta") UserPO userPO);

@Insert(
"INSERT INTO "
+ TABLE_NAME
+ "(user_id, user_name,"
+ "metalake_id, audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES("
+ " #{userMeta.userId},"
+ " #{userMeta.userName},"
+ " #{userMeta.metalakeId},"
+ " #{userMeta.auditInfo},"
+ " #{userMeta.currentVersion},"
+ " #{userMeta.lastVersion},"
+ " #{userMeta.deletedAt}"
+ " )"
+ " ON DUPLICATE KEY UPDATE"
+ " user_name = #{userMeta.userName},"
+ " metalake_id = #{userMeta.metalakeId},"
+ " audit_info = #{userMeta.auditInfo},"
+ " current_version = #{userMeta.currentVersion},"
+ " last_version = #{userMeta.lastVersion},"
+ " deleted_at = #{userMeta.deletedAt}")
void insertUserMetaOnDuplicateKeyUpdate(@Param("userMeta") UserPO userPO);

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

@Update(
"UPDATE "
+ TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE metalake_id = #{metalakeId} AND deleted_at = 0")
void softDeleteUserMetasByMetalakeId(@Param("metalakeId") Long metalakeId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* 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.UserRoleRelPO;
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 UserRoleRelMapper {
String TABLE_NAME = "user_role_rel";

@Insert({
"<script>",
"INSERT INTO "
+ TABLE_NAME
+ "(user_id, role_id,"
+ " audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES ",
"<foreach collection='userRoleRels' item='item' separator=','>",
"(#{item.userId},"
+ " #{item.roleId},"
+ " #{item.auditInfo},"
+ " #{item.currentVersion},"
+ " #{item.lastVersion},"
+ " #{item.deletedAt})",
"</foreach>",
"</script>"
})
void batchInsertUserRoleRel(@Param("userRoleRels") List<UserRoleRelPO> userRoleRelPOs);

@Insert({
"<script>",
"INSERT INTO "
+ TABLE_NAME
+ "(user_id, role_id,"
+ " audit_info,"
+ " current_version, last_version, deleted_at)"
+ " VALUES ",
"<foreach collection='userRoleRels' item='item' separator=','>",
"(#{item.userId},"
+ " #{item.roleId},"
+ " #{item.auditInfo},"
+ " #{item.currentVersion},"
+ " #{item.lastVersion},"
+ " #{item.deletedAt})",
"</foreach>",
" ON DUPLICATE KEY UPDATE"
+ " user_id = VALUES(user_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 batchInsertUserRoleRelOnDuplicateKeyUpdate(
@Param("userRoleRels") List<UserRoleRelPO> userRoleRelPOs);

@Update(
"UPDATE "
+ TABLE_NAME
+ " SET deleted_at = UNIX_TIMESTAMP(CURRENT_TIMESTAMP(3)) * 1000.0"
+ " WHERE user_id = #{userId} AND deleted_at = 0")
void softDeleteUserRoleRelByUserId(Long userId);
}
Loading
Loading