Commit 32620fb3a7d5dd29943227f44bb55c5906225bbe
1 parent
4dc484f5
infra logger 单元测试 (issues I3A9GW)
Showing
11 changed files
with
463 additions
and
13 deletions
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/service/ApiAccessLogFrameworkService.java
| @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service; | @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service; | ||
| 3 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO; | 3 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO; |
| 4 | 4 | ||
| 5 | import javax.validation.Valid; | 5 | import javax.validation.Valid; |
| 6 | +import java.util.concurrent.Future; | ||
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| 8 | * API 访问日志 Framework Service 接口 | 9 | * API 访问日志 Framework Service 接口 |
| @@ -15,7 +16,8 @@ public interface ApiAccessLogFrameworkService { | @@ -15,7 +16,8 @@ public interface ApiAccessLogFrameworkService { | ||
| 15 | * 创建 API 访问日志 | 16 | * 创建 API 访问日志 |
| 16 | * | 17 | * |
| 17 | * @param createDTO 创建信息 | 18 | * @param createDTO 创建信息 |
| 19 | + * @return 是否创建成功 | ||
| 18 | */ | 20 | */ |
| 19 | - void createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO); | 21 | + Future<Boolean> createApiAccessLogAsync(@Valid ApiAccessLogCreateDTO createDTO); |
| 20 | 22 | ||
| 21 | } | 23 | } |
src/main/java/cn/iocoder/dashboard/framework/logger/apilog/core/service/ApiErrorLogFrameworkService.java
| @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service; | @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.framework.logger.apilog.core.service; | ||
| 3 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO; | 3 | import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO; |
| 4 | 4 | ||
| 5 | import javax.validation.Valid; | 5 | import javax.validation.Valid; |
| 6 | +import java.util.concurrent.Future; | ||
| 6 | 7 | ||
| 7 | /** | 8 | /** |
| 8 | * API 错误日志 Framework Service 接口 | 9 | * API 错误日志 Framework Service 接口 |
| @@ -15,7 +16,8 @@ public interface ApiErrorLogFrameworkService { | @@ -15,7 +16,8 @@ public interface ApiErrorLogFrameworkService { | ||
| 15 | * 创建 API 错误日志 | 16 | * 创建 API 错误日志 |
| 16 | * | 17 | * |
| 17 | * @param createDTO 创建信息 | 18 | * @param createDTO 创建信息 |
| 19 | + * @return 是否创建成功 | ||
| 18 | */ | 20 | */ |
| 19 | - void createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO); | 21 | + Future<Boolean> createApiErrorLogAsync(@Valid ApiErrorLogCreateDTO createDTO); |
| 20 | 22 | ||
| 21 | } | 23 | } |
src/main/java/cn/iocoder/dashboard/modules/infra/controller/logger/vo/apierrorlog/InfApiErrorLogExportReqVO.java
| @@ -14,7 +14,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU | @@ -14,7 +14,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU | ||
| 14 | public class InfApiErrorLogExportReqVO { | 14 | public class InfApiErrorLogExportReqVO { |
| 15 | 15 | ||
| 16 | @ApiModelProperty(value = "用户编号", example = "666") | 16 | @ApiModelProperty(value = "用户编号", example = "666") |
| 17 | - private Integer userId; | 17 | + private Long userId; |
| 18 | 18 | ||
| 19 | @ApiModelProperty(value = "用户类型", example = "1") | 19 | @ApiModelProperty(value = "用户类型", example = "1") |
| 20 | private Integer userType; | 20 | private Integer userType; |
src/main/java/cn/iocoder/dashboard/modules/infra/controller/logger/vo/apierrorlog/InfApiErrorLogPageReqVO.java
| @@ -19,7 +19,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU | @@ -19,7 +19,7 @@ import static cn.iocoder.dashboard.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOU | ||
| 19 | public class InfApiErrorLogPageReqVO extends PageParam { | 19 | public class InfApiErrorLogPageReqVO extends PageParam { |
| 20 | 20 | ||
| 21 | @ApiModelProperty(value = "用户编号", example = "666") | 21 | @ApiModelProperty(value = "用户编号", example = "666") |
| 22 | - private Integer userId; | 22 | + private Long userId; |
| 23 | 23 | ||
| 24 | @ApiModelProperty(value = "用户类型", example = "1") | 24 | @ApiModelProperty(value = "用户类型", example = "1") |
| 25 | private Integer userType; | 25 | private Integer userType; |
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/logger/InfApiAccessLogDO.java
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/logger/InfApiErrorLogDO.java
| @@ -30,7 +30,7 @@ public class InfApiErrorLogDO extends BaseDO { | @@ -30,7 +30,7 @@ public class InfApiErrorLogDO extends BaseDO { | ||
| 30 | /** | 30 | /** |
| 31 | * 用户编号 | 31 | * 用户编号 |
| 32 | */ | 32 | */ |
| 33 | - private Integer userId; | 33 | + private Long userId; |
| 34 | /** | 34 | /** |
| 35 | * 链路追踪编号 | 35 | * 链路追踪编号 |
| 36 | * | 36 | * |
| @@ -148,6 +148,6 @@ public class InfApiErrorLogDO extends BaseDO { | @@ -148,6 +148,6 @@ public class InfApiErrorLogDO extends BaseDO { | ||
| 148 | * | 148 | * |
| 149 | * 关联 {@link SysUserDO#getId()} | 149 | * 关联 {@link SysUserDO#getId()} |
| 150 | */ | 150 | */ |
| 151 | - private Integer processUserId; | 151 | + private Long processUserId; |
| 152 | 152 | ||
| 153 | } | 153 | } |
src/main/java/cn/iocoder/dashboard/modules/infra/service/logger/impl/InfApiAccessLogServiceImpl.java
| @@ -9,12 +9,13 @@ import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogD | @@ -9,12 +9,13 @@ import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogD | ||
| 9 | import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper; | 9 | import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper; |
| 10 | import cn.iocoder.dashboard.modules.infra.service.logger.InfApiAccessLogService; | 10 | import cn.iocoder.dashboard.modules.infra.service.logger.InfApiAccessLogService; |
| 11 | import org.springframework.scheduling.annotation.Async; | 11 | import org.springframework.scheduling.annotation.Async; |
| 12 | +import org.springframework.scheduling.annotation.AsyncResult; | ||
| 12 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| 13 | import org.springframework.validation.annotation.Validated; | 14 | import org.springframework.validation.annotation.Validated; |
| 14 | 15 | ||
| 15 | import javax.annotation.Resource; | 16 | import javax.annotation.Resource; |
| 16 | -import javax.validation.Valid; | ||
| 17 | import java.util.List; | 17 | import java.util.List; |
| 18 | +import java.util.concurrent.Future; | ||
| 18 | 19 | ||
| 19 | /** | 20 | /** |
| 20 | * API 访问日志 Service 实现类 | 21 | * API 访问日志 Service 实现类 |
| @@ -30,10 +31,11 @@ public class InfApiAccessLogServiceImpl implements InfApiAccessLogService { | @@ -30,10 +31,11 @@ public class InfApiAccessLogServiceImpl implements InfApiAccessLogService { | ||
| 30 | 31 | ||
| 31 | @Override | 32 | @Override |
| 32 | @Async | 33 | @Async |
| 33 | - public void createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { | 34 | + public Future<Boolean> createApiAccessLogAsync(ApiAccessLogCreateDTO createDTO) { |
| 34 | // 插入 | 35 | // 插入 |
| 35 | InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO); | 36 | InfApiAccessLogDO apiAccessLog = InfApiAccessLogConvert.INSTANCE.convert(createDTO); |
| 36 | - apiAccessLogMapper.insert(apiAccessLog); | 37 | + int insert = apiAccessLogMapper.insert(apiAccessLog); |
| 38 | + return new AsyncResult<>(insert == 1); | ||
| 37 | } | 39 | } |
| 38 | 40 | ||
| 39 | @Override | 41 | @Override |
src/main/java/cn/iocoder/dashboard/modules/infra/service/logger/impl/InfApiErrorLogServiceImpl.java
| @@ -10,12 +10,14 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper; | @@ -10,12 +10,14 @@ import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper; | ||
| 10 | import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; | 10 | import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; |
| 11 | import cn.iocoder.dashboard.modules.infra.service.logger.InfApiErrorLogService; | 11 | import cn.iocoder.dashboard.modules.infra.service.logger.InfApiErrorLogService; |
| 12 | import org.springframework.scheduling.annotation.Async; | 12 | import org.springframework.scheduling.annotation.Async; |
| 13 | +import org.springframework.scheduling.annotation.AsyncResult; | ||
| 13 | import org.springframework.stereotype.Service; | 14 | import org.springframework.stereotype.Service; |
| 14 | import org.springframework.validation.annotation.Validated; | 15 | import org.springframework.validation.annotation.Validated; |
| 15 | 16 | ||
| 16 | import javax.annotation.Resource; | 17 | import javax.annotation.Resource; |
| 17 | import java.util.Date; | 18 | import java.util.Date; |
| 18 | import java.util.List; | 19 | import java.util.List; |
| 20 | +import java.util.concurrent.Future; | ||
| 19 | 21 | ||
| 20 | import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; | 22 | import static cn.iocoder.dashboard.common.exception.util.ServiceExceptionUtil.exception; |
| 21 | import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; | 23 | import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; |
| @@ -35,10 +37,11 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { | @@ -35,10 +37,11 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { | ||
| 35 | 37 | ||
| 36 | @Override | 38 | @Override |
| 37 | @Async | 39 | @Async |
| 38 | - public void createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) { | 40 | + public Future<Boolean> createApiErrorLogAsync(ApiErrorLogCreateDTO createDTO) { |
| 39 | InfApiErrorLogDO apiErrorLog = InfApiErrorLogConvert.INSTANCE.convert(createDTO); | 41 | InfApiErrorLogDO apiErrorLog = InfApiErrorLogConvert.INSTANCE.convert(createDTO); |
| 40 | apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus()); | 42 | apiErrorLog.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus()); |
| 41 | - apiErrorLogMapper.insert(apiErrorLog); | 43 | + int insert = apiErrorLogMapper.insert(apiErrorLog); |
| 44 | + return new AsyncResult<>(insert == 1); | ||
| 42 | } | 45 | } |
| 43 | 46 | ||
| 44 | @Override | 47 | @Override |
| @@ -62,7 +65,7 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { | @@ -62,7 +65,7 @@ public class InfApiErrorLogServiceImpl implements InfApiErrorLogService { | ||
| 62 | } | 65 | } |
| 63 | // 标记处理 | 66 | // 标记处理 |
| 64 | apiErrorLogMapper.updateById(InfApiErrorLogDO.builder().id(id).processStatus(processStatus) | 67 | apiErrorLogMapper.updateById(InfApiErrorLogDO.builder().id(id).processStatus(processStatus) |
| 65 | - .processUserId(processStatus).processTime(new Date()).build()); | 68 | + .processUserId(processUserId).processTime(new Date()).build()); |
| 66 | } | 69 | } |
| 67 | 70 | ||
| 68 | } | 71 | } |
src/test/java/cn/iocoder/dashboard/modules/infra/service/logger/InfApiAccessLogServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.infra.service.logger; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.RandomUtil; | ||
| 4 | +import cn.iocoder.dashboard.BaseDbUnitTest; | ||
| 5 | +import cn.iocoder.dashboard.common.enums.UserTypeEnum; | ||
| 6 | +import cn.iocoder.dashboard.common.exception.enums.GlobalErrorCodeConstants; | ||
| 7 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 8 | +import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiAccessLogCreateDTO; | ||
| 9 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apiaccesslog.InfApiAccessLogExportReqVO; | ||
| 10 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apiaccesslog.InfApiAccessLogPageReqVO; | ||
| 11 | +import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiAccessLogDO; | ||
| 12 | +import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiAccessLogMapper; | ||
| 13 | +import cn.iocoder.dashboard.modules.infra.service.logger.impl.InfApiAccessLogServiceImpl; | ||
| 14 | +import cn.iocoder.dashboard.util.RandomUtils; | ||
| 15 | +import cn.iocoder.dashboard.util.object.ObjectUtils; | ||
| 16 | +import org.junit.jupiter.api.Test; | ||
| 17 | +import org.springframework.context.annotation.Import; | ||
| 18 | + | ||
| 19 | +import javax.annotation.Resource; | ||
| 20 | +import java.util.Date; | ||
| 21 | +import java.util.List; | ||
| 22 | +import java.util.concurrent.Future; | ||
| 23 | + | ||
| 24 | +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; | ||
| 25 | +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime; | ||
| 26 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 27 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * {@link InfApiAccessLogServiceImpl} 单元测试 | ||
| 31 | + */ | ||
| 32 | +@Import(InfApiAccessLogServiceImpl.class) | ||
| 33 | +public class InfApiAccessLogServiceImplTest extends BaseDbUnitTest { | ||
| 34 | + | ||
| 35 | + @Resource | ||
| 36 | + private InfApiAccessLogService infApiAccessLogServiceImpl; | ||
| 37 | + | ||
| 38 | + @Resource | ||
| 39 | + private InfApiAccessLogMapper infApiAccessLogMapper; | ||
| 40 | + | ||
| 41 | + | ||
| 42 | + @Test | ||
| 43 | + public void testCreateApiAccessLogAsync() throws Exception { | ||
| 44 | + ApiAccessLogCreateDTO createDTO = RandomUtils.randomPojo( | ||
| 45 | + ApiAccessLogCreateDTO.class, | ||
| 46 | + dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue()) | ||
| 47 | + ); | ||
| 48 | + | ||
| 49 | + // 执行service方法 | ||
| 50 | + Future<Boolean> future = infApiAccessLogServiceImpl.createApiAccessLogAsync(createDTO); | ||
| 51 | + | ||
| 52 | + // 等异步执行完 | ||
| 53 | + future.get(); | ||
| 54 | + | ||
| 55 | + InfApiAccessLogDO infApiAccessLogDO = infApiAccessLogMapper.selectOne(null); | ||
| 56 | + // 断言 | ||
| 57 | + assertNotNull(infApiAccessLogDO); | ||
| 58 | + // 断言,忽略基本字段 | ||
| 59 | + assertPojoEquals(createDTO, infApiAccessLogDO); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + | ||
| 63 | + @Test | ||
| 64 | + public void testGetApiAccessLogPage() { | ||
| 65 | + // 构造测试数据 | ||
| 66 | + long userId = 2233L; | ||
| 67 | + int userType = UserTypeEnum.ADMIN.getValue(); | ||
| 68 | + String applicationName = "ruoyi-test"; | ||
| 69 | + String requestUrl = "foo"; | ||
| 70 | + Date beginTime = buildTime(2021, 3, 13); | ||
| 71 | + int duration = 1000; | ||
| 72 | + int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode(); | ||
| 73 | + | ||
| 74 | + InfApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(InfApiAccessLogDO.class, dto -> { | ||
| 75 | + dto.setUserId(userId); | ||
| 76 | + dto.setUserType(userType); | ||
| 77 | + dto.setApplicationName(applicationName); | ||
| 78 | + dto.setRequestUrl(requestUrl); | ||
| 79 | + dto.setBeginTime(beginTime); | ||
| 80 | + dto.setDuration(duration); | ||
| 81 | + dto.setResultCode(resultCode); | ||
| 82 | + }); | ||
| 83 | + infApiAccessLogMapper.insert(infApiAccessLogDO); | ||
| 84 | + | ||
| 85 | + // 下面几个都是不匹配的数据 | ||
| 86 | + // userId 不同的 | ||
| 87 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L))); | ||
| 88 | + // userType | ||
| 89 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | ||
| 90 | + // applicationName 不同的 | ||
| 91 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test"))); | ||
| 92 | + // requestUrl 不同的 | ||
| 93 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar"))); | ||
| 94 | + // 构造一个早期时间 2021-02-06 00:00:00 | ||
| 95 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6)))); | ||
| 96 | + // duration 不同的 | ||
| 97 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100))); | ||
| 98 | + // resultCode 不同的 | ||
| 99 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2))); | ||
| 100 | + | ||
| 101 | + // 构造调用参数 | ||
| 102 | + InfApiAccessLogPageReqVO reqVO = new InfApiAccessLogPageReqVO(); | ||
| 103 | + reqVO.setUserId(userId); | ||
| 104 | + reqVO.setUserType(userType); | ||
| 105 | + reqVO.setApplicationName(applicationName); | ||
| 106 | + reqVO.setRequestUrl(requestUrl); | ||
| 107 | + reqVO.setBeginBeginTime(buildTime(2021, 3, 12)); | ||
| 108 | + reqVO.setEndBeginTime(buildTime(2021, 3, 14)); | ||
| 109 | + reqVO.setDuration(duration); | ||
| 110 | + reqVO.setResultCode(resultCode); | ||
| 111 | + | ||
| 112 | + // 调用service方法 | ||
| 113 | + PageResult<InfApiAccessLogDO> pageResult = infApiAccessLogServiceImpl.getApiAccessLogPage(reqVO); | ||
| 114 | + | ||
| 115 | + // 断言,只查到了一条符合条件的 | ||
| 116 | + assertEquals(1, pageResult.getTotal()); | ||
| 117 | + assertEquals(1, pageResult.getList().size()); | ||
| 118 | + assertPojoEquals(infApiAccessLogDO, pageResult.getList().get(0)); | ||
| 119 | + } | ||
| 120 | + | ||
| 121 | + @Test | ||
| 122 | + public void testGetApiAccessLogList() { | ||
| 123 | + // 构造测试数据 | ||
| 124 | + long userId = 2233L; | ||
| 125 | + int userType = UserTypeEnum.ADMIN.getValue(); | ||
| 126 | + String applicationName = "ruoyi-test"; | ||
| 127 | + String requestUrl = "foo"; | ||
| 128 | + Date beginTime = buildTime(2021, 3, 13); | ||
| 129 | + int duration = 1000; | ||
| 130 | + int resultCode = GlobalErrorCodeConstants.SUCCESS.getCode(); | ||
| 131 | + | ||
| 132 | + InfApiAccessLogDO infApiAccessLogDO = RandomUtils.randomPojo(InfApiAccessLogDO.class, dto -> { | ||
| 133 | + dto.setUserId(userId); | ||
| 134 | + dto.setUserType(userType); | ||
| 135 | + dto.setApplicationName(applicationName); | ||
| 136 | + dto.setRequestUrl(requestUrl); | ||
| 137 | + dto.setBeginTime(beginTime); | ||
| 138 | + dto.setDuration(duration); | ||
| 139 | + dto.setResultCode(resultCode); | ||
| 140 | + }); | ||
| 141 | + infApiAccessLogMapper.insert(infApiAccessLogDO); | ||
| 142 | + | ||
| 143 | + // 下面几个都是不匹配的数据 | ||
| 144 | + // userId 不同的 | ||
| 145 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserId(3344L))); | ||
| 146 | + // userType | ||
| 147 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | ||
| 148 | + // applicationName 不同的 | ||
| 149 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setApplicationName("test"))); | ||
| 150 | + // requestUrl 不同的 | ||
| 151 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setRequestUrl("bar"))); | ||
| 152 | + // 构造一个早期时间 2021-02-06 00:00:00 | ||
| 153 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setBeginTime(buildTime(2021, 2, 6)))); | ||
| 154 | + // duration 不同的 | ||
| 155 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setDuration(100))); | ||
| 156 | + // resultCode 不同的 | ||
| 157 | + infApiAccessLogMapper.insert(ObjectUtils.clone(infApiAccessLogDO, logDO -> logDO.setResultCode(2))); | ||
| 158 | + | ||
| 159 | + // 构造调用参数 | ||
| 160 | + InfApiAccessLogExportReqVO reqVO = new InfApiAccessLogExportReqVO(); | ||
| 161 | + reqVO.setUserId(userId); | ||
| 162 | + reqVO.setUserType(userType); | ||
| 163 | + reqVO.setApplicationName(applicationName); | ||
| 164 | + reqVO.setRequestUrl(requestUrl); | ||
| 165 | + reqVO.setBeginBeginTime(buildTime(2021, 3, 12)); | ||
| 166 | + reqVO.setEndBeginTime(buildTime(2021, 3, 14)); | ||
| 167 | + reqVO.setDuration(duration); | ||
| 168 | + reqVO.setResultCode(resultCode); | ||
| 169 | + | ||
| 170 | + // 调用service方法 | ||
| 171 | + List<InfApiAccessLogDO> list = infApiAccessLogServiceImpl.getApiAccessLogList(reqVO); | ||
| 172 | + | ||
| 173 | + // 断言,只查到了一条符合条件的 | ||
| 174 | + assertEquals(1, list.size()); | ||
| 175 | + assertPojoEquals(infApiAccessLogDO, list.get(0)); | ||
| 176 | + } | ||
| 177 | +} |
src/test/java/cn/iocoder/dashboard/modules/infra/service/logger/InfApiErrorLogServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.dashboard.modules.infra.service.logger; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.RandomUtil; | ||
| 4 | +import cn.iocoder.dashboard.BaseDbUnitTest; | ||
| 5 | +import cn.iocoder.dashboard.common.enums.UserTypeEnum; | ||
| 6 | +import cn.iocoder.dashboard.common.pojo.PageResult; | ||
| 7 | +import cn.iocoder.dashboard.framework.logger.apilog.core.service.dto.ApiErrorLogCreateDTO; | ||
| 8 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogExportReqVO; | ||
| 9 | +import cn.iocoder.dashboard.modules.infra.controller.logger.vo.apierrorlog.InfApiErrorLogPageReqVO; | ||
| 10 | +import cn.iocoder.dashboard.modules.infra.dal.dataobject.logger.InfApiErrorLogDO; | ||
| 11 | +import cn.iocoder.dashboard.modules.infra.dal.mysql.logger.InfApiErrorLogMapper; | ||
| 12 | +import cn.iocoder.dashboard.modules.infra.enums.logger.InfApiErrorLogProcessStatusEnum; | ||
| 13 | +import cn.iocoder.dashboard.modules.infra.service.logger.impl.InfApiErrorLogServiceImpl; | ||
| 14 | +import cn.iocoder.dashboard.util.RandomUtils; | ||
| 15 | +import cn.iocoder.dashboard.util.object.ObjectUtils; | ||
| 16 | +import org.junit.jupiter.api.Test; | ||
| 17 | +import org.springframework.context.annotation.Import; | ||
| 18 | + | ||
| 19 | +import javax.annotation.Resource; | ||
| 20 | +import java.util.Date; | ||
| 21 | +import java.util.List; | ||
| 22 | +import java.util.concurrent.Future; | ||
| 23 | + | ||
| 24 | +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_NOT_FOUND; | ||
| 25 | +import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.API_ERROR_LOG_PROCESSED; | ||
| 26 | +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals; | ||
| 27 | +import static cn.iocoder.dashboard.util.AssertUtils.assertServiceException; | ||
| 28 | +import static cn.iocoder.dashboard.util.date.DateUtils.buildTime; | ||
| 29 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 30 | +import static org.junit.jupiter.api.Assertions.assertNotNull; | ||
| 31 | + | ||
| 32 | +/** | ||
| 33 | + * {@link InfApiErrorLogServiceImpl} 单元测试 | ||
| 34 | + */ | ||
| 35 | +@Import(InfApiErrorLogServiceImpl.class) | ||
| 36 | +public class InfApiErrorLogServiceImplTest extends BaseDbUnitTest { | ||
| 37 | + | ||
| 38 | + @Resource | ||
| 39 | + private InfApiErrorLogService infApiErrorLogServiceImpl; | ||
| 40 | + | ||
| 41 | + @Resource | ||
| 42 | + private InfApiErrorLogMapper infApiErrorLogMapper; | ||
| 43 | + | ||
| 44 | + | ||
| 45 | + @Test | ||
| 46 | + public void testCreateApiErrorLogAsync() throws Exception { | ||
| 47 | + ApiErrorLogCreateDTO createDTO = RandomUtils.randomPojo( | ||
| 48 | + ApiErrorLogCreateDTO.class, | ||
| 49 | + dto -> dto.setUserType(RandomUtil.randomEle(UserTypeEnum.values()).getValue()) | ||
| 50 | + ); | ||
| 51 | + | ||
| 52 | + // 执行service方法 | ||
| 53 | + Future<Boolean> future = infApiErrorLogServiceImpl.createApiErrorLogAsync(createDTO); | ||
| 54 | + | ||
| 55 | + // 等异步执行完 | ||
| 56 | + future.get(); | ||
| 57 | + | ||
| 58 | + InfApiErrorLogDO infApiErrorLogDO = infApiErrorLogMapper.selectOne(null); | ||
| 59 | + // 断言 | ||
| 60 | + assertNotNull(infApiErrorLogDO); | ||
| 61 | + // 断言,忽略基本字段 | ||
| 62 | + assertPojoEquals(createDTO, infApiErrorLogDO); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + | ||
| 66 | + @Test | ||
| 67 | + public void testGetApiErrorLogPage() { | ||
| 68 | + // 构造测试数据 | ||
| 69 | + long userId = 2233L; | ||
| 70 | + int userType = UserTypeEnum.ADMIN.getValue(); | ||
| 71 | + String applicationName = "ruoyi-test"; | ||
| 72 | + String requestUrl = "foo"; | ||
| 73 | + Date beginTime = buildTime(2021, 3, 13); | ||
| 74 | + int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus(); | ||
| 75 | + | ||
| 76 | + InfApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | ||
| 77 | + logDO.setUserId(userId); | ||
| 78 | + logDO.setUserType(userType); | ||
| 79 | + logDO.setApplicationName(applicationName); | ||
| 80 | + logDO.setRequestUrl(requestUrl); | ||
| 81 | + logDO.setExceptionTime(beginTime); | ||
| 82 | + logDO.setProcessStatus(progressStatus); | ||
| 83 | + }); | ||
| 84 | + infApiErrorLogMapper.insert(infApiErrorLogDO); | ||
| 85 | + | ||
| 86 | + // 下面几个都是不匹配的数据 | ||
| 87 | + // userId 不同的 | ||
| 88 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L))); | ||
| 89 | + // userType | ||
| 90 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | ||
| 91 | + // applicationName 不同的 | ||
| 92 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test"))); | ||
| 93 | + // requestUrl 不同的 | ||
| 94 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); | ||
| 95 | + // 构造一个早期时间 2021-02-06 00:00:00 | ||
| 96 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); | ||
| 97 | + // progressStatus 不同的 | ||
| 98 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus()))); | ||
| 99 | + | ||
| 100 | + // 构造调用参数 | ||
| 101 | + InfApiErrorLogPageReqVO reqVO = new InfApiErrorLogPageReqVO(); | ||
| 102 | + reqVO.setUserId(userId); | ||
| 103 | + reqVO.setUserType(userType); | ||
| 104 | + reqVO.setApplicationName(applicationName); | ||
| 105 | + reqVO.setRequestUrl(requestUrl); | ||
| 106 | + reqVO.setBeginExceptionTime(buildTime(2021, 3, 12)); | ||
| 107 | + reqVO.setEndExceptionTime(buildTime(2021, 3, 14)); | ||
| 108 | + reqVO.setProcessStatus(progressStatus); | ||
| 109 | + | ||
| 110 | + // 调用service方法 | ||
| 111 | + PageResult<InfApiErrorLogDO> pageResult = infApiErrorLogServiceImpl.getApiErrorLogPage(reqVO); | ||
| 112 | + | ||
| 113 | + // 断言,只查到了一条符合条件的 | ||
| 114 | + assertEquals(1, pageResult.getTotal()); | ||
| 115 | + assertEquals(1, pageResult.getList().size()); | ||
| 116 | + assertPojoEquals(infApiErrorLogDO, pageResult.getList().get(0)); | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + @Test | ||
| 120 | + public void testGetApiErrorLogList() { | ||
| 121 | + // 构造测试数据 | ||
| 122 | + long userId = 2233L; | ||
| 123 | + int userType = UserTypeEnum.ADMIN.getValue(); | ||
| 124 | + String applicationName = "ruoyi-test"; | ||
| 125 | + String requestUrl = "foo"; | ||
| 126 | + Date beginTime = buildTime(2021, 3, 13); | ||
| 127 | + int progressStatus = InfApiErrorLogProcessStatusEnum.INIT.getStatus(); | ||
| 128 | + | ||
| 129 | + InfApiErrorLogDO infApiErrorLogDO = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | ||
| 130 | + logDO.setUserId(userId); | ||
| 131 | + logDO.setUserType(userType); | ||
| 132 | + logDO.setApplicationName(applicationName); | ||
| 133 | + logDO.setRequestUrl(requestUrl); | ||
| 134 | + logDO.setExceptionTime(beginTime); | ||
| 135 | + logDO.setProcessStatus(progressStatus); | ||
| 136 | + }); | ||
| 137 | + infApiErrorLogMapper.insert(infApiErrorLogDO); | ||
| 138 | + | ||
| 139 | + // 下面几个都是不匹配的数据 | ||
| 140 | + // userId 不同的 | ||
| 141 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserId(3344L))); | ||
| 142 | + // userType | ||
| 143 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setUserType(UserTypeEnum.MEMBER.getValue()))); | ||
| 144 | + // applicationName 不同的 | ||
| 145 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setApplicationName("test"))); | ||
| 146 | + // requestUrl 不同的 | ||
| 147 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setRequestUrl("bar"))); | ||
| 148 | + // 构造一个早期时间 2021-02-06 00:00:00 | ||
| 149 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setExceptionTime(buildTime(2021, 2, 6)))); | ||
| 150 | + // progressStatus 不同的 | ||
| 151 | + infApiErrorLogMapper.insert(ObjectUtils.clone(infApiErrorLogDO, logDO -> logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus()))); | ||
| 152 | + | ||
| 153 | + // 构造调用参数 | ||
| 154 | + InfApiErrorLogExportReqVO reqVO = new InfApiErrorLogExportReqVO(); | ||
| 155 | + reqVO.setUserId(userId); | ||
| 156 | + reqVO.setUserType(userType); | ||
| 157 | + reqVO.setApplicationName(applicationName); | ||
| 158 | + reqVO.setRequestUrl(requestUrl); | ||
| 159 | + reqVO.setBeginExceptionTime(buildTime(2021, 3, 12)); | ||
| 160 | + reqVO.setEndExceptionTime(buildTime(2021, 3, 14)); | ||
| 161 | + reqVO.setProcessStatus(progressStatus); | ||
| 162 | + | ||
| 163 | + // 调用service方法 | ||
| 164 | + List<InfApiErrorLogDO> list = infApiErrorLogServiceImpl.getApiErrorLogList(reqVO); | ||
| 165 | + | ||
| 166 | + // 断言,只查到了一条符合条件的 | ||
| 167 | + assertEquals(1, list.size()); | ||
| 168 | + assertPojoEquals(infApiErrorLogDO, list.get(0)); | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | + | ||
| 172 | + @Test | ||
| 173 | + public void testUpdateApiErrorLogProcess() { | ||
| 174 | + // 先构造两条数据,第一条用于抛出异常,第二条用于正常的执行update操作 | ||
| 175 | + Long processUserId = 2233L; | ||
| 176 | + | ||
| 177 | + InfApiErrorLogDO first = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | ||
| 178 | + logDO.setProcessUserId(processUserId); | ||
| 179 | + logDO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||
| 180 | + logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.DONE.getStatus()); | ||
| 181 | + }); | ||
| 182 | + infApiErrorLogMapper.insert(first); | ||
| 183 | + | ||
| 184 | + InfApiErrorLogDO second = RandomUtils.randomPojo(InfApiErrorLogDO.class, logDO -> { | ||
| 185 | + logDO.setProcessUserId(1122L); | ||
| 186 | + logDO.setUserType(UserTypeEnum.ADMIN.getValue()); | ||
| 187 | + logDO.setProcessStatus(InfApiErrorLogProcessStatusEnum.INIT.getStatus()); | ||
| 188 | + }); | ||
| 189 | + infApiErrorLogMapper.insert(second); | ||
| 190 | + | ||
| 191 | + Long firstId = first.getId(); | ||
| 192 | + Long secondId = second.getId(); | ||
| 193 | + | ||
| 194 | + // 执行正常的 update 操作 | ||
| 195 | + infApiErrorLogServiceImpl.updateApiErrorLogProcess(secondId, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId); | ||
| 196 | + InfApiErrorLogDO secondSelect = infApiErrorLogMapper.selectOne("id", secondId); | ||
| 197 | + | ||
| 198 | + // id 为 0 查询不到,应该抛出异常 API_ERROR_LOG_NOT_FOUND | ||
| 199 | + assertServiceException(() -> infApiErrorLogServiceImpl.updateApiErrorLogProcess(0L, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_NOT_FOUND); | ||
| 200 | + // id 为 first 的 progressStatus 为 DONE ,应该抛出 API_ERROR_LOG_PROCESSED | ||
| 201 | + assertServiceException(() -> infApiErrorLogServiceImpl.updateApiErrorLogProcess(firstId, InfApiErrorLogProcessStatusEnum.DONE.getStatus(), processUserId), API_ERROR_LOG_PROCESSED); | ||
| 202 | + // 验证 progressStatus 是否修改成功 | ||
| 203 | + assertEquals(InfApiErrorLogProcessStatusEnum.DONE.getStatus(), secondSelect.getProcessStatus()); | ||
| 204 | + // 验证 progressUserId 是否修改成功 | ||
| 205 | + assertEquals(processUserId, secondSelect.getProcessUserId()); | ||
| 206 | + } | ||
| 207 | +} |
src/test/resources/sql/create_tables.sql
| @@ -241,3 +241,60 @@ create table IF NOT EXISTS "sys_user" ( | @@ -241,3 +241,60 @@ create table IF NOT EXISTS "sys_user" ( | ||
| 241 | "deleted" bit not null default false, | 241 | "deleted" bit not null default false, |
| 242 | primary key ("id") | 242 | primary key ("id") |
| 243 | ) comment '用户信息表'; | 243 | ) comment '用户信息表'; |
| 244 | + | ||
| 245 | + | ||
| 246 | +create table "inf_api_access_log" ( | ||
| 247 | + "id" bigint not null GENERATED BY DEFAULT AS IDENTITY, | ||
| 248 | + "trace_id" varchar(64) not null default '', | ||
| 249 | + "user_id" bigint not null default '0', | ||
| 250 | + "user_type" tinyint not null default '0', | ||
| 251 | + "application_name" varchar(50) not null, | ||
| 252 | + "request_method" varchar(16) not null default '', | ||
| 253 | + "request_url" varchar(255) not null default '', | ||
| 254 | + "request_params" varchar(8000) not null default '', | ||
| 255 | + "user_ip" varchar(50) not null, | ||
| 256 | + "user_agent" varchar(512) not null, | ||
| 257 | + "begin_time" timestamp not null, | ||
| 258 | + "end_time" timestamp not null, | ||
| 259 | + "duration" integer not null, | ||
| 260 | + "result_code" integer not null default '0', | ||
| 261 | + "result_msg" varchar(512) default '', | ||
| 262 | + "creator" varchar(64) default '', | ||
| 263 | + "create_time" timestamp not null default current_timestamp, | ||
| 264 | + "updater" varchar(64) default '', | ||
| 265 | + "update_time" timestamp not null default current_timestamp, | ||
| 266 | + "deleted" bit not null default false, | ||
| 267 | + primary key ("id") | ||
| 268 | +) comment 'API 访问日志表'; | ||
| 269 | + | ||
| 270 | + | ||
| 271 | +create table "inf_api_error_log" ( | ||
| 272 | + "id" integer not null GENERATED BY DEFAULT AS IDENTITY, | ||
| 273 | + "trace_id" varchar(64) not null, | ||
| 274 | + "user_id" bigint not null default '0', | ||
| 275 | + "user_type" tinyint not null default '0', | ||
| 276 | + "application_name" varchar(50) not null, | ||
| 277 | + "request_method" varchar(16) not null, | ||
| 278 | + "request_url" varchar(255) not null, | ||
| 279 | + "request_params" varchar(8000) not null, | ||
| 280 | + "user_ip" varchar(50) not null, | ||
| 281 | + "user_agent" varchar(512) not null, | ||
| 282 | + "exception_time" timestamp not null, | ||
| 283 | + "exception_name" varchar(128) not null default '', | ||
| 284 | + "exception_message" clob not null, | ||
| 285 | + "exception_root_cause_message" clob not null, | ||
| 286 | + "exception_stack_trace" clob not null, | ||
| 287 | + "exception_class_name" varchar(512) not null, | ||
| 288 | + "exception_file_name" varchar(512) not null, | ||
| 289 | + "exception_method_name" varchar(512) not null, | ||
| 290 | + "exception_line_number" integer not null, | ||
| 291 | + "process_status" tinyint not null, | ||
| 292 | + "process_time" timestamp default null, | ||
| 293 | + "process_user_id" bigint default '0', | ||
| 294 | + "creator" varchar(64) default '', | ||
| 295 | + "create_time" timestamp not null default current_timestamp, | ||
| 296 | + "updater" varchar(64) default '', | ||
| 297 | + "update_time" timestamp not null default current_timestamp, | ||
| 298 | + "deleted" bit not null default false, | ||
| 299 | + primary key ("id") | ||
| 300 | +) comment '系统异常日志'; | ||
| 244 | \ No newline at end of file | 301 | \ No newline at end of file |