mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-07 01:18:33 +08:00
定义一个SmsRestrictedUtil接口,用于用户自主实现缓存功能。
This commit is contained in:
parent
93d8f4bcb6
commit
df0ef8e3b3
@ -1,41 +1,47 @@
|
|||||||
package org.dromara.sms4j.api.smsProxy;
|
package org.dromara.sms4j.api.smsProxy;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.universal.SmsRestrictedUtil;
|
||||||
import org.dromara.sms4j.comm.config.SmsConfig;
|
import org.dromara.sms4j.comm.config.SmsConfig;
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtil;
|
import org.dromara.sms4j.comm.utils.SmsUtil;
|
||||||
import org.dromara.sms4j.comm.utils.TimeExpiredPoolCache;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class RestrictedProcess {
|
public class RestrictedProcess {
|
||||||
static Long minTimer = 60 * 1000L;
|
static Long minTimer = 60 * 1000L;
|
||||||
static Long accTimer = 24 * 60 * 60 * 1000L;
|
static Long accTimer = 24 * 60 * 60 * 1000L;
|
||||||
public SmsBlendException process(SmsConfig config, String args) throws Exception{
|
/**
|
||||||
TimeExpiredPoolCache instance = TimeExpiredPoolCache.getInstance();//缓存实例
|
* 缓存实例
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
private SmsRestrictedUtil instance;
|
||||||
|
|
||||||
|
public SmsBlendException process(SmsConfig config, String args) throws Exception {
|
||||||
Integer accountMax = config.getAccountMax();//每日最大发送量
|
Integer accountMax = config.getAccountMax();//每日最大发送量
|
||||||
Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
|
Integer minuteMax = config.getMinuteMax();//每分钟最大发送量
|
||||||
if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
|
if (SmsUtil.isNotEmpty(accountMax)) { //是否配置了每日限制
|
||||||
Integer i = instance.get(args + "max");
|
Integer i = (Integer) instance.getByKey(args + "max");
|
||||||
if (SmsUtil.isEmpty(i)) {
|
if (SmsUtil.isEmpty(i)) {
|
||||||
instance.put(args + "max", 1, accTimer);
|
instance.setOrTime(args + "max", 1, accTimer);
|
||||||
} else if (i > accountMax) {
|
} else if (i > accountMax) {
|
||||||
log.info("The phone:" + args + ",number of short messages reached the maximum today");
|
log.info("The phone:" + args + ",number of short messages reached the maximum today");
|
||||||
return new SmsBlendException("The phone:" + args + ",number of short messages reached the maximum today");
|
return new SmsBlendException("The phone:" + args + ",number of short messages reached the maximum today");
|
||||||
} else {
|
} else {
|
||||||
instance.put(args + "max", i + 1, accTimer);
|
instance.setOrTime(args + "max", i + 1, accTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
|
if (SmsUtil.isNotEmpty(minuteMax)) { //是否配置了每分钟最大限制
|
||||||
Integer o = instance.get(args);
|
Integer o = (Integer) instance.getByKey(args);
|
||||||
if (SmsUtil.isNotEmpty(o)) {
|
if (SmsUtil.isNotEmpty(o)) {
|
||||||
if (o < minuteMax) {
|
if (o < minuteMax) {
|
||||||
instance.put(args, o + 1, minTimer);
|
instance.setOrTime(args, o + 1, minTimer);
|
||||||
} else {
|
} else {
|
||||||
log.info("The phone:", args + " Text messages are sent too often!");
|
log.info("The phone:" + args + " Text messages are sent too often!");
|
||||||
return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
|
return new SmsBlendException("The phone:", args + " Text messages are sent too often!");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
instance.put(args, 1, minTimer);
|
instance.setOrTime(args, 1, minTimer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
package org.dromara.sms4j.comm.utils;
|
package org.dromara.sms4j.api.smsProxy;
|
||||||
|
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.universal.SmsRestrictedUtil;
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
@ -21,7 +22,9 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
* 2023/3/25 18:26
|
* 2023/3/25 18:26
|
||||||
**/
|
**/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TimeExpiredPoolCache {
|
public class TimeExpiredPoolCache implements SmsRestrictedUtil {
|
||||||
|
|
||||||
|
private TimeExpiredPoolCache poolCache = TimeExpiredPoolCache.getInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 持久化文件格式
|
* 持久化文件格式
|
||||||
@ -200,6 +203,31 @@ public class TimeExpiredPoolCache {
|
|||||||
dataPool.remove(key);
|
dataPool.remove(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean setOrTime(String key, Object value, Long time) {
|
||||||
|
try {
|
||||||
|
poolCache.put(key,value,time);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean set(String key, Object value) {
|
||||||
|
try {
|
||||||
|
poolCache.put(key,value,defaultCachedMillis);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getByKey(String key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据构造
|
* 数据构造
|
||||||
*/
|
*/
|
||||||
@ -0,0 +1,13 @@
|
|||||||
|
package org.dromara.sms4j.api.universal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SmsReadConfig
|
||||||
|
* <p> 读取配置接口,实现该接口中的方法则可以按照自己的形式进行配置的读取
|
||||||
|
* <p>这样只关注最终的配置数据而不关注配置的来源,用户可以自由的选择数据来源的方式</p>
|
||||||
|
* <p>该种方式读取配置并非在启动阶段完成,而是在方法第一次调用期间完成</p>
|
||||||
|
* @author :Wind
|
||||||
|
* 2023/8/1 12:06
|
||||||
|
**/
|
||||||
|
public interface SmsReadConfig {
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,17 +7,26 @@ package org.dromara.sms4j.api.universal;
|
|||||||
* @author :Wind
|
* @author :Wind
|
||||||
* 2023/6/6 22:21
|
* 2023/6/6 22:21
|
||||||
**/
|
**/
|
||||||
public interface SmsRedisUtil {
|
public interface SmsRestrictedUtil {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* setOrTime
|
* setOrTime
|
||||||
* <p>设置带有过期时间的key
|
* <p>设置带有过期时间的key
|
||||||
* @param key redis的key
|
* @param key 缓Key值
|
||||||
* @param value redis 的value
|
* @param value 缓存value值
|
||||||
* @param time 过期时间(秒级单位)
|
* @param time 过期时间(秒级单位)
|
||||||
* @author :Wind
|
* @author :Wind
|
||||||
*/
|
*/
|
||||||
public boolean setOrTime(String key, Object value, Long time);
|
public boolean setOrTime(String key, Object value, Long time) throws RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set
|
||||||
|
* <p>
|
||||||
|
* @param key 缓Key值
|
||||||
|
* @param value 缓存value值
|
||||||
|
* @author :Wind
|
||||||
|
*/
|
||||||
|
public boolean set(String key, Object value) throws RuntimeException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* getByKey
|
* getByKey
|
||||||
@ -25,5 +34,12 @@ public interface SmsRedisUtil {
|
|||||||
* @param key redis的key
|
* @param key redis的key
|
||||||
* @author :Wind
|
* @author :Wind
|
||||||
*/
|
*/
|
||||||
public Object getByKey(String key);
|
public Object getByKey(String key) throws RuntimeException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clear
|
||||||
|
* <p>清除缓存</p>
|
||||||
|
* @author :Wind
|
||||||
|
*/
|
||||||
|
public void clean() throws RuntimeException;
|
||||||
}
|
}
|
||||||
@ -1,72 +0,0 @@
|
|||||||
package org.dromara.sms4j.comm.utils;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.Writer;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
|
|
||||||
public class FileTool {
|
|
||||||
|
|
||||||
private FileTool(){}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getPath
|
|
||||||
* <p>获取用户工作目录
|
|
||||||
* @author :Wind
|
|
||||||
*/
|
|
||||||
public static String getPath(){
|
|
||||||
return System.getProperty("user.dir");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* createFile
|
|
||||||
* <p>创建文件
|
|
||||||
* @param path 要创建的文件路径
|
|
||||||
* @return 文件创建成功或存在则为true
|
|
||||||
* @author :Wind
|
|
||||||
*/
|
|
||||||
public static boolean createFile(String path){
|
|
||||||
File file = new File(path);
|
|
||||||
try {
|
|
||||||
file.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
return file.exists();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* writeFile
|
|
||||||
* <p>写入文件
|
|
||||||
* @param isAppend 是否追加写入,true追加写入,false覆盖写入
|
|
||||||
* @author :Wind
|
|
||||||
*/
|
|
||||||
public static void writeFile(File file,String content,boolean isAppend){
|
|
||||||
Writer writer = null;
|
|
||||||
try {
|
|
||||||
writer = new FileWriter(file,isAppend);
|
|
||||||
writer.write(content);
|
|
||||||
}catch (IOException e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}finally {
|
|
||||||
try {
|
|
||||||
writer.close();
|
|
||||||
}catch (IOException e){
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* readFile
|
|
||||||
* <p>读取文件为字符串
|
|
||||||
* @param path 文件路径
|
|
||||||
* @author :Wind
|
|
||||||
*/
|
|
||||||
public static String readFile(String path) throws IOException {
|
|
||||||
return new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
package org.dromara.sms4j.comm.utils;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* REST API 函数式接口
|
|
||||||
*
|
|
||||||
* @param <P> 请求参数
|
|
||||||
* @param <R> 响应
|
|
||||||
* @author Charles7c
|
|
||||||
* @since 2023/4/17 20:57
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface RestApiFunction<P, R> extends Serializable {
|
|
||||||
R apply(P param);
|
|
||||||
}
|
|
||||||
@ -45,11 +45,10 @@ public abstract class SmsFactory {
|
|||||||
* @param config 短信配置
|
* @param config 短信配置
|
||||||
* @author :Wind
|
* @author :Wind
|
||||||
*/
|
*/
|
||||||
public static SmsBlend createSmsBlend(SupplierConfig config) {
|
public static void createSmsBlend(SupplierConfig config) {
|
||||||
SmsBlend sms = create(config);
|
SmsBlend sms = create(config);
|
||||||
register(sms);
|
register(sms);
|
||||||
SmsLoad.starConfig(sms, config);
|
SmsLoad.starConfig(sms, config);
|
||||||
return sms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,14 +59,13 @@ public abstract class SmsFactory {
|
|||||||
* @param isRestricted 是否为开启了短信拦截的实例
|
* @param isRestricted 是否为开启了短信拦截的实例
|
||||||
* @author :Wind
|
* @author :Wind
|
||||||
*/
|
*/
|
||||||
public static SmsBlend createSmsBlend(SupplierConfig config, Boolean isRestricted) {
|
public static void createSmsBlend(SupplierConfig config, Boolean isRestricted) {
|
||||||
SmsBlend sms = create(config);
|
SmsBlend sms = create(config);
|
||||||
if (isRestricted) {
|
if (isRestricted) {
|
||||||
sms = renderWithRestricted(sms);
|
sms = renderWithRestricted(sms);
|
||||||
}
|
}
|
||||||
register(sms);
|
register(sms);
|
||||||
SmsLoad.starConfig(sms, config);
|
SmsLoad.starConfig(sms, config);
|
||||||
return sms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SmsBlend create(SupplierConfig config) {
|
private static SmsBlend create(SupplierConfig config) {
|
||||||
|
|||||||
@ -39,6 +39,7 @@ public abstract class BaseConfig implements SupplierConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 权重
|
* 权重
|
||||||
|
* @since 3.0.0
|
||||||
*/
|
*/
|
||||||
@Builder.Default
|
@Builder.Default
|
||||||
private Integer weight = 1;
|
private Integer weight = 1;
|
||||||
|
|||||||
@ -83,10 +83,6 @@ public class SmsAutowiredConfig implements LifecycleBean {
|
|||||||
public void start() throws Throwable {
|
public void start() throws Throwable {
|
||||||
/* 如果配置中启用了redis,则注入redis工具*/
|
/* 如果配置中启用了redis,则注入redis工具*/
|
||||||
if (BeanFactory.getSmsConfig().getRedisCache()) {
|
if (BeanFactory.getSmsConfig().getRedisCache()) {
|
||||||
//如果容器中不存在一个已经实现的redisUtil则自己注入一个
|
|
||||||
if (!Solon.context().hasWrap(SmsRedisUtil.class)) {
|
|
||||||
Solon.context().wrapAndPut(SmsRedisUtils.class);
|
|
||||||
}
|
|
||||||
SmsInvocationHandler.setRestrictedProcess(new SolonRestrictedProcess(aopContext));
|
SmsInvocationHandler.setRestrictedProcess(new SolonRestrictedProcess(aopContext));
|
||||||
log.debug("The redis cache is enabled for sms4j");
|
log.debug("The redis cache is enabled for sms4j");
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user