Browse Source

组织机构信息和分类信息修改使用RocketMQ同步全库

dev
liuchuang 6 years ago
parent
commit
757d2e4b06
  1. 12
      esua-epdc/epdc-admin/epdc-admin-server/pom.xml
  2. 37
      esua-epdc/epdc-admin/epdc-admin-server/src/main/java/com/elink/esua/epdc/rocketmq/dto/OrganizationModifyDTO.java
  3. 44
      esua-epdc/epdc-admin/epdc-admin-server/src/main/java/com/elink/esua/epdc/rocketmq/producer/OrganizationModifyProducer.java
  4. 36
      esua-epdc/epdc-admin/epdc-admin-server/src/main/java/com/elink/esua/epdc/service/impl/SysDeptServiceImpl.java
  5. 8
      esua-epdc/epdc-admin/epdc-admin-server/src/main/resources/application.yml
  6. 31
      esua-epdc/epdc-commons/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/RocketMqConstant.java
  7. 25
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.github/ISSUE_TEMPLATE.md
  8. 20
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.github/PULL_REQUEST_TEMPLATE.md
  9. 13
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.gitignore
  10. 30
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.travis.yml
  11. 202
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/LICENSE
  12. 5
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/NOTICE
  13. 406
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/README.md
  14. 391
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/README_zh_CN.md
  15. 222
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/pom.xml
  16. 167
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-parent/pom.xml
  17. 202
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/LICENSE
  18. 34
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/README.md
  19. 40
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/README_zh_CN.md
  20. 91
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/pom.xml
  21. 31
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/pom.xml
  22. 39
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ACLStringConsumer.java
  23. 39
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ACLStringTransactionalConsumer.java
  24. 33
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ConsumerACLApplication.java
  25. 10
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/resources/application.properties
  26. 31
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/pom.xml
  27. 33
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/ConsumerApplication.java
  28. 44
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/Checker.java
  29. 46
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/MessageExtConsumer.java
  30. 36
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/OrderPaidEventConsumer.java
  31. 34
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/StringConsumer.java
  32. 34
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/StringConsumerNewNS.java
  33. 34
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/StringTransactionalConsumer.java
  34. 54
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/domain/OrderPaidEvent.java
  35. 12
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/resources/application.properties
  36. 32
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-acl-demo/pom.xml
  37. 151
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ProducerACLApplication.java
  38. 7
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-acl-demo/src/main/resources/application.properties
  39. 32
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/pom.xml
  40. 24
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/java/org/apache/rocketmq/samples/springboot/ExtRocketMQTemplate.java
  41. 195
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/java/org/apache/rocketmq/samples/springboot/ProducerApplication.java
  42. 50
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/java/org/apache/rocketmq/samples/springboot/domain/OrderPaidEvent.java
  43. 11
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/resources/application.properties
  44. 23
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/copyright/Apache.xml
  45. 64
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/copyright/profiles_settings.xml
  46. 135
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/rmq_checkstyle.xml
  47. 157
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/rmq_codeStyle.xml
  48. 7
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/README.md
  49. 102
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/pom.xml
  50. 30
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/ConsumeMode.java
  51. 89
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/ExtRocketMQTemplateConfiguration.java
  52. 33
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/MessageModel.java
  53. 112
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/RocketMQMessageListener.java
  54. 79
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/RocketMQTransactionListener.java
  55. 33
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/SelectorType.java
  56. 158
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/ExtProducerResetConfiguration.java
  57. 34
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/JacksonFallbackConfiguration.java
  58. 139
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/ListenerContainerConfiguration.java
  59. 139
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/RocketMQAutoConfiguration.java
  60. 210
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/RocketMQProperties.java
  61. 32
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/RocketMQConfigUtils.java
  62. 122
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/RocketMQTransactionAnnotationProcessor.java
  63. 85
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/TransactionHandler.java
  64. 52
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/TransactionHandlerRegistry.java
  65. 22
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQListener.java
  66. 25
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQLocalTransactionListener.java
  67. 24
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQLocalTransactionState.java
  68. 24
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQPushConsumerLifecycleListener.java
  69. 677
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQTemplate.java
  70. 494
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/DefaultRocketMQListenerContainer.java
  71. 22
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQConsumerLifecycleListener.java
  72. 34
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQHeaders.java
  73. 30
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQListenerContainer.java
  74. 215
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQUtil.java
  75. 2
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/resources/META-INF/spring.factories
  76. 221
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/autoconfigure/RocketMQAutoConfigurationTest.java
  77. 52
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/support/DefaultRocketMQListenerContainerTest.java
  78. 93
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/support/RocketMQUtilTest.java
  79. 23
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/copyright/Apache.xml
  80. 64
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/copyright/profiles_settings.xml
  81. 135
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/rmq_checkstyle.xml
  82. 157
      esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/rmq_codeStyle.xml
  83. 2
      esua-epdc/epdc-module/epdc-custom/epdc-custom-client/src/main/java/com/elink/esua/epdc/dto/consult/GridOperatorInfoDTO.java
  84. 12
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/pom.xml
  85. 11
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/consult/dao/GridOperatorInfoDao.java
  86. 12
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/consult/service/GridOperatorInfoService.java
  87. 56
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/consult/service/impl/GridOperatorInfoServiceImpl.java
  88. 11
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/enterprise/dao/EnterpriseInfoDao.java
  89. 12
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/enterprise/service/EnterpriseInfoService.java
  90. 56
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/enterprise/service/impl/EnterpriseInfoServiceImpl.java
  91. 22
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/evaluate/dao/EvaluateDeptDao.java
  92. 12
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/evaluate/service/EvaluateDeptService.java
  93. 59
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/evaluate/service/impl/EvaluateDeptServiceImpl.java
  94. 59
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/rocketmq/consumer/OrganizationModifyConsumer.java
  95. 37
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/rocketmq/dto/OrganizationModifyDTO.java
  96. 7
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/application.yml
  97. 13
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/mapper/consult/GridOperatorInfoDao.xml
  98. 13
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/mapper/enterprise/EnterpriseInfoDao.xml
  99. 17
      esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/mapper/evaluate/EvaluateDeptDao.xml
  100. 21
      esua-epdc/epdc-module/epdc-events/epdc-events-client/src/main/java/com/elink/esua/epdc/dto/events/EpdcEventsDTO.java

12
esua-epdc/epdc-admin/epdc-admin-server/pom.xml

@ -62,6 +62,12 @@
<artifactId>feign-httpclient</artifactId>
<version>10.3.0</version>
</dependency>
<!--RocketMq-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
</dependencies>
<build>
@ -141,6 +147,9 @@
<!--数据分析端小程序-->
<analysis.wx.ma.appId>wx9b6102a8ee5add65</analysis.wx.ma.appId>
<analysis.wx.ma.secret>394f47d4e08fc0fd629231d3f68a34dc</analysis.wx.ma.secret>
<!--RocketMQ-->
<rocketmq.name.server>47.104.85.99:9876;114.215.125.123:9876</rocketmq.name.server>
<rocketmq.producer.group>organizationGroup</rocketmq.producer.group>
</properties>
</profile>
<profile>
@ -167,6 +176,9 @@
<!--数据分析端小程序-->
<analysis.wx.ma.appId>wx9b6102a8ee5add65</analysis.wx.ma.appId>
<analysis.wx.ma.secret>394f47d4e08fc0fd629231d3f68a34dc</analysis.wx.ma.secret>
<!--RocketMQ-->
<rocketmq.name.server>47.104.85.99:9876;114.215.125.123:9876</rocketmq.name.server>
<rocketmq.producer.group>organizationGroup</rocketmq.producer.group>
</properties>
</profile>
<profile>

37
esua-epdc/epdc-admin/epdc-admin-server/src/main/java/com/elink/esua/epdc/rocketmq/dto/OrganizationModifyDTO.java

@ -0,0 +1,37 @@
package com.elink.esua.epdc.rocketmq.dto;
import lombok.Data;
import java.io.Serializable;
/**
*
* 组织机构信息修改-发送MQ消息DTO
*
* @Authorliuchuang
* @Date2020/3/6 19:58
*/
@Data
public class OrganizationModifyDTO implements Serializable {
private static final long serialVersionUID = -1330090682508121169L;
/**
* 部门ID
*/
private Long deptId;
/**
* 旧部门名称
*/
private String oldDeptName;
/**
* 新部门名称
*/
private String newDeptName;
/**
* 部门类型
*/
private String typeKey;
}

44
esua-epdc/epdc-admin/epdc-admin-server/src/main/java/com/elink/esua/epdc/rocketmq/producer/OrganizationModifyProducer.java

@ -0,0 +1,44 @@
package com.elink.esua.epdc.rocketmq.producer;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
*
* 组织机构信息修改-发送MQ消息
*
* @Authorliuchuang
* @Date2020/3/5 17:53
*/
@Slf4j
@Component
public class OrganizationModifyProducer {
@Autowired
private RocketMQTemplate rocketMQTemplate;
/**
*
* 发送消息
*
* @params [topic, tag, keys, body]
* @return void
* @author liuchuang
* @since 2020/3/6 21:09
*/
public void sendMessage(String topic, String tag, String keys, String body) {
Message message = new Message(topic, tag, keys, body.getBytes());
try {
SendResult sendResult = rocketMQTemplate.getProducer().send(message);
log.info("EPDC-ADMIN-SERVER发送消息结果:{sendStatus:{}, topic:{}, msgId:{}}", sendResult.getSendStatus(), topic, sendResult.getMsgId());
} catch (Exception e) {
log.error("EPDC-ADMIN-SERVER发送消息异常:{topic:{}, tag:{}, keys:{}, body:{}}", topic, tag, keys, body);
e.printStackTrace();
}
}
}

36
esua-epdc/epdc-admin/epdc-admin-server/src/main/java/com/elink/esua/epdc/service/impl/SysDeptServiceImpl.java

@ -14,10 +14,7 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.elink.esua.epdc.commons.mybatis.service.impl.BaseServiceImpl;
import com.elink.esua.epdc.commons.tools.constant.Constant;
import com.elink.esua.epdc.commons.tools.constant.FieldConstant;
import com.elink.esua.epdc.commons.tools.constant.NumConstant;
import com.elink.esua.epdc.commons.tools.constant.OrganizationTypeConstant;
import com.elink.esua.epdc.commons.tools.constant.*;
import com.elink.esua.epdc.commons.tools.enums.SuperAdminEnum;
import com.elink.esua.epdc.commons.tools.exception.ErrorCode;
import com.elink.esua.epdc.commons.tools.exception.RenException;
@ -37,6 +34,8 @@ import com.elink.esua.epdc.dto.epdc.form.UserSysDeptInfoFormDTO;
import com.elink.esua.epdc.dto.epdc.result.UserSysDeptInfoResultDTO;
import com.elink.esua.epdc.entity.SysDeptEntity;
import com.elink.esua.epdc.feign.GroupFeignClient;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import com.elink.esua.epdc.rocketmq.producer.OrganizationModifyProducer;
import com.elink.esua.epdc.service.SysDeptService;
import com.elink.esua.epdc.service.SysUserService;
import com.google.common.collect.Lists;
@ -75,6 +74,9 @@ public class SysDeptServiceImpl extends BaseServiceImpl<SysDeptDao, SysDeptEntit
@Autowired
private RedisUtils redisUtils;
@Autowired
private OrganizationModifyProducer organizationModifyProducer;
private static final Logger logger = LoggerFactory.getLogger(SysDeptServiceImpl.class);
@Override
@ -155,6 +157,9 @@ public class SysDeptServiceImpl extends BaseServiceImpl<SysDeptDao, SysDeptEntit
}
entity.setPids(getPidList(entity.getPid()));
// 发送消息
sendMqMessage(dto);
updateById(entity);
}
@ -816,4 +821,27 @@ public class SysDeptServiceImpl extends BaseServiceImpl<SysDeptDao, SysDeptEntit
List<CompleteDeptDTO> userDtoList = this.baseDao.selectListCompleteDeptDTO(params);
return new PageData<>(userDtoList, iPage.getTotal());
}
/**
*
* 组织机构名称修改发送MQ消息
*
* @params [dto]
* @return void
* @author liuchuang
* @since 2020/3/6 21:34
*/
private void sendMqMessage(SysDeptDTO dto) {
// 获取旧信息
SysDeptEntity entity = baseDao.getById(dto.getId());
if (!dto.getName().equals(entity.getName())) {
OrganizationModifyDTO body = new OrganizationModifyDTO();
body.setDeptId(dto.getId());
body.setOldDeptName(entity.getName());
body.setNewDeptName(dto.getName());
body.setTypeKey(entity.getTypeKey());
organizationModifyProducer.sendMessage(RocketMqConstant.MQ_TOPIC_ORGANIZATION, RocketMqConstant.MQ_TAG_ORGANIZATION,
dto.getId().toString(), JSONObject.toJSONString(body));
}
}
}

8
esua-epdc/epdc-admin/epdc-admin-server/src/main/resources/application.yml

@ -110,4 +110,10 @@ hystrix:
ribbon:
ReadTimeout: 300000
ConnectTimeout: 300000
ConnectTimeout: 300000
rocketmq:
name-server: @rocketmq.name.server@
producer:
group: @rocketmq.producer.group@

31
esua-epdc/epdc-commons/epdc-commons-tools/src/main/java/com/elink/esua/epdc/commons/tools/constant/RocketMqConstant.java

@ -0,0 +1,31 @@
package com.elink.esua.epdc.commons.tools.constant;
/**
*
* RocketMq 常量类
*
* @Authorliuchuang
* @Date2020/3/6 20:52
*/
public interface RocketMqConstant {
/**
* 组织机构信息修改-消息topic
*/
String MQ_TOPIC_ORGANIZATION = "organizationTopic";
/**
* 组织机构信息修改-消息tag
*/
String MQ_TAG_ORGANIZATION = "organizationTag";
/**
* 分类信息修改-消息topic
*/
String MQ_TOPIC_CATEGORY = "categoryTopic";
/**
* 分类信息修改-消息tag
*/
String MQ_TAG_CATEGORY = "categoryTag";
}

25
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.github/ISSUE_TEMPLATE.md

@ -0,0 +1,25 @@
The issue tracker is **ONLY** used for bug report and feature request.
Any question or RocketMQ proposal please use our [mailing lists](http://rocketmq.apache.org/about/contact/).
**BUG REPORT**
1. Please describe the issue you observed:
- What did you do (The steps to reproduce)?
- What did you expect to see?
- What did you see instead?
2. Please tell us about your environment:
3. Other information (e.g. detailed explanation, logs, related issues, suggestions how to fix, etc):
**FEATURE REQUEST**
1. Please describe the feature you are requesting.
2. Provide any additional detail on your proposed use case for this feature.
3. Indicate the importance of this issue to you (blocker, must-have, should-have, nice-to-have). Are you currently using any workarounds to address this issue?

20
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.github/PULL_REQUEST_TEMPLATE.md

@ -0,0 +1,20 @@
## What is the purpose of the change
XXXXX
## Brief changelog
XX
## Verifying this change
XXXX
Follow this checklist to help us incorporate your contribution quickly and easily. Notice, `it would be helpful if you could finish the following 5 checklist(the last one is not necessary)before request the community to review your PR`.
- [x] Make sure there is a [Github issue](https://github.com/apache/rocketmq/issues) filed for the change (usually before you start working on it). Trivial changes like typos do not require a Github issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
- [x] Format the pull request title like `[ISSUE #123] Fix UnknownException when host config not exist`. Each commit in the pull request should have a meaningful subject line and body.
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [x] Write necessary unit-test(over 80% coverage) to verify your logic correction, more mock a little better when cross module dependency exist.
- [x] Run `mvn -B clean apache-rat:check findbugs:findbugs checkstyle:checkstyle` to make sure basic checks pass. Run `mvn clean install -DskipITs` to make sure unit-test pass. Run `mvn clean test-compile failsafe:integration-test` to make sure integration-test pass.
- [ ] If this contribution is large, please file an [Apache Individual Contributor License Agreement](http://www.apache.org/licenses/#clas).

13
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.gitignore

@ -0,0 +1,13 @@
.idea
.classpath
.project
.settings/
target/
*.log*
*.iml
.idea/
*.versionsBackup
!NOTICE-BIN
!LICENSE-BIN
.DS_Store
.vscode

30
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/.travis.yml

@ -0,0 +1,30 @@
notifications:
email:
recipients:
- dev@rocketmq.apache.org
on_success: change
on_failure: always
language: java
matrix:
include:
# On OSX, run with default JDK only.
# - os: osx
# On Linux, run with specific JDKs only.
- os: linux
env: CUSTOM_JDK="oraclejdk8"
before_install:
- echo 'MAVEN_OPTS="$MAVEN_OPTS -Xmx1024m -XX:MaxPermSize=512m -XX:+BytecodeVerificationLocal"' >> ~/.mavenrc
- cat ~/.mavenrc
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then export JAVA_HOME=$(/usr/libexec/java_home); fi
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then jdk_switcher use "$CUSTOM_JDK"; fi
script:
- travis_retry mvn -B clean apache-rat:check
- travis_retry mvn -B package jacoco:report coveralls:report
after_success:
# - mvn clean install -Pit-test
- mvn sonar:sonar -Psonar-apache

202
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/LICENSE

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

5
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/NOTICE

@ -0,0 +1,5 @@
Apache RocketMQ
Copyright 2016-2018 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).

406
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/README.md

@ -0,0 +1,406 @@
# RocketMQ-Spring [![Build Status](https://travis-ci.org/apache/rocketmq-spring.svg?branch=master)](https://travis-ci.org/apache/rocketmq-spring) [![Coverage Status](https://coveralls.io/repos/github/apache/rocketmq-spring/badge.svg?branch=master)](https://coveralls.io/github/apache/rocketmq-spring?branch=master)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.rocketmq/rocketmq-spring-all/badge.svg)](https://search.maven.org/search?q=g:org.apache.rocketmq%20AND%20a:rocketmq-spring-all)
[![GitHub release](https://img.shields.io/badge/release-download-orange.svg)](https://github.com/apache/rocketmq-spring/releases)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[中文](./README_zh_CN.md)
## Introduction
This project aims to help developers quickly integrate [RocketMQ](http://rocketmq.apache.org/) with [Spring Boot](http://projects.spring.io/spring-boot/).
## How To Contribute
We are always very happy to have contributions, whether for trivial cleanups or big new features. Please see the RocketMQ main website to read [details](http://rocketmq.apache.org/docs/how-to-contribute/)
## Prerequisites
- JDK 1.8 and above
- [Maven](http://maven.apache.org/) 3.0 and above
## Build and Install with local maven repository
```
mvn clean install
```
## Features:
- [x] synchronous transmission
- [x] synchronous ordered transmission
- [x] synchronous batch transmission
- [x] asynchronous transmission
- [x] asynchronous ordered transmission
- [x] orderly consume
- [x] concurrently consume(broadcasting/clustering)
- [x] one-way transmission
- [x] transaction transmission
- [x] message trace
- [x] ACL
- [ ] pull consume
## Quick Start
Please see the complete sample [rocketmq-spring-boot-samples](rocketmq-spring-boot-samples)
Note: Current RELEASE.VERSION=2.0.3
```xml
<!--add dependency in pom.xml-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${RELEASE.VERSION}</version>
</dependency>
```
### Produce Message
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=my-group
```
> Note:
>
> Maybe you need change `127.0.0.1:9876` with your real NameServer address for RocketMQ
```java
@SpringBootApplication
public class ProducerApplication implements CommandLineRunner{
@Resource
private RocketMQTemplate rocketMQTemplate;
public static void main(String[] args){
SpringApplication.run(ProducerApplication.class, args);
}
public void run(String... args) throws Exception {
rocketMQTemplate.convertAndSend("test-topic-1", "Hello, World!");
rocketMQTemplate.send("test-topic-1", MessageBuilder.withPayload("Hello, World! I'm from spring message").build());
rocketMQTemplate.convertAndSend("test-topic-2", new OrderPaidEvent("T_001", new BigDecimal("88.00")));
// rocketMQTemplate.destroy(); // notes: once rocketMQTemplate be destroyed, you can not send any message again with this rocketMQTemplate
}
@Data
@AllArgsConstructor
public class OrderPaidEvent implements Serializable{
private String orderId;
private BigDecimal paidMoney;
}
}
```
> More relevant configurations for producing:
>
> ```properties
> rocketmq.producer.send-message-timeout=300000
> rocketmq.producer.compress-message-body-threshold=4096
> rocketmq.producer.max-message-size=4194304
> rocketmq.producer.retry-times-when-send-async-failed=0
> rocketmq.producer.retry-next-server=true
> rocketmq.producer.retry-times-when-send-failed=2
> ```
### Send message in transaction and implement local check Listener
```java
@SpringBootApplication
public class ProducerApplication implements CommandLineRunner{
@Resource
private RocketMQTemplate rocketMQTemplate;
public static void main(String[] args){
SpringApplication.run(ProducerApplication.class, args);
}
public void run(String... args) throws Exception {
try {
// Build a SpringMessage for sending in transaction
Message msg = MessageBuilder.withPayload(..)...;
// In sendMessageInTransaction(), the first parameter transaction name ("test")
// must be same with the @RocketMQTransactionListener's member field 'transName'
rocketMQTemplate.sendMessageInTransaction("test", "test-topic", msg, null);
} catch (MQClientException e) {
e.printStackTrace(System.out);
}
}
// Define transaction listener with the annotation @RocketMQTransactionListener
@RocketMQTransactionListener(transName="test")
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
// ... local transaction process, return bollback, commit or unknown
return RocketMQLocalTransactionState.UNKNOWN;
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
// ... check transaction status and return bollback, commit or unknown
return RocketMQLocalTransactionState.COMMIT;
}
}
}
```
### Consume Message
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
```
> Note:
>
> Maybe you need change `127.0.0.1:9876` with your real NameServer address for RocketMQ
```java
@SpringBootApplication
public class ConsumerApplication{
public static void main(String[] args){
SpringApplication.run(ConsumerApplication.class, args);
}
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
public class MyConsumer1 implements RocketMQListener<String>{
public void onMessage(String message) {
log.info("received message: {}", message);
}
}
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-2", consumerGroup = "my-consumer_test-topic-2")
public class MyConsumer2 implements RocketMQListener<OrderPaidEvent>{
public void onMessage(OrderPaidEvent orderPaidEvent) {
log.info("received orderPaidEvent: {}", orderPaidEvent);
}
}
}
```
> More relevant configurations for consuming:
>
> see: [RocketMQMessageListener](rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/RocketMQMessageListener.java)
### Message Trace
We need 2 more configurations for support message trace in producer.
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=my-group
rocketmq.producer.enable-msg-trace=true
rocketmq.producer.customized-trace-topic=my-trace-topic
```
The message trace in consumer should configure in `@RocketMQMessageListener`.
```
@Service
@RocketMQMessageListener(
topic = "test-topic-1",
consumerGroup = "my-consumer_test-topic-1",
enableMsgTrace = true,
customizedTraceTopic = "my-trace-topic"
)
public class MyConsumer implements RocketMQListener<String> {
...
}
```
> Note:
>
> Maybe you need change `127.0.0.1:9876` with your real NameServer address for RocketMQ
> By default, the message track feature of Producer and Consumer is turned on and the trace-topic is RMQ_SYS_TRACE_TOPIC
> The topic of message trace can be configured with `rocketmq.consumer.customized-trace-topic` configuration item, not required to be configured in each `@RocketMQTransactionListener`
### ACL
We need 2 more configurations for support ACL in producer.
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=my-group
rocketmq.producer.access-key=AK
rocketmq.producer.secret-key=SK
```
Transaction Message should configure AK/SK in `@RocketMQTransactionListener`.
```
@RocketMQTransactionListener(
txProducerGroup = "test,
accessKey = "AK",
secretKey = "SK"
)
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
...
}
```
> Note:
>
> You do not need to configure AK/SK for each `@RocketMQTransactionListener`, you could configure `rocketmq.producer.access-key` and `rocketmq.producer.secret-key` as default value
The ACL feature in consumer should configure AK/SK in `@RocketMQMessageListener`.
```
@Service
@RocketMQMessageListener(
topic = "test-topic-1",
consumerGroup = "my-consumer_test-topic-1",
accessKey = "AK",
secretKey = "SK"
)
public class MyConsumer implements RocketMQListener<String> {
...
}
```
> Note:
>
> You do not need to configure AK/SK for each `@RocketMQMessageListener`, you could configure `rocketmq.consumer.access-key` and `rocketmq.consumer.secret-key` as default value
## FAQ
1. How to connected many `nameserver` on production environment?
`rocketmq.name-server` support the configuration of multiple `nameserver`, separated by `;`. For example: `172.19.0.1: 9876; 172.19.0.2: 9876`
1. When was `rocketMQTemplate` destroyed?
Developers do not need to manually execute the `rocketMQTemplate.destroy ()` method when using `rocketMQTemplate` to send a message in the project, and` rocketMQTemplate` will be destroyed automatically when the spring container is destroyed.
1. start exception:`Caused by: org.apache.rocketmq.client.exception.MQClientException: The consumer group[xxx] has been created before, specify another name please`
RocketMQ in the design do not want a consumer to deal with multiple types of messages at the same time, so the same `consumerGroup` consumer responsibility should be the same, do not do different things (that is, consumption of multiple topics). Suggested `consumerGroup` and` topic` one correspondence.
1. How is the message content body being serialized and deserialized?
RocketMQ's message body is stored as `byte []`. When the business system message content body if it is `java.lang.String` type, unified in accordance with` utf-8` code into `byte []`; If the business system message content is not `java.lang.String` Type, then use [jackson-databind](https://github.com/FasterXML/jackson-databind) serialized into the `JSON` format string, and then unified in accordance with` utf-8` code into `byte [] `.
1. How do I specify the `tags` for topic?
RocketMQ best practice recommended: an application as much as possible with one Topic, the message sub-type with `tags` to identify,` tags` can be set by the application free.
When you use `rocketMQTemplate` to send a message, set the destination of the message by setting the` destination` parameter of the send method. The `destination` format is `topicName:tagName`, `:` Precedes the name of the topic, followed by the `tags` name.
> Note:
>
> `tags` looks a complex, but when sending a message , the destination can only specify one topic under a `tag`, can not specify multiple.
1. How do I set the message's `key` when sending a message?
You can send a message by overloading method like `xxxSend(String destination, Message<?> msg, ...)`, setting `headers` of `msg`. for example:
```java
Message<?> message = MessageBuilder.withPayload(payload).setHeader(MessageConst.PROPERTY_KEYS, msgId).build();
rocketMQTemplate.send("topic-test", message);
```
Similarly, you can also set the message `FLAG`,` WAIT_STORE_MSG_OK` and some other user-defined other header information according to the above method.
> Note:
>
> In the case of converting Spring's Message to RocketMQ's Message, to prevent the `header` information from conflicting with RocketMQ's system properties, the prefix `USERS_` was added in front of all `header` names. So if you want to get a custom message header when consuming, please pass through the key at the beginning of `USERS_` in the header.
1. When consume message, in addition to get the message `payload`, but also want to get RocketMQ message of other system attributes, how to do?
Consumers in the realization of `RocketMQListener` interface, only need to be generic for the` MessageExt` can, so in the `onMessage` method will receive RocketMQ native 'MessageExt` message.
```java
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
public class MyConsumer2 implements RocketMQListener<MessageExt>{
public void onMessage(MessageExt messageExt) {
log.info("received messageExt: {}", messageExt);
}
}
```
1. How do I specify where consumers start consuming messages?
The default consume offset please refer: [RocketMQ FAQ](http://rocketmq.apache.org/docs/faq/).
To customize the consumer's starting location, simply add a `RocketMQPushConsumerLifecycleListener` interface implementation to the consumer class. Examples are as follows:
```java
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
public class MyConsumer1 implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(String message) {
log.info("received message: {}", message);
}
@Override
public void prepareStart(final DefaultMQPushConsumer consumer) {
// set consumer consume message from now
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
consumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
}
}
```
Similarly, any other configuration on `DefaultMQPushConsumer` can be done in the same way as above.
1. How do I send transactional messages?
It needs two steps on client side:
a) Define a class which is annotated with @RocketMQTransactionListener and implements RocketMQLocalTransactionListener interface, in which, the executeLocalTransaction() and checkLocalTransaction() methods are implemented;
b) Invoke the sendMessageInTransaction() method with the RocketMQTemplate API. Note: The first parameter of this method is correlated with the txProducerGroup attribute of @RocketMQTransactionListener. It can be null if using the default transaction producer group.
1. How do I create more than one RocketMQTemplate with a different name-server or other specific properties?
```java
// Step1. Define an extra RocketMQTemplate with required properties, note, the 'nameServer' property must be different from the value of global
// Spring configuration 'rocketmq.name-server', other properties are optionally defined, they will use the global configuration
// definition by default.
// The RocketMQTemplate's Spring Bean name is 'extRocketMQTemplate', same with the simplified class name (Initials lowercase)
@ExtRocketMQTemplateConfiguration(nameServer="127.0.0.1:9876"
, ... // override other specific properties if needed
)
public class ExtRocketMQTemplate extends RocketMQTemplate {
// keep the body empty
}
// Step2. Use the extra RocketMQTemplate. e.g.
@Resource(name = "extRocketMQTemplate") // Must define the name to qualify to extra-defined RocketMQTemplate bean.
private RocketMQTemplate extRocketMQTemplate;
// you can use the template as normal.
```
1. How do I create a consumer Listener with different name-server other than the global Spring configuration 'rocketmq.name-server' ?
```java
@Service
@RocketMQMessageListener(
nameServer = "NEW-NAMESERVER-LIST", // define new nameServer list
topic = "test-topic-1",
consumerGroup = "my-consumer_test-topic-1",
enableMsgTrace = true,
customizedTraceTopic = "my-trace-topic"
)
public class MyNameServerConsumer implements RocketMQListener<String> {
...
}
```

391
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/README_zh_CN.md

@ -0,0 +1,391 @@
# RocketMQ-Spring [![Build Status](https://travis-ci.org/apache/rocketmq-spring.svg?branch=master)](https://travis-ci.org/apache/rocketmq-spring)
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.apache.rocketmq/rocketmq-spring-all/badge.svg)](https://search.maven.org/search?q=g:org.apache.rocketmq%20AND%20a:rocketmq-spring-all)
[![GitHub release](https://img.shields.io/badge/release-download-orange.svg)](https://github.com/apache/rocketmq-spring/releases)
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
[English](./README.md)
帮助开发者在[Spring Boot](http://projects.spring.io/spring-boot/)中快速集成[RocketMQ](http://rocketmq.apache.org/)。支持Spring Message规范,方便开发者从其它MQ快速切换到RocketMQ。
## 如何贡献和帮助社区
我们永远欢迎开发者的帮助来使这个项目更加完善,无论是小的文档还是大的功能新特性,请参考RocketMQ的主站了解[细节](http://rocketmq.apache.org/docs/how-to-contribute/)
## 前提条件
- JDK 1.8 and above
- [Maven](http://maven.apache.org/) 3.0 and above
功能特性:
- [x] 同步发送
- [x] 同步顺序发送
- [x] 同步批量发送
- [x] 异步发送
- [x] 异步顺序发送
- [x] 顺序消费
- [x] 并发消费(广播/集群)
- [x] one-way方式发送
- [x] 事务方式发送
- [x] 消息轨迹
- [x] ACL
- [ ] pull消费
## Quick Start
下面列出来了一些关键点,完整的示例请参考: [rocketmq-spring-boot-samples](rocketmq-spring-boot-samples)
注意:当前的RELEASE.VERSION=2.0.3
```xml
<!--在pom.xml中添加依赖-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${RELEASE.VERSION}</version>
</dependency>
```
### 发送消息
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=my-group
```
> 注意:
>
> 请将上述示例配置中的`127.0.0.1:9876`替换成真实RocketMQ的NameServer地址与端口
```java
@SpringBootApplication
public class ProducerApplication implements CommandLineRunner{
@Resource
private RocketMQTemplate rocketMQTemplate;
public static void main(String[] args){
SpringApplication.run(ProducerApplication.class, args);
}
public void run(String... args) throws Exception {
rocketMQTemplate.convertAndSend("test-topic-1", "Hello, World!");
rocketMQTemplate.send("test-topic-1", MessageBuilder.withPayload("Hello, World! I'm from spring message").build());
rocketMQTemplate.convertAndSend("test-topic-2", new OrderPaidEvent("T_001", new BigDecimal("88.00")));
// rocketMQTemplate.destroy(); // notes: once rocketMQTemplate be destroyed, you can not send any message again with this rocketMQTemplate
}
@Data
@AllArgsConstructor
public class OrderPaidEvent implements Serializable{
private String orderId;
private BigDecimal paidMoney;
}
}
```
### 在发送客户端发送事务性消息并且实现回查Listener
```java
@SpringBootApplication
public class ProducerApplication implements CommandLineRunner{
@Resource
private RocketMQTemplate rocketMQTemplate;
public static void main(String[] args){
SpringApplication.run(ProducerApplication.class, args);
}
public void run(String... args) throws Exception {
try {
// Build a SpringMessage for sending in transaction
Message msg = MessageBuilder.withPayload(..)...
// In sendMessageInTransaction(), the first parameter transaction name ("test")
// must be same with the @RocketMQTransactionListener's member field 'transName'
rocketMQTemplate.sendMessageInTransaction("test", "test-topic" msg, null);
} catch (MQClientException e) {
e.printStackTrace(System.out);
}
}
// Define transaction listener with the annotation @RocketMQTransactionListener
@RocketMQTransactionListener(transName="test")
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
// ... local transaction process, return bollback, commit or unknown
return RocketMQLocalTransactionState.UNKNOWN;
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
// ... check transaction status and return bollback, commit or unknown
return RocketMQLocalTransactionState.COMMIT;
}
}
}
```
> 更多发送相关配置
>
> ```properties
> rocketmq.producer.send-message-timeout=300000
> rocketmq.producer.compress-message-body-threshold=4096
> rocketmq.producer.max-message-size=4194304
> rocketmq.producer.retry-times-when-send-async-failed=0
> rocketmq.producer.retry-next-server=true
> rocketmq.producer.retry-times-when-send-failed=2
> ```
### 接收消息
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
```
> 注意:
>
> 请将上述示例配置中的`127.0.0.1:9876`替换成真实RocketMQ的NameServer地址与端口
```java
@SpringBootApplication
public class ConsumerApplication{
public static void main(String[] args){
SpringApplication.run(ConsumerApplication.class, args);
}
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
public class MyConsumer1 implements RocketMQListener<String>{
public void onMessage(String message) {
log.info("received message: {}", message);
}
}
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-2", consumerGroup = "my-consumer_test-topic-2")
public class MyConsumer2 implements RocketMQListener<OrderPaidEvent>{
public void onMessage(OrderPaidEvent orderPaidEvent) {
log.info("received orderPaidEvent: {}", orderPaidEvent);
}
}
}
```
> 更多消费相关配置
>
> see: [RocketMQMessageListener](rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/RocketMQMessageListener.java)
### 消息轨迹
Producer 端要想使用消息轨迹,需要多配置两个配置项:
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=my-group
rocketmq.producer.enable-msg-trace=true
rocketmq.producer.customized-trace-topic=my-trace-topic
```
Consumer 端消息轨迹的功能需要在 `@RocketMQMessageListener` 中进行配置对应的属性:
```
@Service
@RocketMQMessageListener(
topic = "test-topic-1",
consumerGroup = "my-consumer_test-topic-1",
enableMsgTrace = true,
customizedTraceTopic = "my-trace-topic"
)
public class MyConsumer implements RocketMQListener<String> {
...
}
```
> 注意:
>
> 默认情况下 Producer 和 Consumer 的消息轨迹功能是开启的且 trace-topic 为 RMQ_SYS_TRACE_TOPIC
> Consumer 端的消息轨迹 trace-topic 可以在配置文件中配置 `rocketmq.consumer.customized-trace-topic` 配置项,不需要为在每个 `@RocketMQTransactionListener` 配置
### ACL
Producer 端要想使用 ACL 功能,需要多配置两个配置项:
```properties
## application.properties
rocketmq.name-server=127.0.0.1:9876
rocketmq.producer.group=my-group
rocketmq.producer.access-key=AK
rocketmq.producer.secret-key=SK
```
事务消息的发送需要在 `@RocketMQTransactionListener` 注解里配置上 AK/SK:
```
@RocketMQTransactionListener(
txProducerGroup = "test,
accessKey = "AK",
secretKey = "SK"
)
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
...
}
```
> 注意:
>
> 可以不用为每个 `@RocketMQTransactionListener` 注解配置 AK/SK,在配置文件中配置 `rocketmq.producer.access-key``rocketmq.producer.secret-key` 配置项,这两个配置项的值就是默认值
Consumer 端 ACL 功能需要在 `@RocketMQMessageListener` 中进行配置
```
@Service
@RocketMQMessageListener(
topic = "test-topic-1",
consumerGroup = "my-consumer_test-topic-1",
accessKey = "AK",
secretKey = "SK"
)
public class MyConsumer implements RocketMQListener<String> {
...
}
```
> 注意:
>
> 可以不用为每个 `@RocketMQMessageListener` 注解配置 AK/SK,在配置文件中配置 `rocketmq.consumer.access-key``rocketmq.consumer.secret-key` 配置项,这两个配置项的值就是默认值
## FAQ
1. 生产环境有多个`nameserver`该如何连接?
`rocketmq.name-server`支持配置多个`nameserver`地址,采用`;`分隔即可。例如:`172.19.0.1:9876;172.19.0.2:9876`
1. `rocketMQTemplate`在什么时候被销毁?
开发者在项目中使用`rocketMQTemplate`发送消息时,不需要手动执行`rocketMQTemplate.destroy()`方法, `rocketMQTemplate`会在spring容器销毁时自动销毁。
1. 启动报错:`Caused by: org.apache.rocketmq.client.exception.MQClientException: The consumer group[xxx] has been created before, specify another name please`
RocketMQ在设计时就不希望一个消费者同时处理多个类型的消息,因此同一个`consumerGroup`下的consumer职责应该是一样的,不要干不同的事情(即消费多个topic)。建议`consumerGroup`与`topic`一一对应。
1. 发送的消息内容体是如何被序列化与反序列化的?
RocketMQ的消息体都是以`byte[]`方式存储。当业务系统的消息内容体如果是`java.lang.String`类型时,统一按照`utf-8`编码转成`byte[]`;如果业务系统的消息内容为非`java.lang.String`类型,则采用[jackson-databind](https://github.com/FasterXML/jackson-databind)序列化成`JSON`格式的字符串之后,再统一按照`utf-8`编码转成`byte[]`。
1. 如何指定topic的`tags`?
RocketMQ的最佳实践中推荐:一个应用尽可能用一个Topic,消息子类型用`tags`来标识,`tags`可以由应用自由设置。
在使用`rocketMQTemplate`发送消息时,通过设置发送方法的`destination`参数来设置消息的目的地,`destination`的格式为`topicName:tagName`,`:`前面表示topic的名称,后面表示`tags`名称。
> 注意:
>
> `tags`从命名来看像是一个复数,但发送消息时,目的地只能指定一个topic下的一个`tag`,不能指定多个。
1. 发送消息时如何设置消息的`key`?
可以通过重载的`xxxSend(String destination, Message<?> msg, ...)`方法来发送消息,指定`msg`的`headers`来完成。示例:
```java
Message<?> message = MessageBuilder.withPayload(payload).setHeader(MessageConst.PROPERTY_KEYS, msgId).build();
rocketMQTemplate.send("topic-test", message);
```
同理还可以根据上面的方式来设置消息的`FLAG`、`WAIT_STORE_MSG_OK`以及一些用户自定义的其它头信息。
> 注意:
>
> 在将Spring的Message转化为RocketMQ的Message时,为防止`header`信息与RocketMQ的系统属性冲突,在所有`header`的名称前面都统一添加了前缀`USERS_`。因此在消费时如果想获取自定义的消息头信息,请遍历头信息中以`USERS_`开头的key即可。
1. 消费消息时,除了获取消息`payload`外,还想获取RocketMQ消息的其它系统属性,需要怎么做?
消费者在实现`RocketMQListener`接口时,只需要起泛型为`MessageExt`即可,这样在`onMessage`方法将接收到RocketMQ原生的`MessageExt`消息。
```java
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
public class MyConsumer2 implements RocketMQListener<MessageExt>{
public void onMessage(MessageExt messageExt) {
log.info("received messageExt: {}", messageExt);
}
}
```
1. 如何指定消费者从哪开始消费消息,或开始消费的位置?
消费者默认开始消费的位置请参考:[RocketMQ FAQ](http://rocketmq.apache.org/docs/faq/)。
若想自定义消费者开始的消费位置,只需在消费者类添加一个`RocketMQPushConsumerLifecycleListener`接口的实现即可。 示例如下:
```java
@Slf4j
@Service
@RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
public class MyConsumer1 implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(String message) {
log.info("received message: {}", message);
}
@Override
public void prepareStart(final DefaultMQPushConsumer consumer) {
// set consumer consume message from now
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
consumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
}
}
```
同理,任何关于`DefaultMQPushConsumer`的更多其它其它配置,都可以采用上述方式来完成。
1. 如何发送事务消息(即半消息支持分布式事务)?
在客户端,首先用户需要实现RocketMQLocalTransactionListener接口,并在接口类上注解声明@RocketMQTransactionListener,实现确认和回查方法;然后再使用资源模板RocketMQTemplate,
调用方法sendMessageInTransaction()来进行消息的发布。 注意:这个方法通过指定发送者组名与具体的声明了txProducerGroup的TransactionListener进行关联,您也可以不指定这个值,从而使用默认的事务发送者组。
1. 如何声明不同name-server或者其他特定的属性来定义非标的RocketMQTemplate?
```java
// 第一步: 定义非标的RocketMQTemplate使用你需要的属性,注意,这里的'nameServer'属性必须要定义,并且其取值不能与全局配置属性'rocketmq.name-server'相同
// 也可以定义其他属性,如果不定义,它们取全局的配置属性值或默认值。
// 这个RocketMQTemplate的Spring Bean名是'extRocketMQTemplate', 与所定义的类名相同(但首字母小写)
@ExtRocketMQTemplateConfiguration(nameServer="127.0.0.1:9876"
, ... // 定义其他属性,如果有必要。
)
public class ExtRocketMQTemplate extends RocketMQTemplate {
//类里面不需要做任何修改
}
// 第二步: 使用这个非标RocketMQTemplate
@Resource(name = "extRocketMQTemplate") // 这里必须定义name属性来指向上具体的Spring Bean.
private RocketMQTemplate extRocketMQTemplate;
// 接下来就可以正常使用这个extRocketMQTemplate了.
```
1. MessageListener消费端,是否可以指定不同的name-server而不是使用全局定义的'rocketmq.name-server'属性值 ?
```java
@Service
@RocketMQMessageListener(
nameServer = "NEW-NAMESERVER-LIST", // 可以使用这个optional属性来指定不同的name-server
topic = "test-topic-1",
consumerGroup = "my-consumer_test-topic-1",
enableMsgTrace = true,
customizedTraceTopic = "my-trace-topic"
)
public class MyNameServerConsumer implements RocketMQListener<String> {
...
}
```

222
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/pom.xml

@ -0,0 +1,222 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache</groupId>
<artifactId>apache</artifactId>
<version>18</version>
</parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-all</artifactId>
<version>2.0.3</version>
<packaging>pom</packaging>
<name>Apache RocketMQ Spring Boot ${project.version}</name>
<description>Build for Apache RocketMQ Spring Boot Support</description>
<url>https://github.com/apache/rocketmq-spring</url>
<scm>
<url>git@github.com:apache/rocketmq-spring.git</url>
<connection>scm:git:git@github.com:apache/rocketmq-spring.git</connection>
<developerConnection>scm:git:git@github.com:apache/rocketmq-spring.git</developerConnection>
<tag>rocketmq-spring-all-2.0.3</tag>
</scm>
<mailingLists>
<mailingList>
<name>Development List</name>
<subscribe>dev-subscribe@rocketmq.apache.org</subscribe>
<unsubscribe>dev-unsubscribe@rocketmq.apache.org</unsubscribe>
<post>dev@rocketmq.apache.org</post>
</mailingList>
<mailingList>
<name>User List</name>
<subscribe>users-subscribe@rocketmq.apache.org</subscribe>
<unsubscribe>users-unsubscribe@rocketmq.apache.org</unsubscribe>
<post>users@rocketmq.apache.org</post>
</mailingList>
<mailingList>
<name>Commits List</name>
<subscribe>commits-subscribe@rocketmq.apache.org</subscribe>
<unsubscribe>commits-unsubscribe@rocketmq.apache.org</unsubscribe>
<post>commits@rocketmq.apache.org</post>
</mailingList>
</mailingLists>
<organization>
<name>Apache Software Foundation</name>
<url>http://www.apache.org</url>
</organization>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
<comments>A business-friendly OSS license</comments>
</license>
</licenses>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<excludes>src/main/resources</excludes>
<configLocation>style/rmq_checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.7.8</version>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco.exec</destFile>
</configuration>
</execution>
<execution>
<id>default-prepare-agent-integration</id>
<phase>pre-integration-test</phase>
<goals>
<goal>prepare-agent-integration</goal>
</goals>
<configuration>
<destFile>${project.build.directory}/jacoco-it.exec</destFile>
<propertyName>failsafeArgLine</propertyName>
</configuration>
</execution>
<execution>
<id>default-report</id>
<goals>
<goal>report</goal>
</goals>
</execution>
<execution>
<id>default-report-integration</id>
<goals>
<goal>report-integration</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<skipAfterFailureCount>1</skipAfterFailureCount>
<forkCount>1</forkCount>
<reuseForks>true</reuseForks>
<excludes>
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
</plugin>
<plugin>
<groupId>org.sonarsource.scanner.maven</groupId>
<artifactId>sonar-maven-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
<version>0.12</version>
<configuration>
<excludes>
<exclude>.gitignore</exclude>
<exclude>.travis.yml</exclude>
<exclude>CONTRIBUTING.md</exclude>
<exclude>**/README.md</exclude>
<exclude>**/README_zh_CN.md</exclude>
<exclude>.github/**</exclude>
<exclude>src/test/resources/certs/*</exclude>
<exclude>src/test/**/*.log</exclude>
<exclude>src/test/resources/META-INF/service/*</exclude>
<exclude>**/target/**</exclude>
<exclude>*/*.iml</exclude>
<exclude>**/*/spring.factories</exclude>
<exclude>**/application.properties</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.eluder.coveralls</groupId>
<artifactId>coveralls-maven-plugin</artifactId>
<version>4.3.0</version>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.0.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<profiles>
<profile>
<id>sonar-apache</id>
<properties>
<!-- URL of the ASF SonarQube server -->
<sonar.host.url>https://builds.apache.org/analysis</sonar.host.url>
</properties>
</profile>
</profiles>
<modules>
<module>rocketmq-spring-boot-parent</module>
<module>rocketmq-spring-boot</module>
<module>rocketmq-spring-boot-starter</module>
<!-- Note: The samples need to mvn compiple in its own directory
<module>rocketmq-spring-boot-samples</module>
-->
</modules>
</project>

167
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-parent/pom.xml

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-all</artifactId>
<version>2.0.3</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>rocketmq-spring-boot-parent</artifactId>
<packaging>pom</packaging>
<name>RocketMQ Spring Boot Parent</name>
<description>Parent package for Apache RocketMQ Spring Boot Support</description>
<url>https://github.com/apache/rocketmq-spring</url>
<properties>
<project.rootdir>${project.basedir}/..</project.rootdir>
<spring.boot.version>2.0.5.RELEASE</spring.boot.version>
<spring.version>5.1.0.RELEASE</spring.version>
<rocketmq.spring.boot.version>2.0.3</rocketmq.spring.boot.version>
<rocketmq-version>4.5.1</rocketmq-version>
<slf4j.version>1.7.25</slf4j.version>
<jackson.version>2.9.7</jackson.version>
<java.version>1.8</java.version>
<resource.delimiter>@</resource.delimiter>
<!-- Delimiter that doesn't clash with Spring ${} placeholders -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.source>${java.version}</maven.compiler.source>
<maven.compiler.target>${java.version}</maven.compiler.target>
<additionalparam>-Xdoclint:none</additionalparam>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<!-- Exclude all generated code -->
<sonar.jacoco.itReportPath>${project.basedir}/../test/target/jacoco-it.exec</sonar.jacoco.itReportPath>
<sonar.exclusions>file:**/generated-sources/**,**/test/**</sonar.exclusions>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${spring.boot.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot</artifactId>
<version>${rocketmq.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>${rocketmq-version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-acl</artifactId>
<version>${rocketmq-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

202
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/LICENSE

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

34
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/README.md

@ -0,0 +1,34 @@
# rocketmq-spring-boot-samples
[中文](./README_zh_CN.md)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
It's a demo project for how to use [rocketmq-spring-boot](https://github.com/apache/rocketmq-spring)
Run the test case locally
1. build and install the rocketmq-spring-boot-starter
2. startup rocketmq according to quick-start, verify the namesvr and broker startup correctly, Note: DON'T do "Shutdown Servers" step.
http://rocketmq.apache.org/docs/quick-start/
3. create topics for the demo test cases
```
bash bin/mqadmin updateTopic -c DefaultCluster -t string-topic
bash bin/mqadmin updateTopic -c DefaultCluster -t order-paid-topic
bash bin/mqadmin updateTopic -c DefaultCluster -t message-ext-topic
bash bin/mqadmin updateTopic -c DefaultCluster -t spring-transaction-topic
```
4. run tests
```
# open a terminal, run produce
cd rocketmq-produce-demo
mvn clean package
java -jar target/rocketmq-produce-demo-0.0.1-SNAPSHOT.jar
# open another terminal, run consume
cd rocketmq-consume-demo
mvn clean package
java -jar target/rocketmq-consume-demo-0.0.1-SNAPSHOT.jar
```

40
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/README_zh_CN.md

@ -0,0 +1,40 @@
# rocketmq-spring-boot-samples
[English](./README.md)
[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
这里是一个使用rocketmq-spring-boot-starter的例子。 [rocketmq-spring-boot](https://github.com/apache/rocketmq-spring)
## 在本地运行这个测试例子
1. 如上面注意项所述,需要开发者在本地build并安装rocketmq-spring-boot-starter
2. 根据RocketMQ官网的quick-start来启动NameServer和Broker,并验证是否启动正确。注意: 测试期间不要停止Broker或者NameServer
http://rocketmq.apache.org/docs/quick-start/
3. 创建测试例子所需要的Topic
```
cd YOUR_ROCKETMQ_HOME
bash bin/mqadmin updateTopic -c DefaultCluster -t string-topic
bash bin/mqadmin updateTopic -c DefaultCluster -t order-paid-topic
bash bin/mqadmin updateTopic -c DefaultCluster -t message-ext-topic
bash bin/mqadmin updateTopic -c DefaultCluster -t spring-transaction-topic
```
4. 编译并运行测试例子
```
# 打开一个终端窗口,编译并启动发送端
cd rocketmq-produce-demo
mvn clean package
java -jar target/rocketmq-produce-demo-0.0.1-SNAPSHOT.jar
# 打开另一个终端窗口,编译并启动消费端
cd rocketmq-consume-demo
mvn clean package
java -jar target/rocketmq-consume-demo-0.0.1-SNAPSHOT.jar
```
结合测试代码,观察窗口中消息的发送和接收情况

91
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/pom.xml

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-samples</artifactId>
<packaging>pom</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>RocketMQ Spring Boot Samples</name>
<description>Samples for RocketMQ Spring Boot</description>
<url>https://github.com/apache/rocketmq-spring</url>
<modules>
<module>rocketmq-produce-demo</module>
<module>rocketmq-consume-demo</module>
<module>rocketmq-produce-acl-demo</module>
<module>rocketmq-consume-acl-demo</module>
</modules>
<properties>
<rocketmq-spring-boot-starter-version>2.0.3</rocketmq-spring-boot-starter-version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>${rocketmq-spring-boot-starter-version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>2.17</version>
<executions>
<execution>
<id>validate</id>
<phase>validate</phase>
<configuration>
<skip>${disable.checks}</skip>
<excludes>src/main/resources</excludes>
<configLocation>style/rmq_checkstyle.xml</configLocation>
<encoding>UTF-8</encoding>
<consoleOutput>true</consoleOutput>
<failsOnError>true</failsOnError>
</configuration>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.0.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

31
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/pom.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-samples</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>rocketmq-consume-acl-demo</artifactId>
</project>

39
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ACLStringConsumer.java

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* RocketMQMessageListener
*/
@Service
@RocketMQMessageListener(
topic = "normal_topic_define_in_Aliware_MQ",
consumerGroup = "group_define_in_Aliware_MQ"
//accessKey = "AK" // It will read by `rocketmq.consumer.access-key` key
//secretKey = "SK" // It will read by `rocketmq.consumer.access-key` key
)
public class ACLStringConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.printf("------- ACL StringConsumer received: %s \n", message);
}
}

39
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ACLStringTransactionalConsumer.java

@ -0,0 +1,39 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* StringTransactionalConsumer
*/
@Service
@RocketMQMessageListener(
topic = "${demo.rocketmq.transTopic}",
consumerGroup = "group_define_in_Aliware_MQ",
accessKey = "AK", // if accessKey is empty, it will read by `rocketmq.consumer.access-key` key
secretKey = "SK" // if accessKey is empty, it will read by `rocketmq.consumer.secret-key` key
)
public class ACLStringTransactionalConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.printf("------- ACL StringTransactionalConsumer received: %s \n", message);
}
}

33
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ConsumerACLApplication.java

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* ConsumerApplication
*/
@SpringBootApplication
public class ConsumerACLApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerACLApplication.class, args);
}
}

10
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-acl-demo/src/main/resources/application.properties

@ -0,0 +1,10 @@
spring.application.name=rocketmq-consume-acl-demo
rocketmq.name-server=Endpoint_of_Aliware_MQ
rocketmq.topic=normal_topic_define_in_Aliware_MQ
# properties used in application code
demo.rocketmq.transTopic=transaction_topic_define_in_Aliware_MQ
rocketmq.consumer.access-key=AK
rocketmq.consumer.secret-key=SK

31
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/pom.xml

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-samples</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>rocketmq-consume-demo</artifactId>
</project>

33
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/ConsumerApplication.java

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* ConsumerApplication
*/
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}

44
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/Checker.java

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.consumer;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
/**
* Note: This is a nagitive testing. It aims to tell user the fact that
* the @RocketMQTransactionListener can not be used on consumer side!!!
*
* <p>How to try it? just uncomment the annotation declaration, then compile
* and run the consumer, it will fail to start.
*/
//@RocketMQTransactionListener
public class Checker implements TransactionListener {
@Override
public LocalTransactionState executeLocalTransaction(Message message, Object o) {
return null;
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
return null;
}
}

46
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/MessageExtConsumer.java

@ -0,0 +1,46 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.consumer;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.common.consumer.ConsumeFromWhere;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.springframework.stereotype.Service;
/**
* MessageExtConsumer, consume listener impl class.
*/
@Service
@RocketMQMessageListener(topic = "message-ext-topic", selectorExpression = "tag1", consumerGroup = "${spring.application.name}-message-ext-consumer")
public class MessageExtConsumer implements RocketMQListener<MessageExt>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(MessageExt message) {
System.out.printf("------- MessageExtConsumer received message, msgId: %s, body:%s \n", message.getMsgId(), new String(message.getBody()));
}
@Override
public void prepareStart(DefaultMQPushConsumer consumer) {
// set consumer consume message from now
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
consumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
}
}

36
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/OrderPaidEventConsumer.java

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.consumer;
import org.apache.rocketmq.samples.springboot.domain.OrderPaidEvent;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* OrderPaidEventConsumer
*/
@Service
@RocketMQMessageListener(topic = "${demo.rocketmq.orderTopic}", consumerGroup = "order-paid-consumer")
public class OrderPaidEventConsumer implements RocketMQListener<OrderPaidEvent> {
@Override
public void onMessage(OrderPaidEvent orderPaidEvent) {
System.out.printf("------- OrderPaidEventConsumer received: %s \n", orderPaidEvent);
}
}

34
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/StringConsumer.java

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.consumer;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* RocketMQMessageListener
*/
@Service
@RocketMQMessageListener(topic = "${demo.rocketmq.topic}", consumerGroup = "string_consumer")
public class StringConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.printf("------- StringConsumer received: %s \n", message);
}
}

34
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/StringConsumerNewNS.java

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.consumer;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* RocketMQMessageListener
*/
@Service
@RocketMQMessageListener(nameServer = "${demo.rocketmq.myNameServer}", topic = "${demo.rocketmq.topic}", consumerGroup = "string_consumer")
public class StringConsumerNewNS implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.printf("------- StringConsumerNewNS received: %s \n", message);
}
}

34
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/consumer/StringTransactionalConsumer.java

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.consumer;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.stereotype.Service;
/**
* StringTransactionalConsumer
*/
@Service
@RocketMQMessageListener(topic = "${demo.rocketmq.transTopic}", consumerGroup = "string_trans_consumer")
public class StringTransactionalConsumer implements RocketMQListener<String> {
@Override
public void onMessage(String message) {
System.out.printf("------- StringTransactionalConsumer received: %s \n", message);
}
}

54
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/java/org/apache/rocketmq/samples/springboot/domain/OrderPaidEvent.java

@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.domain;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* OrderPaidEvent
*/
public class OrderPaidEvent implements Serializable {
private String orderId;
private BigDecimal paidMoney;
public OrderPaidEvent() {
}
public OrderPaidEvent(String orderId, BigDecimal paidMoney) {
this.orderId = orderId;
this.paidMoney = paidMoney;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public BigDecimal getPaidMoney() {
return paidMoney;
}
public void setPaidMoney(BigDecimal paidMoney) {
this.paidMoney = paidMoney;
}
}

12
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-consume-demo/src/main/resources/application.properties

@ -0,0 +1,12 @@
spring.application.name=rocketmq-consume-demo
rocketmq.name-server=localhost:9876
# properties used in application code
demo.rocketmq.topic=string-topic
demo.rocketmq.orderTopic=order-paid-topic
demo.rocketmq.msgExtTopic=message-ext-topic
demo.rocketmq.transTopic=spring-transaction-topic
# another nameserver different global
demo.rocketmq.myNameServer=127.0.0.1:9876

32
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-acl-demo/pom.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-samples</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>rocketmq-produce-acl-demo</artifactId>
</project>

151
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-acl-demo/src/main/java/org/apache/rocketmq/samples/springboot/ProducerACLApplication.java

@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Resource;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.support.MessageBuilder;
/**
* Producer, using RocketMQTemplate sends a variety of messages
*/
@SpringBootApplication
public class ProducerACLApplication implements CommandLineRunner {
private static final String TX_PGROUP_NAME = "myTxProducerGroup";
@Resource
private RocketMQTemplate rocketMQTemplate;
@Value("${demo.rocketmq.transTopic}")
private String springTransTopic;
@Value("${demo.rocketmq.topic}")
private String springTopic;
public static void main(String[] args) {
SpringApplication.run(ProducerACLApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// Send string
SendResult sendResult = rocketMQTemplate.syncSend(springTopic + ":acl", "Hello, ACL Msg!");
System.out.printf("syncSend1 to topic %s sendResult=%s %n", springTopic, sendResult);
// Send string with spring Message
sendResult = rocketMQTemplate.syncSend(springTopic, MessageBuilder.withPayload("Hello, World! I'm from spring message & ACL Msg").build());
System.out.printf("syncSend2 to topic %s sendResult=%s %n", springTopic, sendResult);
//Send transactional messages
testTransaction();
}
private void testTransaction() throws MessagingException {
String[] tags = new String[]{"TagA", "TagB", "TagC", "TagD", "TagE"};
for (int i = 0; i < 10; i++) {
try {
Message msg = MessageBuilder.withPayload("Hello RocketMQ " + i).
setHeader(RocketMQHeaders.KEYS, "KEY_" + i).build();
SendResult sendResult = rocketMQTemplate.sendMessageInTransaction(TX_PGROUP_NAME,
springTransTopic + ":" + tags[i % tags.length], msg, null);
System.out.printf("------ send Transactional msg body = %s , sendResult=%s %n",
msg.getPayload(), sendResult.getSendStatus());
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@RocketMQTransactionListener(
txProducerGroup = TX_PGROUP_NAME,
accessKey = "AK", // if not setting, it will read by `rocketmq.producer.access-key` key
secretKey = "SK" // if not setting, it will read by `rocketmq.producer.secret-key` key
)
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
private AtomicInteger transactionIndex = new AtomicInteger(0);
private ConcurrentHashMap<String, Integer> localTrans = new ConcurrentHashMap<String, Integer>();
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
String transId = (String)msg.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
System.out.printf("#### executeLocalTransaction is executed, msgTransactionId=%s %n",
transId);
int value = transactionIndex.getAndIncrement();
int status = value % 3;
localTrans.put(transId, status);
if (status == 0) {
// Return local transaction with success(commit), in this case,
// this message will not be checked in checkLocalTransaction()
System.out.printf(" # COMMIT # Simulating msg %s related local transaction exec succeeded! ### %n", msg.getPayload());
return RocketMQLocalTransactionState.COMMIT;
}
if (status == 1) {
// Return local transaction with failure(rollback) , in this case,
// this message will not be checked in checkLocalTransaction()
System.out.printf(" # ROLLBACK # Simulating %s related local transaction exec failed! %n", msg.getPayload());
return RocketMQLocalTransactionState.ROLLBACK;
}
System.out.printf(" # UNKNOW # Simulating %s related local transaction exec UNKNOWN! \n");
return RocketMQLocalTransactionState.UNKNOWN;
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
String transId = (String)msg.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
RocketMQLocalTransactionState retState = RocketMQLocalTransactionState.COMMIT;
Integer status = localTrans.get(transId);
if (null != status) {
switch (status) {
case 0:
retState = RocketMQLocalTransactionState.UNKNOWN;
break;
case 1:
retState = RocketMQLocalTransactionState.COMMIT;
break;
case 2:
retState = RocketMQLocalTransactionState.COMMIT;
break;
}
}
System.out.printf("------ !!! checkLocalTransaction is executed once," +
" msgTransactionId=%s, TransactionState=%s status=%s %n",
transId, retState, status);
return retState;
}
}
}

7
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-acl-demo/src/main/resources/application.properties

@ -0,0 +1,7 @@
rocketmq.name-server=Endpoint_of_Aliware_MQ
rocketmq.producer.group=my-group1
rocketmq.producer.access-key=AK
rocketmq.producer.secret-key=SK
demo.rocketmq.topic=normal_topic_define_in_Aliware_MQ
demo.rocketmq.transTopic=transaction_topic_define_in_Aliware_MQ

32
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/pom.xml

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-samples</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>rocketmq-produce-demo</artifactId>
</project>

24
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/java/org/apache/rocketmq/samples/springboot/ExtRocketMQTemplate.java

@ -0,0 +1,24 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import org.apache.rocketmq.spring.annotation.ExtRocketMQTemplateConfiguration;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
@ExtRocketMQTemplateConfiguration(nameServer = "${demo.rocketmq.extNameServer}")
public class ExtRocketMQTemplate extends RocketMQTemplate {
}

195
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/java/org/apache/rocketmq/samples/springboot/ProducerApplication.java

@ -0,0 +1,195 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.samples.springboot.domain.OrderPaidEvent;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.support.MessageBuilder;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Producer, using RocketMQTemplate sends a variety of messages
*/
@SpringBootApplication
public class ProducerApplication implements CommandLineRunner {
private static final String TX_PGROUP_NAME = "myTxProducerGroup";
@Resource
private RocketMQTemplate rocketMQTemplate;
@Value("${demo.rocketmq.transTopic}")
private String springTransTopic;
@Value("${demo.rocketmq.topic}")
private String springTopic;
@Value("${demo.rocketmq.orderTopic}")
private String orderPaidTopic;
@Value("${demo.rocketmq.msgExtTopic}")
private String msgExtTopic;
@Resource(name = "extRocketMQTemplate")
private RocketMQTemplate extRocketMQTemplate;
public static void main(String[] args) {
SpringApplication.run(ProducerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
// Send string
SendResult sendResult = rocketMQTemplate.syncSend(springTopic, "Hello, World!");
System.out.printf("syncSend1 to topic %s sendResult=%s %n", springTopic, sendResult);
// Use the extRocketMQTemplate
sendResult = extRocketMQTemplate.syncSend(springTopic, "Hello, World!");
System.out.printf("extRocketMQTemplate.syncSend1 to topic %s sendResult=%s %n", springTopic, sendResult);
// Send string with spring Message
sendResult = rocketMQTemplate.syncSend(springTopic, MessageBuilder.withPayload("Hello, World! I'm from spring message").build());
System.out.printf("syncSend2 to topic %s sendResult=%s %n", springTopic, sendResult);
// Send user-defined object
rocketMQTemplate.asyncSend(orderPaidTopic, new OrderPaidEvent("T_001", new BigDecimal("88.00")), new SendCallback() {
public void onSuccess(SendResult var1) {
System.out.printf("async onSucess SendResult=%s %n", var1);
}
public void onException(Throwable var1) {
System.out.printf("async onException Throwable=%s %n", var1);
}
});
// Send message with special tag
rocketMQTemplate.convertAndSend(msgExtTopic + ":tag0", "I'm from tag0"); // tag0 will not be consumer-selected
System.out.printf("syncSend topic %s tag %s %n", msgExtTopic, "tag0");
rocketMQTemplate.convertAndSend(msgExtTopic + ":tag1", "I'm from tag1");
System.out.printf("syncSend topic %s tag %s %n", msgExtTopic, "tag1");
// Send a batch of strings
testBatchMessages();
// Send transactional messages
testTransaction();
}
private void testBatchMessages() {
List<Message> msgs = new ArrayList<Message>();
for (int i = 0; i < 10; i++) {
msgs.add(MessageBuilder.withPayload("Hello RocketMQ Batch Msg#" + i).
setHeader(RocketMQHeaders.KEYS, "KEY_" + i).build());
}
SendResult sr = rocketMQTemplate.syncSend(springTopic, msgs, 60000);
System.out.printf("--- Batch messages send result :" + sr);
}
private void testTransaction() throws MessagingException {
String[] tags = new String[]{"TagA", "TagB", "TagC", "TagD", "TagE"};
for (int i = 0; i < 10; i++) {
try {
Message msg = MessageBuilder.withPayload("Hello RocketMQ " + i).
setHeader(RocketMQHeaders.KEYS, "KEY_" + i).build();
SendResult sendResult = rocketMQTemplate.sendMessageInTransaction(TX_PGROUP_NAME,
springTransTopic + ":" + tags[i % tags.length], msg, null);
System.out.printf("------ send Transactional msg body = %s , sendResult=%s %n",
msg.getPayload(), sendResult.getSendStatus());
Thread.sleep(10);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@RocketMQTransactionListener(txProducerGroup = TX_PGROUP_NAME)
class TransactionListenerImpl implements RocketMQLocalTransactionListener {
private AtomicInteger transactionIndex = new AtomicInteger(0);
private ConcurrentHashMap<String, Integer> localTrans = new ConcurrentHashMap<String, Integer>();
@Override
public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
String transId = (String)msg.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
System.out.printf("#### executeLocalTransaction is executed, msgTransactionId=%s %n",
transId);
int value = transactionIndex.getAndIncrement();
int status = value % 3;
localTrans.put(transId, status);
if (status == 0) {
// Return local transaction with success(commit), in this case,
// this message will not be checked in checkLocalTransaction()
System.out.printf(" # COMMIT # Simulating msg %s related local transaction exec succeeded! ### %n", msg.getPayload());
return RocketMQLocalTransactionState.COMMIT;
}
if (status == 1) {
// Return local transaction with failure(rollback) , in this case,
// this message will not be checked in checkLocalTransaction()
System.out.printf(" # ROLLBACK # Simulating %s related local transaction exec failed! %n", msg.getPayload());
return RocketMQLocalTransactionState.ROLLBACK;
}
System.out.printf(" # UNKNOW # Simulating %s related local transaction exec UNKNOWN! \n");
return RocketMQLocalTransactionState.UNKNOWN;
}
@Override
public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
String transId = (String)msg.getHeaders().get(RocketMQHeaders.TRANSACTION_ID);
RocketMQLocalTransactionState retState = RocketMQLocalTransactionState.COMMIT;
Integer status = localTrans.get(transId);
if (null != status) {
switch (status) {
case 0:
retState = RocketMQLocalTransactionState.UNKNOWN;
break;
case 1:
retState = RocketMQLocalTransactionState.COMMIT;
break;
case 2:
retState = RocketMQLocalTransactionState.ROLLBACK;
break;
}
}
System.out.printf("------ !!! checkLocalTransaction is executed once," +
" msgTransactionId=%s, TransactionState=%s status=%s %n",
transId, retState, status);
return retState;
}
}
}

50
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/java/org/apache/rocketmq/samples/springboot/domain/OrderPaidEvent.java

@ -0,0 +1,50 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.samples.springboot.domain;
import java.io.Serializable;
import java.math.BigDecimal;
public class OrderPaidEvent implements Serializable {
private String orderId;
private BigDecimal paidMoney;
public OrderPaidEvent() {
}
public OrderPaidEvent(String orderId, BigDecimal paidMoney) {
this.orderId = orderId;
this.paidMoney = paidMoney;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public BigDecimal getPaidMoney() {
return paidMoney;
}
public void setPaidMoney(BigDecimal paidMoney) {
this.paidMoney = paidMoney;
}
}

11
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/rocketmq-produce-demo/src/main/resources/application.properties

@ -0,0 +1,11 @@
rocketmq.name-server=localhost:9876
rocketmq.producer.group=my-group1
rocketmq.producer.sendMessageTimeout=300000
# properties used in the application
demo.rocketmq.topic=string-topic
demo.rocketmq.orderTopic=order-paid-topic
demo.rocketmq.msgExtTopic=message-ext-topic
demo.rocketmq.transTopic=spring-transaction-topic
demo.rocketmq.extNameServer=127.0.0.1:9876

23
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/copyright/Apache.xml

@ -0,0 +1,23 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<component name="CopyrightManager">
<copyright>
<option name="myName" value="Apache" />
<option name="notice" value="Licensed to the Apache Software Foundation (ASF) under one or more&#10;contributor license agreements. See the NOTICE file distributed with&#10;this work for additional information regarding copyright ownership.&#10;The ASF licenses this file to You under the Apache License, Version 2.0&#10;(the &quot;License&quot;); you may not use this file except in compliance with&#10;the License. You may obtain a copy of the License at&#10;&#10; http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
</copyright>
</component>

64
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/copyright/profiles_settings.xml

@ -0,0 +1,64 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<component name="CopyrightManager">
<settings default="Apache">
<module2copyright>
<element module="All" copyright="Apache"/>
</module2copyright>
<LanguageOptions name="GSP">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="HTML">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="JAVA">
<option name="fileTypeOverride" value="3" />
<option name="addBlankAfter" value="false" />
</LanguageOptions>
<LanguageOptions name="JSP">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="JSPX">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="MXML">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="Properties">
<option name="fileTypeOverride" value="3"/>
<option name="block" value="false"/>
</LanguageOptions>
<LanguageOptions name="SPI">
<option name="fileTypeOverride" value="3"/>
<option name="block" value="false"/>
</LanguageOptions>
<LanguageOptions name="XML">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="__TEMPLATE__">
<option name="separateBefore" value="true"/>
<option name="lenBefore" value="1"/>
</LanguageOptions>
</settings>
</component>

135
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/rmq_checkstyle.xml

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--Refer http://checkstyle.sourceforge.net/reports/google-java-style.html#s2.2-file-encoding -->
<module name="Checker">
<property name="localeLanguage" value="en"/>
<!--To configure the check to report on the first instance in each file-->
<module name="FileTabCharacter"/>
<!-- header -->
<module name="RegexpHeader">
<property name="header" value="/\*\nLicensed to the Apache Software Foundation*"/>
<property name="fileExtensions" value="java" />
</module>
<module name="RegexpSingleline">
<property name="format" value="System\.out\.println"/>
<property name="message" value="Prohibit invoking System.out.println in source code !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="//FIXME"/>
<property name="message" value="Recommended fix FIXME task !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="//TODO"/>
<property name="message" value="Recommended fix TODO task !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@alibaba"/>
<property name="message" value="Recommended remove @alibaba keyword!"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@taobao"/>
<property name="message" value="Recommended remove @taobao keyword!"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@author"/>
<property name="message" value="Recommended remove @author tag in javadoc!"/>
</module>
<module name="RegexpSingleline">
<property name="format"
value=".*[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]+.*"/>
<property name="message" value="Not allow chinese character !"/>
</module>
<module name="FileLength">
<property name="max" value="3000"/>
</module>
<module name="TreeWalker">
<module name="UnusedImports">
<property name="processJavadoc" value="true"/>
</module>
<module name="RedundantImport"/>
<!--<module name="IllegalImport" />-->
<!--Checks that classes that override equals() also override hashCode()-->
<module name="EqualsHashCode"/>
<!--Checks for over-complicated boolean expressions. Currently finds code like if (topic == true), topic || true, !false, etc.-->
<module name="SimplifyBooleanExpression"/>
<module name="OneStatementPerLine"/>
<module name="UnnecessaryParentheses"/>
<!--Checks for over-complicated boolean return statements. For example the following code-->
<module name="SimplifyBooleanReturn"/>
<!--Check that the default is after all the cases in producerGroup switch statement-->
<module name="DefaultComesLast"/>
<!--Detects empty statements (standalone ";" semicolon)-->
<module name="EmptyStatement"/>
<!--Checks that long constants are defined with an upper ell-->
<module name="UpperEll"/>
<module name="ConstantName">
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^log$)"/>
</module>
<!--Checks that local, non-final variable names conform to producerGroup format specified by the format property-->
<module name="LocalVariableName"/>
<!--Validates identifiers for local, final variables, including catch parameters-->
<module name="LocalFinalVariableName"/>
<!--Validates identifiers for non-static fields-->
<module name="MemberName"/>
<!--Validates identifiers for class type parameters-->
<module name="ClassTypeParameterName">
<property name="format" value="^[A-Z0-9]*$"/>
</module>
<!--Validates identifiers for method type parameters-->
<module name="MethodTypeParameterName">
<property name="format" value="^[A-Z0-9]*$"/>
</module>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!--Checks that there are no import statements that use the * notation-->
<module name="AvoidStarImport"/>
<!--whitespace-->
<module name="GenericWhitespace"/>
<module name="NoWhitespaceBefore"/>
<module name="NoWhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
</module>
<module name="Indentation"/>
<module name="MethodParamPad"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
</module>
</module>

157
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot-samples/style/rmq_codeStyle.xml

@ -0,0 +1,157 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<code_scheme name="rocketmq">
<option name="USE_SAME_INDENTS" value="true"/>
<option name="IGNORE_SAME_INDENTS_FOR_LANGUAGES" value="true"/>
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="4"/>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="4"/>
<option name="USE_TAB_CHARACTER" value="false"/>
<option name="SMART_TABS" value="false"/>
<option name="LABEL_INDENT_SIZE" value="0"/>
<option name="LABEL_INDENT_ABSOLUTE" value="false"/>
<option name="USE_RELATIVE_INDENTS" value="false"/>
</value>
</option>
<option name="PREFER_LONGER_NAMES" value="false"/>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value/>
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="" withSubpackages="true" static="true"/>
</value>
</option>
<option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
<option name="JD_P_AT_EMPTY_LINES" value="false"/>
<option name="JD_KEEP_INVALID_TAGS" value="false"/>
<option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true"/>
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="WHILE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
<option name="LABELED_STATEMENT_WRAP" value="1"/>
<option name="WRAP_COMMENTS" value="true"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<JavaCodeStyleSettings>
<option name="CLASS_NAMES_IN_JAVADOC" value="3"/>
</JavaCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
</XML>
<ADDITIONAL_INDENT_OPTIONS fileType="haml">
<option name="INDENT_SIZE" value="2"/>
</ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="Groovy">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="HOCON">
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
</codeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="WHILE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
<option name="LABELED_STATEMENT_WRAP" value="1"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
</codeStyleSettings>
<codeStyleSettings language="Scala">
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="WHILE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions>
<option name="INDENT_SIZE" value="4"/>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
</code_scheme>

7
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/README.md

@ -0,0 +1,7 @@
# RocketMQ Spring Boot Support
This project provides auto-configuration for the following RocketMQ client:
- [Produce and Consume Spring Message](../rocketmq-spring-boot-starter)
- [Send (halp) Message in Transaction](../rocketmq-spring-boot-starter)
For details, please see sample code in the [rocketmq-spring-boot-samples](../rocketmq-spring-boot-samples)

102
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/pom.xml

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Licensed to the Apache Software Foundation (ASF) under one or more
~ contributor license agreements. See the NOTICE file distributed with
~ this work for additional information regarding copyright ownership.
~ The ASF licenses this file to You under the Apache License, Version 2.0
~ (the "License"); you may not use this file except in compliance with
~ the License. You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-parent</artifactId>
<version>2.0.3</version>
<relativePath>../rocketmq-spring-boot-parent/pom.xml</relativePath>
</parent>
<artifactId>rocketmq-spring-boot</artifactId>
<packaging>jar</packaging>
<name>RocketMQ Spring Boot AutoConfigure</name>
<description>SRocketMQ Spring Boot AutoConfigure</description>
<url>https://github.com/apache/rocketmq-spring</url>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-acl</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
</dependencies>
</project>

30
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/ConsumeMode.java

@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.annotation;
public enum ConsumeMode {
/**
* Receive asynchronously delivered messages concurrently
*/
CONCURRENTLY,
/**
* Receive asynchronously delivered messages orderly. one queue, one thread
*/
ORDERLY
}

89
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/ExtRocketMQTemplateConfiguration.java

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.annotation;
import org.springframework.stereotype.Component;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ExtRocketMQTemplateConfiguration {
/**
* The component name of the Producer configuration.
*/
String value() default "";
/**
* The property of "name-server".
*/
String nameServer();
/**
* Name of producer.
*/
String group() default "${rocketmq.producer.group:}";
/**
* Millis of send message timeout.
*/
int sendMessageTimeout() default -1;
/**
* Compress message body threshold, namely, message body larger than 4k will be compressed on default.
*/
int compressMessageBodyThreshold() default -1;
/**
* Maximum number of retry to perform internally before claiming sending failure in synchronous mode.
* This may potentially cause message duplication which is up to application developers to resolve.
*/
int retryTimesWhenSendFailed() default -1;
/**
* <p> Maximum number of retry to perform internally before claiming sending failure in asynchronous mode. </p>
* This may potentially cause message duplication which is up to application developers to resolve.
*/
int retryTimesWhenSendAsyncFailed() default -1;
/**
* Indicate whether to retry another broker on sending failure internally.
*/
boolean retryNextServer() default false;
/**
* Maximum allowed message size in bytes.
*/
int maxMessageSize() default -1;
/**
* The property of "access-key".
*/
String accessKey() default "${rocketmq.producer.accessKey:}";
/**
* The property of "secret-key".
*/
String secretKey() default "${rocketmq.producer.secretKey:}";
/**
* Switch flag instance for message trace.
*/
boolean enableMsgTrace() default true;
/**
* The name value of message trace topic.If you don't config,you can use the default trace topic name.
*/
String customizedTraceTopic() default "${rocketmq.producer.customized-trace-topic:}";
}

33
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/MessageModel.java

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.annotation;
public enum MessageModel {
BROADCASTING("BROADCASTING"),
CLUSTERING("CLUSTERING");
private final String modeCN;
MessageModel(String modeCN) {
this.modeCN = modeCN;
}
public String getModeCN() {
return this.modeCN;
}
}

112
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/RocketMQMessageListener.java

@ -0,0 +1,112 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RocketMQMessageListener {
String NAME_SERVER_PLACEHOLDER = "${rocketmq.name-server:}";
String ACCESS_KEY_PLACEHOLDER = "${rocketmq.consumer.access-key:}";
String SECRET_KEY_PLACEHOLDER = "${rocketmq.consumer.secret-key:}";
String TRACE_TOPIC_PLACEHOLDER = "${rocketmq.consumer.customized-trace-topic:}";
String ACCESS_CHANNEL_PLACEHOLDER = "${rocketmq.access-channel:}";
/**
* Consumers of the same role is required to have exactly same subscriptions and consumerGroup to correctly achieve
* load balance. It's required and needs to be globally unique.
*
*
* See <a href="http://rocketmq.apache.org/docs/core-concept/">here</a> for further discussion.
*/
String consumerGroup();
/**
* Topic name.
*/
String topic();
/**
* Control how to selector message.
*
* @see SelectorType
*/
SelectorType selectorType() default SelectorType.TAG;
/**
* Control which message can be select. Grammar please see {@link SelectorType#TAG} and {@link SelectorType#SQL92}
*/
String selectorExpression() default "*";
/**
* Control consume mode, you can choice receive message concurrently or orderly.
*/
ConsumeMode consumeMode() default ConsumeMode.CONCURRENTLY;
/**
* Control message mode, if you want all subscribers receive message all message, broadcasting is a good choice.
*/
MessageModel messageModel() default MessageModel.CLUSTERING;
/**
* Max consumer thread number.
*/
int consumeThreadMax() default 64;
/**
* Max consumer timeout, default 30s.
*/
long consumeTimeout() default 30000L;
/**
* The property of "access-key".
*/
String accessKey() default ACCESS_KEY_PLACEHOLDER;
/**
* The property of "secret-key".
*/
String secretKey() default SECRET_KEY_PLACEHOLDER;
/**
* Switch flag instance for message trace.
*/
boolean enableMsgTrace() default true;
/**
* The name value of message trace topic.If you don't config,you can use the default trace topic name.
*/
String customizedTraceTopic() default TRACE_TOPIC_PLACEHOLDER;
/**
* The property of "name-server".
*/
String nameServer() default NAME_SERVER_PLACEHOLDER;
/**
* The property of "access-channel".
*/
String accessChannel() default ACCESS_CHANNEL_PLACEHOLDER;
}

79
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/RocketMQTransactionListener.java

@ -0,0 +1,79 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.annotation;
import org.apache.rocketmq.spring.config.RocketMQConfigUtils;
import org.springframework.stereotype.Component;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation is used over a class which implements interface
* org.apache.rocketmq.client.producer.TransactionListener. The class implements
* two methods for process callback events after the txProducer sends a transactional message.
* <p>Note: The annotation is used only on RocketMQ client producer side, it can not be used
* on consumer side.
*/
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface RocketMQTransactionListener {
/**
* Declare the txProducerGroup that is used to relate callback event to the listener, rocketMQTemplate must send a
* transactional message with the declared txProducerGroup.
* <p>
* <p>It is suggested to use the default txProducerGroup if your system only needs to define a TransactionListener class.
*/
String txProducerGroup() default RocketMQConfigUtils.ROCKETMQ_TRANSACTION_DEFAULT_GLOBAL_NAME;
/**
* Set ExecutorService params -- corePoolSize
*/
int corePoolSize() default 1;
/**
* Set ExecutorService params -- maximumPoolSize
*/
int maximumPoolSize() default 1;
/**
* Set ExecutorService params -- keepAliveTime
*/
long keepAliveTime() default 1000 * 60; //60ms
/**
* Set ExecutorService params -- blockingQueueSize
*/
int blockingQueueSize() default 2000;
/**
* The property of "access-key"
*/
String accessKey() default "${rocketmq.producer.access-key}";
/**
* The property of "secret-key"
*/
String secretKey() default "${rocketmq.producer.secret-key}";
}

33
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/annotation/SelectorType.java

@ -0,0 +1,33 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.annotation;
import org.apache.rocketmq.common.filter.ExpressionType;
public enum SelectorType {
/**
* @see ExpressionType#TAG
*/
TAG,
/**
* @see ExpressionType#SQL92
*/
SQL92
}

158
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/ExtProducerResetConfiguration.java

@ -0,0 +1,158 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.spring.annotation.ExtRocketMQTemplateConfiguration;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.StringUtils;
import java.util.Map;
import java.util.Objects;
@Configuration
public class ExtProducerResetConfiguration implements ApplicationContextAware, SmartInitializingSingleton {
private final static Logger log = LoggerFactory.getLogger(ExtProducerResetConfiguration.class);
private ConfigurableApplicationContext applicationContext;
private StandardEnvironment environment;
private RocketMQProperties rocketMQProperties;
private ObjectMapper objectMapper;
public ExtProducerResetConfiguration(ObjectMapper rocketMQMessageObjectMapper,
StandardEnvironment environment,
RocketMQProperties rocketMQProperties) {
this.objectMapper = rocketMQMessageObjectMapper;
this.environment = environment;
this.rocketMQProperties = rocketMQProperties;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
@Override
public void afterSingletonsInstantiated() {
Map<String, Object> beans = this.applicationContext.getBeansWithAnnotation(ExtRocketMQTemplateConfiguration.class);
if (Objects.nonNull(beans)) {
beans.forEach(this::registerTemplate);
}
}
private void registerTemplate(String beanName, Object bean) {
Class<?> clazz = AopProxyUtils.ultimateTargetClass(bean);
if (!RocketMQTemplate.class.isAssignableFrom(bean.getClass())) {
throw new IllegalStateException(clazz + " is not instance of " + RocketMQTemplate.class.getName());
}
ExtRocketMQTemplateConfiguration annotation = clazz.getAnnotation(ExtRocketMQTemplateConfiguration.class);
GenericApplicationContext genericApplicationContext = (GenericApplicationContext) applicationContext;
validate(annotation, genericApplicationContext);
DefaultMQProducer mqProducer = createProducer(annotation);
// Set instanceName same as the beanName
mqProducer.setInstanceName(beanName);
try {
mqProducer.start();
} catch (MQClientException e) {
throw new BeanDefinitionValidationException(String.format("Failed to startup MQProducer for RocketMQTemplate {}",
beanName), e);
}
RocketMQTemplate rocketMQTemplate = (RocketMQTemplate) bean;
rocketMQTemplate.setProducer(mqProducer);
rocketMQTemplate.setObjectMapper(objectMapper);
log.info("Set real producer to :{} {}", beanName, annotation.value());
}
private DefaultMQProducer createProducer(ExtRocketMQTemplateConfiguration annotation) {
DefaultMQProducer producer = null;
RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer();
if (producerConfig == null) {
producerConfig = new RocketMQProperties.Producer();
}
String nameServer = environment.resolvePlaceholders(annotation.nameServer());
String groupName = environment.resolvePlaceholders(annotation.group());
groupName = StringUtils.isEmpty(groupName) ? producerConfig.getGroup() : groupName;
String ak = environment.resolvePlaceholders(annotation.accessKey());
ak = StringUtils.isEmpty(ak) ? producerConfig.getAccessKey() : annotation.accessKey();
String sk = environment.resolvePlaceholders(annotation.secretKey());
sk = StringUtils.isEmpty(sk) ? producerConfig.getSecretKey() : annotation.secretKey();
String customizedTraceTopic = environment.resolvePlaceholders(annotation.customizedTraceTopic());
customizedTraceTopic = StringUtils.isEmpty(customizedTraceTopic) ? producerConfig.getCustomizedTraceTopic() : customizedTraceTopic;
if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
producer = new DefaultMQProducer(groupName, new AclClientRPCHook(new SessionCredentials(ak, sk)),
annotation.enableMsgTrace(), customizedTraceTopic);
producer.setVipChannelEnabled(false);
} else {
producer = new DefaultMQProducer(groupName, annotation.enableMsgTrace(), customizedTraceTopic);
}
producer.setNamesrvAddr(nameServer);
producer.setSendMsgTimeout(annotation.sendMessageTimeout() == -1 ? producerConfig.getSendMessageTimeout() : annotation.sendMessageTimeout());
producer.setRetryTimesWhenSendFailed(annotation.retryTimesWhenSendAsyncFailed() == -1 ? producerConfig.getRetryTimesWhenSendFailed() : annotation.retryTimesWhenSendAsyncFailed());
producer.setRetryTimesWhenSendAsyncFailed(annotation.retryTimesWhenSendAsyncFailed() == -1 ? producerConfig.getRetryTimesWhenSendAsyncFailed() : annotation.retryTimesWhenSendAsyncFailed());
producer.setMaxMessageSize(annotation.maxMessageSize() == -1 ? producerConfig.getMaxMessageSize() : annotation.maxMessageSize());
producer.setCompressMsgBodyOverHowmuch(annotation.compressMessageBodyThreshold() == -1 ? producerConfig.getCompressMessageBodyThreshold() : annotation.compressMessageBodyThreshold());
producer.setRetryAnotherBrokerWhenNotStoreOK(annotation.retryNextServer());
return producer;
}
private void validate(ExtRocketMQTemplateConfiguration annotation, GenericApplicationContext genericApplicationContext) {
if (genericApplicationContext.isBeanNameInUse(annotation.value())) {
throw new BeanDefinitionValidationException(String.format("Bean {} has been used in Spring Application Context, " +
"please check the @ExtRocketMQTemplateConfiguration",
annotation.value()));
}
if (rocketMQProperties.getNameServer() == null ||
rocketMQProperties.getNameServer().equals(environment.resolvePlaceholders(annotation.nameServer()))) {
throw new BeanDefinitionValidationException(
"Bad annotation definition in @ExtRocketMQTemplateConfiguration, nameServer property is same with " +
"global property, please use the default RocketMQTemplate!");
}
}
}

34
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/JacksonFallbackConfiguration.java

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnMissingBean(ObjectMapper.class)
class JacksonFallbackConfiguration {
@Bean
public ObjectMapper rocketMQMessageObjectMapper() {
return new ObjectMapper();
}
}

139
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/ListenerContainerConfiguration.java

@ -0,0 +1,139 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.client.AccessChannel;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.SmartInitializingSingleton;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.util.StringUtils;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
@Configuration
public class ListenerContainerConfiguration implements ApplicationContextAware, SmartInitializingSingleton {
private final static Logger log = LoggerFactory.getLogger(ListenerContainerConfiguration.class);
private ConfigurableApplicationContext applicationContext;
private AtomicLong counter = new AtomicLong(0);
private StandardEnvironment environment;
private RocketMQProperties rocketMQProperties;
private ObjectMapper objectMapper;
public ListenerContainerConfiguration(ObjectMapper rocketMQMessageObjectMapper,
StandardEnvironment environment,
RocketMQProperties rocketMQProperties) {
this.objectMapper = rocketMQMessageObjectMapper;
this.environment = environment;
this.rocketMQProperties = rocketMQProperties;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
}
@Override
public void afterSingletonsInstantiated() {
Map<String, Object> beans = this.applicationContext.getBeansWithAnnotation(RocketMQMessageListener.class);
if (Objects.nonNull(beans)) {
beans.forEach(this::registerContainer);
}
}
private void registerContainer(String beanName, Object bean) {
Class<?> clazz = AopProxyUtils.ultimateTargetClass(bean);
if (!RocketMQListener.class.isAssignableFrom(bean.getClass())) {
throw new IllegalStateException(clazz + " is not instance of " + RocketMQListener.class.getName());
}
RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);
validate(annotation);
String containerBeanName = String.format("%s_%s", DefaultRocketMQListenerContainer.class.getName(),
counter.incrementAndGet());
GenericApplicationContext genericApplicationContext = (GenericApplicationContext) applicationContext;
genericApplicationContext.registerBean(containerBeanName, DefaultRocketMQListenerContainer.class,
() -> createRocketMQListenerContainer(containerBeanName, bean, annotation));
DefaultRocketMQListenerContainer container = genericApplicationContext.getBean(containerBeanName,
DefaultRocketMQListenerContainer.class);
if (!container.isRunning()) {
try {
container.start();
} catch (Exception e) {
log.error("Started container failed. {}", container, e);
throw new RuntimeException(e);
}
}
log.info("Register the listener to container, listenerBeanName:{}, containerBeanName:{}", beanName, containerBeanName);
}
private DefaultRocketMQListenerContainer createRocketMQListenerContainer(String name, Object bean, RocketMQMessageListener annotation) {
DefaultRocketMQListenerContainer container = new DefaultRocketMQListenerContainer();
String nameServer = environment.resolvePlaceholders(annotation.nameServer());
nameServer = StringUtils.isEmpty(nameServer) ? rocketMQProperties.getNameServer() : nameServer;
String accessChannel = environment.resolvePlaceholders(annotation.accessChannel());
container.setNameServer(nameServer);
if (!StringUtils.isEmpty(accessChannel)) {
container.setAccessChannel(AccessChannel.valueOf(accessChannel));
}
container.setTopic(environment.resolvePlaceholders(annotation.topic()));
container.setConsumerGroup(environment.resolvePlaceholders(annotation.consumerGroup()));
container.setRocketMQMessageListener(annotation);
container.setRocketMQListener((RocketMQListener) bean);
container.setObjectMapper(objectMapper);
container.setName(name); // REVIEW ME, use the same clientId or multiple?
return container;
}
private void validate(RocketMQMessageListener annotation) {
if (annotation.consumeMode() == ConsumeMode.ORDERLY &&
annotation.messageModel() == MessageModel.BROADCASTING) {
throw new BeanDefinitionValidationException(
"Bad annotation definition in @RocketMQMessageListener, messageModel BROADCASTING does not support ORDERLY message!");
}
}
}

139
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/RocketMQAutoConfiguration.java

@ -0,0 +1,139 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.AccessChannel;
import org.apache.rocketmq.client.MQAdmin;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.spring.config.RocketMQConfigUtils;
import org.apache.rocketmq.spring.config.RocketMQTransactionAnnotationProcessor;
import org.apache.rocketmq.spring.config.TransactionHandlerRegistry;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Role;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import javax.annotation.PostConstruct;
@Configuration
@EnableConfigurationProperties(RocketMQProperties.class)
@ConditionalOnClass({ MQAdmin.class, ObjectMapper.class })
@ConditionalOnProperty(prefix = "rocketmq", value = "name-server", matchIfMissing = true)
@Import({ JacksonFallbackConfiguration.class, ListenerContainerConfiguration.class, ExtProducerResetConfiguration.class })
@AutoConfigureAfter(JacksonAutoConfiguration.class)
public class RocketMQAutoConfiguration {
private static final Logger log = LoggerFactory.getLogger(RocketMQAutoConfiguration.class);
@Autowired
private Environment environment;
@PostConstruct
public void checkProperties() {
String nameServer = environment.getProperty("rocketmq.name-server", String.class);
log.debug("rocketmq.nameServer = {}", nameServer);
if (nameServer == null) {
log.warn("The necessary spring property 'rocketmq.name-server' is not defined, all rockertmq beans creation are skipped!");
}
}
@Bean
@ConditionalOnMissingBean(DefaultMQProducer.class)
@ConditionalOnProperty(prefix = "rocketmq", value = {"name-server", "producer.group"})
public DefaultMQProducer defaultMQProducer(RocketMQProperties rocketMQProperties) {
RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer();
String nameServer = rocketMQProperties.getNameServer();
String groupName = producerConfig.getGroup();
Assert.hasText(nameServer, "[rocketmq.name-server] must not be null");
Assert.hasText(groupName, "[rocketmq.producer.group] must not be null");
String accessChannel = rocketMQProperties.getAccessChannel();
DefaultMQProducer producer;
String ak = rocketMQProperties.getProducer().getAccessKey();
String sk = rocketMQProperties.getProducer().getSecretKey();
if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
producer = new DefaultMQProducer(groupName, new AclClientRPCHook(new SessionCredentials(ak, sk)),
rocketMQProperties.getProducer().isEnableMsgTrace(),
rocketMQProperties.getProducer().getCustomizedTraceTopic());
producer.setVipChannelEnabled(false);
} else {
producer = new DefaultMQProducer(groupName, rocketMQProperties.getProducer().isEnableMsgTrace(),
rocketMQProperties.getProducer().getCustomizedTraceTopic());
}
producer.setNamesrvAddr(nameServer);
if (!StringUtils.isEmpty(accessChannel)) {
producer.setAccessChannel(AccessChannel.valueOf(accessChannel));
}
producer.setSendMsgTimeout(producerConfig.getSendMessageTimeout());
producer.setRetryTimesWhenSendFailed(producerConfig.getRetryTimesWhenSendFailed());
producer.setRetryTimesWhenSendAsyncFailed(producerConfig.getRetryTimesWhenSendAsyncFailed());
producer.setMaxMessageSize(producerConfig.getMaxMessageSize());
producer.setCompressMsgBodyOverHowmuch(producerConfig.getCompressMessageBodyThreshold());
producer.setRetryAnotherBrokerWhenNotStoreOK(producerConfig.isRetryNextServer());
return producer;
}
@Bean(destroyMethod = "destroy")
@ConditionalOnBean(DefaultMQProducer.class)
@ConditionalOnMissingBean(name = RocketMQConfigUtils.ROCKETMQ_TEMPLATE_DEFAULT_GLOBAL_NAME)
public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer, ObjectMapper rocketMQMessageObjectMapper) {
RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
rocketMQTemplate.setProducer(mqProducer);
rocketMQTemplate.setObjectMapper(rocketMQMessageObjectMapper);
return rocketMQTemplate;
}
@Bean
@ConditionalOnBean(name = RocketMQConfigUtils.ROCKETMQ_TEMPLATE_DEFAULT_GLOBAL_NAME)
@ConditionalOnMissingBean(TransactionHandlerRegistry.class)
public TransactionHandlerRegistry transactionHandlerRegistry(@Qualifier(RocketMQConfigUtils.ROCKETMQ_TEMPLATE_DEFAULT_GLOBAL_NAME)
RocketMQTemplate template) {
return new TransactionHandlerRegistry(template);
}
@Bean(name = RocketMQConfigUtils.ROCKETMQ_TRANSACTION_ANNOTATION_PROCESSOR_BEAN_NAME)
@ConditionalOnBean(TransactionHandlerRegistry.class)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public static RocketMQTransactionAnnotationProcessor transactionAnnotationProcessor(
TransactionHandlerRegistry transactionHandlerRegistry) {
return new RocketMQTransactionAnnotationProcessor(transactionHandlerRegistry);
}
}

210
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/autoconfigure/RocketMQProperties.java

@ -0,0 +1,210 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.autoconfigure;
import org.apache.rocketmq.common.MixAll;
import org.springframework.boot.context.properties.ConfigurationProperties;
@SuppressWarnings("WeakerAccess")
@ConfigurationProperties(prefix = "rocketmq")
public class RocketMQProperties {
/**
* The name server for rocketMQ, formats: `host:port;host:port`.
*/
private String nameServer;
/**
* Enum type for accesChannel, values: LOCAL, CLOUD
*/
private String accessChannel;
private Producer producer;
public String getNameServer() {
return nameServer;
}
public void setNameServer(String nameServer) {
this.nameServer = nameServer;
}
public String getAccessChannel() {
return accessChannel;
}
public void setAccessChannel(String accessChannel) {
this.accessChannel = accessChannel;
}
public Producer getProducer() {
return producer;
}
public void setProducer(Producer producer) {
this.producer = producer;
}
public static class Producer {
/**
* Name of producer.
*/
private String group;
/**
* Millis of send message timeout.
*/
private int sendMessageTimeout = 3000;
/**
* Compress message body threshold, namely, message body larger than 4k will be compressed on default.
*/
private int compressMessageBodyThreshold = 1024 * 4;
/**
* Maximum number of retry to perform internally before claiming sending failure in synchronous mode.
* This may potentially cause message duplication which is up to application developers to resolve.
*/
private int retryTimesWhenSendFailed = 2;
/**
* <p> Maximum number of retry to perform internally before claiming sending failure in asynchronous mode. </p>
* This may potentially cause message duplication which is up to application developers to resolve.
*/
private int retryTimesWhenSendAsyncFailed = 2;
/**
* Indicate whether to retry another broker on sending failure internally.
*/
private boolean retryNextServer = false;
/**
* Maximum allowed message size in bytes.
*/
private int maxMessageSize = 1024 * 1024 * 4;
/**
* The property of "access-key".
*/
private String accessKey;
/**
* The property of "secret-key".
*/
private String secretKey;
/**
* Switch flag instance for message trace.
*/
private boolean enableMsgTrace = true;
/**
* The name value of message trace topic.If you don't config,you can use the default trace topic name.
*/
private String customizedTraceTopic = MixAll.RMQ_SYS_TRACE_TOPIC;
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public int getSendMessageTimeout() {
return sendMessageTimeout;
}
public void setSendMessageTimeout(int sendMessageTimeout) {
this.sendMessageTimeout = sendMessageTimeout;
}
public int getCompressMessageBodyThreshold() {
return compressMessageBodyThreshold;
}
public void setCompressMessageBodyThreshold(int compressMessageBodyThreshold) {
this.compressMessageBodyThreshold = compressMessageBodyThreshold;
}
public int getRetryTimesWhenSendFailed() {
return retryTimesWhenSendFailed;
}
public void setRetryTimesWhenSendFailed(int retryTimesWhenSendFailed) {
this.retryTimesWhenSendFailed = retryTimesWhenSendFailed;
}
public int getRetryTimesWhenSendAsyncFailed() {
return retryTimesWhenSendAsyncFailed;
}
public void setRetryTimesWhenSendAsyncFailed(int retryTimesWhenSendAsyncFailed) {
this.retryTimesWhenSendAsyncFailed = retryTimesWhenSendAsyncFailed;
}
public boolean isRetryNextServer() {
return retryNextServer;
}
public void setRetryNextServer(boolean retryNextServer) {
this.retryNextServer = retryNextServer;
}
public int getMaxMessageSize() {
return maxMessageSize;
}
public void setMaxMessageSize(int maxMessageSize) {
this.maxMessageSize = maxMessageSize;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public boolean isEnableMsgTrace() {
return enableMsgTrace;
}
public void setEnableMsgTrace(boolean enableMsgTrace) {
this.enableMsgTrace = enableMsgTrace;
}
public String getCustomizedTraceTopic() {
return customizedTraceTopic;
}
public void setCustomizedTraceTopic(String customizedTraceTopic) {
this.customizedTraceTopic = customizedTraceTopic;
}
}
}

32
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/RocketMQConfigUtils.java

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.config;
public class RocketMQConfigUtils {
/**
* The bean name of the internally managed RocketMQ transaction annotation processor.
*/
public static final String ROCKETMQ_TRANSACTION_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.rocketmq.spring.starter.internalRocketMQTransAnnotationProcessor";
public static final String ROCKETMQ_TRANSACTION_DEFAULT_GLOBAL_NAME =
"rocketmq_transaction_default_global_name";
public static final String ROCKETMQ_TEMPLATE_DEFAULT_GLOBAL_NAME =
"rocketMQTemplate";
}

122
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/RocketMQTransactionAnnotationProcessor.java

@ -0,0 +1,122 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.config;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.support.RocketMQUtil;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationUtils;
import java.util.Collections;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RocketMQTransactionAnnotationProcessor
implements BeanPostProcessor, Ordered, ApplicationContextAware {
private final static Logger log = LoggerFactory.getLogger(RocketMQTransactionAnnotationProcessor.class);
private ApplicationContext applicationContext;
private final Set<Class<?>> nonProcessedClasses =
Collections.newSetFromMap(new ConcurrentHashMap<Class<?>, Boolean>(64));
private TransactionHandlerRegistry transactionHandlerRegistry;
public RocketMQTransactionAnnotationProcessor(TransactionHandlerRegistry transactionHandlerRegistry) {
this.transactionHandlerRegistry = transactionHandlerRegistry;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (!this.nonProcessedClasses.contains(bean.getClass())) {
Class<?> targetClass = AopUtils.getTargetClass(bean);
RocketMQTransactionListener listener = AnnotationUtils.findAnnotation(targetClass, RocketMQTransactionListener.class);
this.nonProcessedClasses.add(bean.getClass());
if (listener == null) { // for quick search
log.trace("No @RocketMQTransactionListener annotations found on bean type: {}", bean.getClass());
} else {
try {
processTransactionListenerAnnotation(listener, bean);
} catch (MQClientException e) {
log.error("Failed to process annotation " + listener, e);
throw new BeanCreationException("Failed to process annotation " + listener, e);
}
}
}
return bean;
}
private void processTransactionListenerAnnotation(RocketMQTransactionListener listener, Object bean)
throws MQClientException {
if (transactionHandlerRegistry == null) {
throw new MQClientException("Bad usage of @RocketMQTransactionListener, " +
"the class must work with RocketMQTemplate", null);
}
if (!RocketMQLocalTransactionListener.class.isAssignableFrom(bean.getClass())) {
throw new MQClientException("Bad usage of @RocketMQTransactionListener, " +
"the class must implement interface RocketMQLocalTransactionListener",
null);
}
TransactionHandler transactionHandler = new TransactionHandler();
transactionHandler.setBeanFactory(this.applicationContext.getAutowireCapableBeanFactory());
transactionHandler.setName(listener.txProducerGroup());
transactionHandler.setBeanName(bean.getClass().getName());
transactionHandler.setListener((RocketMQLocalTransactionListener) bean);
transactionHandler.setCheckExecutor(listener.corePoolSize(), listener.maximumPoolSize(),
listener.keepAliveTime(), listener.blockingQueueSize());
RPCHook rpcHook = RocketMQUtil.getRPCHookByAkSk(applicationContext.getEnvironment(),
listener.accessKey(), listener.secretKey());
if (Objects.nonNull(rpcHook)) {
transactionHandler.setRpcHook(rpcHook);
} else {
log.debug("Access-key or secret-key not configure in " + listener + ".");
}
transactionHandlerRegistry.registerTransactionHandler(transactionHandler);
}
@Override
public int getOrder() {
return LOWEST_PRECEDENCE;
}
}

85
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/TransactionHandler.java

@ -0,0 +1,85 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.config;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.springframework.beans.factory.BeanFactory;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
class TransactionHandler {
private String name;
private String beanName;
private RocketMQLocalTransactionListener bean;
private BeanFactory beanFactory;
private ThreadPoolExecutor checkExecutor;
private RPCHook rpcHook;
public String getBeanName() {
return beanName;
}
public void setBeanName(String beanName) {
this.beanName = beanName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public RPCHook getRpcHook() {
return rpcHook;
}
public void setRpcHook(RPCHook rpcHook) {
this.rpcHook = rpcHook;
}
public BeanFactory getBeanFactory() {
return beanFactory;
}
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void setListener(RocketMQLocalTransactionListener listener) {
this.bean = listener;
}
public RocketMQLocalTransactionListener getListener() {
return this.bean;
}
public void setCheckExecutor(int corePoolSize, int maxPoolSize, long keepAliveTime, int blockingQueueSize) {
this.checkExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
keepAliveTime, TimeUnit.MILLISECONDS,
new LinkedBlockingDeque<>(blockingQueueSize));
}
public ThreadPoolExecutor getCheckExecutor() {
return checkExecutor;
}
}

52
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/config/TransactionHandlerRegistry.java

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.config;
import io.netty.util.internal.ConcurrentSet;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.DisposableBean;
import java.util.Set;
public class TransactionHandlerRegistry implements DisposableBean {
private RocketMQTemplate rocketMQTemplate;
private final Set<String> listenerContainers = new ConcurrentSet<>();
public TransactionHandlerRegistry(RocketMQTemplate template) {
this.rocketMQTemplate = template;
}
@Override
public void destroy() throws Exception {
listenerContainers.clear();
}
public void registerTransactionHandler(TransactionHandler handler) throws MQClientException {
if (listenerContainers.contains(handler.getName())) {
throw new MQClientException(-1,
String
.format("The transaction name [%s] has been defined in TransactionListener [%s]", handler.getName(),
handler.getBeanName()));
}
listenerContainers.add(handler.getName());
rocketMQTemplate.createAndStartTransactionMQProducer(handler.getName(), handler.getListener(), handler.getCheckExecutor(), handler.getRpcHook());
}
}

22
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQListener.java

@ -0,0 +1,22 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.core;
public interface RocketMQListener<T> {
void onMessage(T message);
}

25
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQLocalTransactionListener.java

@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.core;
import org.springframework.messaging.Message;
public interface RocketMQLocalTransactionListener {
RocketMQLocalTransactionState executeLocalTransaction(final Message msg, final Object arg);
RocketMQLocalTransactionState checkLocalTransaction(final Message msg);
}

24
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQLocalTransactionState.java

@ -0,0 +1,24 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.core;
public enum RocketMQLocalTransactionState {
COMMIT,
ROLLBACK,
UNKNOWN
}

24
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQPushConsumerLifecycleListener.java

@ -0,0 +1,24 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.core;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.spring.support.RocketMQConsumerLifecycleListener;
public interface RocketMQPushConsumerLifecycleListener extends RocketMQConsumerLifecycleListener<DefaultMQPushConsumer> {
}

677
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/core/RocketMQTemplate.java

@ -0,0 +1,677 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.core;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.MessageQueueSelector;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.client.producer.TransactionSendResult;
import org.apache.rocketmq.client.producer.selector.SelectMessageQueueByHash;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.spring.config.RocketMQConfigUtils;
import org.apache.rocketmq.spring.support.RocketMQUtil;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.core.AbstractMessageSendingTemplate;
import org.springframework.messaging.core.MessagePostProcessor;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.Assert;
import org.springframework.util.MimeTypeUtils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings({"WeakerAccess", "unused"})
public class RocketMQTemplate extends AbstractMessageSendingTemplate<String> implements InitializingBean, DisposableBean {
private static final Logger log = LoggerFactory.getLogger(RocketMQTemplate.class);
private DefaultMQProducer producer;
private ObjectMapper objectMapper;
private String charset = "UTF-8";
private MessageQueueSelector messageQueueSelector = new SelectMessageQueueByHash();
private final Map<String, TransactionMQProducer> cache = new ConcurrentHashMap<>(); //only put TransactionMQProducer by now!!!
public DefaultMQProducer getProducer() {
return producer;
}
public void setProducer(DefaultMQProducer producer) {
this.producer = producer;
}
public ObjectMapper getObjectMapper() {
return objectMapper;
}
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public MessageQueueSelector getMessageQueueSelector() {
return messageQueueSelector;
}
public void setMessageQueueSelector(MessageQueueSelector messageQueueSelector) {
this.messageQueueSelector = messageQueueSelector;
}
/**
* <p> Send message in synchronous mode. This method returns only when the sending procedure totally completes.
* Reliable synchronous transmission is used in extensive scenes, such as important notification messages, SMS
* notification, SMS marketing system, etc.. </p>
* <p>
* <strong>Warn:</strong> this method has internal retry-mechanism, that is, internal implementation will retry
* {@link DefaultMQProducer#getRetryTimesWhenSendFailed} times before claiming failure. As a result, multiple
* messages may potentially delivered to broker(s). It's up to the application developers to resolve potential
* duplication issue.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @return {@link SendResult}
*/
public SendResult syncSend(String destination, Message<?> message) {
return syncSend(destination, message, producer.getSendMsgTimeout());
}
/**
* Same to {@link #syncSend(String, Message)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param timeout send timeout with millis
* @return {@link SendResult}
*/
public SendResult syncSend(String destination, Message<?> message, long timeout) {
return syncSend(destination, message, timeout, 0);
}
/**
* syncSend batch messages in a given timeout.
*
* @param destination formats: `topicName:tags`
* @param messages Collection of {@link Message}
* @param timeout send timeout with millis
* @return {@link SendResult}
*/
public SendResult syncSend(String destination, Collection<Message<?>> messages, long timeout) {
if (Objects.isNull(messages) || messages.size() == 0) {
log.error("syncSend with batch failed. destination:{}, messages is empty ", destination);
throw new IllegalArgumentException("`messages` can not be empty");
}
try {
long now = System.currentTimeMillis();
Collection<org.apache.rocketmq.common.message.Message> rmqMsgs = new ArrayList<>();
org.apache.rocketmq.common.message.Message rocketMsg;
for (Message<?> msg:messages) {
if (Objects.isNull(msg) || Objects.isNull(msg.getPayload())) {
log.warn("Found a message empty in the batch, skip it");
continue;
}
rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper, charset, destination, msg);
rmqMsgs.add(rocketMsg);
}
SendResult sendResult = producer.send(rmqMsgs, timeout);
long costTime = System.currentTimeMillis() - now;
log.debug("send messages cost: {} ms, msgId:{}", costTime, sendResult.getMsgId());
return sendResult;
} catch (Exception e) {
log.error("syncSend with batch failed. destination:{}, messages.size:{} ", destination, messages.size());
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #syncSend(String, Message)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param timeout send timeout with millis
* @param delayLevel level for the delay message
* @return {@link SendResult}
*/
public SendResult syncSend(String destination, Message<?> message, long timeout, int delayLevel) {
if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {
log.error("syncSend failed. destination:{}, message is null ", destination);
throw new IllegalArgumentException("`message` and `message.payload` cannot be null");
}
try {
long now = System.currentTimeMillis();
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
if (delayLevel > 0) {
rocketMsg.setDelayTimeLevel(delayLevel);
}
SendResult sendResult = producer.send(rocketMsg, timeout);
long costTime = System.currentTimeMillis() - now;
log.debug("send message cost: {} ms, msgId:{}", costTime, sendResult.getMsgId());
return sendResult;
} catch (Exception e) {
log.error("syncSend failed. destination:{}, message:{} ", destination, message);
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #syncSend(String, Message)}.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @return {@link SendResult}
*/
public SendResult syncSend(String destination, Object payload) {
return syncSend(destination, payload, producer.getSendMsgTimeout());
}
/**
* Same to {@link #syncSend(String, Object)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param timeout send timeout with millis
* @return {@link SendResult}
*/
public SendResult syncSend(String destination, Object payload, long timeout) {
Message<?> message = this.doConvert(payload, null, null);
return syncSend(destination, message, timeout);
}
/**
* Same to {@link #syncSend(String, Message)} with send orderly with hashKey by specified.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @return {@link SendResult}
*/
public SendResult syncSendOrderly(String destination, Message<?> message, String hashKey) {
return syncSendOrderly(destination, message, hashKey, producer.getSendMsgTimeout());
}
/**
* Same to {@link #syncSendOrderly(String, Message, String)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @param timeout send timeout with millis
* @return {@link SendResult}
*/
public SendResult syncSendOrderly(String destination, Message<?> message, String hashKey, long timeout) {
if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {
log.error("syncSendOrderly failed. destination:{}, message is null ", destination);
throw new IllegalArgumentException("`message` and `message.payload` cannot be null");
}
try {
long now = System.currentTimeMillis();
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
SendResult sendResult = producer.send(rocketMsg, messageQueueSelector, hashKey, timeout);
long costTime = System.currentTimeMillis() - now;
log.debug("send message cost: {} ms, msgId:{}", costTime, sendResult.getMsgId());
return sendResult;
} catch (Exception e) {
log.error("syncSendOrderly failed. destination:{}, message:{} ", destination, message);
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #syncSend(String, Object)} with send orderly with hashKey by specified.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @return {@link SendResult}
*/
public SendResult syncSendOrderly(String destination, Object payload, String hashKey) {
return syncSendOrderly(destination, payload, hashKey, producer.getSendMsgTimeout());
}
/**
* Same to {@link #syncSendOrderly(String, Object, String)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @param timeout send timeout with millis
* @return {@link SendResult}
*/
public SendResult syncSendOrderly(String destination, Object payload, String hashKey, long timeout) {
Message<?> message = this.doConvert(payload, null, null);
return syncSendOrderly(destination, message, hashKey, producer.getSendMsgTimeout());
}
/**
* Same to {@link #asyncSend(String, Message, SendCallback)} with send timeout and delay level specified in addition.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param sendCallback {@link SendCallback}
* @param timeout send timeout with millis
* @param delayLevel level for the delay message
*/
public void asyncSend(String destination, Message<?> message, SendCallback sendCallback, long timeout, int delayLevel) {
if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {
log.error("asyncSend failed. destination:{}, message is null ", destination);
throw new IllegalArgumentException("`message` and `message.payload` cannot be null");
}
try {
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
if (delayLevel > 0) {
rocketMsg.setDelayTimeLevel(delayLevel);
}
producer.send(rocketMsg, sendCallback, timeout);
} catch (Exception e) {
log.info("asyncSend failed. destination:{}, message:{} ", destination, message);
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #asyncSend(String, Message, SendCallback)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param sendCallback {@link SendCallback}
* @param timeout send timeout with millis
*/
public void asyncSend(String destination, Message<?> message, SendCallback sendCallback, long timeout) {
asyncSend(destination,message,sendCallback,timeout,0);
}
/**
* <p> Send message to broker asynchronously. asynchronous transmission is generally used in response time sensitive
* business scenarios. </p>
* <p>
* This method returns immediately. On sending completion, <code>sendCallback</code> will be executed.
* <p>
* Similar to {@link #syncSend(String, Object)}, internal implementation would potentially retry up to {@link
* DefaultMQProducer#getRetryTimesWhenSendAsyncFailed} times before claiming sending failure, which may yield
* message duplication and application developers are the one to resolve this potential issue.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param sendCallback {@link SendCallback}
*/
public void asyncSend(String destination, Message<?> message, SendCallback sendCallback) {
asyncSend(destination, message, sendCallback, producer.getSendMsgTimeout());
}
/**
* Same to {@link #asyncSend(String, Object, SendCallback)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param sendCallback {@link SendCallback}
* @param timeout send timeout with millis
*/
public void asyncSend(String destination, Object payload, SendCallback sendCallback, long timeout) {
Message<?> message = this.doConvert(payload, null, null);
asyncSend(destination, message, sendCallback, timeout);
}
/**
* Same to {@link #asyncSend(String, Message, SendCallback)}.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param sendCallback {@link SendCallback}
*/
public void asyncSend(String destination, Object payload, SendCallback sendCallback) {
asyncSend(destination, payload, sendCallback, producer.getSendMsgTimeout());
}
/**
* Same to {@link #asyncSendOrderly(String, Message, String, SendCallback)} with send timeout specified in
* addition.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @param sendCallback {@link SendCallback}
* @param timeout send timeout with millis
*/
public void asyncSendOrderly(String destination, Message<?> message, String hashKey, SendCallback sendCallback,
long timeout) {
if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {
log.error("asyncSendOrderly failed. destination:{}, message is null ", destination);
throw new IllegalArgumentException("`message` and `message.payload` cannot be null");
}
try {
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
producer.send(rocketMsg, messageQueueSelector, hashKey, sendCallback, timeout);
} catch (Exception e) {
log.error("asyncSendOrderly failed. destination:{}, message:{} ", destination, message);
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #asyncSend(String, Message, SendCallback)} with send orderly with hashKey by specified.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @param sendCallback {@link SendCallback}
*/
public void asyncSendOrderly(String destination, Message<?> message, String hashKey, SendCallback sendCallback) {
asyncSendOrderly(destination, message, hashKey, sendCallback, producer.getSendMsgTimeout());
}
/**
* Same to {@link #asyncSendOrderly(String, Message, String, SendCallback)}.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @param sendCallback {@link SendCallback}
*/
public void asyncSendOrderly(String destination, Object payload, String hashKey, SendCallback sendCallback) {
asyncSendOrderly(destination, payload, hashKey, sendCallback, producer.getSendMsgTimeout());
}
/**
* Same to {@link #asyncSendOrderly(String, Object, String, SendCallback)} with send timeout specified in addition.
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
* @param hashKey use this key to select queue. for example: orderId, productId ...
* @param sendCallback {@link SendCallback}
* @param timeout send timeout with millis
*/
public void asyncSendOrderly(String destination, Object payload, String hashKey, SendCallback sendCallback,
long timeout) {
Message<?> message = this.doConvert(payload, null, null);
asyncSendOrderly(destination, message, hashKey, sendCallback, timeout);
}
/**
* Similar to <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol">UDP</a>, this method won't wait for
* acknowledgement from broker before return. Obviously, it has maximums throughput yet potentials of message loss.
* <p>
* One-way transmission is used for cases requiring moderate reliability, such as log collection.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
*/
public void sendOneWay(String destination, Message<?> message) {
if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {
log.error("sendOneWay failed. destination:{}, message is null ", destination);
throw new IllegalArgumentException("`message` and `message.payload` cannot be null");
}
try {
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
producer.sendOneway(rocketMsg);
} catch (Exception e) {
log.error("sendOneWay failed. destination:{}, message:{} ", destination, message);
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #sendOneWay(String, Message)}
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
*/
public void sendOneWay(String destination, Object payload) {
Message<?> message = this.doConvert(payload, null, null);
sendOneWay(destination, message);
}
/**
* Same to {@link #sendOneWay(String, Message)} with send orderly with hashKey by specified.
*
* @param destination formats: `topicName:tags`
* @param message {@link Message}
* @param hashKey use this key to select queue. for example: orderId, productId ...
*/
public void sendOneWayOrderly(String destination, Message<?> message, String hashKey) {
if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {
log.error("sendOneWayOrderly failed. destination:{}, message is null ", destination);
throw new IllegalArgumentException("`message` and `message.payload` cannot be null");
}
try {
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
producer.sendOneway(rocketMsg, messageQueueSelector, hashKey);
} catch (Exception e) {
log.error("sendOneWayOrderly failed. destination:{}, message:{}", destination, message);
throw new MessagingException(e.getMessage(), e);
}
}
/**
* Same to {@link #sendOneWayOrderly(String, Message, String)}
*
* @param destination formats: `topicName:tags`
* @param payload the Object to use as payload
*/
public void sendOneWayOrderly(String destination, Object payload, String hashKey) {
Message<?> message = this.doConvert(payload, null, null);
sendOneWayOrderly(destination, message, hashKey);
}
@Override
public void afterPropertiesSet() throws Exception {
if (producer != null) {
producer.start();
}
}
@Override
protected void doSend(String destination, Message<?> message) {
SendResult sendResult = syncSend(destination, message);
log.debug("send message to `{}` finished. result:{}", destination, sendResult);
}
@Override
protected Message<?> doConvert(Object payload, Map<String, Object> headers, MessagePostProcessor postProcessor) {
String content;
if (payload instanceof String) {
content = (String) payload;
} else {
// If payload not as string, use objectMapper change it.
try {
content = objectMapper.writeValueAsString(payload);
} catch (JsonProcessingException e) {
log.error("convert payload to String failed. payload:{}", payload);
throw new RuntimeException("convert to payload to String failed.", e);
}
}
MessageBuilder<?> builder = MessageBuilder.withPayload(content);
if (headers != null) {
builder.copyHeaders(headers);
}
builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN);
Message<?> message = builder.build();
if (postProcessor != null) {
message = postProcessor.postProcessMessage(message);
}
return message;
}
@Override
public void destroy() {
if (Objects.nonNull(producer)) {
producer.shutdown();
}
for (Map.Entry<String, TransactionMQProducer> kv : cache.entrySet()) {
if (Objects.nonNull(kv.getValue())) {
kv.getValue().shutdown();
}
}
cache.clear();
}
private String getTxProducerGroupName(String name) {
return name == null ? RocketMQConfigUtils.ROCKETMQ_TRANSACTION_DEFAULT_GLOBAL_NAME : name;
}
private TransactionMQProducer stageMQProducer(String name) throws MessagingException {
name = getTxProducerGroupName(name);
TransactionMQProducer cachedProducer = cache.get(name);
if (cachedProducer == null) {
throw new MessagingException(
String.format("Can not found MQProducer '%s' in cache! please define @RocketMQLocalTransactionListener class or invoke createOrGetStartedTransactionMQProducer() to create it firstly", name));
}
return cachedProducer;
}
/**
* Send Spring Message in Transaction
*
* @param txProducerGroup the validate txProducerGroup name, set null if using the default name
* @param destination destination formats: `topicName:tags`
* @param message message {@link Message}
* @param arg ext arg
* @return TransactionSendResult
* @throws MessagingException
*/
public TransactionSendResult sendMessageInTransaction(final String txProducerGroup, final String destination, final Message<?> message, final Object arg) throws MessagingException {
try {
TransactionMQProducer txProducer = this.stageMQProducer(txProducerGroup);
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, message);
return txProducer.sendMessageInTransaction(rocketMsg, arg);
} catch (MQClientException e) {
throw RocketMQUtil.convert(e);
}
}
/**
* Remove a TransactionMQProducer from cache by manual.
* <p>Note: RocketMQTemplate can release all cached producers when bean destroying, it is not recommended to directly
* use this method by user.
*
* @param txProducerGroup
* @throws MessagingException
*/
public void removeTransactionMQProducer(String txProducerGroup) throws MessagingException {
txProducerGroup = getTxProducerGroupName(txProducerGroup);
if (cache.containsKey(txProducerGroup)) {
DefaultMQProducer cachedProducer = cache.get(txProducerGroup);
cachedProducer.shutdown();
cache.remove(txProducerGroup);
}
}
/**
* Create and start a transaction MQProducer, this new producer is cached in memory.
* <p>Note: This method is invoked internally when processing {@code @RocketMQLocalTransactionListener}, it is not
* recommended to directly use this method by user.
*
* @param txProducerGroup Producer (group) name, unique for each producer
* @param transactionListener TransactoinListener impl class
* @param executorService Nullable.
* @param rpcHook Nullable.
* @return true if producer is created and started; false if the named producer already exists in cache.
* @throws MessagingException
*/
public boolean createAndStartTransactionMQProducer(String txProducerGroup,
RocketMQLocalTransactionListener transactionListener,
ExecutorService executorService, RPCHook rpcHook) throws MessagingException {
txProducerGroup = getTxProducerGroupName(txProducerGroup);
if (cache.containsKey(txProducerGroup)) {
log.info(String.format("get TransactionMQProducer '%s' from cache", txProducerGroup));
return false;
}
TransactionMQProducer txProducer = createTransactionMQProducer(txProducerGroup, transactionListener, executorService, rpcHook);
try {
txProducer.start();
cache.put(txProducerGroup, txProducer);
} catch (MQClientException e) {
throw RocketMQUtil.convert(e);
}
return true;
}
private TransactionMQProducer createTransactionMQProducer(String name,
RocketMQLocalTransactionListener transactionListener,
ExecutorService executorService, RPCHook rpcHook) {
Assert.notNull(producer, "Property 'producer' is required");
Assert.notNull(transactionListener, "Parameter 'transactionListener' is required");
TransactionMQProducer txProducer;
if (Objects.nonNull(rpcHook)) {
txProducer = new TransactionMQProducer(name, rpcHook);
txProducer.setVipChannelEnabled(false);
txProducer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook, name));
} else {
txProducer = new TransactionMQProducer(name);
}
txProducer.setTransactionListener(RocketMQUtil.convert(transactionListener));
txProducer.setNamesrvAddr(producer.getNamesrvAddr());
if (executorService != null) {
txProducer.setExecutorService(executorService);
}
txProducer.setSendMsgTimeout(producer.getSendMsgTimeout());
txProducer.setRetryTimesWhenSendFailed(producer.getRetryTimesWhenSendFailed());
txProducer.setRetryTimesWhenSendAsyncFailed(producer.getRetryTimesWhenSendAsyncFailed());
txProducer.setMaxMessageSize(producer.getMaxMessageSize());
txProducer.setCompressMsgBodyOverHowmuch(producer.getCompressMsgBodyOverHowmuch());
txProducer.setRetryAnotherBrokerWhenNotStoreOK(producer.isRetryAnotherBrokerWhenNotStoreOK());
return txProducer;
}
}

494
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/DefaultRocketMQListenerContainer.java

@ -0,0 +1,494 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.client.AccessChannel;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.MessageSelector;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.spring.annotation.ConsumeMode;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.annotation.SelectorType;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.SmartLifecycle;
import org.springframework.util.Assert;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Objects;
@SuppressWarnings("WeakerAccess")
public class DefaultRocketMQListenerContainer implements InitializingBean,
RocketMQListenerContainer, SmartLifecycle, ApplicationContextAware {
private final static Logger log = LoggerFactory.getLogger(DefaultRocketMQListenerContainer.class);
private ApplicationContext applicationContext;
/**
* The name of the DefaultRocketMQListenerContainer instance
*/
private String name;
private long suspendCurrentQueueTimeMillis = 1000;
/**
* Message consume retry strategy<br> -1,no retry,put into DLQ directly<br> 0,broker control retry frequency<br>
* >0,client control retry frequency.
*/
private int delayLevelWhenNextConsume = 0;
private String nameServer;
private AccessChannel accessChannel = AccessChannel.LOCAL;
private String consumerGroup;
private String topic;
private int consumeThreadMax = 64;
private String charset = "UTF-8";
private ObjectMapper objectMapper;
private RocketMQListener rocketMQListener;
private RocketMQMessageListener rocketMQMessageListener;
private DefaultMQPushConsumer consumer;
private Class messageType;
private boolean running;
// The following properties came from @RocketMQMessageListener.
private ConsumeMode consumeMode;
private SelectorType selectorType;
private String selectorExpression;
private MessageModel messageModel;
private long consumeTimeout;
public long getSuspendCurrentQueueTimeMillis() {
return suspendCurrentQueueTimeMillis;
}
public void setSuspendCurrentQueueTimeMillis(long suspendCurrentQueueTimeMillis) {
this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
}
public int getDelayLevelWhenNextConsume() {
return delayLevelWhenNextConsume;
}
public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
}
public String getNameServer() {
return nameServer;
}
public void setNameServer(String nameServer) {
this.nameServer = nameServer;
}
public AccessChannel getAccessChannel() {
return accessChannel;
}
public void setAccessChannel(AccessChannel accessChannel) {
this.accessChannel = accessChannel;
}
public String getConsumerGroup() {
return consumerGroup;
}
public void setConsumerGroup(String consumerGroup) {
this.consumerGroup = consumerGroup;
}
public String getTopic() {
return topic;
}
public void setTopic(String topic) {
this.topic = topic;
}
public int getConsumeThreadMax() {
return consumeThreadMax;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public ObjectMapper getObjectMapper() {
return objectMapper;
}
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
public RocketMQListener getRocketMQListener() {
return rocketMQListener;
}
public void setRocketMQListener(RocketMQListener rocketMQListener) {
this.rocketMQListener = rocketMQListener;
}
public RocketMQMessageListener getRocketMQMessageListener() {
return rocketMQMessageListener;
}
public void setRocketMQMessageListener(RocketMQMessageListener anno) {
this.rocketMQMessageListener = anno;
this.consumeMode = anno.consumeMode();
this.consumeThreadMax = anno.consumeThreadMax();
this.messageModel = anno.messageModel();
this.selectorExpression = anno.selectorExpression();
this.selectorType = anno.selectorType();
this.consumeTimeout = anno.consumeTimeout();
}
public ConsumeMode getConsumeMode() {
return consumeMode;
}
public SelectorType getSelectorType() {
return selectorType;
}
public String getSelectorExpression() {
return selectorExpression;
}
public MessageModel getMessageModel() {
return messageModel;
}
public DefaultMQPushConsumer getConsumer() {
return consumer;
}
public void setConsumer(DefaultMQPushConsumer consumer) {
this.consumer = consumer;
}
@Override
public void setupMessageListener(RocketMQListener rocketMQListener) {
this.rocketMQListener = rocketMQListener;
}
@Override
public void destroy() {
this.setRunning(false);
if (Objects.nonNull(consumer)) {
consumer.shutdown();
}
log.info("container destroyed, {}", this.toString());
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public void stop(Runnable callback) {
stop();
callback.run();
}
@Override
public void start() {
if (this.isRunning()) {
throw new IllegalStateException("container already running. " + this.toString());
}
try {
consumer.start();
} catch (MQClientException e) {
throw new IllegalStateException("Failed to start RocketMQ push consumer", e);
}
this.setRunning(true);
log.info("running container: {}", this.toString());
}
@Override
public void stop() {
if (this.isRunning()) {
if (Objects.nonNull(consumer)) {
consumer.shutdown();
}
setRunning(false);
}
}
@Override
public boolean isRunning() {
return running;
}
private void setRunning(boolean running) {
this.running = running;
}
@Override
public int getPhase() {
// Returning Integer.MAX_VALUE only suggests that
// we will be the first bean to shutdown and last bean to start
return Integer.MAX_VALUE;
}
@Override
public void afterPropertiesSet() throws Exception {
initRocketMQPushConsumer();
this.messageType = getMessageType();
log.debug("RocketMQ messageType: {}", messageType.getName());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
public String toString() {
return "DefaultRocketMQListenerContainer{" +
"consumerGroup='" + consumerGroup + '\'' +
", nameServer='" + nameServer + '\'' +
", topic='" + topic + '\'' +
", consumeMode=" + consumeMode +
", selectorType=" + selectorType +
", selectorExpression='" + selectorExpression + '\'' +
", messageModel=" + messageModel +
'}';
}
public void setName(String name) {
this.name = name;
}
public class DefaultMessageListenerConcurrently implements MessageListenerConcurrently {
@SuppressWarnings("unchecked")
@Override
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
for (MessageExt messageExt : msgs) {
log.debug("received msg: {}", messageExt);
try {
long now = System.currentTimeMillis();
rocketMQListener.onMessage(doConvertMessage(messageExt));
long costTime = System.currentTimeMillis() - now;
log.debug("consume {} cost: {} ms", messageExt.getMsgId(), costTime);
} catch (Exception e) {
log.warn("consume message failed. messageExt:{}", messageExt, e);
context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
}
public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
@SuppressWarnings("unchecked")
@Override
public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
for (MessageExt messageExt : msgs) {
log.debug("received msg: {}", messageExt);
try {
long now = System.currentTimeMillis();
rocketMQListener.onMessage(doConvertMessage(messageExt));
long costTime = System.currentTimeMillis() - now;
log.info("consume {} cost: {} ms", messageExt.getMsgId(), costTime);
} catch (Exception e) {
log.warn("consume message failed. messageExt:{}", messageExt, e);
context.setSuspendCurrentQueueTimeMillis(suspendCurrentQueueTimeMillis);
return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
}
}
return ConsumeOrderlyStatus.SUCCESS;
}
}
@SuppressWarnings("unchecked")
private Object doConvertMessage(MessageExt messageExt) {
if (Objects.equals(messageType, MessageExt.class)) {
return messageExt;
} else {
String str = new String(messageExt.getBody(), Charset.forName(charset));
if (Objects.equals(messageType, String.class)) {
return str;
} else {
// If msgType not string, use objectMapper change it.
try {
return objectMapper.readValue(str, messageType);
} catch (Exception e) {
log.info("convert failed. str:{}, msgType:{}", str, messageType);
throw new RuntimeException("cannot convert message to " + messageType, e);
}
}
}
}
private Class getMessageType() {
Class<?> targetClass = AopProxyUtils.ultimateTargetClass(rocketMQListener);
Type[] interfaces = targetClass.getGenericInterfaces();
Class<?> superclass = targetClass.getSuperclass();
while ((Objects.isNull(interfaces) || 0 == interfaces.length) && Objects.nonNull(superclass)) {
interfaces = superclass.getGenericInterfaces();
superclass = targetClass.getSuperclass();
}
if (Objects.nonNull(interfaces)) {
for (Type type : interfaces) {
if (type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) type;
if (Objects.equals(parameterizedType.getRawType(), RocketMQListener.class)) {
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
if (Objects.nonNull(actualTypeArguments) && actualTypeArguments.length > 0) {
return (Class) actualTypeArguments[0];
} else {
return Object.class;
}
}
}
}
return Object.class;
} else {
return Object.class;
}
}
private void initRocketMQPushConsumer() throws MQClientException {
Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
Assert.notNull(nameServer, "Property 'nameServer' is required");
Assert.notNull(topic, "Property 'topic' is required");
RPCHook rpcHook = RocketMQUtil.getRPCHookByAkSk(applicationContext.getEnvironment(),
this.rocketMQMessageListener.accessKey(), this.rocketMQMessageListener.secretKey());
boolean enableMsgTrace = rocketMQMessageListener.enableMsgTrace();
if (Objects.nonNull(rpcHook)) {
consumer = new DefaultMQPushConsumer(consumerGroup, rpcHook, new AllocateMessageQueueAveragely(),
enableMsgTrace, this.applicationContext.getEnvironment().
resolveRequiredPlaceholders(this.rocketMQMessageListener.customizedTraceTopic()));
consumer.setVipChannelEnabled(false);
consumer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook, consumerGroup));
} else {
log.debug("Access-key or secret-key not configure in " + this + ".");
consumer = new DefaultMQPushConsumer(consumerGroup, enableMsgTrace,
this.applicationContext.getEnvironment().
resolveRequiredPlaceholders(this.rocketMQMessageListener.customizedTraceTopic()));
}
String customizedNameServer = this.applicationContext.getEnvironment().resolveRequiredPlaceholders(this.rocketMQMessageListener.nameServer());
if (customizedNameServer != null) {
consumer.setNamesrvAddr(customizedNameServer);
} else {
consumer.setNamesrvAddr(nameServer);
}
if (accessChannel != null) {
consumer.setAccessChannel(accessChannel);
}
consumer.setConsumeThreadMax(consumeThreadMax);
if (consumeThreadMax < consumer.getConsumeThreadMin()) {
consumer.setConsumeThreadMin(consumeThreadMax);
}
consumer.setConsumeTimeout(consumeTimeout);
consumer.setInstanceName(this.name);
switch (messageModel) {
case BROADCASTING:
consumer.setMessageModel(org.apache.rocketmq.common.protocol.heartbeat.MessageModel.BROADCASTING);
break;
case CLUSTERING:
consumer.setMessageModel(org.apache.rocketmq.common.protocol.heartbeat.MessageModel.CLUSTERING);
break;
default:
throw new IllegalArgumentException("Property 'messageModel' was wrong.");
}
switch (selectorType) {
case TAG:
consumer.subscribe(topic, selectorExpression);
break;
case SQL92:
consumer.subscribe(topic, MessageSelector.bySql(selectorExpression));
break;
default:
throw new IllegalArgumentException("Property 'selectorType' was wrong.");
}
switch (consumeMode) {
case ORDERLY:
consumer.setMessageListener(new DefaultMessageListenerOrderly());
break;
case CONCURRENTLY:
consumer.setMessageListener(new DefaultMessageListenerConcurrently());
break;
default:
throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
}
if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {
((RocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumer);
}
}
}

22
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQConsumerLifecycleListener.java

@ -0,0 +1,22 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
public interface RocketMQConsumerLifecycleListener<T> {
void prepareStart(final T consumer);
}

34
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQHeaders.java

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
/**
* Represents the RocketMQ message protocol that is used during the data exchange.
*/
public class RocketMQHeaders {
public static final String PREFIX = "rocketmq_";
public static final String KEYS = "KEYS";
public static final String TAGS = "TAGS";
public static final String TOPIC = "TOPIC";
public static final String MESSAGE_ID = "MESSAGE_ID";
public static final String BORN_TIMESTAMP = "BORN_TIMESTAMP";
public static final String BORN_HOST = "BORN_HOST";
public static final String FLAG = "FLAG";
public static final String QUEUE_ID = "QUEUE_ID";
public static final String SYS_FLAG = "SYS_FLAG";
public static final String TRANSACTION_ID = "TRANSACTION_ID";
}

30
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQListenerContainer.java

@ -0,0 +1,30 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.DisposableBean;
public interface RocketMQListenerContainer extends DisposableBean {
/**
* Setup the message listener to use. Throws an {@link IllegalArgumentException} if that message listener type is
* not supported.
*/
void setupMessageListener(RocketMQListener<?> messageListener);
}

215
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/java/org/apache/rocketmq/spring/support/RocketMQUtil.java

@ -0,0 +1,215 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageConst;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.remoting.RPCHook;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.springframework.core.env.Environment;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.MessagingException;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Objects;
public class RocketMQUtil {
private final static Logger log = LoggerFactory.getLogger(RocketMQUtil.class);
public static TransactionListener convert(RocketMQLocalTransactionListener listener) {
return new TransactionListener() {
@Override
public LocalTransactionState executeLocalTransaction(Message message, Object obj) {
RocketMQLocalTransactionState state = listener.executeLocalTransaction(convertToSpringMessage(message), obj);
return convertLocalTransactionState(state);
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt messageExt) {
RocketMQLocalTransactionState state = listener.checkLocalTransaction(convertToSpringMessage(messageExt));
return convertLocalTransactionState(state);
}
};
}
private static LocalTransactionState convertLocalTransactionState(RocketMQLocalTransactionState state) {
switch (state) {
case UNKNOWN:
return LocalTransactionState.UNKNOW;
case COMMIT:
return LocalTransactionState.COMMIT_MESSAGE;
case ROLLBACK:
return LocalTransactionState.ROLLBACK_MESSAGE;
}
// Never happen
log.warn("Failed to covert enum type RocketMQLocalTransactionState.%s", state);
return LocalTransactionState.UNKNOW;
}
public static MessagingException convert(MQClientException e) {
return new MessagingException(e.getErrorMessage(), e);
}
public static org.springframework.messaging.Message convertToSpringMessage(
MessageExt message) {
MessageBuilder messageBuilder =
MessageBuilder.withPayload(message.getBody()).
setHeader(toRocketHeaderKey(RocketMQHeaders.KEYS), message.getKeys()).
setHeader(toRocketHeaderKey(RocketMQHeaders.TAGS), message.getTags()).
setHeader(toRocketHeaderKey(RocketMQHeaders.TOPIC), message.getTopic()).
setHeader(toRocketHeaderKey(RocketMQHeaders.MESSAGE_ID), message.getMsgId()).
setHeader(toRocketHeaderKey(RocketMQHeaders.BORN_TIMESTAMP), message.getBornTimestamp()).
setHeader(toRocketHeaderKey(RocketMQHeaders.BORN_HOST), message.getBornHostString()).
setHeader(toRocketHeaderKey(RocketMQHeaders.FLAG), message.getFlag()).
setHeader(toRocketHeaderKey(RocketMQHeaders.QUEUE_ID), message.getQueueId()).
setHeader(toRocketHeaderKey(RocketMQHeaders.SYS_FLAG), message.getSysFlag()).
setHeader(toRocketHeaderKey(RocketMQHeaders.TRANSACTION_ID), message.getTransactionId());
addUserProperties(message.getProperties(), messageBuilder);
return messageBuilder.build();
}
public static String toRocketHeaderKey(String rawKey) {
return RocketMQHeaders.PREFIX + rawKey;
}
private static void addUserProperties(Map<String, String> properties, MessageBuilder messageBuilder) {
if (!CollectionUtils.isEmpty(properties)) {
properties.forEach((key, val) -> {
if (!MessageConst.STRING_HASH_SET.contains(key) && !MessageHeaders.ID.equals(key)
&& !MessageHeaders.TIMESTAMP.equals(key)) {
messageBuilder.setHeader(key, val);
}
});
}
}
public static org.springframework.messaging.Message convertToSpringMessage(
Message message) {
MessageBuilder messageBuilder =
MessageBuilder.withPayload(message.getBody()).
setHeader(toRocketHeaderKey(RocketMQHeaders.KEYS), message.getKeys()).
setHeader(toRocketHeaderKey(RocketMQHeaders.TAGS), message.getTags()).
setHeader(toRocketHeaderKey(RocketMQHeaders.TOPIC), message.getTopic()).
setHeader(toRocketHeaderKey(RocketMQHeaders.FLAG), message.getFlag()).
setHeader(toRocketHeaderKey(RocketMQHeaders.TRANSACTION_ID), message.getTransactionId());
addUserProperties(message.getProperties(), messageBuilder);
return messageBuilder.build();
}
public static Message convertToRocketMessage(
ObjectMapper objectMapper, String charset,
String destination, org.springframework.messaging.Message<?> message) {
Object payloadObj = message.getPayload();
byte[] payloads;
if (payloadObj instanceof String) {
payloads = ((String) payloadObj).getBytes(Charset.forName(charset));
} else if (payloadObj instanceof byte[]) {
payloads = (byte[]) message.getPayload();
} else {
try {
String jsonObj = objectMapper.writeValueAsString(payloadObj);
payloads = jsonObj.getBytes(Charset.forName(charset));
} catch (Exception e) {
throw new RuntimeException("convert to RocketMQ message failed.", e);
}
}
String[] tempArr = destination.split(":", 2);
String topic = tempArr[0];
String tags = "";
if (tempArr.length > 1) {
tags = tempArr[1];
}
Message rocketMsg = new Message(topic, tags, payloads);
MessageHeaders headers = message.getHeaders();
if (Objects.nonNull(headers) && !headers.isEmpty()) {
Object keys = headers.get(RocketMQHeaders.KEYS);
if (!StringUtils.isEmpty(keys)) { // if headers has 'KEYS', set rocketMQ message key
rocketMsg.setKeys(keys.toString());
}
Object flagObj = headers.getOrDefault("FLAG", "0");
int flag = 0;
try {
flag = Integer.parseInt(flagObj.toString());
} catch (NumberFormatException e) {
// Ignore it
log.info("flag must be integer, flagObj:{}", flagObj);
}
rocketMsg.setFlag(flag);
Object waitStoreMsgOkObj = headers.getOrDefault("WAIT_STORE_MSG_OK", "true");
boolean waitStoreMsgOK = Boolean.TRUE.equals(waitStoreMsgOkObj);
rocketMsg.setWaitStoreMsgOK(waitStoreMsgOK);
headers.entrySet().stream()
.filter(entry -> !Objects.equals(entry.getKey(), "FLAG")
&& !Objects.equals(entry.getKey(), "WAIT_STORE_MSG_OK")) // exclude "FLAG", "WAIT_STORE_MSG_OK"
.forEach(entry -> {
if (!MessageConst.STRING_HASH_SET.contains(entry.getKey())) {
rocketMsg.putUserProperty(entry.getKey(), String.valueOf(entry.getValue()));
}
});
}
return rocketMsg;
}
public static RPCHook getRPCHookByAkSk(Environment env, String accessKeyOrExpr, String secretKeyOrExpr) {
String ak, sk;
try {
ak = env.resolveRequiredPlaceholders(accessKeyOrExpr);
sk = env.resolveRequiredPlaceholders(secretKeyOrExpr);
} catch (Exception e) {
// Ignore it
ak = null;
sk = null;
}
if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
return new AclClientRPCHook(new SessionCredentials(ak, sk));
}
return null;
}
public static String getInstanceName(RPCHook rpcHook, String identify) {
String separator = "|";
StringBuilder instanceName = new StringBuilder();
SessionCredentials sessionCredentials = ((AclClientRPCHook) rpcHook).getSessionCredentials();
instanceName.append(sessionCredentials.getAccessKey())
.append(separator).append(sessionCredentials.getSecretKey())
.append(separator).append(identify);
return instanceName.toString();
}
}

2
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/main/resources/META-INF/spring.factories

@ -0,0 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration

221
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/autoconfigure/RocketMQAutoConfigurationTest.java

@ -0,0 +1,221 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.autoconfigure;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.spring.annotation.ExtRocketMQTemplateConfiguration;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.support.BeanDefinitionValidationException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.assertj.core.api.Assertions.assertThat;
public class RocketMQAutoConfigurationTest {
private ApplicationContextRunner runner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(RocketMQAutoConfiguration.class));
@Test(expected = NoSuchBeanDefinitionException.class)
public void testDefaultMQProducerNotCreatedByDefault() {
// You will see the WARN log message about missing rocketmq.name-server spring property when running this test case.
runner.run(context -> context.getBean(DefaultMQProducer.class));
}
@Test
public void testDefaultMQProducerWithRelaxPropertyName() {
runner.withPropertyValues("rocketmq.nameServer=127.0.0.1:9876",
"rocketmq.producer.group=spring_rocketmq",
"rocketmq.accessChannel=LOCAL").
run((context) -> {
assertThat(context).hasSingleBean(DefaultMQProducer.class);
assertThat(context).hasSingleBean(RocketMQProperties.class);
});
}
@Test
public void testBadAccessChannelProperty() {
runner.withPropertyValues("rocketmq.nameServer=127.0.0.1:9876",
"rocketmq.producer.group=spring_rocketmq",
"rocketmq.accessChannel=LOCAL123").
run((context) -> {
//Should throw exception for bad accessChannel property
assertThat(context).getFailure();
});
}
@Test
public void testDefaultMQProducer() {
runner.withPropertyValues("rocketmq.name-server=127.0.0.1:9876",
"rocketmq.producer.group=spring_rocketmq").
run((context) -> {
assertThat(context).hasSingleBean(DefaultMQProducer.class);
});
}
@Test
public void testRocketMQListenerContainer() {
runner.withPropertyValues("rocketmq.name-server=127.0.0.1:9876").
withUserConfiguration(TestConfig.class).
run((context) -> {
// No producer on consume side
assertThat(context).doesNotHaveBean(DefaultMQProducer.class);
// Auto-create consume container if existing Bean annotated with @RocketMQMessageListener
assertThat(context).hasBean("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1");
assertThat(context).hasBean("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_2");
assertThat(context).getBean("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1").
hasFieldOrPropertyWithValue("nameServer", "127.0.0.1:9876");
assertThat(context).getBean("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_2").
hasFieldOrPropertyWithValue("nameServer", "127.0.1.1:9876");
});
}
@Test
public void testRocketMQListenerWithCustomObjectMapper() {
runner.withPropertyValues("rocketmq.name-server=127.0.0.1:9876").
withUserConfiguration(TestConfig.class, CustomObjectMapperConfig.class).
run((context) -> {
assertThat(context.getBean("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1",
DefaultRocketMQListenerContainer.class).getObjectMapper())
.isSameAs(context.getBean(CustomObjectMapperConfig.class).testObjectMapper());
});
}
@Test
public void testRocketMQListenerWithSeveralObjectMappers() {
runner.withPropertyValues("rocketmq.name-server=127.0.0.1:9876").
withUserConfiguration(TestConfig.class, CustomObjectMappersConfig.class).
run((context) -> {
assertThat(context.getBean("org.apache.rocketmq.spring.support.DefaultRocketMQListenerContainer_1",
DefaultRocketMQListenerContainer.class).getObjectMapper())
.isSameAs(context.getBean(CustomObjectMappersConfig.class).rocketMQMessageObjectMapper());
});
}
@Test
public void testExtRocketMQTemplate() {
runner.withPropertyValues("rocketmq.name-server=127.0.0.1:9876").
withUserConfiguration(ExtRocketMQTemplateConfig.class, CustomObjectMappersConfig.class).
run(new ContextConsumer<AssertableApplicationContext>() {
@Override
public void accept(AssertableApplicationContext context) throws Throwable {
Throwable th = context.getStartupFailure();
System.out.printf("th==" + th + "\n");
Assert.assertTrue(th instanceof BeanDefinitionValidationException);
}
});
runner.withPropertyValues("rocketmq.name-server=127.0.1.1:9876").
withUserConfiguration(ExtRocketMQTemplateConfig.class, CustomObjectMappersConfig.class).
run((context) -> {
// No producer on consume side
assertThat(context).getBean("extRocketMQTemplate").hasFieldOrProperty("producer");
// Auto-create consume container if existing Bean annotated with @RocketMQMessageListener
});
}
@Configuration
static class TestConfig {
@Bean
public Object consumeListener() {
return new MyMessageListener();
}
@Bean
public Object consumeListener1() {
return new MyMessageListener1();
}
}
@Configuration
static class CustomObjectMapperConfig {
@Bean
public ObjectMapper testObjectMapper() {
return new ObjectMapper();
}
}
@Configuration
static class CustomObjectMappersConfig {
@Bean
public ObjectMapper testObjectMapper() {
return new ObjectMapper();
}
@Bean
public ObjectMapper rocketMQMessageObjectMapper() {
return new ObjectMapper();
}
}
@RocketMQMessageListener(consumerGroup = "abc", topic = "test")
static class MyMessageListener implements RocketMQListener {
@Override
public void onMessage(Object message) {
}
}
@RocketMQMessageListener(nameServer = "127.0.1.1:9876", consumerGroup = "abc1", topic = "test")
static class MyMessageListener1 implements RocketMQListener {
@Override
public void onMessage(Object message) {
}
}
@Configuration
static class ExtRocketMQTemplateConfig {
@Bean
public RocketMQTemplate extRocketMQTemplate() {
return new MyExtRocketMQTemplate();
}
}
@ExtRocketMQTemplateConfiguration(group = "test", nameServer = "127.0.0.1:9876")
static class MyExtRocketMQTemplate extends RocketMQTemplate {
}
}

52
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/support/DefaultRocketMQListenerContainerTest.java

@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static org.assertj.core.api.Assertions.assertThat;
public class DefaultRocketMQListenerContainerTest {
@Test
public void testGetMessageType() throws Exception {
DefaultRocketMQListenerContainer listenerContainer = new DefaultRocketMQListenerContainer();
Method getMessageType = DefaultRocketMQListenerContainer.class.getDeclaredMethod("getMessageType");
getMessageType.setAccessible(true);
listenerContainer.setRocketMQListener(new RocketMQListener<String>() {
@Override
public void onMessage(String message) {
}
});
Class result = (Class)getMessageType.invoke(listenerContainer);
assertThat(result.getName().equals(String.class.getName()));
listenerContainer.setRocketMQListener(new RocketMQListener<MessageExt>() {
@Override
public void onMessage(MessageExt message) {
}
});
result = (Class)getMessageType.invoke(listenerContainer);
assertThat(result.getName().equals(MessageExt.class.getName()));
}
}

93
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/rocketmq-spring-boot/src/test/java/org/apache/rocketmq/spring/support/RocketMQUtilTest.java

@ -0,0 +1,93 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.rocketmq.spring.support;
import java.util.Arrays;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class RocketMQUtilTest {
private ObjectMapper objectMapper = new ObjectMapper();
@Test
public void testMessageBuilder() {
Message msg = MessageBuilder.withPayload("test").
setHeader("A", "test1").
setHeader("B", "test2").
build();
System.out.printf("header size=%d %s %n", msg.getHeaders().size(), msg.getHeaders().toString());
assertTrue(msg.getHeaders().get("A") != null);
assertTrue(msg.getHeaders().get("B") != null);
}
@Test
public void testPayload() {
String charset = "UTF-8";
String destination = "test-topic";
Message msgWithStringPayload = MessageBuilder.withPayload("test").build();
org.apache.rocketmq.common.message.Message rocketMsg1 = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, msgWithStringPayload);
Message msgWithBytePayload = MessageBuilder.withPayload("test".getBytes()).build();
org.apache.rocketmq.common.message.Message rocketMsg2 = RocketMQUtil.convertToRocketMessage(objectMapper,
charset, destination, msgWithBytePayload);
assertTrue(Arrays.equals(((String)msgWithStringPayload.getPayload()).getBytes(), rocketMsg1.getBody()));
assertTrue(Arrays.equals((byte[])msgWithBytePayload.getPayload(), rocketMsg2.getBody()));
}
@Test
public void testHeaderConvertToRMQMsg() {
Message msgWithStringPayload = MessageBuilder.withPayload("test body")
.setHeader("test", 1)
.setHeader(RocketMQHeaders.TAGS, "tags")
.setHeader(RocketMQHeaders.KEYS, "my_keys")
.build();
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
"UTF-8", "test-topic", msgWithStringPayload);
assertEquals(String.valueOf("1"), rocketMsg.getProperty("test"));
assertNull(rocketMsg.getProperty(RocketMQHeaders.TAGS));
assertEquals("my_keys", rocketMsg.getProperty(RocketMQHeaders.KEYS));
}
@Test
public void testHeaderConvertToSpringMsg() {
org.apache.rocketmq.common.message.Message rmqMsg = new org.apache.rocketmq.common.message.Message();
rmqMsg.setBody("test body".getBytes());
rmqMsg.setTopic("test-topic");
rmqMsg.putUserProperty("test", "1");
rmqMsg.setTags("tags");
Message springMsg = RocketMQUtil.convertToSpringMessage(rmqMsg);
assertEquals(String.valueOf("1"), springMsg.getHeaders().get("test"));
assertEquals("tags", springMsg.getHeaders().get(RocketMQHeaders.PREFIX + RocketMQHeaders.TAGS));
org.apache.rocketmq.common.message.Message rocketMsg = RocketMQUtil.convertToRocketMessage(objectMapper,
"UTF-8", "test-topic", springMsg);
assertEquals(String.valueOf("1"), rocketMsg.getProperty("test"));
assertEquals(String.valueOf("tags"), rocketMsg.getProperty(RocketMQHeaders.PREFIX + RocketMQHeaders.TAGS));
assertNull(rocketMsg.getTags());
}
}

23
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/copyright/Apache.xml

@ -0,0 +1,23 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<component name="CopyrightManager">
<copyright>
<option name="myName" value="Apache" />
<option name="notice" value="Licensed to the Apache Software Foundation (ASF) under one or more&#10;contributor license agreements. See the NOTICE file distributed with&#10;this work for additional information regarding copyright ownership.&#10;The ASF licenses this file to You under the Apache License, Version 2.0&#10;(the &quot;License&quot;); you may not use this file except in compliance with&#10;the License. You may obtain a copy of the License at&#10;&#10; http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
</copyright>
</component>

64
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/copyright/profiles_settings.xml

@ -0,0 +1,64 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<component name="CopyrightManager">
<settings default="Apache">
<module2copyright>
<element module="All" copyright="Apache"/>
</module2copyright>
<LanguageOptions name="GSP">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="HTML">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="JAVA">
<option name="fileTypeOverride" value="3" />
<option name="addBlankAfter" value="false" />
</LanguageOptions>
<LanguageOptions name="JSP">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="JSPX">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="MXML">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="Properties">
<option name="fileTypeOverride" value="3"/>
<option name="block" value="false"/>
</LanguageOptions>
<LanguageOptions name="SPI">
<option name="fileTypeOverride" value="3"/>
<option name="block" value="false"/>
</LanguageOptions>
<LanguageOptions name="XML">
<option name="fileTypeOverride" value="3"/>
<option name="prefixLines" value="false"/>
</LanguageOptions>
<LanguageOptions name="__TEMPLATE__">
<option name="separateBefore" value="true"/>
<option name="lenBefore" value="1"/>
</LanguageOptions>
</settings>
</component>

135
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/rmq_checkstyle.xml

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!--Refer http://checkstyle.sourceforge.net/reports/google-java-style.html#s2.2-file-encoding -->
<module name="Checker">
<property name="localeLanguage" value="en"/>
<!--To configure the check to report on the first instance in each file-->
<module name="FileTabCharacter"/>
<!-- header -->
<module name="RegexpHeader">
<property name="header" value="/\*\nLicensed to the Apache Software Foundation*"/>
<property name="fileExtensions" value="java" />
</module>
<module name="RegexpSingleline">
<property name="format" value="System\.out\.println"/>
<property name="message" value="Prohibit invoking System.out.println in source code !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="//FIXME"/>
<property name="message" value="Recommended fix FIXME task !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="//TODO"/>
<property name="message" value="Recommended fix TODO task !"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@alibaba"/>
<property name="message" value="Recommended remove @alibaba keyword!"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@taobao"/>
<property name="message" value="Recommended remove @taobao keyword!"/>
</module>
<module name="RegexpSingleline">
<property name="format" value="@author"/>
<property name="message" value="Recommended remove @author tag in javadoc!"/>
</module>
<module name="RegexpSingleline">
<property name="format"
value=".*[\u3400-\u4DB5\u4E00-\u9FA5\u9FA6-\u9FBB\uF900-\uFA2D\uFA30-\uFA6A\uFA70-\uFAD9\uFF00-\uFFEF\u2E80-\u2EFF\u3000-\u303F\u31C0-\u31EF]+.*"/>
<property name="message" value="Not allow chinese character !"/>
</module>
<module name="FileLength">
<property name="max" value="3000"/>
</module>
<module name="TreeWalker">
<module name="UnusedImports">
<property name="processJavadoc" value="true"/>
</module>
<module name="RedundantImport"/>
<!--<module name="IllegalImport" />-->
<!--Checks that classes that override equals() also override hashCode()-->
<module name="EqualsHashCode"/>
<!--Checks for over-complicated boolean expressions. Currently finds code like if (topic == true), topic || true, !false, etc.-->
<module name="SimplifyBooleanExpression"/>
<module name="OneStatementPerLine"/>
<module name="UnnecessaryParentheses"/>
<!--Checks for over-complicated boolean return statements. For example the following code-->
<module name="SimplifyBooleanReturn"/>
<!--Check that the default is after all the cases in producerGroup switch statement-->
<module name="DefaultComesLast"/>
<!--Detects empty statements (standalone ";" semicolon)-->
<module name="EmptyStatement"/>
<!--Checks that long constants are defined with an upper ell-->
<module name="UpperEll"/>
<module name="ConstantName">
<property name="format" value="(^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$)|(^log$)"/>
</module>
<!--Checks that local, non-final variable names conform to producerGroup format specified by the format property-->
<module name="LocalVariableName"/>
<!--Validates identifiers for local, final variables, including catch parameters-->
<module name="LocalFinalVariableName"/>
<!--Validates identifiers for non-static fields-->
<module name="MemberName"/>
<!--Validates identifiers for class type parameters-->
<module name="ClassTypeParameterName">
<property name="format" value="^[A-Z0-9]*$"/>
</module>
<!--Validates identifiers for method type parameters-->
<module name="MethodTypeParameterName">
<property name="format" value="^[A-Z0-9]*$"/>
</module>
<module name="PackageName"/>
<module name="ParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!--Checks that there are no import statements that use the * notation-->
<module name="AvoidStarImport"/>
<!--whitespace-->
<module name="GenericWhitespace"/>
<module name="NoWhitespaceBefore"/>
<module name="NoWhitespaceAfter"/>
<module name="WhitespaceAround">
<property name="allowEmptyConstructors" value="true"/>
<property name="allowEmptyMethods" value="true"/>
</module>
<module name="Indentation"/>
<module name="MethodParamPad"/>
<module name="ParenPad"/>
<module name="TypecastParenPad"/>
</module>
</module>

157
esua-epdc/epdc-commons/rocketmq-spring-rocketmq-spring-all/style/rmq_codeStyle.xml

@ -0,0 +1,157 @@
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<code_scheme name="rocketmq">
<option name="USE_SAME_INDENTS" value="true"/>
<option name="IGNORE_SAME_INDENTS_FOR_LANGUAGES" value="true"/>
<option name="OTHER_INDENT_OPTIONS">
<value>
<option name="INDENT_SIZE" value="4"/>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="4"/>
<option name="USE_TAB_CHARACTER" value="false"/>
<option name="SMART_TABS" value="false"/>
<option name="LABEL_INDENT_SIZE" value="0"/>
<option name="LABEL_INDENT_ABSOLUTE" value="false"/>
<option name="USE_RELATIVE_INDENTS" value="false"/>
</value>
</option>
<option name="PREFER_LONGER_NAMES" value="false"/>
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="1000"/>
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
<value/>
</option>
<option name="IMPORT_LAYOUT_TABLE">
<value>
<package name="" withSubpackages="true" static="false"/>
<emptyLine/>
<package name="" withSubpackages="true" static="true"/>
</value>
</option>
<option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
<option name="JD_P_AT_EMPTY_LINES" value="false"/>
<option name="JD_KEEP_INVALID_TAGS" value="false"/>
<option name="JD_DO_NOT_WRAP_ONE_LINE_COMMENTS" value="true"/>
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="WHILE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
<option name="LABELED_STATEMENT_WRAP" value="1"/>
<option name="WRAP_COMMENTS" value="true"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<JavaCodeStyleSettings>
<option name="CLASS_NAMES_IN_JAVADOC" value="3"/>
</JavaCodeStyleSettings>
<XML>
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
</XML>
<ADDITIONAL_INDENT_OPTIONS fileType="haml">
<option name="INDENT_SIZE" value="2"/>
</ADDITIONAL_INDENT_OPTIONS>
<codeStyleSettings language="Groovy">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="HOCON">
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
</codeStyleSettings>
<codeStyleSettings language="JAVA">
<option name="KEEP_CONTROL_STATEMENT_IN_ONE_LINE" value="false"/>
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="WHILE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="SPACE_AFTER_TYPE_CAST" value="false"/>
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="ARRAY_INITIALIZER_LBRACE_ON_NEXT_LINE" value="true"/>
<option name="LABELED_STATEMENT_WRAP" value="1"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="JSON">
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
</codeStyleSettings>
<codeStyleSettings language="Scala">
<option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1"/>
<option name="KEEP_BLANK_LINES_IN_CODE" value="1"/>
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
<option name="ELSE_ON_NEW_LINE" value="true"/>
<option name="WHILE_ON_NEW_LINE" value="true"/>
<option name="CATCH_ON_NEW_LINE" value="true"/>
<option name="FINALLY_ON_NEW_LINE" value="true"/>
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
<option name="ALIGN_MULTILINE_FOR" value="false"/>
<option name="METHOD_PARAMETERS_WRAP" value="1"/>
<option name="METHOD_ANNOTATION_WRAP" value="1"/>
<option name="CLASS_ANNOTATION_WRAP" value="1"/>
<option name="FIELD_ANNOTATION_WRAP" value="1"/>
<option name="PARENT_SETTINGS_INSTALLED" value="true"/>
<indentOptions>
<option name="INDENT_SIZE" value="4"/>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
<option name="TAB_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
<codeStyleSettings language="XML">
<indentOptions>
<option name="CONTINUATION_INDENT_SIZE" value="4"/>
</indentOptions>
</codeStyleSettings>
</code_scheme>

2
esua-epdc/epdc-module/epdc-custom/epdc-custom-client/src/main/java/com/elink/esua/epdc/dto/consult/GridOperatorInfoDTO.java

@ -108,6 +108,8 @@ public class GridOperatorInfoDTO implements Serializable {
*/
private String[] allDeptIds;
private String allDeptIdsStr;
/**
* 所有部门名称
*/

12
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/pom.xml

@ -86,6 +86,12 @@
<artifactId>epdc-commons-tools-wx-ma</artifactId>
<version>${project.version}</version>
</dependency>
<!--RocketMQ-->
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.0.3</version>
</dependency>
</dependencies>
<build>
@ -175,6 +181,9 @@
<nacos.register-enabled>false</nacos.register-enabled>
<nacos.server-addr>47.104.224.45:8848</nacos.server-addr>
<nacos.register.ip></nacos.register.ip>
<!--RocketMQ-->
<rocketmq.name.server>47.104.85.99:9876;114.215.125.123:9876</rocketmq.name.server>
<rocketmq.consumer.group>organizationGroup</rocketmq.consumer.group>
</properties>
</profile>
@ -208,6 +217,9 @@
<nacos.register-enabled>true</nacos.register-enabled>
<nacos.server-addr>47.104.224.45:8848</nacos.server-addr>
<!--RocketMQ-->
<rocketmq.name.server>47.104.85.99:9876;114.215.125.123:9876</rocketmq.name.server>
<rocketmq.consumer.group>organizationGroup</rocketmq.consumer.group>
</properties>
</profile>

11
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/consult/dao/GridOperatorInfoDao.java

@ -56,4 +56,15 @@ public interface GridOperatorInfoDao extends BaseDao<GridOperatorInfoEntity> {
* @date 2020/3/3 9:57
*/
List<GridOperatorListResultDTO> selectListGridOperator(GridOperatorListFormDTO formDto);
/**
*
* 查询需要修改的组织机构信息
*
* @params [deptId]
* @return java.util.List<com.elink.esua.epdc.dto.consult.GridOperatorInfoDTO>
* @author liuchuang
* @since 2020/3/7 14:09
*/
List<GridOperatorInfoDTO> selectListOfOrganizationInfo(String deptId);
}

12
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/consult/service/GridOperatorInfoService.java

@ -25,6 +25,7 @@ import com.elink.esua.epdc.dto.enterprise.EnterpriseInfoDTO;
import com.elink.esua.epdc.dto.consult.form.GridOperatorListFormDTO;
import com.elink.esua.epdc.dto.consult.result.GridOperatorListResultDTO;
import com.elink.esua.epdc.modules.consult.entity.GridOperatorInfoEntity;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import java.util.List;
import java.util.Map;
@ -132,4 +133,15 @@ public interface GridOperatorInfoService extends BaseService<GridOperatorInfoEnt
* @date 2020/3/4 12:43
*/
boolean isExistsByDutyId(String dutyCategoryId);
/**
*
* 修改组织机构信息
*
* @params [dto]
* @return void
* @author liuchuang
* @since 2020/3/7 1:23
*/
void modifyOrganizationInfo(OrganizationModifyDTO dto);
}

56
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/consult/service/impl/GridOperatorInfoServiceImpl.java

@ -35,11 +35,13 @@ import com.elink.esua.epdc.modules.consult.entity.GridOperatorInfoEntity;
import com.elink.esua.epdc.modules.consult.redis.GridOperatorInfoRedis;
import com.elink.esua.epdc.modules.consult.service.GridOperatorInfoService;
import com.elink.esua.epdc.modules.feign.AdminFeignClient;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -181,4 +183,58 @@ public class GridOperatorInfoServiceImpl extends BaseServiceImpl<GridOperatorInf
return false;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void modifyOrganizationInfo(OrganizationModifyDTO dto) {
// 查询需要修改的组织机构信息
List<GridOperatorInfoDTO> gridList = baseDao.selectListOfOrganizationInfo(dto.getDeptId().toString());
if (null != gridList && gridList.size() > 0) {
// 组织机构信息处理
List<GridOperatorInfoEntity> entities = handleOrganizationInfo(dto, gridList);
// 更新事件组织机构信息
updateBatchById(entities);
}
}
/**
*
* 组织机构信息处理
*
* @params [dto, gridList]
* @return java.util.List<com.elink.esua.epdc.modules.consult.entity.GridOperatorInfoEntity>
* @author liuchuang
* @since 2020/3/7 14:12
*/
private List<GridOperatorInfoEntity> handleOrganizationInfo(OrganizationModifyDTO dto, List<GridOperatorInfoDTO> gridList) {
List<GridOperatorInfoEntity> entities = new ArrayList<>();
for (GridOperatorInfoDTO grid: gridList) {
GridOperatorInfoEntity entity = new GridOperatorInfoEntity();
if (StringUtils.isNotEmpty(grid.getParentDeptIds()) && StringUtils.isNotEmpty(grid.getParentDeptNames())) {
List<String> parentDeptIds = Arrays.asList(grid.getParentDeptIds().split(","));
List<String> parentDeptNames = Arrays.asList(grid.getParentDeptNames().split("-"));
int index = parentDeptIds.indexOf(dto.getDeptId().toString());
if (index >= 0 && parentDeptNames.size() > index) {
parentDeptNames.set(index, dto.getNewDeptName());
entity.setId(grid.getId());
entity.setParentDeptNames(StringUtils.join(parentDeptNames, "-"));
}
}
if (StringUtils.isNotEmpty(grid.getAllDeptIdsStr()) && StringUtils.isNotEmpty(grid.getAllDeptNames())) {
List<String> allDeptIds = Arrays.asList(grid.getAllDeptIdsStr().split(","));
List<String> allDeptNames = Arrays.asList(grid.getAllDeptNames().split("-"));
int index = allDeptIds.indexOf(dto.getDeptId().toString());
if (index >= 0 && allDeptNames.size() > index) {
allDeptNames.set(index, dto.getNewDeptName());
entity.setId(grid.getId());
entity.setAllDeptNames(StringUtils.join(allDeptNames, "-"));
}
}
entities.add(entity);
}
return entities;
}
}

11
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/enterprise/dao/EnterpriseInfoDao.java

@ -62,4 +62,15 @@ public interface EnterpriseInfoDao extends BaseDao<EnterpriseInfoEntity> {
* @Param [params]
**/
List<EnterpriseInfoDTO> selectEnterpriseInfoPageFromPc(Map<String, Object> params);
/**
*
* 查询需要修改组织机构信息的企业信息
*
* @params [deptId]
* @return java.util.List<com.elink.esua.epdc.dto.enterprise.EnterpriseInfoDTO>
* @author liuchuang
* @since 2020/3/7 13:52
*/
List<EnterpriseInfoDTO> selectListOfOrganizationInfo(String deptId);
}

12
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/enterprise/service/EnterpriseInfoService.java

@ -25,6 +25,7 @@ import com.elink.esua.epdc.dto.enterprise.form.EnterpriseInfoFormDTO;
import com.elink.esua.epdc.dto.enterprise.result.EnterpriseInfoResultDTO;
import com.elink.esua.epdc.dto.form.CompleteRequisiteInfoDTO;
import com.elink.esua.epdc.modules.enterprise.entity.EnterpriseInfoEntity;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -143,4 +144,15 @@ public interface EnterpriseInfoService extends BaseService<EnterpriseInfoEntity>
* @Param [params]
**/
List<EnterpriseInfoDTO> listExport(Map<String, Object> params);
/**
*
* 企业信息表修改组织机构信息
*
* @params [dto]
* @return void
* @author liuchuang
* @since 2020/3/7 1:23
*/
void modifyOrganizationInfo(OrganizationModifyDTO dto);
}

56
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/enterprise/service/impl/EnterpriseInfoServiceImpl.java

@ -39,12 +39,14 @@ import com.elink.esua.epdc.modules.enterprise.entity.EnterpriseInfoEntity;
import com.elink.esua.epdc.modules.enterprise.service.EnterpriseInfoService;
import com.elink.esua.epdc.modules.feign.AdminFeignClient;
import com.elink.esua.epdc.modules.feign.UserFeignClient;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -185,4 +187,58 @@ public class EnterpriseInfoServiceImpl extends BaseServiceImpl<EnterpriseInfoDao
public List<EnterpriseInfoDTO> listExport(Map<String, Object> params) {
return baseDao.selectEnterpriseInfoPageFromPc(params);
}
@Override
@Transactional(rollbackFor = Exception.class)
public void modifyOrganizationInfo(OrganizationModifyDTO dto) {
// 查询需要修改组织机构信息企业
List<EnterpriseInfoDTO> enterpriseList = baseDao.selectListOfOrganizationInfo(dto.getDeptId().toString());
if (null != enterpriseList && enterpriseList.size() > 0) {
// 组织机构信息处理
List<EnterpriseInfoEntity> entities = handleOrganizationInfo(dto, enterpriseList);
// 更新事件组织机构信息
updateBatchById(entities);
}
}
/**
*
* 组织机构信息处理
*
* @params [dto, eventsList]
* @return java.util.List<EpdcEventsEntity>
* @author liuchuang
* @since 2020/3/7 13:54
*/
private List<EnterpriseInfoEntity> handleOrganizationInfo(OrganizationModifyDTO dto, List<EnterpriseInfoDTO> enterpriseList) {
List<EnterpriseInfoEntity> entities = new ArrayList<>();
for (EnterpriseInfoDTO enterprise: enterpriseList) {
EnterpriseInfoEntity entity = new EnterpriseInfoEntity();
if (StringUtils.isNotEmpty(enterprise.getParentDeptIds()) && StringUtils.isNotEmpty(enterprise.getParentDeptNames())) {
List<String> parentDeptIds = Arrays.asList(enterprise.getParentDeptIds().split(","));
List<String> parentDeptNames = Arrays.asList(enterprise.getParentDeptNames().split("-"));
int index = parentDeptIds.indexOf(dto.getDeptId().toString());
if (index >= 0 && parentDeptNames.size() > index) {
parentDeptNames.set(index, dto.getNewDeptName());
entity.setId(enterprise.getId());
entity.setParentDeptNames(StringUtils.join(parentDeptNames, "-"));
}
}
if (StringUtils.isNotEmpty(enterprise.getAllDeptIds()) && StringUtils.isNotEmpty(enterprise.getAllDeptNames())) {
List<String> allDeptIds = Arrays.asList(enterprise.getAllDeptIds().split(","));
List<String> allDeptNames = Arrays.asList(enterprise.getAllDeptNames().split("-"));
int index = allDeptIds.indexOf(dto.getDeptId().toString());
if (index >= 0 && allDeptNames.size() > index) {
allDeptNames.set(index, dto.getNewDeptName());
entity.setId(enterprise.getId());
entity.setAllDeptNames(StringUtils.join(allDeptNames, "-"));
}
}
entities.add(entity);
}
return entities;
}
}

22
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/evaluate/dao/EvaluateDeptDao.java

@ -50,4 +50,26 @@ public interface EvaluateDeptDao extends BaseDao<EvaluateDeptEntity> {
List<EvaluateDeptCountResultDTO> getEvaluateDeptCount(Map<String, Object> params);
void deptUpdate();
/**
*
* 查询需要修改组织机构信息事件
*
* @params [deptId]
* @return java.util.List<com.elink.esua.epdc.dto.evaluate.EvaluateDeptDTO>
* @author liuchuang
* @since 2020/3/7 13:58
*/
List<EvaluateDeptDTO> selectListOfOrganizationInfo(String deptId);
/**
*
* 更新部门名称
*
* @params [newDeptName, deptId]
* @return void
* @author liuchuang
* @since 2020/3/7 1:20
*/
void updateDeptNameByDeptId(String newDeptName, Long deptId);
}

12
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/evaluate/service/EvaluateDeptService.java

@ -22,6 +22,7 @@ import com.elink.esua.epdc.commons.tools.page.PageData;
import com.elink.esua.epdc.dto.evaluate.result.EvaluateDeptCountResultDTO;
import com.elink.esua.epdc.dto.evaluate.EvaluateDeptDTO;
import com.elink.esua.epdc.modules.evaluate.entity.EvaluateDeptEntity;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import java.util.List;
import java.util.Map;
@ -109,4 +110,15 @@ public interface EvaluateDeptService extends BaseService<EvaluateDeptEntity> {
* @date 2020-02-05
*/
void delete(String[] ids);
/**
*
* 评价部门表修改组织机构信息
*
* @params [dto]
* @return void
* @author liuchuang
* @since 2020/3/7 1:23
*/
void modifyOrganizationInfo(OrganizationModifyDTO dto);
}

59
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/modules/evaluate/service/impl/EvaluateDeptServiceImpl.java

@ -29,11 +29,13 @@ import com.elink.esua.epdc.modules.evaluate.dao.EvaluateDeptDao;
import com.elink.esua.epdc.modules.evaluate.entity.EvaluateDeptEntity;
import com.elink.esua.epdc.modules.evaluate.redis.EvaluateDeptRedis;
import com.elink.esua.epdc.modules.evaluate.service.EvaluateDeptService;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
@ -131,4 +133,61 @@ public class EvaluateDeptServiceImpl extends BaseServiceImpl<EvaluateDeptDao, Ev
baseDao.deleteBatchIds(Arrays.asList(ids));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void modifyOrganizationInfo(OrganizationModifyDTO dto) {
// 查询需要修改的组织机构信息
List<EvaluateDeptDTO> evaluateList = baseDao.selectListOfOrganizationInfo(dto.getDeptId().toString());
if (null != evaluateList && evaluateList.size() > 0) {
// 组织机构信息处理
List<EvaluateDeptEntity> entities = handleOrganizationInfo(dto, evaluateList);
// 更新事件组织机构信息
updateBatchById(entities);
}
// 更新网格名称
baseDao.updateDeptNameByDeptId(dto.getNewDeptName(), dto.getDeptId());
}
/**
*
* 组织机构信息处理
*
* @params [dto, eventsList]
* @return java.util.List<EvaluateDeptEntity>
* @author liuchuang
* @since 2020/3/7 14:02
*/
private List<EvaluateDeptEntity> handleOrganizationInfo(OrganizationModifyDTO dto, List<EvaluateDeptDTO> evaluateList) {
List<EvaluateDeptEntity> entities = new ArrayList<>();
for (EvaluateDeptDTO evaluate: evaluateList) {
EvaluateDeptEntity entity = new EvaluateDeptEntity();
if (StringUtils.isNotEmpty(evaluate.getParentDeptIds()) && StringUtils.isNotEmpty(evaluate.getParentDeptNames())) {
List<String> parentDeptIds = Arrays.asList(evaluate.getParentDeptIds().split(","));
List<String> parentDeptNames = Arrays.asList(evaluate.getParentDeptNames().split("-"));
int index = parentDeptIds.indexOf(dto.getDeptId().toString());
if (index >= 0 && parentDeptNames.size() > index) {
parentDeptNames.set(index, dto.getNewDeptName());
entity.setId(evaluate.getId());
entity.setParentDeptNames(StringUtils.join(parentDeptNames, "-"));
}
}
if (StringUtils.isNotEmpty(evaluate.getAllDeptIds()) && StringUtils.isNotEmpty(evaluate.getAllDeptNames())) {
List<String> allDeptIds = Arrays.asList(evaluate.getAllDeptIds().split(","));
List<String> allDeptNames = Arrays.asList(evaluate.getAllDeptNames().split("-"));
int index = allDeptIds.indexOf(dto.getDeptId().toString());
if (index >= 0 && allDeptNames.size() > index) {
allDeptNames.set(index, dto.getNewDeptName());
entity.setId(evaluate.getId());
entity.setAllDeptNames(StringUtils.join(allDeptNames, "-"));
}
}
entities.add(entity);
}
return entities;
}
}

59
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/rocketmq/consumer/OrganizationModifyConsumer.java

@ -0,0 +1,59 @@
package com.elink.esua.epdc.rocketmq.consumer;
import com.alibaba.fastjson.JSONObject;
import com.elink.esua.epdc.commons.tools.constant.RocketMqConstant;
import com.elink.esua.epdc.modules.consult.service.GridOperatorInfoService;
import com.elink.esua.epdc.modules.enterprise.service.EnterpriseInfoService;
import com.elink.esua.epdc.modules.evaluate.service.EvaluateDeptService;
import com.elink.esua.epdc.rocketmq.dto.OrganizationModifyDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.common.message.MessageExt;
import org.apache.rocketmq.spring.annotation.MessageModel;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.xml.ws.Action;
/**
*
* 组织机构信息修改-监听MQ消息
*
* @Authorliuchuang
* @Date2020/3/7 13:38
*/
@Slf4j
@Component
@RocketMQMessageListener(topic = RocketMqConstant.MQ_TOPIC_ORGANIZATION, consumerGroup = "${rocketmq.consumer.group}", messageModel = MessageModel.BROADCASTING)
public class OrganizationModifyConsumer implements RocketMQListener<MessageExt> {
@Autowired
private EnterpriseInfoService enterpriseInfoService;
@Autowired
private EvaluateDeptService evaluateDeptService;
@Autowired
private GridOperatorInfoService gridOperatorInfoService;
@Override
public void onMessage(MessageExt messageExt) {
log.info("EPDC-CUSTOM-SERVER消费消息START:{topic:{}, msgId:{}}", RocketMqConstant.MQ_TOPIC_ORGANIZATION, messageExt.getMsgId());
try {
String charset = "UTF-8";
String body = new String(messageExt.getBody(), charset);
OrganizationModifyDTO dto = JSONObject.parseObject(body, OrganizationModifyDTO.class);
// 企业信息表修改组织机构信息
enterpriseInfoService.modifyOrganizationInfo(dto);
// 评价部门表修改组织机构信息
evaluateDeptService.modifyOrganizationInfo(dto);
// 网格员信息表修改组织机构信息
gridOperatorInfoService.modifyOrganizationInfo(dto);
log.info("EPDC-CUSTOM-SERVER消费消息END:{topic:{}, msgId:{}, body:{}}", RocketMqConstant.MQ_TOPIC_ORGANIZATION, messageExt.getMsgId(), body);
} catch (Exception e) {
log.info("EPDC-CUSTOM-SERVER消费消息失败:msgId:{}", messageExt.getMsgId());
e.printStackTrace();
}
}
}

37
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/java/com/elink/esua/epdc/rocketmq/dto/OrganizationModifyDTO.java

@ -0,0 +1,37 @@
package com.elink.esua.epdc.rocketmq.dto;
import lombok.Data;
import java.io.Serializable;
/**
*
* 组织机构信息修改-接收MQ消息DTO
*
* @Authorliuchuang
* @Date2020/3/6 22:34
*/
@Data
public class OrganizationModifyDTO implements Serializable {
private static final long serialVersionUID = -6534846437298229554L;
/**
* 部门ID
*/
private Long deptId;
/**
* 旧部门名称
*/
private String oldDeptName;
/**
* 新部门名称
*/
private String newDeptName;
/**
* 部门类型
*/
private String typeKey;
}

7
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/application.yml

@ -90,4 +90,9 @@ wx:
# 工作端的appId
work: @work.wx.ma.appId@
# 数据分析端的appId
analysis: @analysis.wx.ma.appId@
analysis: @analysis.wx.ma.appId@
rocketmq:
name-server: @rocketmq.name.server@
consumer:
group: @rocketmq.consumer.group@

13
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/mapper/consult/GridOperatorInfoDao.xml

@ -67,4 +67,17 @@
LIMIT #{pageIndex}, #{pageSize}
</select>
<select id="selectListOfOrganizationInfo" resultType="com.elink.esua.epdc.dto.consult.GridOperatorInfoDTO">
SELECT
ID,
PARENT_DEPT_IDS,
PARENT_DEPT_NAMES,
ALL_DEPT_IDS as allDeptIdsStr,
ALL_DEPT_NAMES
FROM
epdc_grid_operator_info
WHERE
FIND_IN_SET( #{deptId}, ALL_DEPT_IDS )
</select>
</mapper>

13
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/mapper/enterprise/EnterpriseInfoDao.xml

@ -70,4 +70,17 @@
ORDER BY
CREATED_TIME DESC
</select>
<select id="selectListOfOrganizationInfo" resultType="com.elink.esua.epdc.dto.enterprise.EnterpriseInfoDTO">
SELECT
ID,
PARENT_DEPT_IDS,
PARENT_DEPT_NAMES,
ALL_DEPT_IDS,
ALL_DEPT_NAMES
FROM
epdc_enterprise_info
WHERE
FIND_IN_SET( #{deptId}, ALL_DEPT_IDS )
</select>
</mapper>

17
esua-epdc/epdc-module/epdc-custom/epdc-custom-server/src/main/resources/mapper/evaluate/EvaluateDeptDao.xml

@ -249,4 +249,21 @@
) dept
</insert>
<select id="selectListOfOrganizationInfo" resultType="com.elink.esua.epdc.dto.evaluate.EvaluateDeptDTO">
SELECT
ID,
PARENT_DEPT_IDS,
PARENT_DEPT_NAMES,
ALL_DEPT_IDS,
ALL_DEPT_NAMES
FROM
epdc_evaluate_dept
WHERE
FIND_IN_SET( #{deptId}, ALL_DEPT_IDS )
</select>
<update id="updateDeptNameByDeptId">
UPDATE epdc_evaluate_dept SET DEPT_NAME = #{newDeptName}, UPDATED_TIME = NOW() WHERE DEPT_ID = #{deptId}
</update>
</mapper>

21
esua-epdc/epdc-module/epdc-events/epdc-events-client/src/main/java/com/elink/esua/epdc/dto/events/EpdcEventsDTO.java

@ -48,5 +48,26 @@ public class EpdcEventsDTO implements Serializable {
* 提交时间
*/
private Date createdTime;
/**
* 父所有部门ID
*/
private String parentDeptIds;
/**
* 父所有部门名称
*/
private String parentDeptNames;
/**
* 所有部门ID
*/
private String allDeptIds;
/**
* 所有部门名称
*/
private String allDeptNames;
/**
* 分类全称
*/
private String categoryFullName;
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save