Commit 5e7e3d816cd34f4cc53e23c4264ec62cd6ecdb0f
1 parent
95edd1d4
彻底移除 RedisKeyDefine
Showing
18 changed files
with
50 additions
and
404 deletions
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/main/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefine.java deleted
| 1 | -package cn.iocoder.yudao.framework.tenant.core.redis; | ||
| 2 | - | ||
| 3 | -import cn.hutool.core.util.ArrayUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 5 | -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 6 | - | ||
| 7 | -import java.time.Duration; | ||
| 8 | - | ||
| 9 | -/** | ||
| 10 | - * 多租户拓展的 RedisKeyDefine 实现类 | ||
| 11 | - * | ||
| 12 | - * 由于 Redis 不同于 MySQL 有 column 字段,无法通过类似 WHERE tenant_id = ? 的方式过滤 | ||
| 13 | - * 所以需要通过在 Redis Key 上增加后缀的方式,进行租户之间的隔离。具体的步骤是: | ||
| 14 | - * 1. 假设 Redis Key 是 user:%d,示例是 user:1;对应到多租户的 Redis Key 是 user:%d:%d, | ||
| 15 | - * 2. 在 Redis DAO 中,需要使用 {@link #formatKey(Object...)} 方法,进行 Redis Key 的格式化 | ||
| 16 | - * | ||
| 17 | - * 注意,大多数情况下,并不用使用 TenantRedisKeyDefine 实现。主要的使用场景,还是 Redis Key 可能存在冲突的情况。 | ||
| 18 | - * 例如说,租户 1 和 2 都有一个手机号作为 Key,则他们会存在冲突的问题 | ||
| 19 | - * | ||
| 20 | - * @author 芋道源码 | ||
| 21 | - */ | ||
| 22 | -public class TenantRedisKeyDefine extends RedisKeyDefine { | ||
| 23 | - | ||
| 24 | - /** | ||
| 25 | - * 多租户的 KEY 模板 | ||
| 26 | - */ | ||
| 27 | - private static final String KEY_TEMPLATE_SUFFIX = ":%d"; | ||
| 28 | - | ||
| 29 | - public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) { | ||
| 30 | - super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeout); | ||
| 31 | - } | ||
| 32 | - | ||
| 33 | - public TenantRedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) { | ||
| 34 | - super(memo, buildKeyTemplate(keyTemplate), keyType, valueType, timeoutType); | ||
| 35 | - } | ||
| 36 | - | ||
| 37 | - private static String buildKeyTemplate(String keyTemplate) { | ||
| 38 | - return keyTemplate + KEY_TEMPLATE_SUFFIX; | ||
| 39 | - } | ||
| 40 | - | ||
| 41 | - @Override | ||
| 42 | - public String formatKey(Object... args) { | ||
| 43 | - args = ArrayUtil.append(args, TenantContextHolder.getRequiredTenantId()); | ||
| 44 | - return super.formatKey(args); | ||
| 45 | - } | ||
| 46 | - | ||
| 47 | -} |
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/test/java/cn/iocoder/yudao/framework/tenant/core/redis/TenantRedisKeyDefineTest.java deleted
| 1 | -package cn.iocoder.yudao.framework.tenant.core.redis; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 4 | -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder; | ||
| 5 | -import org.junit.jupiter.api.Test; | ||
| 6 | - | ||
| 7 | -import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 8 | - | ||
| 9 | -class TenantRedisKeyDefineTest { | ||
| 10 | - | ||
| 11 | - @Test | ||
| 12 | - public void testFormatKey() { | ||
| 13 | - Long tenantId = 30L; | ||
| 14 | - TenantContextHolder.setTenantId(tenantId); | ||
| 15 | - // 准备参数 | ||
| 16 | - TenantRedisKeyDefine define = new TenantRedisKeyDefine("", "user:%d:%d", RedisKeyDefine.KeyTypeEnum.HASH, | ||
| 17 | - Object.class, RedisKeyDefine.TimeoutTypeEnum.FIXED); | ||
| 18 | - Long userId = 10L; | ||
| 19 | - Integer userType = 1; | ||
| 20 | - | ||
| 21 | - // 调用 | ||
| 22 | - String key = define.formatKey(userId, userType); | ||
| 23 | - // 断言 | ||
| 24 | - assertEquals("user:10:1:30", key); | ||
| 25 | - } | ||
| 26 | - | ||
| 27 | -} |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/config/YudaoCaptchaConfiguration.java
| 1 | package cn.iocoder.yudao.framework.captcha.config; | 1 | package cn.iocoder.yudao.framework.captcha.config; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.ClassUtil; | ||
| 4 | -import cn.iocoder.yudao.framework.captcha.core.enums.CaptchaRedisKeyConstants; | ||
| 5 | import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl; | 3 | import cn.iocoder.yudao.framework.captcha.core.service.RedisCaptchaServiceImpl; |
| 6 | import com.xingyuv.captcha.properties.AjCaptchaProperties; | 4 | import com.xingyuv.captcha.properties.AjCaptchaProperties; |
| 7 | import com.xingyuv.captcha.service.CaptchaCacheService; | 5 | import com.xingyuv.captcha.service.CaptchaCacheService; |
| @@ -15,12 +13,6 @@ import javax.annotation.Resource; | @@ -15,12 +13,6 @@ import javax.annotation.Resource; | ||
| 15 | @AutoConfiguration | 13 | @AutoConfiguration |
| 16 | public class YudaoCaptchaConfiguration { | 14 | public class YudaoCaptchaConfiguration { |
| 17 | 15 | ||
| 18 | - static { | ||
| 19 | - // 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到 | ||
| 20 | - // 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举 | ||
| 21 | - ClassUtil.loadClass(CaptchaRedisKeyConstants.class.getName()); | ||
| 22 | - } | ||
| 23 | - | ||
| 24 | @Resource | 16 | @Resource |
| 25 | private StringRedisTemplate stringRedisTemplate; | 17 | private StringRedisTemplate stringRedisTemplate; |
| 26 | 18 |
yudao-framework/yudao-spring-boot-starter-captcha/src/main/java/cn/iocoder/yudao/framework/captcha/core/enums/CaptchaRedisKeyConstants.java
| 1 | package cn.iocoder.yudao.framework.captcha.core.enums; | 1 | package cn.iocoder.yudao.framework.captcha.core.enums; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 4 | -import com.xingyuv.captcha.model.vo.PointVO; | ||
| 5 | - | ||
| 6 | -import java.time.Duration; | ||
| 7 | - | ||
| 8 | -import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING; | ||
| 9 | - | ||
| 10 | /** | 3 | /** |
| 11 | * 验证码 Redis Key 枚举类 | 4 | * 验证码 Redis Key 枚举类 |
| 12 | * | 5 | * |
| @@ -14,12 +7,22 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S | @@ -14,12 +7,22 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S | ||
| 14 | */ | 7 | */ |
| 15 | public interface CaptchaRedisKeyConstants { | 8 | public interface CaptchaRedisKeyConstants { |
| 16 | 9 | ||
| 17 | - RedisKeyDefine AJ_CAPTCHA_REQ_LIMIT = new RedisKeyDefine("验证码的请求限流", | ||
| 18 | - "AJ.CAPTCHA.REQ.LIMIT-%s-%s", | ||
| 19 | - STRING, Integer.class, Duration.ofSeconds(60)); // 例如说:验证失败 5 次,get 接口锁定 | 10 | + /** |
| 11 | + * 验证码的请求限流 | ||
| 12 | + * | ||
| 13 | + * KEY 格式:AJ.CAPTCHA.REQ.LIMIT-%s-%s | ||
| 14 | + * VALUE 数据类型:String // 例如说:验证失败 5 次,get 接口锁定 | ||
| 15 | + * 过期时间:60 秒 | ||
| 16 | + */ | ||
| 17 | + String AJ_CAPTCHA_REQ_LIMIT = "AJ.CAPTCHA.REQ.LIMIT-%s-%s"; | ||
| 20 | 18 | ||
| 21 | - RedisKeyDefine AJ_CAPTCHA_RUNNING = new RedisKeyDefine("验证码的坐标", | ||
| 22 | - "RUNNING:CAPTCHA:%s", // AbstractCaptchaService.REDIS_CAPTCHA_KEY | ||
| 23 | - STRING, PointVO.class, Duration.ofSeconds(120)); // {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5} | 19 | + /** |
| 20 | + * 验证码的坐标 | ||
| 21 | + * | ||
| 22 | + * KEY 格式:RUNNING:CAPTCHA:%s // AbstractCaptchaService.REDIS_CAPTCHA_KEY | ||
| 23 | + * VALUE 数据类型:String // PointVO.class {"secretKey":"PP1w2Frr2KEejD2m","x":162,"y":5} | ||
| 24 | + * 过期时间:120 秒 | ||
| 25 | + */ | ||
| 26 | + String AJ_CAPTCHA_RUNNING = "RUNNING:CAPTCHA:%s"; | ||
| 24 | 27 | ||
| 25 | } | 28 | } |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
| @@ -106,6 +106,7 @@ public interface BaseMapperX<T> extends BaseMapper<T> { | @@ -106,6 +106,7 @@ public interface BaseMapperX<T> extends BaseMapper<T> { | ||
| 106 | default void updateBatch(Collection<T> entities) { | 106 | default void updateBatch(Collection<T> entities) { |
| 107 | Db.updateBatchById(entities); | 107 | Db.updateBatchById(entities); |
| 108 | } | 108 | } |
| 109 | + | ||
| 109 | default void updateBatch(Collection<T> entities, int size) { | 110 | default void updateBatch(Collection<T> entities, int size) { |
| 110 | Db.updateBatchById(entities, size); | 111 | Db.updateBatchById(entities, size); |
| 111 | } | 112 | } |
yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/idempotent/core/redis/IdempotentRedisDAO.java
| 1 | package cn.iocoder.yudao.framework.idempotent.core.redis; | 1 | package cn.iocoder.yudao.framework.idempotent.core.redis; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 4 | import lombok.AllArgsConstructor; | 3 | import lombok.AllArgsConstructor; |
| 5 | import org.springframework.data.redis.core.StringRedisTemplate; | 4 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 6 | 5 | ||
| 7 | import java.util.concurrent.TimeUnit; | 6 | import java.util.concurrent.TimeUnit; |
| 8 | 7 | ||
| 9 | -import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.STRING; | ||
| 10 | - | ||
| 11 | /** | 8 | /** |
| 12 | * 幂等 Redis DAO | 9 | * 幂等 Redis DAO |
| 13 | * | 10 | * |
| @@ -16,9 +13,14 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S | @@ -16,9 +13,14 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.S | ||
| 16 | @AllArgsConstructor | 13 | @AllArgsConstructor |
| 17 | public class IdempotentRedisDAO { | 14 | public class IdempotentRedisDAO { |
| 18 | 15 | ||
| 19 | - private static final RedisKeyDefine IDEMPOTENT = new RedisKeyDefine("幂等操作", | ||
| 20 | - "idempotent:%s", // 参数为 uuid | ||
| 21 | - STRING, String.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); | 16 | + /** |
| 17 | + * 幂等操作 | ||
| 18 | + * | ||
| 19 | + * KEY 格式:idempotent:%s // 参数为 uuid | ||
| 20 | + * VALUE 格式:String | ||
| 21 | + * 过期时间:不固定 | ||
| 22 | + */ | ||
| 23 | + private static final String IDEMPOTENT = "idempotent:%s"; | ||
| 22 | 24 | ||
| 23 | private final StringRedisTemplate redisTemplate; | 25 | private final StringRedisTemplate redisTemplate; |
| 24 | 26 | ||
| @@ -28,7 +30,7 @@ public class IdempotentRedisDAO { | @@ -28,7 +30,7 @@ public class IdempotentRedisDAO { | ||
| 28 | } | 30 | } |
| 29 | 31 | ||
| 30 | private static String formatKey(String key) { | 32 | private static String formatKey(String key) { |
| 31 | - return String.format(IDEMPOTENT.getKeyTemplate(), key); | 33 | + return String.format(IDEMPOTENT, key); |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | } | 36 | } |
yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/config/YudaoLock4jConfiguration.java
| 1 | package cn.iocoder.yudao.framework.lock4j.config; | 1 | package cn.iocoder.yudao.framework.lock4j.config; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.util.ClassUtil; | ||
| 4 | -import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration; | ||
| 5 | import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy; | 3 | import cn.iocoder.yudao.framework.lock4j.core.DefaultLockFailureStrategy; |
| 6 | -import cn.iocoder.yudao.framework.lock4j.core.Lock4jRedisKeyConstants; | 4 | +import com.baomidou.lock.spring.boot.autoconfigure.LockAutoConfiguration; |
| 7 | import org.springframework.boot.autoconfigure.AutoConfiguration; | 5 | import org.springframework.boot.autoconfigure.AutoConfiguration; |
| 8 | import org.springframework.context.annotation.Bean; | 6 | import org.springframework.context.annotation.Bean; |
| 9 | 7 | ||
| 10 | @AutoConfiguration(before = LockAutoConfiguration.class) | 8 | @AutoConfiguration(before = LockAutoConfiguration.class) |
| 11 | public class YudaoLock4jConfiguration { | 9 | public class YudaoLock4jConfiguration { |
| 12 | 10 | ||
| 13 | - static { | ||
| 14 | - // 手动加载 Lock4jRedisKeyConstants 类,因为它不会被使用到 | ||
| 15 | - // 如果不加载,会导致 Redis 监控,看到它的 Redis Key 枚举 | ||
| 16 | - ClassUtil.loadClass(Lock4jRedisKeyConstants.class.getName()); | ||
| 17 | - } | ||
| 18 | - | ||
| 19 | @Bean | 11 | @Bean |
| 20 | public DefaultLockFailureStrategy lockFailureStrategy() { | 12 | public DefaultLockFailureStrategy lockFailureStrategy() { |
| 21 | return new DefaultLockFailureStrategy(); | 13 | return new DefaultLockFailureStrategy(); |
yudao-framework/yudao-spring-boot-starter-protection/src/main/java/cn/iocoder/yudao/framework/lock4j/core/Lock4jRedisKeyConstants.java
| 1 | package cn.iocoder.yudao.framework.lock4j.core; | 1 | package cn.iocoder.yudao.framework.lock4j.core; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 4 | -import org.redisson.api.RLock; | ||
| 5 | - | ||
| 6 | -import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.HASH; | ||
| 7 | - | ||
| 8 | /** | 3 | /** |
| 9 | * Lock4j Redis Key 枚举类 | 4 | * Lock4j Redis Key 枚举类 |
| 10 | * | 5 | * |
| @@ -12,8 +7,13 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.H | @@ -12,8 +7,13 @@ import static cn.iocoder.yudao.framework.redis.core.RedisKeyDefine.KeyTypeEnum.H | ||
| 12 | */ | 7 | */ |
| 13 | public interface Lock4jRedisKeyConstants { | 8 | public interface Lock4jRedisKeyConstants { |
| 14 | 9 | ||
| 15 | - RedisKeyDefine LOCK4J = new RedisKeyDefine("分布式锁", | ||
| 16 | - "lock4j:%s", // 参数来自 DefaultLockKeyBuilder 类 | ||
| 17 | - HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构 | 10 | + /** |
| 11 | + * 分布式锁 | ||
| 12 | + * | ||
| 13 | + * KEY 格式:lock4j:%s // 参数来自 DefaultLockKeyBuilder 类 | ||
| 14 | + * VALUE 数据格式:HASH // RLock.class:Redisson 的 Lock 锁,使用 Hash 数据结构 | ||
| 15 | + * 过期时间:不固定 | ||
| 16 | + */ | ||
| 17 | + String LOCK4J = "lock4j:%s"; | ||
| 18 | 18 | ||
| 19 | } | 19 | } |
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/RedisKeyDefine.java deleted
| 1 | -package cn.iocoder.yudao.framework.redis.core; | ||
| 2 | - | ||
| 3 | -import com.fasterxml.jackson.annotation.JsonValue; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | -import lombok.Data; | ||
| 6 | -import lombok.Getter; | ||
| 7 | - | ||
| 8 | -import java.time.Duration; | ||
| 9 | - | ||
| 10 | -/** | ||
| 11 | - * Redis Key 定义类 | ||
| 12 | - * | ||
| 13 | - * @author 芋道源码 | ||
| 14 | - */ | ||
| 15 | -@Data | ||
| 16 | -public class RedisKeyDefine { | ||
| 17 | - | ||
| 18 | - @Getter | ||
| 19 | - @AllArgsConstructor | ||
| 20 | - public enum KeyTypeEnum { | ||
| 21 | - | ||
| 22 | - STRING("String"), | ||
| 23 | - LIST("List"), | ||
| 24 | - HASH("Hash"), | ||
| 25 | - SET("Set"), | ||
| 26 | - ZSET("Sorted Set"), | ||
| 27 | - STREAM("Stream"), | ||
| 28 | - PUBSUB("Pub/Sub"); | ||
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * 类型 | ||
| 32 | - */ | ||
| 33 | - @JsonValue | ||
| 34 | - private final String type; | ||
| 35 | - | ||
| 36 | - } | ||
| 37 | - | ||
| 38 | - @Getter | ||
| 39 | - @AllArgsConstructor | ||
| 40 | - public enum TimeoutTypeEnum { | ||
| 41 | - | ||
| 42 | - FOREVER(1), // 永不超时 | ||
| 43 | - DYNAMIC(2), // 动态超时 | ||
| 44 | - FIXED(3); // 固定超时 | ||
| 45 | - | ||
| 46 | - /** | ||
| 47 | - * 类型 | ||
| 48 | - */ | ||
| 49 | - @JsonValue | ||
| 50 | - private final Integer type; | ||
| 51 | - | ||
| 52 | - } | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * Key 模板 | ||
| 56 | - */ | ||
| 57 | - private final String keyTemplate; | ||
| 58 | - /** | ||
| 59 | - * Key 类型的枚举 | ||
| 60 | - */ | ||
| 61 | - private final KeyTypeEnum keyType; | ||
| 62 | - /** | ||
| 63 | - * Value 类型 | ||
| 64 | - * | ||
| 65 | - * 如果是使用分布式锁,设置为 {@link java.util.concurrent.locks.Lock} 类型 | ||
| 66 | - */ | ||
| 67 | - private final Class<?> valueType; | ||
| 68 | - /** | ||
| 69 | - * 超时类型 | ||
| 70 | - */ | ||
| 71 | - private final TimeoutTypeEnum timeoutType; | ||
| 72 | - /** | ||
| 73 | - * 过期时间 | ||
| 74 | - */ | ||
| 75 | - private final Duration timeout; | ||
| 76 | - /** | ||
| 77 | - * 备注 | ||
| 78 | - */ | ||
| 79 | - private final String memo; | ||
| 80 | - | ||
| 81 | - private RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, | ||
| 82 | - TimeoutTypeEnum timeoutType, Duration timeout) { | ||
| 83 | - this.memo = memo; | ||
| 84 | - this.keyTemplate = keyTemplate; | ||
| 85 | - this.keyType = keyType; | ||
| 86 | - this.valueType = valueType; | ||
| 87 | - this.timeout = timeout; | ||
| 88 | - this.timeoutType = timeoutType; | ||
| 89 | - // 添加注册表 | ||
| 90 | - RedisKeyRegistry.add(this); | ||
| 91 | - } | ||
| 92 | - | ||
| 93 | - public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, Duration timeout) { | ||
| 94 | - this(memo, keyTemplate, keyType, valueType, TimeoutTypeEnum.FIXED, timeout); | ||
| 95 | - } | ||
| 96 | - | ||
| 97 | - public RedisKeyDefine(String memo, String keyTemplate, KeyTypeEnum keyType, Class<?> valueType, TimeoutTypeEnum timeoutType) { | ||
| 98 | - this(memo, keyTemplate, keyType, valueType, timeoutType, Duration.ZERO); | ||
| 99 | - } | ||
| 100 | - | ||
| 101 | - /** | ||
| 102 | - * 格式化 Key | ||
| 103 | - * | ||
| 104 | - * 注意,内部采用 {@link String#format(String, Object...)} 实现 | ||
| 105 | - * | ||
| 106 | - * @param args 格式化的参数 | ||
| 107 | - * @return Key | ||
| 108 | - */ | ||
| 109 | - public String formatKey(Object... args) { | ||
| 110 | - return String.format(keyTemplate, args); | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | -} |
yudao-framework/yudao-spring-boot-starter-redis/src/main/java/cn/iocoder/yudao/framework/redis/core/RedisKeyRegistry.java deleted
| 1 | -package cn.iocoder.yudao.framework.redis.core; | ||
| 2 | - | ||
| 3 | -import java.util.ArrayList; | ||
| 4 | -import java.util.List; | ||
| 5 | - | ||
| 6 | -/** | ||
| 7 | - * {@link RedisKeyDefine} 注册表 | ||
| 8 | - */ | ||
| 9 | -public class RedisKeyRegistry { | ||
| 10 | - | ||
| 11 | - /** | ||
| 12 | - * Redis RedisKeyDefine 数组 | ||
| 13 | - */ | ||
| 14 | - private static final List<RedisKeyDefine> DEFINES = new ArrayList<>(); | ||
| 15 | - | ||
| 16 | - public static void add(RedisKeyDefine define) { | ||
| 17 | - DEFINES.add(define); | ||
| 18 | - } | ||
| 19 | - | ||
| 20 | - public static List<RedisKeyDefine> list() { | ||
| 21 | - return DEFINES; | ||
| 22 | - } | ||
| 23 | - | ||
| 24 | - public static int size() { | ||
| 25 | - return DEFINES.size(); | ||
| 26 | - } | ||
| 27 | - | ||
| 28 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.http
| @@ -2,8 +2,3 @@ | @@ -2,8 +2,3 @@ | ||
| 2 | GET {{baseUrl}}/infra/redis/get-monitor-info | 2 | GET {{baseUrl}}/infra/redis/get-monitor-info |
| 3 | Authorization: Bearer {{token}} | 3 | Authorization: Bearer {{token}} |
| 4 | tenant-id: {{adminTenentId}} | 4 | tenant-id: {{adminTenentId}} |
| 5 | - | ||
| 6 | -### 请求 /infra/redis/get-key-list 接口 => 成功 | ||
| 7 | -GET {{baseUrl}}/infra/redis/get-key-list | ||
| 8 | -Authorization: Bearer {{token}} | ||
| 9 | -tenant-id: {{adminTenentId}} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/RedisController.java
| 1 | package cn.iocoder.yudao.module.infra.controller.admin.redis; | 1 | package cn.iocoder.yudao.module.infra.controller.admin.redis; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.collection.CollUtil; | ||
| 4 | -import cn.hutool.core.util.StrUtil; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 6 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 7 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyRegistry; | ||
| 8 | -import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO; | ||
| 9 | -import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyValueRespVO; | ||
| 10 | import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO; | 4 | import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO; |
| 11 | import cn.iocoder.yudao.module.infra.convert.redis.RedisConvert; | 5 | import cn.iocoder.yudao.module.infra.convert.redis.RedisConvert; |
| 12 | -import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 13 | -import io.swagger.v3.oas.annotations.Parameter; | ||
| 14 | import io.swagger.v3.oas.annotations.Operation; | 6 | import io.swagger.v3.oas.annotations.Operation; |
| 7 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 15 | import org.springframework.data.redis.connection.RedisServerCommands; | 8 | import org.springframework.data.redis.connection.RedisServerCommands; |
| 16 | -import org.springframework.data.redis.core.Cursor; | ||
| 17 | import org.springframework.data.redis.core.RedisCallback; | 9 | import org.springframework.data.redis.core.RedisCallback; |
| 18 | -import org.springframework.data.redis.core.ScanOptions; | ||
| 19 | import org.springframework.data.redis.core.StringRedisTemplate; | 10 | import org.springframework.data.redis.core.StringRedisTemplate; |
| 20 | import org.springframework.security.access.prepost.PreAuthorize; | 11 | import org.springframework.security.access.prepost.PreAuthorize; |
| 21 | -import org.springframework.web.bind.annotation.*; | 12 | +import org.springframework.web.bind.annotation.GetMapping; |
| 13 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 14 | +import org.springframework.web.bind.annotation.RestController; | ||
| 22 | 15 | ||
| 23 | import javax.annotation.Resource; | 16 | import javax.annotation.Resource; |
| 24 | -import java.util.*; | 17 | +import java.util.Properties; |
| 25 | 18 | ||
| 26 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 19 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 27 | 20 | ||
| @@ -47,66 +40,4 @@ public class RedisController { | @@ -47,66 +40,4 @@ public class RedisController { | ||
| 47 | return success(RedisConvert.INSTANCE.build(info, dbSize, commandStats)); | 40 | return success(RedisConvert.INSTANCE.build(info, dbSize, commandStats)); |
| 48 | } | 41 | } |
| 49 | 42 | ||
| 50 | - @GetMapping("/get-key-define-list") | ||
| 51 | - @Operation(summary = "获得 Redis Key 模板列表") | ||
| 52 | - @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 53 | - public CommonResult<List<RedisKeyDefineRespVO>> getKeyDefineList() { | ||
| 54 | - List<RedisKeyDefine> keyDefines = RedisKeyRegistry.list(); | ||
| 55 | - return success(RedisConvert.INSTANCE.convertList(keyDefines)); | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - @GetMapping("/get-key-list") | ||
| 59 | - @Operation(summary = "获得 Redis keys 键名列表") | ||
| 60 | - @Parameter(name = "keyTemplate", description = "Redis Key 定义", example = "true") | ||
| 61 | - @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 62 | - public CommonResult<Set<String>> getKeyDefineList(@RequestParam("keyTemplate") String keyTemplate) { | ||
| 63 | - return success(getKeyDefineList0(keyTemplate)); | ||
| 64 | - } | ||
| 65 | - | ||
| 66 | - private Set<String> getKeyDefineList0(String keyTemplate) { | ||
| 67 | - // key 格式化 | ||
| 68 | - String key = StrUtil.replace(keyTemplate, "%[s|c|b|d|x|o|f|a|e|g]", parameter -> "*"); | ||
| 69 | - // scan 扫描 key | ||
| 70 | - Set<String> keys = new LinkedHashSet<>(); | ||
| 71 | - stringRedisTemplate.execute((RedisCallback<Set<String>>) connection -> { | ||
| 72 | - try (Cursor<byte[]> cursor = connection.scan(ScanOptions.scanOptions().match(key).count(100).build())) { | ||
| 73 | - cursor.forEachRemaining(value -> keys.add(StrUtil.utf8Str(value))); | ||
| 74 | - } catch (Exception e) { | ||
| 75 | - throw new RuntimeException(e); | ||
| 76 | - } | ||
| 77 | - return keys; | ||
| 78 | - }); | ||
| 79 | - return keys; | ||
| 80 | - } | ||
| 81 | - | ||
| 82 | - @GetMapping("/get-key-value") | ||
| 83 | - @Operation(summary = "获得 Redis key 内容") | ||
| 84 | - @Parameter(name = "key", description = "Redis Key", example = "oauth2_access_token:233") | ||
| 85 | - @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 86 | - public CommonResult<RedisKeyValueRespVO> getKeyValue(@RequestParam("key") String key) { | ||
| 87 | - String value = stringRedisTemplate.opsForValue().get(key); | ||
| 88 | - return success(new RedisKeyValueRespVO(key, value)); | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - @DeleteMapping("/delete-key") | ||
| 92 | - @Operation(summary = "删除 Redis Key") | ||
| 93 | - @Parameter(name = "key", description = "Redis Key", example = "oauth2_access_token:233") | ||
| 94 | - @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 95 | - public CommonResult<Boolean> deleteKey(@RequestParam("key") String key) { | ||
| 96 | - stringRedisTemplate.delete(key); | ||
| 97 | - return success(Boolean.TRUE); | ||
| 98 | - } | ||
| 99 | - | ||
| 100 | - @DeleteMapping("/delete-keys") | ||
| 101 | - @Operation(summary = "删除 Redis Key 根据模板") | ||
| 102 | - @Parameter(name = "keyTemplate", description = "Redis Key 定义", example = "true") | ||
| 103 | - @PreAuthorize("@ss.hasPermission('infra:redis:get-key-list')") | ||
| 104 | - public CommonResult<Boolean> deleteKeys(@RequestParam("keyTemplate") String keyTemplate) { | ||
| 105 | - Set<String> keys = getKeyDefineList0(keyTemplate); | ||
| 106 | - if (CollUtil.isNotEmpty(keys)) { | ||
| 107 | - stringRedisTemplate.delete(keys); | ||
| 108 | - } | ||
| 109 | - return success(Boolean.TRUE); | ||
| 110 | - } | ||
| 111 | - | ||
| 112 | } | 43 | } |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyDefineRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.controller.admin.redis.vo; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 4 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 5 | -import lombok.AllArgsConstructor; | ||
| 6 | -import lombok.Builder; | ||
| 7 | -import lombok.Data; | ||
| 8 | - | ||
| 9 | -import java.time.Duration; | ||
| 10 | - | ||
| 11 | -@Schema(description = "管理后台 - Redis Key 信息 Response VO") | ||
| 12 | -@Data | ||
| 13 | -@Builder | ||
| 14 | -@AllArgsConstructor | ||
| 15 | -public class RedisKeyDefineRespVO { | ||
| 16 | - | ||
| 17 | - @Schema(description = "Key 模板", requiredMode = Schema.RequiredMode.REQUIRED, example = "login_user:%s") | ||
| 18 | - private String keyTemplate; | ||
| 19 | - | ||
| 20 | - @Schema(description = "Key 类型的枚举", requiredMode = Schema.RequiredMode.REQUIRED, example = "String") | ||
| 21 | - private RedisKeyDefine.KeyTypeEnum keyType; | ||
| 22 | - | ||
| 23 | - @Schema(description = "Value 类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "java.lang.String") | ||
| 24 | - private Class<?> valueType; | ||
| 25 | - | ||
| 26 | - @Schema(description = "超时类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 27 | - private RedisKeyDefine.TimeoutTypeEnum timeoutType; | ||
| 28 | - | ||
| 29 | - @Schema(description = "过期时间,单位:毫秒", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 30 | - private Duration timeout; | ||
| 31 | - | ||
| 32 | - @Schema(description = "备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "啦啦啦啦~") | ||
| 33 | - private String memo; | ||
| 34 | - | ||
| 35 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/redis/vo/RedisKeyValueRespVO.java deleted
| 1 | -package cn.iocoder.yudao.module.infra.controller.admin.redis.vo; | ||
| 2 | - | ||
| 3 | -import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | -import lombok.AllArgsConstructor; | ||
| 5 | -import lombok.Data; | ||
| 6 | - | ||
| 7 | -@Schema(description = "管理后台 - 单个 Redis Key Value Response VO") | ||
| 8 | -@Data | ||
| 9 | -@AllArgsConstructor | ||
| 10 | -public class RedisKeyValueRespVO { | ||
| 11 | - | ||
| 12 | - @Schema(description = "c5f6990767804a928f4bb96ca249febf", requiredMode = Schema.RequiredMode.REQUIRED, example = "String") | ||
| 13 | - private String key; | ||
| 14 | - | ||
| 15 | - @Schema(requiredMode = Schema.RequiredMode.REQUIRED, example = "String") | ||
| 16 | - private String value; | ||
| 17 | - | ||
| 18 | -} |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/convert/redis/RedisConvert.java
| 1 | package cn.iocoder.yudao.module.infra.convert.redis; | 1 | package cn.iocoder.yudao.module.infra.convert.redis; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.StrUtil; | 3 | import cn.hutool.core.util.StrUtil; |
| 4 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 5 | -import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisKeyDefineRespVO; | ||
| 6 | import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO; | 4 | import cn.iocoder.yudao.module.infra.controller.admin.redis.vo.RedisMonitorRespVO; |
| 7 | import org.mapstruct.Mapper; | 5 | import org.mapstruct.Mapper; |
| 8 | import org.mapstruct.factory.Mappers; | 6 | import org.mapstruct.factory.Mappers; |
| 9 | 7 | ||
| 10 | import java.util.ArrayList; | 8 | import java.util.ArrayList; |
| 11 | -import java.util.List; | ||
| 12 | import java.util.Properties; | 9 | import java.util.Properties; |
| 13 | 10 | ||
| 14 | @Mapper | 11 | @Mapper |
| @@ -29,6 +26,4 @@ public interface RedisConvert { | @@ -29,6 +26,4 @@ public interface RedisConvert { | ||
| 29 | return respVO; | 26 | return respVO; |
| 30 | } | 27 | } |
| 31 | 28 | ||
| 32 | - List<RedisKeyDefineRespVO> convertList(List<RedisKeyDefine> list); | ||
| 33 | - | ||
| 34 | } | 29 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/RedisKeyConstants.java
| 1 | package cn.iocoder.yudao.module.pay.dal.redis; | 1 | package cn.iocoder.yudao.module.pay.dal.redis; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.framework.redis.core.RedisKeyDefine; | ||
| 4 | -import org.redisson.api.RLock; | ||
| 5 | - | ||
| 6 | /** | 3 | /** |
| 7 | * 支付 Redis Key 枚举类 | 4 | * 支付 Redis Key 枚举类 |
| 8 | * | 5 | * |
| @@ -10,9 +7,14 @@ import org.redisson.api.RLock; | @@ -10,9 +7,14 @@ import org.redisson.api.RLock; | ||
| 10 | */ | 7 | */ |
| 11 | public interface RedisKeyConstants { | 8 | public interface RedisKeyConstants { |
| 12 | 9 | ||
| 13 | - RedisKeyDefine PAY_NOTIFY_LOCK = new RedisKeyDefine("通知任务的分布式锁", | ||
| 14 | - "pay_notify:lock:%d", // 参数来自 DefaultLockKeyBuilder 类 | ||
| 15 | - RedisKeyDefine.KeyTypeEnum.HASH, RLock.class, RedisKeyDefine.TimeoutTypeEnum.DYNAMIC); // Redisson 的 Lock 锁,使用 Hash 数据结构 | 10 | + /** |
| 11 | + * 通知任务的分布式锁 | ||
| 12 | + * | ||
| 13 | + * KEY 格式:pay_notify:lock:%d // 参数来自 DefaultLockKeyBuilder 类 | ||
| 14 | + * VALUE 数据格式:HASH // RLock.class:Redisson 的 Lock 锁,使用 Hash 数据结构 | ||
| 15 | + * 过期时间:不固定 | ||
| 16 | + */ | ||
| 17 | + String PAY_NOTIFY_LOCK = "pay_notify:lock:%d"; | ||
| 16 | 18 | ||
| 17 | /** | 19 | /** |
| 18 | * 支付序号的缓存 | 20 | * 支付序号的缓存 |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/redis/notify/PayNotifyLockRedisDAO.java
| @@ -33,7 +33,7 @@ public class PayNotifyLockRedisDAO { | @@ -33,7 +33,7 @@ public class PayNotifyLockRedisDAO { | ||
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | private static String formatKey(Long id) { | 35 | private static String formatKey(Long id) { |
| 36 | - return String.format(PAY_NOTIFY_LOCK.getKeyTemplate(), id); | 36 | + return String.format(PAY_NOTIFY_LOCK, id); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | } | 39 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.http
| @@ -2,6 +2,7 @@ | @@ -2,6 +2,7 @@ | ||
| 2 | POST {{baseUrl}}/system/auth/login | 2 | POST {{baseUrl}}/system/auth/login |
| 3 | Content-Type: application/json | 3 | Content-Type: application/json |
| 4 | tenant-id: {{adminTenentId}} | 4 | tenant-id: {{adminTenentId}} |
| 5 | +tag: Yunai.local | ||
| 5 | 6 | ||
| 6 | { | 7 | { |
| 7 | "username": "admin", | 8 | "username": "admin", |