mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-07 01:18:33 +08:00
refactor(SmsProcessor): 重构SmsProcessor体系
This commit is contained in:
parent
428cafc1e1
commit
feb6540508
@ -0,0 +1,471 @@
|
|||||||
|
package org.dromara.sms4j.api.proxy;
|
||||||
|
|
||||||
|
import org.dromara.sms4j.api.callback.CallBack;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsMethodInterceptor}的通用实现,
|
||||||
|
* 能够根据{@link SmsMethodType}将调用分发到某个具体的拦截方法上。
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
*/
|
||||||
|
public abstract class AbstractGenericMethodInterceptor implements SmsMethodInterceptor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置拦截,在方法执行前调用
|
||||||
|
*
|
||||||
|
* @param methodType 方法类型,若不是{@link SmsMethodType}则可能为{@code null}
|
||||||
|
* @param method 方法
|
||||||
|
* @param target 调用对象
|
||||||
|
* @param params 调用参数
|
||||||
|
* @return 调用参数
|
||||||
|
* @implNote 若重写此方法,则务必调用{@link #doBeforeInvoke}方法实现调用分发
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object[] beforeInvoke(SmsMethodType methodType, Method method, Object target, Object[] params) {
|
||||||
|
if (Objects.nonNull(methodType)) {
|
||||||
|
// 将方法分发到具体的调用
|
||||||
|
doBeforeInvoke(params, methodType);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected final void doBeforeInvoke(Object[] params, SmsMethodType methodType) {
|
||||||
|
Objects.requireNonNull(methodType);
|
||||||
|
switch (methodType) {
|
||||||
|
case SEND_MESSAGE:
|
||||||
|
beforeSendMessage((String)params[0], (String)params[1]);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_WITH_TEMPLATE:
|
||||||
|
beforeSendMessageWithTemplate((String)params[0], (LinkedHashMap<String, String>)params[1]);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_WITH_CUSTOM_TEMPLATE:
|
||||||
|
beforeSendMessageWithCustomTemplate((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2]);
|
||||||
|
break;
|
||||||
|
case MASS_TEXTING:
|
||||||
|
beforeMassTexting((List<String>)params[0], (String)params[1]);
|
||||||
|
break;
|
||||||
|
case MASS_TEXTING_WITH_TEMPLATE:
|
||||||
|
beforeMassTextingWithTemplate((List<String>)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2]);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC:
|
||||||
|
beforeSendMessageAsync((String)params[0], (String)params[1], (CallBack)params[2]);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC_NO_CALLBACK:
|
||||||
|
beforeSendMessageAsyncNoCallback((String)params[0], (String)params[1]);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC_WITH_TEMPLATE:
|
||||||
|
beforeSendMessageAsyncWithTemplate((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], (CallBack)params[3]);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC_WITH_TEMPLATE_NO_CALLBACK:
|
||||||
|
beforeSendMessageAsyncWithTemplateNoCallback((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2]);
|
||||||
|
break;
|
||||||
|
case DELAYED_MESSAGE:
|
||||||
|
beforeDelayedMessage((String)params[0], (String)params[1], (Long)params[2]);
|
||||||
|
break;
|
||||||
|
case DELAYED_MESSAGE_WITH_TEMPLATE:
|
||||||
|
beforeDelayedMessageWithTemplate((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], (Long)params[3]);
|
||||||
|
break;
|
||||||
|
case DELAY_MASS_TEXTING:
|
||||||
|
beforeDelayMassTexting((List<String>)params[0], (String)params[1], (Long)params[2]);
|
||||||
|
break;
|
||||||
|
case DELAY_MASS_TEXTING_WITH_TEMPLATE:
|
||||||
|
beforeDelayMassTextingWithTemplate((List<String>)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], (Long)params[3]);
|
||||||
|
break;
|
||||||
|
default: // do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置拦截,在方法执行后,无论是否发生异常都会调用
|
||||||
|
*
|
||||||
|
* @param methodType 方法类型,若不是{@link SmsMethodType}则可能为{@code null}
|
||||||
|
* @param method 调用方法
|
||||||
|
* @param params 调用参数
|
||||||
|
* @param result 返回值
|
||||||
|
* @param ex 调用过程捕获的异常,可能为{@code null}
|
||||||
|
* @return 返回值,不为{@code null}时将覆盖原有的返回值
|
||||||
|
* @implNote 若重写此方法,则务必调用{@link ##doAfterCompletion}方法实现调用分发
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object afterCompletion(SmsMethodType methodType, Method method, Object[] params, Object result, Exception ex) {
|
||||||
|
if (Objects.nonNull(methodType)) {
|
||||||
|
// 将方法分发到具体的调用...
|
||||||
|
doAfterCompletion(params, result, ex, methodType);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void doAfterCompletion(Object[] params, Object result, Exception ex, SmsMethodType methodType) {
|
||||||
|
Objects.requireNonNull(methodType);
|
||||||
|
switch (methodType) {
|
||||||
|
case SEND_MESSAGE:
|
||||||
|
afterSendMessage((String)params[0], (String)params[1], result, ex);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_WITH_TEMPLATE:
|
||||||
|
afterSendMessageWithTemplate((String)params[0], (LinkedHashMap<String, String>)params[1], result, ex);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_WITH_CUSTOM_TEMPLATE:
|
||||||
|
afterSendMessageWithCustomTemplate((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], result, ex);
|
||||||
|
break;
|
||||||
|
case MASS_TEXTING:
|
||||||
|
afterMassTexting((List<String>)params[0], (String)params[1], result, ex);
|
||||||
|
break;
|
||||||
|
case MASS_TEXTING_WITH_TEMPLATE:
|
||||||
|
afterMassTextingWithTemplate((List<String>)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], result, ex);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC:
|
||||||
|
afterSendMessageAsync((String)params[0], (String)params[1], (CallBack)params[2], result, ex);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC_NO_CALLBACK:
|
||||||
|
afterSendMessageAsyncNoCallback((String)params[0], (String)params[1], result, ex);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC_WITH_TEMPLATE:
|
||||||
|
afterSendMessageAsyncWithTemplate((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], (CallBack)params[3], result, ex);
|
||||||
|
break;
|
||||||
|
case SEND_MESSAGE_ASYNC_WITH_TEMPLATE_NO_CALLBACK:
|
||||||
|
afterSendMessageAsyncWithTemplateNoCallback((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], result, ex);
|
||||||
|
break;
|
||||||
|
case DELAYED_MESSAGE:
|
||||||
|
afterDelayedMessage((String)params[0], (String)params[1], (Long)params[2], result, ex);
|
||||||
|
break;
|
||||||
|
case DELAYED_MESSAGE_WITH_TEMPLATE:
|
||||||
|
afterDelayedMessageWithTemplate((String)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], (Long)params[3], result, ex);
|
||||||
|
break;
|
||||||
|
case DELAY_MASS_TEXTING:
|
||||||
|
afterDelayMassTexting((List<String>)params[0], (String)params[1], (Long)params[2], result, ex);
|
||||||
|
break;
|
||||||
|
case DELAY_MASS_TEXTING_WITH_TEMPLATE:
|
||||||
|
afterDelayMassTextingWithTemplate((List<String>)params[0], (String)params[1], (LinkedHashMap<String, String>)params[2], (Long)params[3], result, ex);
|
||||||
|
break;
|
||||||
|
default: // do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// region ===== before =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.dromara.sms4j.api.SmsBlend#sendMessage(String, String)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessage(String phone, String message) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.dromara.sms4j.api.SmsBlend#sendMessage(String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param messages 模板内容
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessageWithTemplate(String phone, LinkedHashMap<String, String> messages) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.dromara.sms4j.api.SmsBlend#sendMessage(String, String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param templateId 模板ID
|
||||||
|
* @param messages 内容
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessageWithCustomTemplate(
|
||||||
|
String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.dromara.sms4j.api.SmsBlend#massTexting(List, String)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
*/
|
||||||
|
protected void beforeMassTexting(List<String> phones, String message) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link org.dromara.sms4j.api.SmsBlend#massTexting(List, String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param templateId 模板ID
|
||||||
|
* @param messages 内容
|
||||||
|
*/
|
||||||
|
protected void beforeMassTextingWithTemplate(
|
||||||
|
List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String, CallBack)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param callBack 回调
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessageAsync(String phone, String message, CallBack callBack) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessageAsyncNoCallback(String phone, String message) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String, LinkedHashMap, CallBack)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param callBack 回调
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessageAsyncWithTemplate(String phone, String message, LinkedHashMap<String, String> template, CallBack callBack) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
*/
|
||||||
|
protected void beforeSendMessageAsyncWithTemplateNoCallback(String phone, String message, LinkedHashMap<String, String> template) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#delayedMessage(String, String, Long)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param delay 延迟时间
|
||||||
|
*/
|
||||||
|
protected void beforeDelayedMessage(String phone, String message, Long delay) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#delayedMessage(String, String, LinkedHashMap, Long)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param delay 延迟时间
|
||||||
|
*/
|
||||||
|
protected void beforeDelayedMessageWithTemplate(String phone, String message, LinkedHashMap<String, String> template, Long delay) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#delayMassTexting(List, String, Long)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param delay 延迟时间
|
||||||
|
*/
|
||||||
|
protected void beforeDelayMassTexting(List<String> phones, String message, Long delay) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置处理 {@link org.dromara.sms4j.api.SmsBlend#delayMassTexting(List, String, LinkedHashMap, Long)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param delay 延迟时间
|
||||||
|
*/
|
||||||
|
protected void beforeDelayMassTextingWithTemplate(List<String> phones, String message, LinkedHashMap<String, String> template, Long delay) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|
||||||
|
// region ===== after =====
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessage(String, String)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessage(String phone, String message, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessage(String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param messages 模板内容
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessageWithTemplate(String phone, LinkedHashMap<String, String> messages, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessage(String, String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param templateId 模板ID
|
||||||
|
* @param messages 内容
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessageWithCustomTemplate(String phone, String templateId, LinkedHashMap<String, String> messages, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#massTexting(List, String)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterMassTexting(List<String> phones, String message, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#massTexting(List, String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param templateId 模板ID
|
||||||
|
* @param messages 内容
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterMassTextingWithTemplate(List<String> phones, String templateId, LinkedHashMap<String, String> messages, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String, CallBack)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param callBack 回调
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessageAsync(String phone, String message, CallBack callBack, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessageAsyncNoCallback(String phone, String message, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String, LinkedHashMap, CallBack)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param callBack 回调
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessageAsyncWithTemplate(String phone, String message, LinkedHashMap<String, String> template, CallBack callBack, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#sendMessageAsync(String, String, LinkedHashMap)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterSendMessageAsyncWithTemplateNoCallback(String phone, String message, LinkedHashMap<String, String> template, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#delayedMessage(String, String, Long)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param delay 延迟时间
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterDelayedMessage(String phone, String message, Long delay, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#delayedMessage(String, String, LinkedHashMap, Long)}
|
||||||
|
*
|
||||||
|
* @param phone 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param delay 延迟时间
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterDelayedMessageWithTemplate(String phone, String message, LinkedHashMap<String, String> template, Long delay, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#delayMassTexting(List, String, Long)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param delay 延迟时间
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterDelayMassTexting(List<String> phones, String message, Long delay, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置处理 {@link org.dromara.sms4j.api.SmsBlend#delayMassTexting(List, String, LinkedHashMap, Long)}
|
||||||
|
*
|
||||||
|
* @param phones 接收短信的手机号
|
||||||
|
* @param message 内容
|
||||||
|
* @param template 模板
|
||||||
|
* @param delay 延迟时间
|
||||||
|
* @param result 方法返回值
|
||||||
|
* @param ex 异常信息
|
||||||
|
*/
|
||||||
|
protected void afterDelayMassTextingWithTemplate(List<String> phones, String message, LinkedHashMap<String, String> template, Long delay, Object result, Exception ex) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
}
|
||||||
@ -1,44 +0,0 @@
|
|||||||
package org.dromara.sms4j.api.proxy;
|
|
||||||
|
|
||||||
import org.dromara.sms4j.comm.constant.NumberOfParasmeters;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
/**
|
|
||||||
* 核心方法执行器接口
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
public interface CoreMethodProcessor extends SmsProcessor {
|
|
||||||
default Object[] preProcessor(Method method, Object source, Object[] param) {
|
|
||||||
String name = method.getName();
|
|
||||||
int parameterCount = method.getParameterCount();
|
|
||||||
if ("sendMessage".equals(name)) {
|
|
||||||
if (NumberOfParasmeters.TWO == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) {
|
|
||||||
sendMessagePreProcess((String) param[0], param[1]);
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
if (NumberOfParasmeters.THREE == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) {
|
|
||||||
sendMessageByTemplatePreProcess((String)param[0],(String) param[1],(LinkedHashMap<String, String>)param[2]);
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ("massTexting".equals(name)) {
|
|
||||||
if (NumberOfParasmeters.TWO == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) {
|
|
||||||
massTextingPreProcess((List<String>)param[0],(String)param[1]);
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
if (NumberOfParasmeters.THREE == NumberOfParasmeters.getNumberOfParasmetersEnum(parameterCount)) {
|
|
||||||
massTextingByTemplatePreProcess((List<String>)param[0],(String)param[1],(LinkedHashMap<String, String>)param[2]);
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
void sendMessagePreProcess(String phone, Object message);
|
|
||||||
void sendMessageByTemplatePreProcess(String phone, String templateId, LinkedHashMap<String, String> messages);
|
|
||||||
void massTextingPreProcess(List<String> phones, String message);
|
|
||||||
void massTextingByTemplatePreProcess(List<String> phones, String templateId, LinkedHashMap<String, String> messages);
|
|
||||||
}
|
|
||||||
@ -1,4 +1,5 @@
|
|||||||
package org.dromara.sms4j.api.proxy;
|
package org.dromara.sms4j.api.proxy;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 排序接口
|
* 排序接口
|
||||||
*
|
*
|
||||||
@ -6,7 +7,13 @@ package org.dromara.sms4j.api.proxy;
|
|||||||
* @since 2023/10/27 13:03
|
* @since 2023/10/27 13:03
|
||||||
*/
|
*/
|
||||||
public interface Order {
|
public interface Order {
|
||||||
default public int getOrder(){
|
|
||||||
return 999;
|
/**
|
||||||
|
* 获取排序值,排序值越大的对象则优先级越低
|
||||||
|
*
|
||||||
|
* @return 排序值
|
||||||
|
*/
|
||||||
|
default int getOrder(){
|
||||||
|
return Integer.MAX_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,46 @@
|
|||||||
|
package org.dromara.sms4j.api.proxy;
|
||||||
|
|
||||||
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>方法拦截器,用于拦截{@link SmsBlend}中的方法。<br />
|
||||||
|
* 推荐基于{@link AbstractGenericMethodInterceptor}实现自定义拦截器。
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
* @see AbstractGenericMethodInterceptor
|
||||||
|
* @see SmsMethodType
|
||||||
|
*/
|
||||||
|
public interface SmsMethodInterceptor extends Order {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前置拦截,在方法执行前调用
|
||||||
|
*
|
||||||
|
* @param methodType 方法类型,若不是{@link SmsMethodType}则可能为{@code null}
|
||||||
|
* @param method 方法
|
||||||
|
* @param target 调用对象
|
||||||
|
* @param params 调用参数
|
||||||
|
* @return 调用参数
|
||||||
|
*/
|
||||||
|
default Object[] beforeInvoke(
|
||||||
|
SmsMethodType methodType, Method method, Object target, Object[] params) {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后置拦截,在方法执行后,无论是否发生异常都会调用
|
||||||
|
*
|
||||||
|
* @param methodType 方法类型,若不是{@link SmsMethodType}则可能为{@code null}
|
||||||
|
* @param method 调用方法
|
||||||
|
* @param params 调用参数
|
||||||
|
* @param result 返回值
|
||||||
|
* @param ex 调用过程捕获的异常,可能为{@code null}
|
||||||
|
* @return 返回值,不为{@code null}时将覆盖原有的返回值
|
||||||
|
*/
|
||||||
|
default Object afterCompletion(
|
||||||
|
SmsMethodType methodType, Method method, Object[] params, Object result, Exception ex) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,140 @@
|
|||||||
|
package org.dromara.sms4j.api.proxy;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.hutool.core.util.ClassUtil;
|
||||||
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
|
import org.dromara.sms4j.api.callback.CallBack;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend}中的主要方法
|
||||||
|
*
|
||||||
|
* @author huangchengxing
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public enum SmsMethodType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessage(String, String)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE("sendMessage", String.class, String.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessage(String, LinkedHashMap)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE_WITH_TEMPLATE("sendMessage", String.class, LinkedHashMap.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessage(String, String, LinkedHashMap)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE_WITH_CUSTOM_TEMPLATE("sendMessage", String.class, String.class, LinkedHashMap.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#massTexting(List, String)}
|
||||||
|
*/
|
||||||
|
MASS_TEXTING("massTexting", List.class, String.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#massTexting(List, String, LinkedHashMap)}
|
||||||
|
*/
|
||||||
|
MASS_TEXTING_WITH_TEMPLATE("massTexting", List.class, String.class, LinkedHashMap.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessageAsync(String, String, CallBack)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE_ASYNC("sendMessageAsync", String.class, String.class, CallBack.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessageAsync(String, String)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE_ASYNC_NO_CALLBACK("sendMessageAsync", String.class, String.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessageAsync(String, String, LinkedHashMap, CallBack)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE_ASYNC_WITH_TEMPLATE("sendMessageAsync", String.class, String.class, LinkedHashMap.class, CallBack.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#sendMessageAsync(String, String, LinkedHashMap)}
|
||||||
|
*/
|
||||||
|
SEND_MESSAGE_ASYNC_WITH_TEMPLATE_NO_CALLBACK("sendMessageAsync", String.class, String.class, LinkedHashMap.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#delayedMessage(String, String, Long)}
|
||||||
|
*/
|
||||||
|
DELAYED_MESSAGE("delayedMessage", String.class, String.class, Long.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#delayedMessage(String, String, LinkedHashMap, Long)}
|
||||||
|
*/
|
||||||
|
DELAYED_MESSAGE_WITH_TEMPLATE("delayedMessage", String.class, String.class, LinkedHashMap.class, Long.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#delayMassTexting(List, String, Long)}
|
||||||
|
*/
|
||||||
|
DELAY_MASS_TEXTING("delayMassTexting", List.class, String.class, Long.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link SmsBlend#delayMassTexting(List, String, LinkedHashMap, Long)}
|
||||||
|
*/
|
||||||
|
DELAY_MASS_TEXTING_WITH_TEMPLATE("delayMassTexting", List.class, String.class, LinkedHashMap.class, Long.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 方法
|
||||||
|
*/
|
||||||
|
private final Method method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取方法名称
|
||||||
|
*
|
||||||
|
* @return 方法名称
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return method.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查指定方法是否与{@link SmsBlend}中的方法匹配
|
||||||
|
*
|
||||||
|
* @param target 目标方法
|
||||||
|
* @return 是否
|
||||||
|
*/
|
||||||
|
public boolean isMatch(Method target) {
|
||||||
|
if (target == method) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return Objects.nonNull(target)
|
||||||
|
&& Objects.equals(method.getName(), target.getName())
|
||||||
|
&& ClassUtil.isAllAssignableFrom(method.getParameterTypes(), target.getParameterTypes())
|
||||||
|
&& ClassUtil.isAssignable(method.getReturnType(), target.getReturnType());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取与目标方法对应的{@link SmsBlend}方法
|
||||||
|
*
|
||||||
|
* @param targetMethod 目标方法
|
||||||
|
* @return {@link SmsMethodType}
|
||||||
|
*/
|
||||||
|
public static SmsMethodType of(Method targetMethod) {
|
||||||
|
return Stream.of(values())
|
||||||
|
.filter(m -> m.isMatch(targetMethod))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
SmsMethodType(String methodName, Class<?>... parameterTypes) {
|
||||||
|
this.method = ReflectUtil.getMethod(SmsBlend.class, methodName, parameterTypes);
|
||||||
|
Assert.notNull(
|
||||||
|
method, "Cannot find best match method from SmsBlend: ({})[{}]",
|
||||||
|
methodName, Arrays.asList(parameterTypes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,24 +0,0 @@
|
|||||||
package org.dromara.sms4j.api.proxy;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
/**
|
|
||||||
* 执行器接口
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
public interface SmsProcessor extends Order {
|
|
||||||
default Object[] preProcessor(Method method, Object source, Object[] param) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
default Object postProcessor(Object result, Object[] param) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
default Object exceptionHandleProcessor(Method method, Object source, Object[] param,Exception exception) throws InvocationTargetException, IllegalAccessException {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,19 @@
|
|||||||
|
package org.dromara.sms4j.api.proxy;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 限制拦截器仅针对哪些厂商生效,如果拦截器需要根据支持厂商加载,那可以实现此接口
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
*/
|
||||||
|
public interface SupplierSupportedMethodInterceptor extends SmsMethodInterceptor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取支持的供应商名称
|
||||||
|
*
|
||||||
|
* @return 供应商名称
|
||||||
|
*/
|
||||||
|
Set<String> getSupportedSuppliers();
|
||||||
|
}
|
||||||
@ -1,12 +0,0 @@
|
|||||||
package org.dromara.sms4j.api.proxy;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
/**
|
|
||||||
* 支持接口,如果执行器需要根据支持厂商加载,那可以实现此接口
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
public interface SuppotFilter{
|
|
||||||
List<String> getSupports();
|
|
||||||
}
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
package org.dromara.sms4j.api.proxy.aware;
|
package org.dromara.sms4j.api.proxy.aware;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 系统配置感知接口
|
* 系统配置感知接口
|
||||||
*
|
*
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package org.dromara.sms4j.api.proxy.aware;
|
package org.dromara.sms4j.api.proxy.aware;
|
||||||
|
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存感知接口
|
* 缓存感知接口
|
||||||
*
|
*
|
||||||
|
|||||||
@ -142,8 +142,6 @@ public abstract class SmsFactory {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* renderWithRestricted
|
* renderWithRestricted
|
||||||
* <p> 构建smsBlend对象的代理对象
|
* <p> 构建smsBlend对象的代理对象
|
||||||
@ -152,7 +150,7 @@ public abstract class SmsFactory {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
private static SmsBlend renderWithProxy(SmsBlend sms) {
|
private static SmsBlend renderWithProxy(SmsBlend sms) {
|
||||||
return SmsProxyFactory.getProxySmsBlend(sms);
|
return SmsProxyFactory.getProxiedSmsBlend(sms);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,34 +0,0 @@
|
|||||||
package org.dromara.sms4j.core.proxy;
|
|
||||||
|
|
||||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 环境信息持有
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
public class EnvirmentHolder {
|
|
||||||
private static SmsConfig smsConfig = null;
|
|
||||||
private static Map<String, Map<String, Object>> blends = null;
|
|
||||||
|
|
||||||
public static void frozenEnvirmet(SmsConfig smsConfig, Map<String, Map<String, Object>> blends) {
|
|
||||||
if (null!=EnvirmentHolder.smsConfig||null!=EnvirmentHolder.blends){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
EnvirmentHolder.smsConfig = smsConfig;
|
|
||||||
EnvirmentHolder.blends = blends;
|
|
||||||
}
|
|
||||||
|
|
||||||
//只有核心包执行器部分才能获取
|
|
||||||
static SmsConfig getSmsConfig() {
|
|
||||||
return smsConfig;
|
|
||||||
}
|
|
||||||
|
|
||||||
//只有核心包执行器部分才能获取
|
|
||||||
static Map<String, Map<String, Object>> getBlends() {
|
|
||||||
return blends;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package org.dromara.sms4j.core.proxy;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 环境信息持有
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class EnvironmentHolder {
|
||||||
|
|
||||||
|
private static SmsConfig smsConfig = null;
|
||||||
|
private static Map<String, Map<String, Object>> blends = null;
|
||||||
|
|
||||||
|
public static void frozen(SmsConfig smsConfig, Map<String, Map<String, Object>> blends) {
|
||||||
|
if (Objects.nonNull(EnvironmentHolder.smsConfig) || Objects.nonNull(EnvironmentHolder.blends)) {
|
||||||
|
log.warn("The environmental information has been loaded and cannot be overwritten!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
EnvironmentHolder.smsConfig = smsConfig;
|
||||||
|
EnvironmentHolder.blends = blends;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置信息
|
||||||
|
*
|
||||||
|
* @return 配置
|
||||||
|
*/
|
||||||
|
static SmsConfig getSmsConfig() {
|
||||||
|
return smsConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取短信配置信息
|
||||||
|
*
|
||||||
|
* @return 短信配置信息
|
||||||
|
*/
|
||||||
|
static Map<String, Map<String, Object>> getBlends() {
|
||||||
|
return blends;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,69 +1,54 @@
|
|||||||
package org.dromara.sms4j.core.proxy;
|
package org.dromara.sms4j.core.proxy;
|
||||||
|
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.sms4j.api.SmsBlend;
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
import org.dromara.sms4j.api.proxy.SmsProcessor;
|
import org.dromara.sms4j.api.proxy.SmsMethodType;
|
||||||
import org.dromara.sms4j.api.proxy.SuppotFilter;
|
import org.dromara.sms4j.api.proxy.SmsMethodInterceptor;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SmsBlend增强,封装smsblend和执行器
|
* {@link SmsBlend}代理,用于织入{@link SmsMethodInterceptor}实现前置和后置拦截
|
||||||
*
|
*
|
||||||
* @author sh1yu
|
* @author sh1yu
|
||||||
* @since 2023/10/27 13:03
|
* @since 2023/10/27 13:03
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@RequiredArgsConstructor
|
||||||
public class SmsInvocationHandler implements InvocationHandler {
|
public class SmsInvocationHandler implements InvocationHandler {
|
||||||
private final SmsBlend smsBlend;
|
|
||||||
private final LinkedList<SmsProcessor> processors;
|
|
||||||
|
|
||||||
|
private final SmsBlend delegate;
|
||||||
public SmsInvocationHandler(SmsBlend smsBlend, LinkedList<SmsProcessor> processors) {
|
private final List<SmsMethodInterceptor> interceptors;
|
||||||
this.smsBlend = smsBlend;
|
|
||||||
this.processors = processors;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
|
public Object invoke(Object target, Method method, Object[] params) {
|
||||||
|
SmsMethodType methodType = SmsMethodType.of(method);
|
||||||
Object result = null;
|
Object result = null;
|
||||||
//前置执行器
|
// 前置拦截
|
||||||
objects = doPreProcess(smsBlend, method, objects);
|
params = invokePreHandle(methodType, delegate, method, params);
|
||||||
|
Exception ex = null;
|
||||||
try {
|
try {
|
||||||
result = method.invoke(smsBlend, objects);
|
result = method.invoke(delegate, params);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
//错误执行器
|
ex = e;
|
||||||
doErrorHandleProcess(smsBlend, method, objects,e);
|
|
||||||
}
|
}
|
||||||
//后置执行器
|
// 后置拦截
|
||||||
doPostrocess(smsBlend, method, objects, result);
|
return invokeAfterCompletion(methodType, method, params, result, ex);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] doPreProcess(Object o, Method method, Object[] objects) {
|
private Object[] invokePreHandle(SmsMethodType methodType, Object o, Method method, Object[] objects) {
|
||||||
for (SmsProcessor processor : processors) {
|
for (SmsMethodInterceptor interceptor : interceptors) {
|
||||||
objects = processor.preProcessor(method, o, objects);
|
objects = interceptor.beforeInvoke(methodType, method, o, objects);
|
||||||
}
|
}
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doErrorHandleProcess(Object o, Method method, Object[] objects,Exception e) throws InvocationTargetException, IllegalAccessException {
|
private Object invokeAfterCompletion(SmsMethodType methodType, Method method, Object[] params, Object result, Exception ex) {
|
||||||
for (SmsProcessor processor : processors) {
|
for (SmsMethodInterceptor interceptor : interceptors) {
|
||||||
processor.exceptionHandleProcessor(method, o, objects,e);
|
result = interceptor.afterCompletion(methodType, method, params, result, ex);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object doPostrocess(Object o, Method method, Object[] objects, Object result) {
|
|
||||||
for (SmsProcessor processor : processors) {
|
|
||||||
Object overrideResult = processor.postProcessor(result, objects);
|
|
||||||
if (overrideResult != null) {
|
|
||||||
return overrideResult;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,14 @@
|
|||||||
package org.dromara.sms4j.core.proxy;
|
package org.dromara.sms4j.core.proxy;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.sms4j.api.SmsBlend;
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
import org.dromara.sms4j.api.dao.SmsDaoDefaultImpl;
|
import org.dromara.sms4j.api.dao.SmsDaoDefaultImpl;
|
||||||
import org.dromara.sms4j.api.proxy.Order;
|
import org.dromara.sms4j.api.proxy.Order;
|
||||||
import org.dromara.sms4j.api.proxy.SmsProcessor;
|
import org.dromara.sms4j.api.proxy.SmsMethodInterceptor;
|
||||||
import org.dromara.sms4j.api.proxy.SuppotFilter;
|
import org.dromara.sms4j.api.proxy.SupplierSupportedMethodInterceptor;
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsBlendConfigAware;
|
import org.dromara.sms4j.api.proxy.aware.SmsBlendConfigAware;
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsConfigAware;
|
import org.dromara.sms4j.api.proxy.aware.SmsConfigAware;
|
||||||
@ -14,9 +16,10 @@ import org.dromara.sms4j.api.proxy.aware.SmsConfigAware;
|
|||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Proxy;
|
import java.lang.reflect.Proxy;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,68 +27,80 @@ import java.util.stream.Collectors;
|
|||||||
*
|
*
|
||||||
* @author sh1yu
|
* @author sh1yu
|
||||||
* @since 2023/10/27 13:03
|
* @since 2023/10/27 13:03
|
||||||
|
* @see SmsMethodInterceptor
|
||||||
|
* @see SmsInvocationHandler
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
public abstract class SmsProxyFactory {
|
public abstract class SmsProxyFactory {
|
||||||
private static final LinkedList<SmsProcessor> processors = new LinkedList<>();
|
|
||||||
|
|
||||||
public static SmsBlend getProxySmsBlend(SmsBlend smsBlend) {
|
private static final List<SmsMethodInterceptor> INTERCEPTORS = new ArrayList<>();
|
||||||
LinkedList<SmsProcessor> ownerProcessors = processors.stream().filter(processor -> !shouldSkipProcess(processor,smsBlend)).collect(Collectors.toCollection(LinkedList::new));
|
private static final String SPRING_SMS_DAO_LOAD_PATH = "org.dromara.sms4j.starter.holder.SpringSmsDaoHolder";
|
||||||
return (SmsBlend) Proxy.newProxyInstance(smsBlend.getClass().getClassLoader(), new Class[]{SmsBlend.class}, new SmsInvocationHandler(smsBlend, ownerProcessors));
|
private static final String SOLON_SMS_DAO_LOAD_PATH = "org.dromara.sms4j.solon.holder.SolonSmsDaoHolder";
|
||||||
|
|
||||||
|
public static final int CORE_PARAM_VALIDATE_METHOD_INTERCEPTOR_ORDER = -1;
|
||||||
|
public static final int BLACK_LIST_METHOD_INTERCEPTOR_ORDER = 0;
|
||||||
|
public static final int BLACK_LIST_RECORDING_METHOD_INTERCEPTOR_ORDER = 1;
|
||||||
|
public static final int RESTRICTED_METHOD_INTERCEPTOR = 3;
|
||||||
|
public static final int SINGLE_BLEND_RESTRICTED_METHOD_INTERCEPTOR_ORDER = 2;
|
||||||
|
|
||||||
|
public static SmsBlend getProxiedSmsBlend(SmsBlend smsBlend) {
|
||||||
|
Objects.requireNonNull(smsBlend);
|
||||||
|
// 若已被代理则直接返回,避免重复代理
|
||||||
|
if (smsBlend instanceof Proxied) {
|
||||||
|
return smsBlend;
|
||||||
|
}
|
||||||
|
List<SmsMethodInterceptor> appliedInterceptors = INTERCEPTORS.stream()
|
||||||
|
.filter(processor -> canApply(processor, smsBlend))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
return (SmsBlend) Proxy.newProxyInstance(
|
||||||
|
smsBlend.getClass().getClassLoader(),
|
||||||
|
new Class[]{ SmsBlend.class, Proxied.class },
|
||||||
|
new SmsInvocationHandler(smsBlend, appliedInterceptors)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 增加拦截器
|
* 增加拦截器
|
||||||
|
*
|
||||||
|
* @param processor 处理器
|
||||||
|
* TODO 当在SpringBoot或Solon环境中使用时,应当在完成加载后,主动从IOC容器获取并注册用户自定义的方法拦截器
|
||||||
*/
|
*/
|
||||||
public static void addProcessor(SmsProcessor processor) {
|
public static void addProcessor(SmsMethodInterceptor processor) {
|
||||||
//校验拦截器是否正确
|
Objects.requireNonNull(processor);
|
||||||
processorValidate(processor);
|
// 调用Aware接口,将必要参数传递给处理器
|
||||||
awareTransfer(processor);
|
awareTransfer(processor);
|
||||||
processors.add(processor);
|
// 尝试移除旧拦截器避免重复添加
|
||||||
processors.sort(Comparator.comparingInt(Order::getOrder));
|
INTERCEPTORS.remove(processor);
|
||||||
|
INTERCEPTORS.add(processor);
|
||||||
|
INTERCEPTORS.sort(Comparator.comparingInt(Order::getOrder));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
private static boolean canApply(SmsMethodInterceptor processor, SmsBlend smsBlend) {
|
||||||
* @see SuppotFilter
|
// 判断当前的执行器有没有开厂商过滤,支不支持当前厂商
|
||||||
*/
|
return !(processor instanceof SupplierSupportedMethodInterceptor)
|
||||||
public static boolean shouldSkipProcess(SmsProcessor processor, SmsBlend smsBlend) {
|
|| ((SupplierSupportedMethodInterceptor)processor).getSupportedSuppliers().contains(smsBlend.getSupplier());
|
||||||
//判断当前的执行器有没有开厂商过滤,支不支持当前厂商
|
|
||||||
if (processor instanceof SuppotFilter) {
|
|
||||||
List<String> supports = ((SuppotFilter) processor).getSupports();
|
|
||||||
boolean exsit = supports.stream().filter(support -> support.equals(smsBlend.getSupplier())).findAny().isPresent();
|
|
||||||
if (!exsit) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//所有处理器需要的各个参数可以通过这种aware接口形式传给对象
|
private static void awareTransfer(SmsMethodInterceptor processor) {
|
||||||
private static void awareTransfer(SmsProcessor processor) {
|
|
||||||
if (processor instanceof SmsDaoAware){
|
if (processor instanceof SmsDaoAware){
|
||||||
((SmsDaoAware) processor).setSmsDao(getSmsDaoFromFramework());
|
((SmsDaoAware) processor).setSmsDao(getSmsDaoFromFramework());
|
||||||
}
|
}
|
||||||
if (processor instanceof SmsConfigAware){
|
if (processor instanceof SmsConfigAware){
|
||||||
((SmsConfigAware) processor).setSmsConfig(EnvirmentHolder.getSmsConfig());
|
((SmsConfigAware) processor).setSmsConfig(EnvironmentHolder.getSmsConfig());
|
||||||
}
|
}
|
||||||
if (processor instanceof SmsBlendConfigAware){
|
if (processor instanceof SmsBlendConfigAware){
|
||||||
((SmsBlendConfigAware) processor).setSmsBlendsConfig(EnvirmentHolder.getBlends());
|
((SmsBlendConfigAware) processor).setSmsBlendsConfig(EnvironmentHolder.getBlends());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//校验拦截器是否正确
|
|
||||||
private static void processorValidate(SmsProcessor processor) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取Sms的实现
|
|
||||||
private static SmsDao getSmsDaoFromFramework() {
|
private static SmsDao getSmsDaoFromFramework() {
|
||||||
SmsDao smsDao;
|
SmsDao smsDao;
|
||||||
smsDao = getSmsDaoFromFramework("org.dromara.sms4j.starter.holder.SpringSmsDaoHolder", "SpringBoot");
|
smsDao = getSmsDaoFromFramework(SPRING_SMS_DAO_LOAD_PATH, "SpringBoot");
|
||||||
if (null != smsDao) {
|
if (null != smsDao) {
|
||||||
return smsDao;
|
return smsDao;
|
||||||
}
|
}
|
||||||
smsDao = getSmsDaoFromFramework("org.dromara.sms4j.solon.holder.SolonSmsDaoHolder", "Solon");
|
smsDao = getSmsDaoFromFramework(SOLON_SMS_DAO_LOAD_PATH, "Solon");
|
||||||
if (null != smsDao) {
|
if (null != smsDao) {
|
||||||
return smsDao;
|
return smsDao;
|
||||||
}
|
}
|
||||||
@ -93,16 +108,16 @@ public abstract class SmsProxyFactory {
|
|||||||
return SmsDaoDefaultImpl.getInstance();
|
return SmsDaoDefaultImpl.getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取Sms的实现
|
|
||||||
private static SmsDao getSmsDaoFromFramework(String className, String frameworkName) {
|
private static SmsDao getSmsDaoFromFramework(String className, String frameworkName) {
|
||||||
try {
|
try {
|
||||||
Class<?> clazz = Class.forName(className);
|
Class<?> clazz = Class.forName(className);
|
||||||
Method getSmsDao = clazz.getMethod("getSmsDao", null);
|
Method getSmsDao = clazz.getMethod("getSmsDao");
|
||||||
return (SmsDao) getSmsDao.invoke(null, null);
|
return (SmsDao) getSmsDao.invoke(null);
|
||||||
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||||
log.error("{}:加载SmsDao失败,尝试其他框架加载......", frameworkName);
|
log.error("{}:加载SmsDao失败,尝试其他框架加载......", frameworkName);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface Proxied {}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,70 @@
|
|||||||
|
package org.dromara.sms4j.core.proxy.interceptor;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
|
import org.dromara.sms4j.api.proxy.AbstractGenericMethodInterceptor;
|
||||||
|
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
||||||
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黑名单前置拦截执行器
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class BlackListMethodInterceptor extends AbstractGenericMethodInterceptor implements SmsDaoAware {
|
||||||
|
|
||||||
|
private static final String CONFIG_PROPERTIES_PREFIX = "sms:blacklist:global";
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private SmsDao smsDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return SmsProxyFactory.BLACK_LIST_METHOD_INTERCEPTOR_ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeSendMessage(String phone, String message) {
|
||||||
|
doRestricted(Collections.singletonList(phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeSendMessageWithTemplate(String phone, LinkedHashMap<String, String> messages) {
|
||||||
|
doRestricted(Collections.singletonList(phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeSendMessageWithCustomTemplate(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
doRestricted(Collections.singletonList(phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeMassTexting(List<String> phones, String message) {
|
||||||
|
doRestricted(phones);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeMassTextingWithTemplate(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
doRestricted(phones);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void doRestricted(List<String> phones) {
|
||||||
|
List<String> blackList = (List<String>) smsDao.get(CONFIG_PROPERTIES_PREFIX);
|
||||||
|
if (CollUtil.isEmpty(blackList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String phone : phones) {
|
||||||
|
if (blackList.stream().anyMatch(black -> black.replace("-","").equals(phone))) {
|
||||||
|
throw new SmsBlendException("The phone:", phone + " hit global blacklist!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
package org.dromara.sms4j.core.proxy.interceptor;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
|
import org.dromara.sms4j.api.proxy.SmsMethodType;
|
||||||
|
import org.dromara.sms4j.api.proxy.SmsMethodInterceptor;
|
||||||
|
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
||||||
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 黑名单前置拦截执行器
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
* @see SmsBlend#batchJoinBlacklist
|
||||||
|
* @see SmsBlend#batchRemovalFromBlacklist
|
||||||
|
* @see SmsBlend#joinInBlacklist
|
||||||
|
* @see SmsBlend#removeFromBlacklist
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class BlackListRecordingMethodInterceptor implements SmsMethodInterceptor, SmsDaoAware {
|
||||||
|
|
||||||
|
private static final String REDIS_KEY_PREFIX = "sms:blacklist:global";
|
||||||
|
private static final String CONFIG_PROPERTIES_PREFIX = "sms:blacklist:global";
|
||||||
|
|
||||||
|
private static final String JOIN_IN_BLACKLIST_METHOD = "joinInBlacklist";
|
||||||
|
private static final String REMOVE_FROM_BLACKLIST_METHOD = "removeFromBlacklist";
|
||||||
|
private static final String BATCH_JOIN_BLACKLIST_METHOD = "batchJoinBlacklist";
|
||||||
|
private static final String BATCH_REMOVAL_FROM_BLACKLIST_METHOD = "batchRemovalFromBlacklist";
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
private SmsDao smsDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder(){
|
||||||
|
return SmsProxyFactory.BLACK_LIST_RECORDING_METHOD_INTERCEPTOR_ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public Object[] beforeInvoke(SmsMethodType methodType, Method method, Object target, Object[] params) {
|
||||||
|
// TODO 并发操作是否可以保证安全性?
|
||||||
|
// TODO 不同的SmsBlend对象操作的确是同一份黑名单配置是否合理?
|
||||||
|
// TODO 是否应该同时支持黑白名单?
|
||||||
|
//添加到黑名单
|
||||||
|
String methodName = method.getName();
|
||||||
|
if (JOIN_IN_BLACKLIST_METHOD.equals(methodName)) {
|
||||||
|
String cacheKey = REDIS_KEY_PREFIX;
|
||||||
|
List<String> blackList = getBlackList(cacheKey);
|
||||||
|
blackList.add((String) params[0]);
|
||||||
|
flushBlackList(cacheKey,blackList);
|
||||||
|
}
|
||||||
|
//从黑名单移除
|
||||||
|
else if (REMOVE_FROM_BLACKLIST_METHOD.equals(methodName)) {
|
||||||
|
String cacheKey = REDIS_KEY_PREFIX;
|
||||||
|
List<String> blackList = getBlackList(cacheKey);
|
||||||
|
blackList.remove((String) params[0]);
|
||||||
|
flushBlackList(cacheKey,blackList);
|
||||||
|
}
|
||||||
|
//批量添加到黑名单
|
||||||
|
else if (BATCH_JOIN_BLACKLIST_METHOD.equals(methodName)) {
|
||||||
|
String cacheKey = REDIS_KEY_PREFIX;
|
||||||
|
List<String> blackList = getBlackList(cacheKey);
|
||||||
|
blackList.addAll((List<String>) params[0]);
|
||||||
|
flushBlackList(cacheKey,blackList);
|
||||||
|
}
|
||||||
|
//批量从黑名单移除
|
||||||
|
else if (BATCH_REMOVAL_FROM_BLACKLIST_METHOD.equals(methodName)) {
|
||||||
|
String cacheKey = REDIS_KEY_PREFIX;
|
||||||
|
List<String> blackList = getBlackList(cacheKey);
|
||||||
|
blackList.removeAll((List<String>) params[0]);
|
||||||
|
flushBlackList(cacheKey, blackList);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private List<String> getBlackList(String cacheKey) {
|
||||||
|
List<String> blackList;
|
||||||
|
Object cache = smsDao.get(cacheKey);
|
||||||
|
if (null != cache) {
|
||||||
|
blackList = (List<String>) cache;
|
||||||
|
return blackList;
|
||||||
|
}
|
||||||
|
blackList = new ArrayList<>();
|
||||||
|
smsDao.set(CONFIG_PROPERTIES_PREFIX, blackList);
|
||||||
|
return blackList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 刷新黑名单
|
||||||
|
*
|
||||||
|
* @param cacheKey cacheKey
|
||||||
|
* @param blackList 新的黑名单列表
|
||||||
|
*/
|
||||||
|
private void flushBlackList(String cacheKey, List<String> blackList) {
|
||||||
|
smsDao.set(cacheKey, blackList);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,132 @@
|
|||||||
|
package org.dromara.sms4j.core.proxy.interceptor;
|
||||||
|
|
||||||
|
import lombok.Setter;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
|
import org.dromara.sms4j.api.proxy.AbstractGenericMethodInterceptor;
|
||||||
|
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
||||||
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
|
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||||
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
|
import org.dromara.sms4j.provider.config.SmsConfig;
|
||||||
|
import org.dromara.sms4j.provider.factory.BeanFactory;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短信发送账号级上限前置拦截执行器
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class RestrictedMethodInterceptor extends AbstractGenericMethodInterceptor implements SmsDaoAware {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 每分钟最多可发送条数
|
||||||
|
* TODO 每分钟最多可发送条数应当可配置
|
||||||
|
*/
|
||||||
|
private static final Long MINUTE_MAXIMUM_COUNT = 60 * 1000L;
|
||||||
|
/**
|
||||||
|
* 每个账号最多可发送条数
|
||||||
|
* TODO 每个账号最多可发送条数应当可配置
|
||||||
|
*/
|
||||||
|
private static final Long ACCOUNT_MAXIMUM_COUNT = 24 * 60 * 60 * 1000L;
|
||||||
|
/**
|
||||||
|
* redis缓存前缀
|
||||||
|
* TODO redis缓存前缀应当可配置
|
||||||
|
*/
|
||||||
|
private static final String REDIS_KEY = "sms:restricted:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存实例
|
||||||
|
*/
|
||||||
|
@Setter
|
||||||
|
private SmsDao smsDao;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return SmsProxyFactory.RESTRICTED_METHOD_INTERCEPTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeSendMessage(String phone, String message) {
|
||||||
|
restricted(Collections.singletonList(phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeSendMessageWithTemplate(String phone, LinkedHashMap<String, String> messages) {
|
||||||
|
restricted(Collections.singletonList(phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeSendMessageWithCustomTemplate(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
restricted(Collections.singletonList(phone));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeMassTexting(List<String> phones, String message) {
|
||||||
|
restricted(phones);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeMassTextingWithTemplate(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
restricted(phones);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void restricted(List<String> phones) {
|
||||||
|
if (Objects.isNull(smsDao)) {
|
||||||
|
throw new SmsBlendException("The dao tool could not be found");
|
||||||
|
}
|
||||||
|
SmsConfig config = BeanFactory.getSmsConfig();
|
||||||
|
// 每日最大发送量
|
||||||
|
Integer accountMax = config.getAccountMax();
|
||||||
|
// 每分钟最大发送量
|
||||||
|
Integer minuteMax = config.getMinuteMax();
|
||||||
|
for (String phone : phones) {
|
||||||
|
doRestricted(accountMax, minuteMax, phone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doRestricted(Integer accountMax, Integer minuteMax, String phone) {
|
||||||
|
// 是否配置了每日限制
|
||||||
|
if (SmsUtils.isNotEmpty(accountMax)) {
|
||||||
|
checkAccountMax(accountMax, phone);
|
||||||
|
}
|
||||||
|
// 是否配置了每分钟最大限制
|
||||||
|
if (SmsUtils.isNotEmpty(minuteMax)) {
|
||||||
|
Integer count = (Integer) smsDao.get(REDIS_KEY + phone);
|
||||||
|
checkMinuteMax(minuteMax, phone, count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkMinuteMax(Integer minuteMax, String phone, Integer count) {
|
||||||
|
if (SmsUtils.isEmpty(count)) {
|
||||||
|
smsDao.set(REDIS_KEY + phone, 1, MINUTE_MAXIMUM_COUNT / 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (count < minuteMax) {
|
||||||
|
smsDao.set(REDIS_KEY + phone, count + 1, MINUTE_MAXIMUM_COUNT / 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info("The phone: {}, number of short messages reached the maximum today", phone);
|
||||||
|
throw new SmsBlendException("The phone:", phone + " Text messages are sent too often!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkAccountMax(Integer accountMax, String phone) {
|
||||||
|
Integer i = (Integer) smsDao.get(REDIS_KEY + phone + "max");
|
||||||
|
if (SmsUtils.isEmpty(i)) {
|
||||||
|
smsDao.set(REDIS_KEY + phone + "max", 1, ACCOUNT_MAXIMUM_COUNT / 1000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (i >= accountMax) {
|
||||||
|
log.info("The phone: {}, number of short messages reached the maximum today", phone);
|
||||||
|
throw new SmsBlendException("The phone:" + phone + ",number of short messages reached the maximum today");
|
||||||
|
}
|
||||||
|
smsDao.set(REDIS_KEY + phone + "max", i + 1, ACCOUNT_MAXIMUM_COUNT / 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,17 +1,16 @@
|
|||||||
package org.dromara.sms4j.core.proxy.processor;
|
package org.dromara.sms4j.core.proxy.interceptor;
|
||||||
|
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.sms4j.api.SmsBlend;
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
import org.dromara.sms4j.api.dao.SmsDao;
|
||||||
import org.dromara.sms4j.api.proxy.CoreMethodProcessor;
|
import org.dromara.sms4j.api.proxy.SmsMethodType;
|
||||||
import org.dromara.sms4j.api.proxy.SmsProcessor;
|
import org.dromara.sms4j.api.proxy.SmsMethodInterceptor;
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsBlendConfigAware;
|
import org.dromara.sms4j.api.proxy.aware.SmsBlendConfigAware;
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||||
import org.dromara.sms4j.provider.config.BaseConfig;
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
import org.dromara.sms4j.provider.service.AbstractSmsBlend;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -24,9 +23,11 @@ import java.util.*;
|
|||||||
* @since 2023/10/27 13:03
|
* @since 2023/10/27 13:03
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SingleBlendRestrictedProcessor implements SmsProcessor, SmsDaoAware, SmsBlendConfigAware {
|
public class SingleBlendRestrictedMethodInterceptor implements SmsMethodInterceptor, SmsDaoAware, SmsBlendConfigAware {
|
||||||
|
|
||||||
private static final String REDIS_KEY = "sms:restricted:";
|
private static final String REDIS_KEY = "sms:restricted:";
|
||||||
|
private static final String SEND_MESSAGE_METHOD = "sendMessage";
|
||||||
|
private static final String MASS_TEXT_METHOD = "massText";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存实例
|
* 缓存实例
|
||||||
@ -35,30 +36,31 @@ public class SingleBlendRestrictedProcessor implements SmsProcessor, SmsDaoAware
|
|||||||
private SmsDao smsDao;
|
private SmsDao smsDao;
|
||||||
|
|
||||||
@Setter
|
@Setter
|
||||||
Map smsBlendsConfig;
|
private Map<String, Map<String, Object>> smsBlendsConfig;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getOrder() {
|
public int getOrder() {
|
||||||
return 2;
|
return SmsProxyFactory.SINGLE_BLEND_RESTRICTED_METHOD_INTERCEPTOR_ORDER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object[] preProcessor(Method method, Object source, Object[] param) {
|
public Object[] beforeInvoke(SmsMethodType methodType, Method method, Object target, Object[] params) {
|
||||||
String name = method.getName();
|
if (Objects.isNull(methodType)
|
||||||
if (!"sendMessage".equals(name) && !"massText".equals(name)) {
|
|| !Objects.equals(methodType.getName(), SEND_MESSAGE_METHOD)
|
||||||
return param;
|
|| !Objects.equals(methodType.getName(), MASS_TEXT_METHOD)) {
|
||||||
|
return params;
|
||||||
}
|
}
|
||||||
SmsBlend smsBlend = (SmsBlend) source;
|
SmsBlend smsBlend = (SmsBlend)target;
|
||||||
String configId = smsBlend.getConfigId();
|
String configId = smsBlend.getConfigId();
|
||||||
Map targetConfig = (Map) smsBlendsConfig.get(configId);
|
Map<String, Object> targetConfig = smsBlendsConfig.get(configId);
|
||||||
Object maximumObj = targetConfig.get("maximum");
|
Object maximumObj = targetConfig.get("maximum");
|
||||||
if (SmsUtils.isEmpty(maximumObj)) {
|
if (SmsUtils.isEmpty(maximumObj)) {
|
||||||
return param;
|
return params;
|
||||||
}
|
}
|
||||||
int maximum = 0;
|
int maximum = 0;
|
||||||
try{
|
try {
|
||||||
maximum = (int) maximumObj ;
|
maximum = (int)maximumObj;
|
||||||
}catch (Exception e){
|
} catch (Exception e) {
|
||||||
log.error("获取厂商级发送上限参数错误!请检查!");
|
log.error("获取厂商级发送上限参数错误!请检查!");
|
||||||
throw new IllegalArgumentException("获取厂商级发送上限参数错误");
|
throw new IllegalArgumentException("获取厂商级发送上限参数错误");
|
||||||
}
|
}
|
||||||
@ -66,11 +68,11 @@ public class SingleBlendRestrictedProcessor implements SmsProcessor, SmsDaoAware
|
|||||||
if (SmsUtils.isEmpty(i)) {
|
if (SmsUtils.isEmpty(i)) {
|
||||||
smsDao.set(REDIS_KEY + configId + "maximum", 1);
|
smsDao.set(REDIS_KEY + configId + "maximum", 1);
|
||||||
} else if (i >= maximum) {
|
} else if (i >= maximum) {
|
||||||
log.info("The channel:" + configId + ",messages reached the maximum");
|
log.info("The channel: {}, messages reached the maximum", configId);
|
||||||
throw new SmsBlendException("The channel:" + configId + ",messages reached the maximum");
|
throw new SmsBlendException("The channel: " + configId + ", messages reached the maximum", configId);
|
||||||
} else {
|
} else {
|
||||||
smsDao.set(REDIS_KEY + configId + "maximum", i + 1);
|
smsDao.set(REDIS_KEY + configId + "maximum", i + 1);
|
||||||
}
|
}
|
||||||
return param;
|
return params;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -0,0 +1,91 @@
|
|||||||
|
package org.dromara.sms4j.core.proxy.interceptor;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.dromara.sms4j.api.proxy.AbstractGenericMethodInterceptor;
|
||||||
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步调用方法参数校验前置拦截执行器
|
||||||
|
*
|
||||||
|
* @author sh1yu
|
||||||
|
* @since 2023/10/27 13:03
|
||||||
|
* TODO 异步调用和延迟调用的参数是否需要校验?
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class SyncMethodParamValidateMethodInterceptor extends AbstractGenericMethodInterceptor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return SmsProxyFactory.CORE_PARAM_VALIDATE_METHOD_INTERCEPTOR_ORDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeSendMessage(String phone, String message) {
|
||||||
|
validatePhone(phone);
|
||||||
|
validateMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void beforeSendMessageWithTemplate(String phone, LinkedHashMap<String, String> messages) {
|
||||||
|
validatePhone(phone);
|
||||||
|
validateMessage(messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeSendMessageWithCustomTemplate(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
validatePhone(phone);
|
||||||
|
validateMessages(templateId, messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeMassTexting(List<String> phones, String message) {
|
||||||
|
validateMessage(message);
|
||||||
|
validatePhones(phones);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeMassTextingWithTemplate(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
validatePhones(phones);
|
||||||
|
validateMessages(templateId, messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateMessage(Object messageObj) {
|
||||||
|
if (messageObj instanceof String){
|
||||||
|
String message = (String) messageObj;
|
||||||
|
if (CharSequenceUtil.isEmpty(message)) {
|
||||||
|
throw new SmsBlendException("can't send a null message!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (messageObj instanceof Map){
|
||||||
|
Map<?, ?> message = (Map<?, ?>) messageObj;
|
||||||
|
if (CollUtil.isEmpty(message)) {
|
||||||
|
throw new SmsBlendException("can't send a null message!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validatePhone(String phone) {
|
||||||
|
if (CharSequenceUtil.isEmpty(phone)) {
|
||||||
|
throw new SmsBlendException("can't send message to null!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validatePhones(List<String> phones) {
|
||||||
|
if (CollUtil.isEmpty(phones)) {
|
||||||
|
throw new SmsBlendException("can't send message to null!");
|
||||||
|
}
|
||||||
|
phones.forEach(this::validatePhone);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validateMessages(String templateId, LinkedHashMap<String, String> messages) {
|
||||||
|
if (CharSequenceUtil.isNotEmpty(templateId) && CollUtil.isEmpty(messages)) {
|
||||||
|
throw new SmsBlendException("can't use template without template param");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,61 +0,0 @@
|
|||||||
package org.dromara.sms4j.core.proxy.processor;
|
|
||||||
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
|
||||||
import org.dromara.sms4j.api.proxy.CoreMethodProcessor;
|
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsConfigAware;
|
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
|
||||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 黑名单前置拦截执行器
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class BlackListProcessor implements CoreMethodProcessor, SmsDaoAware {
|
|
||||||
@Setter
|
|
||||||
SmsDao smsDao;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrder() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessagePreProcess(String phone, Object message) {
|
|
||||||
doRestricted(Collections.singletonList(phone));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessageByTemplatePreProcess(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
doRestricted(Collections.singletonList(phone));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void massTextingPreProcess(List<String> phones, String message) {
|
|
||||||
doRestricted(phones);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void massTextingByTemplatePreProcess(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
doRestricted(phones);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doRestricted(List<String> phones) {
|
|
||||||
ArrayList<String> blackList = (ArrayList<String>) smsDao.get("sms:blacklist:global");
|
|
||||||
if(null==blackList){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (String phone : phones) {
|
|
||||||
if (blackList.stream().filter(black -> black.replace("-","").equals(phone)).findAny().isPresent()) {
|
|
||||||
throw new SmsBlendException("The phone:", phone + " hit global blacklist!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,87 +0,0 @@
|
|||||||
package org.dromara.sms4j.core.proxy.processor;
|
|
||||||
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
|
||||||
import org.dromara.sms4j.api.proxy.SmsProcessor;
|
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsConfigAware;
|
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 黑名单前置拦截执行器
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class BlackListRecordingProcessor implements SmsProcessor, SmsDaoAware, SmsConfigAware {
|
|
||||||
@Setter
|
|
||||||
SmsDao smsDao;
|
|
||||||
|
|
||||||
@Setter
|
|
||||||
Object smsConfig;
|
|
||||||
|
|
||||||
public int getOrder(){
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[] preProcessor(Method method, Object source, Object[] param) {
|
|
||||||
//添加到黑名单
|
|
||||||
if (method.getName().equals("joinInBlacklist")) {
|
|
||||||
String cacheKey = getCacheKey();
|
|
||||||
ArrayList<String> blackList = getBlackList(cacheKey);
|
|
||||||
blackList.add((String) param[0]);
|
|
||||||
flushBlackList(cacheKey,blackList);
|
|
||||||
}
|
|
||||||
//从黑名单移除
|
|
||||||
if (method.getName().equals("removeFromBlacklist")) {
|
|
||||||
String cacheKey = getCacheKey();
|
|
||||||
ArrayList<String> blackList = getBlackList(cacheKey);
|
|
||||||
blackList.remove((String) param[0]);
|
|
||||||
flushBlackList(cacheKey,blackList);
|
|
||||||
}
|
|
||||||
//批量添加到黑名单
|
|
||||||
if (method.getName().equals("batchJoinBlacklist")) {
|
|
||||||
String cacheKey = getCacheKey();
|
|
||||||
ArrayList<String> blackList = getBlackList(cacheKey);
|
|
||||||
blackList.addAll((List<String>) param[0]);
|
|
||||||
flushBlackList(cacheKey,blackList);
|
|
||||||
}
|
|
||||||
//批量从黑名单移除
|
|
||||||
if (method.getName().equals("batchRemovalFromBlacklist")) {
|
|
||||||
String cacheKey = getCacheKey();
|
|
||||||
ArrayList<String> blackList = getBlackList(cacheKey);
|
|
||||||
blackList.removeAll((List<String>) param[0]);
|
|
||||||
flushBlackList(cacheKey,blackList);
|
|
||||||
}
|
|
||||||
return param;
|
|
||||||
}
|
|
||||||
|
|
||||||
//构建cachekey
|
|
||||||
public String getCacheKey(){
|
|
||||||
return "sms:blacklist:global";
|
|
||||||
}
|
|
||||||
|
|
||||||
//获取黑名单,没有就新建
|
|
||||||
public ArrayList<String> getBlackList(String cacheKey) {
|
|
||||||
ArrayList<String> blackList;
|
|
||||||
Object cache = smsDao.get(cacheKey);
|
|
||||||
if (null != cache) {
|
|
||||||
blackList = (ArrayList<String>) cache;
|
|
||||||
return blackList;
|
|
||||||
}
|
|
||||||
blackList = new ArrayList<>();
|
|
||||||
smsDao.set("sms:blacklist:global", blackList);
|
|
||||||
return blackList;
|
|
||||||
}
|
|
||||||
|
|
||||||
//让黑名单生效
|
|
||||||
public void flushBlackList(String cacheKey ,ArrayList<String> blackList) {
|
|
||||||
smsDao.set(cacheKey, blackList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,85 +0,0 @@
|
|||||||
package org.dromara.sms4j.core.proxy.processor;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.dromara.sms4j.api.proxy.CoreMethodProcessor;
|
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 核心方法参数校验前置拦截执行器
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class CoreMethodParamValidateProcessor implements CoreMethodProcessor {
|
|
||||||
@Override
|
|
||||||
public int getOrder() {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessagePreProcess(String phone, Object message) {
|
|
||||||
validatePhone(phone);
|
|
||||||
validateMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessageByTemplatePreProcess(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
validatePhone(phone);
|
|
||||||
validateMessages(templateId, messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void massTextingPreProcess(List<String> phones, String message) {
|
|
||||||
validateMessage(message);
|
|
||||||
validatePhones(phones);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void massTextingByTemplatePreProcess(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
validatePhones(phones);
|
|
||||||
validateMessages(templateId, messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validateMessage(Object messageObj) {
|
|
||||||
if (messageObj instanceof String){
|
|
||||||
String message = (String) messageObj;
|
|
||||||
if (null == message || "".equals(message)) {
|
|
||||||
throw new SmsBlendException("cant send a null message!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (messageObj instanceof Map){
|
|
||||||
Map message = (Map) messageObj;
|
|
||||||
if (message.size()<1) {
|
|
||||||
throw new SmsBlendException("cant send a null message!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validatePhone(String phone) {
|
|
||||||
if (null == phone || "".equals(phone)) {
|
|
||||||
throw new SmsBlendException("cant send message to null!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validatePhones(List<String> phones) {
|
|
||||||
if (null == phones) {
|
|
||||||
throw new SmsBlendException("cant send message to null!");
|
|
||||||
}
|
|
||||||
for (String phone : phones) {
|
|
||||||
if (null != phone && !"".equals(phone)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new SmsBlendException("cant send message to null!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void validateMessages(String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
if (null != templateId && !"".equals(templateId) && (messages == null || messages.size() < 1)) {
|
|
||||||
throw new SmsBlendException("cant use template without template param");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,96 +0,0 @@
|
|||||||
package org.dromara.sms4j.core.proxy.processor;
|
|
||||||
|
|
||||||
import lombok.Setter;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.dromara.sms4j.api.dao.SmsDao;
|
|
||||||
import org.dromara.sms4j.api.proxy.CoreMethodProcessor;
|
|
||||||
import org.dromara.sms4j.api.proxy.aware.SmsDaoAware;
|
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
|
||||||
import org.dromara.sms4j.provider.config.SmsConfig;
|
|
||||||
import org.dromara.sms4j.provider.factory.BeanFactory;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 短信发送账号级上限前置拦截执行器
|
|
||||||
*
|
|
||||||
* @author sh1yu
|
|
||||||
* @since 2023/10/27 13:03
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class RestrictedProcessor implements CoreMethodProcessor, SmsDaoAware {
|
|
||||||
static Long minTimer = 60 * 1000L;
|
|
||||||
static Long accTimer = 24 * 60 * 60 * 1000L;
|
|
||||||
private static final String REDIS_KEY = "sms:restricted:";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存实例
|
|
||||||
*/
|
|
||||||
@Setter
|
|
||||||
private SmsDao smsDao;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getOrder() {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessagePreProcess(String phone, Object message) {
|
|
||||||
doRestricted(Collections.singletonList(phone));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void sendMessageByTemplatePreProcess(String phone, String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
doRestricted(Collections.singletonList(phone));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void massTextingPreProcess(List<String> phones, String message) {
|
|
||||||
doRestricted(phones);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void massTextingByTemplatePreProcess(List<String> phones, String templateId, LinkedHashMap<String, String> messages) {
|
|
||||||
doRestricted(phones);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doRestricted(List<String> phones) {
|
|
||||||
if (Objects.isNull(smsDao)) {
|
|
||||||
throw new SmsBlendException("The dao tool could not be found");
|
|
||||||
}
|
|
||||||
SmsConfig config = BeanFactory.getSmsConfig();
|
|
||||||
Integer accountMax = config.getAccountMax(); // 每日最大发送量
|
|
||||||
Integer minuteMax = config.getMinuteMax(); // 每分钟最大发送量
|
|
||||||
for (String phone : phones) {
|
|
||||||
if (SmsUtils.isNotEmpty(accountMax)) { // 是否配置了每日限制
|
|
||||||
Integer i = (Integer) smsDao.get(REDIS_KEY + phone + "max");
|
|
||||||
if (SmsUtils.isEmpty(i)) {
|
|
||||||
smsDao.set(REDIS_KEY + phone + "max", 1, accTimer / 1000);
|
|
||||||
} else if (i >= accountMax) {
|
|
||||||
log.info("The phone:" + phone + ",number of short messages reached the maximum today");
|
|
||||||
throw new SmsBlendException("The phone:" + phone + ",number of short messages reached the maximum today");
|
|
||||||
} else {
|
|
||||||
smsDao.set(REDIS_KEY + phone + "max", i + 1, accTimer / 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (SmsUtils.isNotEmpty(minuteMax)) { // 是否配置了每分钟最大限制
|
|
||||||
Integer o = (Integer) smsDao.get(REDIS_KEY + phone);
|
|
||||||
if (SmsUtils.isNotEmpty(o)) {
|
|
||||||
if (o < minuteMax) {
|
|
||||||
smsDao.set(REDIS_KEY + phone, o + 1, minTimer / 1000);
|
|
||||||
} else {
|
|
||||||
log.info("The phone:" + phone + ",number of short messages reached the maximum today");
|
|
||||||
throw new SmsBlendException("The phone:", phone + " Text messages are sent too often!");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
smsDao.set(REDIS_KEY + phone, 1, minTimer / 1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -19,9 +19,9 @@ import org.dromara.sms4j.cloopen.config.CloopenFactory;
|
|||||||
import org.dromara.sms4j.comm.constant.Constant;
|
import org.dromara.sms4j.comm.constant.Constant;
|
||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||||
import org.dromara.sms4j.core.proxy.EnvirmentHolder;
|
import org.dromara.sms4j.core.proxy.EnvironmentHolder;
|
||||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||||
import org.dromara.sms4j.core.proxy.processor.*;
|
import org.dromara.sms4j.core.proxy.interceptor.*;
|
||||||
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
import org.dromara.sms4j.ctyun.config.CtyunFactory;
|
import org.dromara.sms4j.ctyun.config.CtyunFactory;
|
||||||
import org.dromara.sms4j.emay.config.EmayFactory;
|
import org.dromara.sms4j.emay.config.EmayFactory;
|
||||||
@ -154,14 +154,14 @@ public class SEInitializer {
|
|||||||
Map<String, Map<String, Object>> blends = smsConfig.getBlends();
|
Map<String, Map<String, Object>> blends = smsConfig.getBlends();
|
||||||
|
|
||||||
//持有初始化配置信息
|
//持有初始化配置信息
|
||||||
EnvirmentHolder.frozenEnvirmet(smsConfig, blends);
|
EnvironmentHolder.frozen(smsConfig, blends);
|
||||||
|
|
||||||
//注册执行器实现
|
//注册执行器实现
|
||||||
SmsProxyFactory.addProcessor(new RestrictedProcessor());
|
SmsProxyFactory.addProcessor(new RestrictedMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new BlackListProcessor());
|
SmsProxyFactory.addProcessor(new BlackListMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new BlackListRecordingProcessor());
|
SmsProxyFactory.addProcessor(new BlackListRecordingMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new SingleBlendRestrictedProcessor());
|
SmsProxyFactory.addProcessor(new SingleBlendRestrictedMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor());
|
SmsProxyFactory.addProcessor(new SyncMethodParamValidateMethodInterceptor());
|
||||||
blends.forEach((configId, configMap) -> {
|
blends.forEach((configId, configMap) -> {
|
||||||
Object supplierObj = configMap.get(Constant.SUPPLIER_KEY);
|
Object supplierObj = configMap.get(Constant.SUPPLIER_KEY);
|
||||||
String supplier = supplierObj == null ? "" : String.valueOf(supplierObj);
|
String supplier = supplierObj == null ? "" : String.valueOf(supplierObj);
|
||||||
|
|||||||
@ -10,9 +10,9 @@ import org.dromara.sms4j.api.universal.SupplierConfig;
|
|||||||
import org.dromara.sms4j.cloopen.config.CloopenFactory;
|
import org.dromara.sms4j.cloopen.config.CloopenFactory;
|
||||||
import org.dromara.sms4j.comm.constant.Constant;
|
import org.dromara.sms4j.comm.constant.Constant;
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||||
import org.dromara.sms4j.core.proxy.EnvirmentHolder;
|
import org.dromara.sms4j.core.proxy.EnvironmentHolder;
|
||||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||||
import org.dromara.sms4j.core.proxy.processor.*;
|
import org.dromara.sms4j.core.proxy.interceptor.*;
|
||||||
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
import org.dromara.sms4j.ctyun.config.CtyunFactory;
|
import org.dromara.sms4j.ctyun.config.CtyunFactory;
|
||||||
import org.dromara.sms4j.emay.config.EmayFactory;
|
import org.dromara.sms4j.emay.config.EmayFactory;
|
||||||
@ -60,15 +60,15 @@ public class SmsBlendsInitializer {
|
|||||||
// 注册短信对象工厂
|
// 注册短信对象工厂
|
||||||
ProviderFactoryHolder.registerFactory(factoryList);
|
ProviderFactoryHolder.registerFactory(factoryList);
|
||||||
//持有初始化配置信息
|
//持有初始化配置信息
|
||||||
EnvirmentHolder.frozenEnvirmet(smsConfig, blends);
|
EnvironmentHolder.frozen(smsConfig, blends);
|
||||||
//框架依赖持有缓存扩展
|
//框架依赖持有缓存扩展
|
||||||
new SolonSmsDaoHolder(context);
|
new SolonSmsDaoHolder(context);
|
||||||
//注册执行器实现
|
//注册执行器实现
|
||||||
SmsProxyFactory.addProcessor(new RestrictedProcessor());
|
SmsProxyFactory.addProcessor(new RestrictedMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new BlackListProcessor());
|
SmsProxyFactory.addProcessor(new BlackListMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new BlackListRecordingProcessor());
|
SmsProxyFactory.addProcessor(new BlackListRecordingMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new SingleBlendRestrictedProcessor());
|
SmsProxyFactory.addProcessor(new SingleBlendRestrictedMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor());
|
SmsProxyFactory.addProcessor(new SyncMethodParamValidateMethodInterceptor());
|
||||||
// 解析供应商配置
|
// 解析供应商配置
|
||||||
for(String configId : blends.keySet()) {
|
for(String configId : blends.keySet()) {
|
||||||
Map<String, Object> configMap = blends.get(configId);
|
Map<String, Object> configMap = blends.get(configId);
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import org.dromara.sms4j.comm.constant.SupplierConstant;
|
|||||||
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
import org.dromara.sms4j.comm.exception.SmsBlendException;
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ import java.util.LinkedHashMap;
|
|||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@SpringBootTest
|
@SpringBootTest
|
||||||
public class SmsProcessorTest {
|
public class SmsMethodInterceptorTest {
|
||||||
/**
|
/**
|
||||||
* 填测试手机号
|
* 填测试手机号
|
||||||
*/
|
*/
|
||||||
@ -31,7 +32,7 @@ public class SmsProcessorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void test1() {
|
public void test1() {
|
||||||
System.out.println("------------");
|
System.out.println("------------");
|
||||||
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.UNISMS);
|
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.LOCAL);
|
||||||
SmsResponse smsResponse = smsBlend.sendMessage(PHONE, SmsUtils.getRandomInt(6));
|
SmsResponse smsResponse = smsBlend.sendMessage(PHONE, SmsUtils.getRandomInt(6));
|
||||||
Assert.isTrue(smsResponse.isSuccess());
|
Assert.isTrue(smsResponse.isSuccess());
|
||||||
System.out.println(smsResponse.getData());
|
System.out.println(smsResponse.getData());
|
||||||
@ -44,7 +45,7 @@ public class SmsProcessorTest {
|
|||||||
public void test2() {
|
public void test2() {
|
||||||
System.out.println("------------");
|
System.out.println("------------");
|
||||||
|
|
||||||
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.HUAWEI);
|
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.LOCAL);
|
||||||
SmsResponse smsResponse = smsBlend.sendMessage(PHONE1, SmsUtils.getRandomInt(6));
|
SmsResponse smsResponse = smsBlend.sendMessage(PHONE1, SmsUtils.getRandomInt(6));
|
||||||
Assert.isTrue(smsResponse.isSuccess());
|
Assert.isTrue(smsResponse.isSuccess());
|
||||||
System.out.println(smsResponse.getData());
|
System.out.println(smsResponse.getData());
|
||||||
@ -56,62 +57,28 @@ public class SmsProcessorTest {
|
|||||||
public void test3() {
|
public void test3() {
|
||||||
System.out.println("------------");
|
System.out.println("------------");
|
||||||
|
|
||||||
SmsBlendException knowEx = null;
|
SmsBlend sb = SmsFactory.getBySupplier(SupplierConstant.LOCAL);
|
||||||
try {
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE, new LinkedHashMap<>());
|
() -> sb.sendMessage(PHONE, new LinkedHashMap<>())
|
||||||
} catch (SmsBlendException e) {
|
);
|
||||||
knowEx = e;
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
System.out.println(knowEx.getMessage());
|
() -> sb.sendMessage("", SmsUtils.getRandomInt(6))
|
||||||
}
|
);
|
||||||
Assert.notNull(knowEx);
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
knowEx = null;
|
() -> sb.sendMessage(PHONE, "")
|
||||||
try {
|
);
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage("", SmsUtils.getRandomInt(6));
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
} catch (SmsBlendException e) {
|
() -> sb.sendMessage(PHONE, "111", new LinkedHashMap<>())
|
||||||
knowEx = e;
|
);
|
||||||
System.out.println(knowEx.getMessage());
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
}
|
() -> sb.massTexting(Collections.singletonList(PHONE), "")
|
||||||
Assert.notNull(knowEx);
|
);
|
||||||
knowEx = null;
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
try {
|
() -> sb.massTexting(Collections.singletonList(PHONE), "2222", new LinkedHashMap<>())
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE, "");
|
);
|
||||||
} catch (SmsBlendException e) {
|
Assertions.assertThrows(SmsBlendException.class,
|
||||||
knowEx = e;
|
() -> sb.massTexting(new ArrayList<>(), "321321")
|
||||||
System.out.println(knowEx.getMessage());
|
);
|
||||||
}
|
|
||||||
Assert.notNull(knowEx);
|
|
||||||
knowEx = null;
|
|
||||||
try {
|
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE, "111", new LinkedHashMap<>());
|
|
||||||
} catch (SmsBlendException e) {
|
|
||||||
knowEx = e;
|
|
||||||
System.out.println(knowEx.getMessage());
|
|
||||||
}
|
|
||||||
Assert.notNull(knowEx);
|
|
||||||
knowEx = null;
|
|
||||||
try {
|
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).massTexting(Collections.singletonList(PHONE), "");
|
|
||||||
} catch (SmsBlendException e) {
|
|
||||||
knowEx = e;
|
|
||||||
System.out.println(knowEx.getMessage());
|
|
||||||
}
|
|
||||||
Assert.notNull(knowEx);
|
|
||||||
knowEx = null;
|
|
||||||
try {
|
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).massTexting(Collections.singletonList(PHONE), "2222", new LinkedHashMap<>());
|
|
||||||
} catch (SmsBlendException e) {
|
|
||||||
knowEx = e;
|
|
||||||
System.out.println(knowEx.getMessage());
|
|
||||||
}
|
|
||||||
Assert.notNull(knowEx);
|
|
||||||
knowEx = null;
|
|
||||||
try {
|
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).massTexting(new ArrayList<String>(), "321321");
|
|
||||||
} catch (SmsBlendException e) {
|
|
||||||
knowEx = e;
|
|
||||||
System.out.println(knowEx.getMessage());
|
|
||||||
}
|
|
||||||
Assert.notNull(knowEx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//黑名单测试
|
//黑名单测试
|
||||||
@ -119,7 +86,7 @@ public class SmsProcessorTest {
|
|||||||
public void test4() {
|
public void test4() {
|
||||||
System.out.println("------------");
|
System.out.println("------------");
|
||||||
|
|
||||||
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.UNISMS);
|
SmsBlend smsBlend = SmsFactory.getBySupplier(SupplierConstant.LOCAL);
|
||||||
//单黑名单添加
|
//单黑名单添加
|
||||||
smsBlend.joinInBlacklist(PHONE);
|
smsBlend.joinInBlacklist(PHONE);
|
||||||
SmsBlendException knowEx = null;
|
SmsBlendException knowEx = null;
|
||||||
@ -155,17 +122,10 @@ public class SmsProcessorTest {
|
|||||||
@Test
|
@Test
|
||||||
public void test5() {
|
public void test5() {
|
||||||
System.out.println("------------");
|
System.out.println("------------");
|
||||||
|
SmsBlend sb = SmsFactory.getBySupplier(SupplierConstant.LOCAL);
|
||||||
SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE, SmsUtils.getRandomInt(6));
|
SmsResponse smsResponse = sb.sendMessage(PHONE, SmsUtils.getRandomInt(6));
|
||||||
Assert.isTrue(smsResponse.isSuccess());
|
Assert.isTrue(smsResponse.isSuccess());
|
||||||
SmsBlendException knowEx = null;
|
Assertions.assertThrows(SmsBlendException.class, () -> sb.sendMessage(PHONE, SmsUtils.getRandomInt(6)));
|
||||||
try {
|
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE, SmsUtils.getRandomInt(6));
|
|
||||||
} catch (SmsBlendException e) {
|
|
||||||
knowEx = e;
|
|
||||||
System.out.println(knowEx.getMessage());
|
|
||||||
}
|
|
||||||
Assert.notNull(knowEx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//渠道级上限测试、需成功发送6笔,再发就会报错 参数配置 6
|
//渠道级上限测试、需成功发送6笔,再发就会报错 参数配置 6
|
||||||
@ -173,12 +133,13 @@ public class SmsProcessorTest {
|
|||||||
public void test6() {
|
public void test6() {
|
||||||
System.out.println("------------");
|
System.out.println("------------");
|
||||||
|
|
||||||
SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE1, SmsUtils.getRandomInt(6));
|
SmsResponse smsResponse = SmsFactory.getBySupplier(SupplierConstant.LOCAL)
|
||||||
|
.sendMessage(PHONE1, SmsUtils.getRandomInt(6));
|
||||||
Assert.isTrue(smsResponse.isSuccess());
|
Assert.isTrue(smsResponse.isSuccess());
|
||||||
|
|
||||||
SmsBlendException knowEx = null;
|
SmsBlendException knowEx = null;
|
||||||
try {
|
try {
|
||||||
SmsFactory.getBySupplier(SupplierConstant.UNISMS).sendMessage(PHONE1, SmsUtils.getRandomInt(6));
|
SmsFactory.getBySupplier(SupplierConstant.LOCAL).sendMessage(PHONE1, SmsUtils.getRandomInt(6));
|
||||||
} catch (SmsBlendException e) {
|
} catch (SmsBlendException e) {
|
||||||
knowEx = e;
|
knowEx = e;
|
||||||
System.out.println(knowEx.getMessage());
|
System.out.println(knowEx.getMessage());
|
||||||
@ -11,9 +11,9 @@ import org.dromara.sms4j.cloopen.config.CloopenFactory;
|
|||||||
import org.dromara.sms4j.comm.constant.Constant;
|
import org.dromara.sms4j.comm.constant.Constant;
|
||||||
import org.dromara.sms4j.comm.enumerate.ConfigType;
|
import org.dromara.sms4j.comm.enumerate.ConfigType;
|
||||||
import org.dromara.sms4j.comm.utils.SmsUtils;
|
import org.dromara.sms4j.comm.utils.SmsUtils;
|
||||||
import org.dromara.sms4j.core.proxy.EnvirmentHolder;
|
import org.dromara.sms4j.core.proxy.EnvironmentHolder;
|
||||||
import org.dromara.sms4j.core.factory.SmsFactory;
|
import org.dromara.sms4j.core.factory.SmsFactory;
|
||||||
import org.dromara.sms4j.core.proxy.processor.*;
|
import org.dromara.sms4j.core.proxy.interceptor.*;
|
||||||
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
import org.dromara.sms4j.core.proxy.SmsProxyFactory;
|
||||||
import org.dromara.sms4j.ctyun.config.CtyunFactory;
|
import org.dromara.sms4j.ctyun.config.CtyunFactory;
|
||||||
import org.dromara.sms4j.emay.config.EmayFactory;
|
import org.dromara.sms4j.emay.config.EmayFactory;
|
||||||
@ -58,13 +58,13 @@ public class SmsBlendsInitializer {
|
|||||||
|
|
||||||
if(ConfigType.YAML.equals(this.smsConfig.getConfigType())) {
|
if(ConfigType.YAML.equals(this.smsConfig.getConfigType())) {
|
||||||
//持有初始化配置信息
|
//持有初始化配置信息
|
||||||
EnvirmentHolder.frozenEnvirmet(smsConfig, blends);
|
EnvironmentHolder.frozen(smsConfig, blends);
|
||||||
//注册执行器实现
|
//注册执行器实现
|
||||||
SmsProxyFactory.addProcessor(new RestrictedProcessor());
|
SmsProxyFactory.addProcessor(new RestrictedMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new BlackListProcessor());
|
SmsProxyFactory.addProcessor(new BlackListMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new BlackListRecordingProcessor());
|
SmsProxyFactory.addProcessor(new BlackListRecordingMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new SingleBlendRestrictedProcessor());
|
SmsProxyFactory.addProcessor(new SingleBlendRestrictedMethodInterceptor());
|
||||||
SmsProxyFactory.addProcessor(new CoreMethodParamValidateProcessor());
|
SmsProxyFactory.addProcessor(new SyncMethodParamValidateMethodInterceptor());
|
||||||
// 解析供应商配置
|
// 解析供应商配置
|
||||||
blends.forEach((configId, configMap) -> {
|
blends.forEach((configId, configMap) -> {
|
||||||
Object supplierObj = configMap.get(Constant.SUPPLIER_KEY);
|
Object supplierObj = configMap.get(Constant.SUPPLIER_KEY);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user