diff --git a/README.md b/README.md index 749c938..44fa1f4 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ austin项目**核心流程**:`austin-api`接收到发送消息请求,直接 - 接入腾讯云渠道发送一条短信 - 使用SpringData JPA将短信发送记录存储至MySQL - 完成对Kafka接入 +- 接入层(api)代码架构实现(责任链模式) diff --git a/austin-common/src/main/java/com/java3y/austin/constant/AustinConstant.java b/austin-common/src/main/java/com/java3y/austin/constant/AustinConstant.java new file mode 100644 index 0000000..b39832e --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/constant/AustinConstant.java @@ -0,0 +1,15 @@ +package com.java3y.austin.constant; + + +/** + * 基础的常量信息 + */ +public class AustinConstant { + + /** + * boolean转换 + */ + public final static Integer TRUE = 1; + public final static Integer FALSE = 0; + +} diff --git a/austin-common/src/main/java/com/java3y/austin/pojo/TaskInfo.java b/austin-common/src/main/java/com/java3y/austin/domain/TaskInfo.java similarity index 75% rename from austin-common/src/main/java/com/java3y/austin/pojo/TaskInfo.java rename to austin-common/src/main/java/com/java3y/austin/domain/TaskInfo.java index 2ad9c40..0221fb2 100644 --- a/austin-common/src/main/java/com/java3y/austin/pojo/TaskInfo.java +++ b/austin-common/src/main/java/com/java3y/austin/domain/TaskInfo.java @@ -1,5 +1,6 @@ -package com.java3y.austin.pojo; +package com.java3y.austin.domain; +import com.java3y.austin.dto.ContentModel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -9,6 +10,7 @@ import java.util.Set; /** * 发送任务信息 + * * @author 3y */ @Data @@ -24,6 +26,7 @@ public class TaskInfo { /** * 业务Id(数据追踪使用) + * 生成逻辑参考 */ private Long businessId; @@ -53,9 +56,12 @@ public class TaskInfo { private Integer msgType; /** - * 发送文案内容 + * 发送文案模型 + * message_template表存储的content是JSON(所有内容都会塞进去) + * 不同的渠道要发送的内容不一样(比如发push会有img,而短信没有) + * 所以会有ContentModel */ - private String content; + private ContentModel contentModel; /** * 发送账号(邮件下可有多个发送账号、短信可有多个发送账号..) diff --git a/austin-common/src/main/java/com/java3y/austin/dto/ContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/ContentModel.java new file mode 100644 index 0000000..47f27a4 --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/ContentModel.java @@ -0,0 +1,8 @@ +package com.java3y.austin.dto; + +/** + * 发送内容的模型 + * (不同的渠道会有不同的消息体) + */ +public class ContentModel { +} diff --git a/austin-common/src/main/java/com/java3y/austin/dto/EmailContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/EmailContentModel.java new file mode 100644 index 0000000..5aa5082 --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/EmailContentModel.java @@ -0,0 +1,6 @@ +package com.java3y.austin.dto; + +public class EmailContentModel extends ContentModel { + + +} diff --git a/austin-common/src/main/java/com/java3y/austin/dto/ImContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/ImContentModel.java new file mode 100644 index 0000000..6b44a2f --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/ImContentModel.java @@ -0,0 +1,6 @@ +package com.java3y.austin.dto; + +public class ImContentModel extends ContentModel { + + +} diff --git a/austin-common/src/main/java/com/java3y/austin/dto/MiniProgramContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/MiniProgramContentModel.java new file mode 100644 index 0000000..6986d14 --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/MiniProgramContentModel.java @@ -0,0 +1,5 @@ +package com.java3y.austin.dto; + +public class MiniProgramContentModel extends ContentModel { + +} diff --git a/austin-common/src/main/java/com/java3y/austin/dto/OfficialAccountsContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/OfficialAccountsContentModel.java new file mode 100644 index 0000000..0e5bb5c --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/OfficialAccountsContentModel.java @@ -0,0 +1,5 @@ +package com.java3y.austin.dto; + +public class OfficialAccountsContentModel extends ContentModel { + +} diff --git a/austin-common/src/main/java/com/java3y/austin/dto/PushContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/PushContentModel.java new file mode 100644 index 0000000..5104c5a --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/PushContentModel.java @@ -0,0 +1,5 @@ +package com.java3y.austin.dto; + +public class PushContentModel extends ContentModel { + +} diff --git a/austin-common/src/main/java/com/java3y/austin/dto/SmsContentModel.java b/austin-common/src/main/java/com/java3y/austin/dto/SmsContentModel.java new file mode 100644 index 0000000..59ba0f9 --- /dev/null +++ b/austin-common/src/main/java/com/java3y/austin/dto/SmsContentModel.java @@ -0,0 +1,31 @@ +package com.java3y.austin.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author 3y + *

+ * 短信内容模型 + * + * 在前端填写的时候分开,但最后处理的时候会将url拼接在content上 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SmsContentModel extends ContentModel { + + /** + * 短信发送内容 + */ + private String content; + + /** + * 短信发送链接 + */ + private String url; + +} diff --git a/austin-common/src/main/java/com/java3y/austin/enums/ChannelType.java b/austin-common/src/main/java/com/java3y/austin/enums/ChannelType.java index 71d9296..e623a04 100644 --- a/austin-common/src/main/java/com/java3y/austin/enums/ChannelType.java +++ b/austin-common/src/main/java/com/java3y/austin/enums/ChannelType.java @@ -1,6 +1,7 @@ package com.java3y.austin.enums; +import com.java3y.austin.dto.*; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.ToString; @@ -12,16 +13,26 @@ import lombok.ToString; @ToString @AllArgsConstructor public enum ChannelType { - IM(10, "IM(站内信)"), - PUSH(20, "push(通知栏)"), - SMS(30, "sms(短信)"), - EMAIL(40, "email(邮件)"), - OFFICIAL_ACCOUNT(50, "OfficialAccounts(服务号)"), - MINI_PROGRAM(60, "miniProgram(小程序)") + IM(10, "IM(站内信)", ImContentModel.class), + PUSH(20, "push(通知栏)", PushContentModel.class), + SMS(30, "sms(短信)", SmsContentModel.class), + EMAIL(40, "email(邮件)", EmailContentModel.class), + OFFICIAL_ACCOUNT(50, "OfficialAccounts(服务号)", OfficialAccountsContentModel.class), + MINI_PROGRAM(60, "miniProgram(小程序)", MiniProgramContentModel.class), ; private Integer code; private String description; + private Class contentModelClass; + public static Class getChanelModelClassByCode(Integer code) { + ChannelType[] values = values(); + for (ChannelType value : values) { + if (value.getCode().equals(code)) { + return value.getContentModelClass(); + } + } + return null; + } } diff --git a/austin-common/src/main/java/com/java3y/austin/enums/IdType.java b/austin-common/src/main/java/com/java3y/austin/enums/IdType.java index 7805366..53d277d 100644 --- a/austin-common/src/main/java/com/java3y/austin/enums/IdType.java +++ b/austin-common/src/main/java/com/java3y/austin/enums/IdType.java @@ -12,7 +12,7 @@ import lombok.ToString; @ToString @AllArgsConstructor public enum IdType { - USER_ID(10, "userid"), + USER_ID(10, "userId"), DID(20, "did"), PHONE(30, "phone"), OPEN_ID(40, "openId"), diff --git a/austin-common/src/main/java/com/java3y/austin/constant/RespStatusEnum.java b/austin-common/src/main/java/com/java3y/austin/enums/RespStatusEnum.java similarity index 84% rename from austin-common/src/main/java/com/java3y/austin/constant/RespStatusEnum.java rename to austin-common/src/main/java/com/java3y/austin/enums/RespStatusEnum.java index d0057a0..022821d 100644 --- a/austin-common/src/main/java/com/java3y/austin/constant/RespStatusEnum.java +++ b/austin-common/src/main/java/com/java3y/austin/enums/RespStatusEnum.java @@ -1,4 +1,4 @@ -package com.java3y.austin.constant; +package com.java3y.austin.enums; import lombok.AllArgsConstructor; import lombok.Getter; @@ -24,7 +24,8 @@ public enum RespStatusEnum { /** * 客户端 */ - CLIENT_BAD_PARAMETERS("A0100", "客户端参数错误"), + CLIENT_BAD_PARAMETERS("A0001", "客户端参数错误"), + TEMPLATE_NOT_FOUND("A0002", "找不到模板或模板已被删除"), /** * 系统 @@ -41,6 +42,8 @@ public enum RespStatusEnum { PROCESS_TEMPLATE_IS_NULL("P0003","流程模板配置为空"), PROCESS_LIST_IS_NULL("P0004","业务处理器配置为空" ), + + ; /** diff --git a/austin-common/src/main/java/com/java3y/austin/vo/BasicResultVO.java b/austin-common/src/main/java/com/java3y/austin/vo/BasicResultVO.java index e803ffc..8b3429d 100644 --- a/austin-common/src/main/java/com/java3y/austin/vo/BasicResultVO.java +++ b/austin-common/src/main/java/com/java3y/austin/vo/BasicResultVO.java @@ -1,6 +1,6 @@ package com.java3y.austin.vo; -import com.java3y.austin.constant.RespStatusEnum; +import com.java3y.austin.enums.RespStatusEnum; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; diff --git a/austin-handler/src/main/java/com/java3y/austin/Receiver.java b/austin-handler/src/main/java/com/java3y/austin/Receiver.java new file mode 100644 index 0000000..a2db5ee --- /dev/null +++ b/austin-handler/src/main/java/com/java3y/austin/Receiver.java @@ -0,0 +1,40 @@ +package com.java3y.austin; + +import com.alibaba.fastjson.JSON; +import com.java3y.austin.config.TaskInfoParseConfig; +import com.java3y.austin.domain.TaskInfo; +import com.java3y.austin.handler.SmsHandler; +import lombok.extern.slf4j.Slf4j; +import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.kafka.annotation.KafkaListener; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Optional; + +/** + * @author 3y + * 消费MQ的消息 + */ +@Component +@Slf4j +public class Receiver { + + @Autowired + private SmsHandler smsHandler; + + @KafkaListener(topics = {"austin"}, groupId = "sms") + public void consumer(ConsumerRecord consumerRecord) { + Optional kafkaMessage = Optional.ofNullable(consumerRecord.value()); + if (kafkaMessage.isPresent()) { + List lists = JSON.parseArray(kafkaMessage.get(), TaskInfo.class); + for (TaskInfo taskInfo : lists) { + smsHandler.doHandler(taskInfo); + } + log.info("receiver message:{}", JSON.toJSONString(lists)); + } + + } + +} diff --git a/austin-common/src/main/java/com/java3y/austin/pojo/SmsParam.java b/austin-handler/src/main/java/com/java3y/austin/domain/SmsParam.java similarity index 93% rename from austin-common/src/main/java/com/java3y/austin/pojo/SmsParam.java rename to austin-handler/src/main/java/com/java3y/austin/domain/SmsParam.java index 521966a..bc5a10a 100644 --- a/austin-common/src/main/java/com/java3y/austin/pojo/SmsParam.java +++ b/austin-handler/src/main/java/com/java3y/austin/domain/SmsParam.java @@ -1,4 +1,4 @@ -package com.java3y.austin.pojo; +package com.java3y.austin.domain; import lombok.Builder; import lombok.Data; diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/Handler.java b/austin-handler/src/main/java/com/java3y/austin/handler/Handler.java index 8fbcc47..0ba51c9 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/Handler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/Handler.java @@ -1,7 +1,6 @@ package com.java3y.austin.handler; -import com.java3y.austin.domain.MessageTemplate; -import com.java3y.austin.pojo.TaskInfo; +import com.java3y.austin.domain.TaskInfo; public interface Handler { diff --git a/austin-handler/src/main/java/com/java3y/austin/handler/SmsHandler.java b/austin-handler/src/main/java/com/java3y/austin/handler/SmsHandler.java index 5784c03..6ba2392 100644 --- a/austin-handler/src/main/java/com/java3y/austin/handler/SmsHandler.java +++ b/austin-handler/src/main/java/com/java3y/austin/handler/SmsHandler.java @@ -1,11 +1,13 @@ package com.java3y.austin.handler; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; import com.java3y.austin.dao.SmsRecordDao; -import com.java3y.austin.domain.MessageTemplate; import com.java3y.austin.domain.SmsRecord; -import com.java3y.austin.pojo.SmsParam; -import com.java3y.austin.pojo.TaskInfo; +import com.java3y.austin.domain.SmsParam; +import com.java3y.austin.domain.TaskInfo; +import com.java3y.austin.dto.ContentModel; +import com.java3y.austin.dto.SmsContentModel; import com.java3y.austin.script.SmsScript; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -28,12 +30,21 @@ public class SmsHandler implements Handler { @Override public boolean doHandler(TaskInfo taskInfo) { + SmsContentModel smsContentModel = (SmsContentModel) taskInfo.getContentModel(); + + String resultContent; + if (StrUtil.isNotBlank(smsContentModel.getUrl())) { + resultContent = smsContentModel.getContent() + " " + smsContentModel.getUrl(); + } else { + resultContent = smsContentModel.getContent(); + } + SmsParam smsParam = SmsParam.builder() - .phones(taskInfo.getReceiver()) - .content(taskInfo.getContent()) - .messageTemplateId(taskInfo.getMessageTemplateId()) - .supplierId(10) - .supplierName("腾讯云通知类消息渠道").build(); + .phones(taskInfo.getReceiver()) + .content(resultContent) + .messageTemplateId(taskInfo.getMessageTemplateId()) + .supplierId(10) + .supplierName("腾讯云通知类消息渠道").build(); List recordList = smsScript.send(smsParam); if (CollUtil.isEmpty(recordList)) { diff --git a/austin-handler/src/main/java/com/java3y/austin/script/SmsScript.java b/austin-handler/src/main/java/com/java3y/austin/script/SmsScript.java index fe34b7c..0ddd8a1 100644 --- a/austin-handler/src/main/java/com/java3y/austin/script/SmsScript.java +++ b/austin-handler/src/main/java/com/java3y/austin/script/SmsScript.java @@ -1,7 +1,7 @@ package com.java3y.austin.script; import com.java3y.austin.domain.SmsRecord; -import com.java3y.austin.pojo.SmsParam; +import com.java3y.austin.domain.SmsParam; import java.util.List; diff --git a/austin-handler/src/main/java/com/java3y/austin/script/TencentSmsScript.java b/austin-handler/src/main/java/com/java3y/austin/script/TencentSmsScript.java index eddc237..4ff20c4 100644 --- a/austin-handler/src/main/java/com/java3y/austin/script/TencentSmsScript.java +++ b/austin-handler/src/main/java/com/java3y/austin/script/TencentSmsScript.java @@ -3,12 +3,11 @@ package com.java3y.austin.script; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.IdUtil; -import cn.hutool.core.util.StrUtil; import com.alibaba.fastjson.JSON; import com.google.common.base.Throwables; import com.java3y.austin.domain.SmsRecord; import com.java3y.austin.enums.SmsStatus; -import com.java3y.austin.pojo.SmsParam; +import com.java3y.austin.domain.SmsParam; import com.tencentcloudapi.common.Credential; import com.tencentcloudapi.common.exception.TencentCloudSDKException; import com.tencentcloudapi.common.profile.ClientProfile; @@ -73,7 +72,7 @@ public class TencentSmsScript implements SmsScript { return assembleSmsRecord(smsParam,response); - } catch (TencentCloudSDKException e) { + } catch (Exception e) { log.error("send tencent sms fail!{},params:{}", Throwables.getStackTraceAsString(e), JSON.toJSONString(smsParam)); return null; diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/action/AssembleAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/action/AssembleAction.java index e3705e7..a8619f4 100644 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/action/AssembleAction.java +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/action/AssembleAction.java @@ -1,17 +1,131 @@ package com.java3y.austin.action; +import cn.hutool.core.util.ReflectUtil; +import cn.hutool.core.util.StrUtil; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.base.Throwables; +import com.java3y.austin.constant.AustinConstant; +import com.java3y.austin.dto.ContentModel; +import com.java3y.austin.dto.SmsContentModel; +import com.java3y.austin.enums.ChannelType; +import com.java3y.austin.enums.RespStatusEnum; +import com.java3y.austin.dao.MessageTemplateDao; +import com.java3y.austin.domain.MessageParam; +import com.java3y.austin.domain.MessageTemplate; +import com.java3y.austin.domain.SendTaskModel; import com.java3y.austin.pipeline.BusinessProcess; import com.java3y.austin.pipeline.ProcessContext; +import com.java3y.austin.domain.TaskInfo; +import com.java3y.austin.utils.ContentHolderUtil; +import com.java3y.austin.utils.TaskInfoUtils; +import com.java3y.austin.vo.BasicResultVO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; + +import java.lang.reflect.Field; +import java.util.*; /** * @author 3y * @date 2021/11/22 * @description 拼装参数 */ +@Slf4j public class AssembleAction implements BusinessProcess { + @Autowired + private MessageTemplateDao messageTemplateDao; + @Override public void process(ProcessContext context) { + SendTaskModel sendTaskModel = (SendTaskModel) context.getProcessModel(); + Long messageTemplateId = sendTaskModel.getMessageTemplateId(); + + try { + Optional messageTemplate = messageTemplateDao.findById(messageTemplateId); + if (!messageTemplate.isPresent() || messageTemplate.get().getIsDeleted().equals(AustinConstant.TRUE)) { + context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.TEMPLATE_NOT_FOUND)); + return; + } + + List taskInfos = assembleTaskInfo(sendTaskModel, messageTemplate.get()); + sendTaskModel.setTaskInfo(taskInfos); + } catch (Exception e) { + context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.SERVICE_ERROR)); + log.error("assemble task fail! templateId:{}, e:{}", messageTemplateId, Throwables.getStackTraceAsString(e)); + } + + } + + /** + * 组装 TaskInfo 任务消息 + * + * @param sendTaskModel + * @param messageTemplate + */ + private List assembleTaskInfo(SendTaskModel sendTaskModel, MessageTemplate messageTemplate) { + List messageParamList = sendTaskModel.getMessageParamList(); + List taskInfoList = new ArrayList<>(); + + for (MessageParam messageParam : messageParamList) { + TaskInfo taskInfo = TaskInfo.builder() + .messageTemplateId(messageTemplate.getId()) + .businessId(TaskInfoUtils.generateBusinessId(messageTemplate.getId(), messageTemplate.getTemplateType())) + .receiver(new HashSet<>(Arrays.asList(messageParam.getReceiver().split(String.valueOf(StrUtil.C_COMMA))))) + .idType(messageTemplate.getIdType()) + .sendChannel(messageTemplate.getSendChannel()) + .templateType(messageTemplate.getTemplateType()) + .msgType(messageTemplate.getMsgType()) + .sendAccount(messageTemplate.getSendAccount()) + .contentModel(getContentModelValue(messageTemplate, messageParam)) + .deduplicationTime(messageTemplate.getDeduplicationTime()) + .isNightShield(messageTemplate.getIsNightShield()).build(); + + taskInfoList.add(taskInfo); + } + + return taskInfoList; + + } + + + /** + * 获取 contentModel,替换占位符信息 + */ + private static ContentModel getContentModelValue(MessageTemplate messageTemplate, MessageParam messageParam) { + Integer sendChannel = messageTemplate.getSendChannel(); + Map variables = messageParam.getVariables(); + JSONObject jsonObject = JSON.parseObject(messageTemplate.getMsgContent()); + Class contentModelClass = ChannelType.getChanelModelClassByCode(sendChannel); + + + /** + * 反射获取得到不同的渠道对应的值 + */ + Field[] fields = ReflectUtil.getFields(contentModelClass); + ContentModel contentModel = (ContentModel) ReflectUtil.newInstance(contentModelClass); + for (Field field : fields) { + String originValue = jsonObject.getString(field.getName()); + + if (StrUtil.isNotBlank(originValue)) { + String resultValue = ContentHolderUtil.replacePlaceHolder(originValue, variables); + ReflectUtil.setFieldValue(contentModel, field, resultValue); + } + } + + return contentModel; + } + + public static void main(String[] args) { + + MessageTemplate messageTemplate = MessageTemplate.builder().sendChannel(ChannelType.SMS.getCode()).msgContent("{\"url\":\"www.baidu.com/{$urlParam}\",\"content\":\"{$contentValue}\"}").build(); + HashMap map = new HashMap<>(); + map.put("urlParam", "2222"); + map.put("contentValue", "3333"); + MessageParam messageParam = new MessageParam().setVariables(map); + ContentModel contentModelValue = getContentModelValue(messageTemplate, messageParam); + System.out.println(JSON.toJSONString(contentModelValue)); } } diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/action/ParamAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/action/ParamAction.java deleted file mode 100644 index 842a553..0000000 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/action/ParamAction.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.java3y.austin.action; - -import com.java3y.austin.domain.SendTaskModel; -import com.java3y.austin.pipeline.BusinessProcess; -import com.java3y.austin.pipeline.ProcessContext; - -/** - * @author 3y - * @date 2021/11/22 - * @description 参数校验 - */ -public class ParamAction implements BusinessProcess { - @Override - public void process(ProcessContext context) { - SendTaskModel sendTaskModel = (SendTaskModel) context.getProcessModel(); - } -} diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/action/PreParamAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/action/PreParamAction.java new file mode 100644 index 0000000..49f7c43 --- /dev/null +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/action/PreParamAction.java @@ -0,0 +1,34 @@ +package com.java3y.austin.action; + +import cn.hutool.core.collection.CollUtil; +import com.java3y.austin.enums.RespStatusEnum; +import com.java3y.austin.domain.MessageParam; +import com.java3y.austin.domain.SendTaskModel; +import com.java3y.austin.pipeline.BusinessProcess; +import com.java3y.austin.pipeline.ProcessContext; +import com.java3y.austin.vo.BasicResultVO; +import lombok.extern.slf4j.Slf4j; + +import java.util.List; + +/** + * @author 3y + * @date 2021/11/22 + * @description 前置参数校验 + */ +@Slf4j +public class PreParamAction implements BusinessProcess { + + @Override + public void process(ProcessContext context) { + SendTaskModel sendTaskModel = (SendTaskModel) context.getProcessModel(); + + Long messageTemplateId = sendTaskModel.getMessageTemplateId(); + List messageParamList = sendTaskModel.getMessageParamList(); + + if (messageTemplateId == null || CollUtil.isEmpty(messageParamList)) { + context.setNeedBreak(true); + context.setResponse(BasicResultVO.fail(RespStatusEnum.CLIENT_BAD_PARAMETERS)); + } + } +} diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/action/SendMqAction.java b/austin-service-api-impl/src/main/java/com/java3y/austin/action/SendMqAction.java new file mode 100644 index 0000000..d2e729b --- /dev/null +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/action/SendMqAction.java @@ -0,0 +1,42 @@ +package com.java3y.austin.action; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.SerializerFeature; +import com.google.common.base.Throwables; +import com.java3y.austin.domain.SendTaskModel; +import com.java3y.austin.domain.TaskInfo; +import com.java3y.austin.enums.RespStatusEnum; +import com.java3y.austin.pipeline.BusinessProcess; +import com.java3y.austin.pipeline.ProcessContext; +import com.java3y.austin.pipeline.ProcessModel; +import com.java3y.austin.vo.BasicResultVO; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.kafka.core.KafkaTemplate; + +/** + * @author 3y + * 将消息发送到MQ + */ +@Slf4j +public class SendMqAction implements BusinessProcess { + + @Autowired + private KafkaTemplate kafkaTemplate; + + @Value("${austin.topic.name}") + private String topicName; + + @Override + public void process(ProcessContext context) { + SendTaskModel sendTaskModel = (SendTaskModel) context.getProcessModel(); + try { + kafkaTemplate.send(topicName, JSON.toJSONString(sendTaskModel.getTaskInfo(), + new SerializerFeature[] {SerializerFeature.WriteClassName})); + } catch (Exception e) { + context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.SERVICE_ERROR)); + log.error("send kafka fail! e:{}", Throwables.getStackTraceAsString(e)); + } + } +} diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/config/PipelineConfig.java b/austin-service-api-impl/src/main/java/com/java3y/austin/config/PipelineConfig.java new file mode 100644 index 0000000..3f96a0f --- /dev/null +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/config/PipelineConfig.java @@ -0,0 +1,84 @@ +package com.java3y.austin.config; + +import com.java3y.austin.action.AssembleAction; +import com.java3y.austin.action.PreParamAction; +import com.java3y.austin.action.SendMqAction; +import com.java3y.austin.enums.BusinessCode; +import com.java3y.austin.pipeline.BusinessProcess; +import com.java3y.austin.pipeline.ProcessController; +import com.java3y.austin.pipeline.ProcessTemplate; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +@Configuration +public class PipelineConfig { + + + /** + * 普通发送执行流程 + * 1. 参数校验 + * 2. 组装参数 + * 3. 发送消息至MQ + * @return + */ + @Bean("commonSendTemplate") + public ProcessTemplate commonSendTemplate() { + ProcessTemplate processTemplate = new ProcessTemplate(); + ArrayList processList = new ArrayList<>(); + + processList.add(preParamAction()); + processList.add(assembleAction()); + processList.add(sendMqAction()); + + processTemplate.setProcessList(processList); + return processTemplate; + } + + /** + * pipeline流程控制器 + * 目前暂定只有 普通发送的流程 + * 后续扩展则加BusinessCode和ProcessTemplate + * @return + */ + @Bean + public ProcessController processController() { + ProcessController processController = new ProcessController(); + Map templateConfig = new HashMap<>(); + templateConfig.put(BusinessCode.COMMON_SEND.getCode(), commonSendTemplate()); + processController.setTemplateConfig(templateConfig); + return processController; + } + + + /** + * 组装参数Action + * @return + */ + @Bean + public AssembleAction assembleAction() { + return new AssembleAction(); + } + + /** + * 参数校验Action + * @return + */ + @Bean + public PreParamAction preParamAction() { + return new PreParamAction(); + } + + /** + * 发送消息至MQ的Action + * @return + */ + @Bean + public SendMqAction sendMqAction() { + return new SendMqAction(); + } + +} diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/domain/SendTaskModel.java b/austin-service-api-impl/src/main/java/com/java3y/austin/domain/SendTaskModel.java index 960a7d3..c022ed7 100644 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/domain/SendTaskModel.java +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/domain/SendTaskModel.java @@ -1,12 +1,10 @@ package com.java3y.austin.domain; import com.java3y.austin.pipeline.ProcessModel; -import com.java3y.austin.pojo.TaskInfo; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; -import lombok.experimental.Accessors; import java.util.List; @@ -21,27 +19,20 @@ import java.util.List; @Builder public class SendTaskModel implements ProcessModel { - /** - * 请求类型 10:single 20:batch + * 消息模板Id */ - private int requestType; + private Long messageTemplateId; /** - * 请求参数 single 接口 - */ - private MessageParam messageParam; - - /** - * 请求参数 batch 接口 + * 请求参数 */ private List messageParamList; - /** - * 发送任务信息 + * 发送任务的信息 */ - private TaskInfo taskInfo; + private List taskInfo; } diff --git a/austin-service-api-impl/src/main/java/com/java3y/austin/service/SendServiceImpl.java b/austin-service-api-impl/src/main/java/com/java3y/austin/service/SendServiceImpl.java index 0602fbd..7032156 100644 --- a/austin-service-api-impl/src/main/java/com/java3y/austin/service/SendServiceImpl.java +++ b/austin-service-api-impl/src/main/java/com/java3y/austin/service/SendServiceImpl.java @@ -4,14 +4,14 @@ import com.java3y.austin.domain.BatchSendRequest; import com.java3y.austin.domain.SendRequest; import com.java3y.austin.domain.SendResponse; import com.java3y.austin.domain.SendTaskModel; -import com.java3y.austin.enums.RequestType; import com.java3y.austin.pipeline.ProcessContext; import com.java3y.austin.pipeline.ProcessController; -import com.java3y.austin.pojo.TaskInfo; import com.java3y.austin.vo.BasicResultVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.Arrays; + /** * 发送接口 * @author 3y @@ -26,14 +26,15 @@ public class SendServiceImpl implements SendService { public SendResponse send(SendRequest sendRequest) { SendTaskModel sendTaskModel = SendTaskModel.builder() - .requestType(RequestType.SINGLE.getCode()) - .messageParam(sendRequest.getMessageParam()) - .taskInfo(TaskInfo.builder().messageTemplateId(sendRequest.getMessageTemplateId()).build()) + .messageTemplateId(sendRequest.getMessageTemplateId()) + .messageParamList(Arrays.asList(sendRequest.getMessageParam())) .build(); ProcessContext context = ProcessContext.builder() .code(sendRequest.getCode()) - .processModel(sendTaskModel).build(); + .processModel(sendTaskModel) + .needBreak(false) + .response(BasicResultVO.success()).build(); ProcessContext process = processController.process(context); @@ -43,14 +44,15 @@ public class SendServiceImpl implements SendService { @Override public SendResponse batchSend(BatchSendRequest batchSendRequest) { SendTaskModel sendTaskModel = SendTaskModel.builder() - .requestType(RequestType.BATCH.getCode()) + .messageTemplateId(batchSendRequest.getMessageTemplateId()) .messageParamList(batchSendRequest.getMessageParamList()) - .taskInfo(TaskInfo.builder().messageTemplateId(batchSendRequest.getMessageTemplateId()).build()) .build(); ProcessContext context = ProcessContext.builder() .code(batchSendRequest.getCode()) - .processModel(sendTaskModel).build(); + .processModel(sendTaskModel) + .needBreak(false) + .response(BasicResultVO.success()).build(); ProcessContext process = processController.process(context); diff --git a/austin-service-api/src/main/java/com/java3y/austin/domain/BatchSendRequest.java b/austin-service-api/src/main/java/com/java3y/austin/domain/BatchSendRequest.java index aba66e0..48b7257 100644 --- a/austin-service-api/src/main/java/com/java3y/austin/domain/BatchSendRequest.java +++ b/austin-service-api/src/main/java/com/java3y/austin/domain/BatchSendRequest.java @@ -18,18 +18,21 @@ public class BatchSendRequest { /** * 执行业务类型 + * 必传,参考 BusinessCode枚举 */ private String code; /** * 消息模板Id + * 必传 */ private Long messageTemplateId; /** * 消息相关的参数 + * 必传 */ private List messageParamList; diff --git a/austin-service-api/src/main/java/com/java3y/austin/domain/MessageParam.java b/austin-service-api/src/main/java/com/java3y/austin/domain/MessageParam.java index 8c25373..833cce8 100644 --- a/austin-service-api/src/main/java/com/java3y/austin/domain/MessageParam.java +++ b/austin-service-api/src/main/java/com/java3y/austin/domain/MessageParam.java @@ -16,16 +16,19 @@ public class MessageParam { /** * @Description: 接收者 * 多个用,逗号号分隔开 + * 必传 */ private String receiver; /** * @Description: 消息内容中的可变部分 + * 可选 */ private Map variables; /** * @Description: 扩展参数 + * 可选 */ private Map extra; } diff --git a/austin-service-api/src/main/java/com/java3y/austin/enums/BusinessCode.java b/austin-service-api/src/main/java/com/java3y/austin/enums/BusinessCode.java index a335521..abcf678 100644 --- a/austin-service-api/src/main/java/com/java3y/austin/enums/BusinessCode.java +++ b/austin-service-api/src/main/java/com/java3y/austin/enums/BusinessCode.java @@ -15,7 +15,7 @@ public enum BusinessCode { COMMON_SEND("send", "普通发送"), - RECALL_SEND("recall", "撤回消息"); + RECALL("recall", "撤回消息"); /** code 关联着责任链的模板 */ diff --git a/austin-support/pom.xml b/austin-support/pom.xml index 1d51ced..9fc1cff 100644 --- a/austin-support/pom.xml +++ b/austin-support/pom.xml @@ -52,6 +52,11 @@ org.springframework.boot spring-boot-starter-data-jpa + + + org.springframework.kafka + spring-kafka + \ No newline at end of file diff --git a/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessContext.java b/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessContext.java index e7cf17a..685ef72 100644 --- a/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessContext.java +++ b/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessContext.java @@ -5,15 +5,18 @@ import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; /** * 责任链上下文 + * * @author 3y */ @Data @AllArgsConstructor @NoArgsConstructor @Builder +@Accessors(chain = true) public class ProcessContext { /** @@ -29,11 +32,11 @@ public class ProcessContext { /** * 责任链中断的标识 */ - private Boolean needBreak = false; + private Boolean needBreak; /** * 流程处理的结果 */ - BasicResultVO response = BasicResultVO.success(); + BasicResultVO response; } diff --git a/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessController.java b/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessController.java index 97f3858..c63d045 100644 --- a/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessController.java +++ b/austin-support/src/main/java/com/java3y/austin/pipeline/ProcessController.java @@ -3,9 +3,11 @@ package com.java3y.austin.pipeline; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; -import com.java3y.austin.constant.RespStatusEnum; +import com.java3y.austin.enums.RespStatusEnum; import com.java3y.austin.vo.BasicResultVO; +import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Map; @@ -16,6 +18,7 @@ import java.util.Map; * @author 3y */ @Slf4j +@Data public class ProcessController { /** @@ -32,49 +35,57 @@ public class ProcessController { */ public ProcessContext process(ProcessContext context) { + /** + * 前置检查 + */ + if (!preCheck(context)) { + return context; + } + + /** + * 遍历流程节点 + */ + List processList = templateConfig.get(context.getCode()).getProcessList(); + for (BusinessProcess businessProcess : processList) { + businessProcess.process(context); + if (context.getNeedBreak()) { + break; + } + } + return context; + } + + + private Boolean preCheck(ProcessContext context) { // 上下文 if (context == null) { context.setResponse(BasicResultVO.fail(RespStatusEnum.CONTEXT_IS_NULL)); - return context; + return false; } - //业务代码 + // 业务代码 String businessCode = context.getCode(); if (StrUtil.isBlank(businessCode)) { context.setResponse(BasicResultVO.fail(RespStatusEnum.BUSINESS_CODE_IS_NULL)); - return context; + return false; } // 执行模板 ProcessTemplate processTemplate = templateConfig.get(businessCode); if (processTemplate == null) { context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_TEMPLATE_IS_NULL)); - return context; + return false; } // 执行模板列表 List processList = processTemplate.getProcessList(); if (CollUtil.isEmpty(processList)) { context.setResponse(BasicResultVO.fail(RespStatusEnum.PROCESS_LIST_IS_NULL)); - return context; + return false; } - //遍历某个流程节点,出现异常往外抛 - for (BusinessProcess businessProcess : processList) { - businessProcess.process(context); - if (context.getNeedBreak()) { - break; - } - } - return context; + return true; } - public Map getTemplateConfig() { - return templateConfig; - } - - public void setTemplateConfig(Map templateConfig) { - this.templateConfig = templateConfig; - } } diff --git a/austin-support/src/main/java/com/java3y/austin/utils/ContentHolderUtil.java b/austin-support/src/main/java/com/java3y/austin/utils/ContentHolderUtil.java new file mode 100644 index 0000000..34f31b8 --- /dev/null +++ b/austin-support/src/main/java/com/java3y/austin/utils/ContentHolderUtil.java @@ -0,0 +1,59 @@ +package com.java3y.austin.utils; + +import org.springframework.context.expression.MapAccessor; +import org.springframework.expression.spel.support.StandardEvaluationContext; +import org.springframework.util.PropertyPlaceholderHelper; + +import java.text.MessageFormat; +import java.util.Map; + +/** + * @author 3y + * 内容占位符 替换 + * + * austin占位符格式{$var} + */ +public class ContentHolderUtil { + + // 占位符前缀 + private static final String PLACE_HOLDER_PREFIX = "{$"; + // 占位符后缀 + private static final String PLACE_HOLDER_ENDFIX = "}"; + + private static final StandardEvaluationContext evalutionContext; + + private static PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper( + PLACE_HOLDER_PREFIX, PLACE_HOLDER_ENDFIX); + + static { + evalutionContext = new StandardEvaluationContext(); + evalutionContext.addPropertyAccessor(new MapAccessor()); + } + + public static String replacePlaceHolder(final String template, final Map paramMap) { + String replacedPushContent = propertyPlaceholderHelper.replacePlaceholders(template, + new CustomPlaceholderResolver(paramMap)); + return replacedPushContent; + } + + private static class CustomPlaceholderResolver implements PropertyPlaceholderHelper.PlaceholderResolver { + private Map paramMap; + + public CustomPlaceholderResolver(Map paramMap) { + super(); + this.paramMap = paramMap; + } + + @Override + public String resolvePlaceholder(String placeholderName) { + String value = paramMap.get(placeholderName); + if (null == value) { + String errorStr = MessageFormat.format("template:{} require param:{},but not exist! paramMap:{}", + placeholderName, paramMap.toString()); + throw new IllegalArgumentException(errorStr); + } + return value; + } + } + +} diff --git a/austin-support/src/main/java/com/java3y/austin/utils/TaskInfoUtils.java b/austin-support/src/main/java/com/java3y/austin/utils/TaskInfoUtils.java new file mode 100644 index 0000000..e9e4c2f --- /dev/null +++ b/austin-support/src/main/java/com/java3y/austin/utils/TaskInfoUtils.java @@ -0,0 +1,26 @@ +package com.java3y.austin.utils; + +import cn.hutool.core.date.DateUtil; + +import java.util.Date; + +/** + * 生成 消息推送的URL 工具类 + * + * @author 3y + */ +public class TaskInfoUtils { + + private static int TYPE_FLAG = 1000000; + + /** + * 生成BusinessId + * 模板类型+模板ID+当天日期 + * (固定16位) + */ + public static Long generateBusinessId(Long templateId, Integer templateType) { + Integer today = Integer.valueOf(DateUtil.format(new Date(), "yyyyMMdd")); + return Long.valueOf(String.format("%d%s", templateType * TYPE_FLAG + templateId, today)); + } + +} diff --git a/austin-web/pom.xml b/austin-web/pom.xml index 693bc67..64c5c3f 100644 --- a/austin-web/pom.xml +++ b/austin-web/pom.xml @@ -22,9 +22,16 @@ 0.0.1-SNAPSHOT - org.springframework.kafka - spring-kafka + com.java3y.austin + austin-service-api + 0.0.1-SNAPSHOT + + com.java3y.austin + austin-service-api-impl + 0.0.1-SNAPSHOT + + diff --git a/austin-web/src/main/java/com/java3y/austin/AustinApplication.java b/austin-web/src/main/java/com/java3y/austin/AustinApplication.java index 2fd6b32..5b21c58 100644 --- a/austin-web/src/main/java/com/java3y/austin/AustinApplication.java +++ b/austin-web/src/main/java/com/java3y/austin/AustinApplication.java @@ -1,19 +1,7 @@ package com.java3y.austin; -import cn.hutool.core.date.DateUtil; -import com.alibaba.fastjson.JSON; -import com.java3y.austin.dao.MessageTemplateDao; -import com.java3y.austin.domain.MessageTemplate; -import com.java3y.austin.pojo.SmsParam; -import com.java3y.austin.script.TencentSmsScript; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import java.util.Arrays; -import java.util.HashSet; @SpringBootApplication diff --git a/austin-web/src/main/java/com/java3y/austin/controller/KafkaTestController.java b/austin-web/src/main/java/com/java3y/austin/controller/KafkaTestController.java index 70b6939..f5875fd 100644 --- a/austin-web/src/main/java/com/java3y/austin/controller/KafkaTestController.java +++ b/austin-web/src/main/java/com/java3y/austin/controller/KafkaTestController.java @@ -1,24 +1,24 @@ -package com.java3y.austin.controller; - -import com.java3y.austin.kafkatest.UserLogProducer; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class KafkaTestController { - - @Autowired - private UserLogProducer userLogProducer; - - /** - * test insert - */ - @GetMapping("/kafka/insert") - public String insert(String userId) { - userLogProducer.sendLog(userId); - - return null; - } - -} +//package com.java3y.austin.controller; +// +//import com.java3y.austin.kafkatest.UserLogProducer; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.GetMapping; +//import org.springframework.web.bind.annotation.RestController; +// +//@RestController +//public class KafkaTestController { +// +// @Autowired +// private UserLogProducer userLogProducer; +// +// /** +// * test insert +// */ +// @GetMapping("/kafka/insert") +// public String insert(String userId) { +// userLogProducer.sendLog(userId); +// +// return null; +// } +// +//} diff --git a/austin-web/src/main/java/com/java3y/austin/controller/SendController.java b/austin-web/src/main/java/com/java3y/austin/controller/SendController.java index 855529f..16a5c2e 100644 --- a/austin-web/src/main/java/com/java3y/austin/controller/SendController.java +++ b/austin-web/src/main/java/com/java3y/austin/controller/SendController.java @@ -1,15 +1,17 @@ package com.java3y.austin.controller; -import com.java3y.austin.handler.SmsHandler; -import com.java3y.austin.pojo.TaskInfo; -import java.util.Collections; -import java.util.HashSet; - -import com.java3y.austin.vo.BasicResultVO; +import com.java3y.austin.domain.MessageParam; +import com.java3y.austin.domain.SendRequest; +import com.java3y.austin.domain.SendResponse; +import com.java3y.austin.enums.BusinessCode; +import com.java3y.austin.service.SendService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; +import java.util.HashMap; +import java.util.Map; + /** * @author 三歪 */ @@ -17,29 +19,33 @@ import org.springframework.web.bind.annotation.RestController; @RestController public class SendController { + @Autowired + private SendService sendService; - @Autowired - private SmsHandler smsHandler; + @GetMapping("/sendSmsV2") + public SendResponse sendSmsV2(String phone) { - /** - * 测试发送短信 - * @param phone 手机号 - * @return BasicResultVO - */ - @GetMapping("/sendSms") - public BasicResultVO sendSms(String phone, String content, Long messageTemplateId) { + /** + * + * messageTemplate Id 为1 的模板内容 + * {"auditStatus":10,"auditor":"yyyyyyz","created":1636978066,"creator":"yyyyc","deduplicationTime":1,"expectPushTime":"0","flowId":"yyyy","id":1,"idType":20,"isDeleted":0,"isNightShield":0,"msgContent":"{\"content\":\"{$contentValue}\"}","msgStatus":10,"msgType":10,"name":"test短信","proposer":"yyyy22","sendAccount":66,"sendChannel":30,"team":"yyyt","templateType":10,"updated":1636978066,"updator":"yyyyu"} + * + */ - TaskInfo taskInfo = TaskInfo.builder().receiver(new HashSet<>( - Collections.singletonList(phone))) - .content(content) - .messageTemplateId(messageTemplateId) - .build(); + // 文案参数 + Map variables = new HashMap<>(); + variables.put("contentValue", "6666"); - if (smsHandler.doHandler(taskInfo)) { - return BasicResultVO.success("发送信息成功"); - } + MessageParam messageParam = new MessageParam().setReceiver(phone).setVariables(variables); - return BasicResultVO.fail(); - } + // ID为1的消息模板 + SendRequest sendRequest = new SendRequest().setCode(BusinessCode.COMMON_SEND.getCode()) + .setMessageTemplateId(1L) + .setMessageParam(messageParam); + + SendResponse response = sendService.send(sendRequest); + + return response; + } } diff --git a/austin-web/src/main/resources/application.yml b/austin-web/src/main/resources/application.yml index dd772c1..4ecbc77 100644 --- a/austin-web/src/main/resources/application.yml +++ b/austin-web/src/main/resources/application.yml @@ -38,4 +38,8 @@ spring: offset: reset: earliest -# tomcat / HikariPool(数据库连接池 配置) TODO \ No newline at end of file +# tomcat / HikariPool(数据库连接池 配置) TODO +# 消息topicName TODO +austin: + topic: + name: austin \ No newline at end of file