SysUserSessionServiceImplTest 测试父类替换

SysUserSessionDO.java 表结构新增字段 username;
create_tables.sql 修改
ruoyi-vue-pro.sql 修改
移除超时的在线用户-
This commit is contained in:
Lyon
2021-03-09 17:54:53 +08:00
parent bcb6a68b80
commit ea34197dd7
5 changed files with 173 additions and 124 deletions

View File

@ -38,6 +38,14 @@ public class SysUserSessionDO extends BaseDO {
* 关联 {@link SysUserDO#getId()}
*/
private Long userId;
/**
* 用户账号
*
* 冗余,因为账号可以变更
*/
private String username;
/**
* 用户 IP
*/

View File

@ -6,21 +6,24 @@ import cn.hutool.core.util.StrUtil;
import cn.iocoder.dashboard.common.pojo.PageResult;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.framework.security.core.LoginUser;
import cn.iocoder.dashboard.framework.tracer.core.util.TracerUtils;
import cn.iocoder.dashboard.modules.system.controller.auth.vo.session.SysUserSessionPageReqVO;
import cn.iocoder.dashboard.modules.system.controller.logger.vo.loginlog.SysLoginLogCreateReqVO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.auth.SysUserSessionDO;
import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.auth.SysUserSessionMapper;
import cn.iocoder.dashboard.modules.system.dal.redis.auth.SysLoginUserRedisDAO;
import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginLogTypeEnum;
import cn.iocoder.dashboard.modules.system.enums.logger.SysLoginResultEnum;
import cn.iocoder.dashboard.modules.system.service.auth.SysUserSessionService;
import cn.iocoder.dashboard.modules.system.service.logger.SysLoginLogService;
import cn.iocoder.dashboard.modules.system.service.user.SysUserService;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.time.Duration;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import static cn.iocoder.dashboard.util.collection.CollectionUtils.convertSet;
@ -36,14 +39,14 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
@Resource
private SecurityProperties securityProperties;
@Resource
private SysLoginUserRedisDAO loginUserRedisDAO;
@Resource
private SysUserSessionMapper userSessionMapper;
@Resource
private SysUserService userService;
@Resource
private SysLoginLogService loginLogService;
@Override
public String createUserSession(LoginUser loginUser, String userIp, String userAgent) {
@ -54,7 +57,7 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
loginUserRedisDAO.set(sessionId, loginUser);
// 写入 DB 中
SysUserSessionDO userSession = SysUserSessionDO.builder().id(sessionId)
.userId(loginUser.getId()).userIp(userIp).userAgent(userAgent)
.userId(loginUser.getId()).userIp(userIp).userAgent(userAgent).username(loginUser.getUsername())
.sessionTimeout(addTime(Duration.ofMillis(getSessionTimeoutMillis())))
.build();
userSessionMapper.insert(userSession);
@ -69,6 +72,7 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
loginUserRedisDAO.set(sessionId, loginUser);
// 更新 DB 中
SysUserSessionDO updateObj = SysUserSessionDO.builder().id(sessionId).build();
updateObj.setUsername(loginUser.getUsername());
updateObj.setUpdateTime(new Date());
updateObj.setSessionTimeout(addTime(Duration.ofMillis(getSessionTimeoutMillis())));
userSessionMapper.updateById(updateObj);
@ -109,16 +113,30 @@ public class SysUserSessionServiceImpl implements SysUserSessionService {
public long clearSessionTimeout() {
// 获取db里已经超时的用户列表
List<SysUserSessionDO> sessionTimeoutDOS = userSessionMapper.selectListBySessionTimoutLt();
List<String> timeoutIdList = sessionTimeoutDOS
Map<String, SysUserSessionDO> timeoutSessionDOMap = sessionTimeoutDOS
.stream()
.filter(sessionDO -> loginUserRedisDAO.get(sessionDO.getId()) == null)
.map(SysUserSessionDO::getId)
.collect(Collectors.toList());
.collect(Collectors.toMap(SysUserSessionDO::getId, o -> o));
// 确认已经超时,按批次移出在线用户列表
if (CollUtil.isNotEmpty(timeoutIdList)) {
Lists.partition(timeoutIdList, 100).forEach(userSessionMapper::deleteBatchIds);
if (CollUtil.isNotEmpty(timeoutSessionDOMap)) {
Lists.partition(new ArrayList<>(timeoutSessionDOMap.keySet()), 100).forEach(userSessionMapper::deleteBatchIds);
//记录用户超时退出日志
createTimeoutLogoutLog(timeoutSessionDOMap.values());
}
return timeoutSessionDOMap.size();
}
private void createTimeoutLogoutLog(Collection<SysUserSessionDO> timeoutSessionDOS) {
for (SysUserSessionDO timeoutSessionDO : timeoutSessionDOS) {
SysLoginLogCreateReqVO reqVO = new SysLoginLogCreateReqVO();
reqVO.setLogType(SysLoginLogTypeEnum.LOGOUT_TIMEOUT.getType());
reqVO.setTraceId(TracerUtils.getTraceId());
reqVO.setUsername(timeoutSessionDO.getUsername());
reqVO.setUserAgent(timeoutSessionDO.getUserAgent());
reqVO.setUserIp(timeoutSessionDO.getUserIp());
reqVO.setResult(SysLoginResultEnum.SUCCESS.getResult());
loginLogService.createLoginLog(reqVO);
}
return timeoutIdList.size();
}
/**

View File

@ -1,12 +1,20 @@
package cn.iocoder.dashboard.modules.system.service.auth;
import cn.hutool.core.date.DateUtil;
import cn.iocoder.dashboard.BaseSpringBootUnitTest;
import cn.iocoder.dashboard.BaseDbAndRedisUnitTest;
import cn.iocoder.dashboard.framework.mybatis.core.query.QueryWrapperX;
import cn.iocoder.dashboard.framework.security.config.SecurityProperties;
import cn.iocoder.dashboard.modules.system.dal.dataobject.auth.SysUserSessionDO;
import cn.iocoder.dashboard.modules.system.dal.mysql.auth.SysUserSessionMapper;
import cn.iocoder.dashboard.modules.system.dal.redis.auth.SysLoginUserRedisDAO;
import cn.iocoder.dashboard.modules.system.service.auth.impl.SysUserSessionServiceImpl;
import cn.iocoder.dashboard.modules.system.service.dept.impl.SysDeptServiceImpl;
import cn.iocoder.dashboard.modules.system.service.logger.impl.SysLoginLogServiceImpl;
import cn.iocoder.dashboard.modules.system.service.user.SysUserServiceImpl;
import cn.iocoder.dashboard.util.RandomUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Import;
import javax.annotation.Resource;
import java.util.Date;
@ -23,12 +31,25 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
* @version 1.0
* @since <pre>3月 8, 2021</pre>
*/
public class SysUserSessionServiceImplTest extends BaseSpringBootUnitTest {
@Import({
SysUserSessionServiceImpl.class
})
public class SysUserSessionServiceImplTest extends BaseDbAndRedisUnitTest {
@Resource
SysUserSessionService sysUserSessionService;
SysUserSessionServiceImpl sysUserSessionService;
@Resource
SysUserSessionMapper sysUserSessionMapper;
@MockBean
SecurityProperties securityProperties;
@MockBean
SysDeptServiceImpl sysDeptService;
@MockBean
SysUserServiceImpl sysUserService;
@MockBean
SysLoginLogServiceImpl sysLoginLogService;
@MockBean
SysLoginUserRedisDAO sysLoginUserRedisDAO;
@Test
public void testClearSessionTimeout_success() throws Exception {

View File

@ -118,12 +118,13 @@ CREATE TABLE "sys_dict_type" (
CREATE TABLE `sys_user_session` (
`id` varchar(32) NOT NULL,
`user_id` bigint DEFAULT NULL,
`username` varchar(50) NOT NULL DEFAULT '',
`user_ip` varchar(50) DEFAULT NULL,
`user_agent` varchar(512) DEFAULT NULL,
`session_timeout` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"create_by" varchar(64) DEFAULT '',
"creator" varchar(64) DEFAULT '',
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_by` varchar(64) DEFAULT '' ,
`updater` varchar(64) DEFAULT '' ,
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY (`id`)