fix:(userRole): 实现数据清理细节

This commit is contained in:
zhansihu 2024-03-14 16:38:37 +08:00
parent fcda1f3281
commit 790d5c15a8
5 changed files with 131 additions and 19 deletions

View File

@ -95,6 +95,12 @@
<artifactId>feign-httpclient</artifactId>
<version>${feign-httpclient.version}</version>
</dependency>
<dependency>
<groupId>cn.axzo.maokai</groupId>
<artifactId>maokai-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>

View File

@ -1,8 +1,17 @@
package cn.axzo.tyr.server.job;
import cn.axzo.basics.common.BeanMapper;
import cn.axzo.maokai.api.client.CooperateShipQueryApi;
import cn.axzo.maokai.api.vo.request.PersonIdentityCheckReq;
import cn.axzo.pokonyan.config.redis.RedisUtil;
import cn.axzo.tyr.server.repository.dao.SaasRoleUserRelationDao;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import cn.axzo.tyr.server.util.RpcInternalUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.XxlJob;
@ -17,11 +26,9 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
/**
* 用户角色关系清理任务
@ -33,38 +40,59 @@ import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class UserRoleRelationCleanJob extends IJobHandler {
private static final String CACHE_KEY = "tyr:job:u-r-r-c";
private volatile boolean runFlag = false;
@Qualifier("userRoleCleanExecutor")
@Autowired
private ExecutorService userRoleCleanExecutor;
@Autowired
private SaasRoleUserRelationDao roleUserRelationDao;
@Autowired
private CooperateShipQueryApi cooperateShipQueryApi;
@XxlJob("userRoleRelationCleanJob")
@Override
public ReturnT<String> execute(String param) throws Exception {
StopWatch watch = new StopWatch("userRoleRelationCleanJob");
XxlJobLogger.log("start user role relation clean job param{}", param);
CleanTarget cleanParam = parseParam(param);
//加载待处理数据
watch.start("load data");
loadCleanTarget(cleanParam);
watch.stop();
watch.start("check clean");
runFlag = true;
Integer page = 1;
while (runFlag) {
List<CleanTarget> targetList = pullCleanTarget(cleanParam, page);
if (CollectionUtil.isEmpty(targetList)) {
XxlJobLogger.log("no target need to clean");
break;
}
for (CleanTarget target : targetList) {
CompletableFuture.runAsync(() -> doClean(target), userRoleCleanExecutor);
CleanTarget target = getTarget();
if (target == null) {
XxlJobLogger.log("all clean target are processed");
}
//数据库并发锁
CompletableFuture.runAsync(() -> doClean(target), userRoleCleanExecutor);
}
watch.stop();
XxlJobLogger.log("user role relation clean job finish");
XxlJobLogger.log("user role relation clean job finish, cost:{} s", watch.getTotalTimeSeconds());
return ReturnT.SUCCESS;
}
private CleanTarget getTarget() {
try {
String cacheTarget = RedisUtil.ListOps.lRightPop(CACHE_KEY);
return StrUtil.isBlank(cacheTarget) ? null : JSON.parseObject(cacheTarget, CleanTarget.class);
} catch (Exception ex) {
XxlJobLogger.log("get cached data error:{}", ex.getMessage());
}
return null;
}
@Override
public void destroy() throws InvocationTargetException, IllegalAccessException {
this.runFlag = false;
@ -73,16 +101,49 @@ public class UserRoleRelationCleanJob extends IJobHandler {
private void doClean(CleanTarget target) {
try {
TimeUnit.SECONDS.sleep(5);
//检查person profile是否存在 ?
//检查人是否还在工作台
PersonIdentityCheckReq checkReq = BeanMapper.copyBean(target, PersonIdentityCheckReq.class);
Boolean exists = RpcInternalUtil.rpcProcessor(() -> cooperateShipQueryApi.checkPersonIdentity(checkReq),
"check identity in workspace", checkReq).getData();
if (exists) {
return;
}
XxlJobLogger.log("---------> user role relation need to clean for:{} <----------", JSON.toJSONString(target));
roleUserRelationDao.cleanTargetRelation(target);
} catch (Exception ex) {
XxlJobLogger.log("clean target:{} error", JSON.toJSONString(target));
log.warn("clean target:{} error", JSON.toJSONString(target), ex);
}
}
private List<CleanTarget> pullCleanTarget(CleanTarget cleanParam, Integer page) {
XxlJobLogger.log("get bat clean target, page:{}", page);
return Collections.singletonList(new CleanTarget());
private void loadCleanTarget(CleanTarget cleanParam) {
XxlJobLogger.log("clear cache data");
RedisUtil.KeyOps.delete(CACHE_KEY);
XxlJobLogger.log("load all clean target data from db");
SaasRoleUserRelation condition = new SaasRoleUserRelation();
condition.setOuId(cleanParam.getOuId());
condition.setWorkspaceId(cleanParam.getWorkspaceId());
condition.setNaturalPersonId(cleanParam.getPersonId());
int page = 1;
int count = 0;
while (true) {
Page<SaasRoleUserRelation> pageResult = roleUserRelationDao.batListCleanRelation(condition, new Page<>(page++, 20));
List<SaasRoleUserRelation> records = pageResult.getRecords();
if (CollectionUtil.isEmpty(records)) {
break;
}
count += records.size();
records.forEach(r -> RedisUtil.ListOps.lLeftPush("key", JSON.toJSONString(CleanTarget.builder()
.ouId(r.getOuId())
.workspaceId(r.getWorkspaceId())
.personId(r.getNaturalPersonId())
.identityId(r.getIdentityId())
.identityType(r.getIdentityType())
.build())));
}
XxlJobLogger.log("all target need to check count:{}", count);
}
private CleanTarget parseParam(String param) {
@ -98,10 +159,14 @@ public class UserRoleRelationCleanJob extends IJobHandler {
@AllArgsConstructor
public static class CleanTarget {
private Long personId;
private Long ouId;
private Long workspaceId;
private Long personId;
private Long identityId;
private Integer identityType;
}
}

View File

@ -6,12 +6,16 @@ import cn.axzo.tyr.client.common.enums.RoleResourceTypeEnum;
import cn.axzo.tyr.client.model.BaseWorkspaceModel;
import cn.axzo.tyr.client.model.enums.IdentityType;
import cn.axzo.tyr.client.model.roleuser.dto.IdentityInfo;
import cn.axzo.tyr.server.job.UserRoleRelationCleanJob;
import cn.axzo.tyr.server.model.RoleUserInfo;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Repository;
@ -166,5 +170,17 @@ public class SaasRoleUserRelationDao extends ServiceImpl<SaasRoleUserRelationMap
}
public Page<SaasRoleUserRelation> batListCleanRelation(SaasRoleUserRelation cleanParam, IPage<SaasRoleUserRelation> page) {
return this.baseMapper.batListCleanRelation(page, cleanParam);
}
public void cleanTargetRelation(UserRoleRelationCleanJob.CleanTarget target) {
this.remove(new LambdaQueryWrapper<SaasRoleUserRelation>()
.eq(SaasRoleUserRelation::getOuId, target.getOuId())
.eq(SaasRoleUserRelation::getWorkspaceId, target.getWorkspaceId())
.eq(SaasRoleUserRelation::getIdentityId, target.getIdentityId())
.eq(SaasRoleUserRelation::getIdentityType, target.getIdentityType()));
}
}

View File

@ -1,12 +1,15 @@
package cn.axzo.tyr.server.repository.mapper;
import cn.axzo.tyr.server.repository.entity.SaasRole;
import cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface SaasRoleUserRelationMapper extends BaseMapper<SaasRoleUserRelation> {
Page<SaasRoleUserRelation> batListCleanRelation(IPage<SaasRoleUserRelation> page, @Param("param") SaasRoleUserRelation cleanParam);
}

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.axzo.tyr.server.repository.mapper.SaasRoleUserRelationMapper">
<select id="batListCleanRelation" resultType="cn.axzo.tyr.server.repository.entity.SaasRoleUserRelation">
SELECT DISTINCT ou_id AS ouId, workspace_id AS workspaceId,
natural_person_id AS naturalPersonId,
identity_id AS identityId, identity_type AS identityType
FROM saas_role_user_relation
WHERE is_delete = 0
<if test="param.ouId !=0 and param.ouId != null">
AND ou_id = #{param.ouId}
</if>
<if test="param.workspaceId !=0 and param.workspaceId != null">
AND workspace_id = #{param.workspaceId}
</if>
<if test="param.personId !=0 and param.personId != null">
AND natural_person_id = #{param.personId}
</if>
</select>
</mapper>