From 4250eff7859ee908edb04b0b9f5d91fd80c25d81 Mon Sep 17 00:00:00 2001
From: 王彪总
Date: Tue, 1 Jul 2025 22:45:29 +0800
Subject: [PATCH] 1.master1.1.1
---
.classpath | 26 ++++++++++++++++++++++++++
.project | 11 +++++++++++
pom.xml | 10 +++++-----
src/main/java/org/apache/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java | 236 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/RocketMQProperties.java | 86 --------------------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/annotation/RocketMQMessageListener.java | 77 -----------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java | 440 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java | 23 -----------------------
src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java | 355 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java | 52 ----------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java | 22 ----------------------
src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListener.java | 27 ---------------------------
src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListenerContainer.java | 29 -----------------------------
src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQTemplate.java | 302 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/enums/ConsumeMode.java | 35 -----------------------------------
src/main/java/org/apache/rocketmq/spring/starter/enums/SelectorType.java | 34 ----------------------------------
src/main/java/org/apache/rocketmq/spring/starter/exception/ConvertMsgException.java | 27 ---------------------------
src/main/java/org/apache/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java | 149 -----------------------------------------------------------------------------------------------------------------------------------------------------
src/main/java/org/apache/rocketmq/spring/starter/utils/ExceptionUtil.java | 21 ---------------------
src/main/java/org/apache/rocketmq/spring/starter/utils/IPUtil.java | 49 -------------------------------------------------
src/main/java/zteits/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java | 233 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/RocketMQProperties.java | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/annotation/RocketMQMessageListener.java | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java | 441 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java | 23 +++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java | 355 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java | 22 ++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListener.java | 27 +++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListenerContainer.java | 29 +++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/core/RocketMQTemplate.java | 302 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/enums/ConsumeMode.java | 35 +++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/enums/SelectorType.java | 34 ++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/exception/ConvertMsgException.java | 27 +++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/utils/ExceptionUtil.java | 21 +++++++++++++++++++++
src/main/java/zteits/rocketmq/spring/starter/utils/IPUtil.java | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
src/main/resources/META-INF/spring.factories | 2 +-
src/test/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java | 184 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
src/test/java/zteits/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 files changed, 2219 insertions(+), 2154 deletions(-)
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/RocketMQProperties.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListener.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListenerContainer.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQTemplate.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/enums/ConsumeMode.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/enums/SelectorType.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/exception/ConvertMsgException.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/utils/ExceptionUtil.java
delete mode 100644 src/main/java/org/apache/rocketmq/spring/starter/utils/IPUtil.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/RocketMQProperties.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListener.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListenerContainer.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/core/RocketMQTemplate.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/enums/ConsumeMode.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/enums/SelectorType.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/exception/ConvertMsgException.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/utils/ExceptionUtil.java
create mode 100644 src/main/java/zteits/rocketmq/spring/starter/utils/IPUtil.java
delete mode 100644 src/test/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
create mode 100644 src/test/java/zteits/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
diff --git a/.classpath b/.classpath
index 6d7587a..a97cb0e 100644
--- a/.classpath
+++ b/.classpath
@@ -9,12 +9,14 @@
+
+
@@ -27,5 +29,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.project b/.project
index f84930e..4e30ca7 100644
--- a/.project
+++ b/.project
@@ -20,4 +20,15 @@
org.eclipse.jdt.core.javanature
org.eclipse.m2e.core.maven2Nature
+
+
+ 1751124793989
+
+ 30
+
+ org.eclipse.core.resources.regexFilterMatcher
+ node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__
+
+
+
diff --git a/pom.xml b/pom.xml
index 6ce8363..6a298b0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,9 +20,9 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
- org.apache.rocketmq
+ com.zteits.rocketmq
spring-boot-starter-rocketmq
- 1.0.8-SNAPSHOT
+ 1.1.1
Spring Boot Rocket Starter
Starter for messaging using Apache RocketMQ
@@ -107,12 +107,12 @@
nexus_releases
core Release Repository
- http://maven.renniting.cn/repository/maven-releases/
+ https://maven2.renniting.cn/repository/maven-releases/
nexus_snapshots
core Snapshots Repository
- http://maven.renniting.cn/repository/maven-snapshots/
+ https://maven2.renniting.cn/repository/maven-snapshots/
@@ -169,4 +169,4 @@
-
\ No newline at end of file
+
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java b/src/main/java/org/apache/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
deleted file mode 100644
index 2d65d3d..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.starter;
-
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.METHOD_DESTROY;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUMER_GROUP;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_MODE;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_THREAD_MAX;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_MESSAGE_MODEL;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_OBJECT_MAPPER;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_LISTENER;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_TEMPLATE;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_EXPRESS;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_TYPE;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.*;
-
-import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
-import java.util.UUID;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.annotation.Resource;
-
-import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
-import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;
-import org.apache.rocketmq.spring.starter.core.AliyunRocketMQListenerContainer;
-import org.apache.rocketmq.spring.starter.core.RocketMQListener;
-import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;
-import org.json.JSONObject;
-import org.springframework.aop.support.AopUtils;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-import org.springframework.beans.factory.support.DefaultListableBeanFactory;
-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.context.properties.EnableConfigurationProperties;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.annotation.Order;
-import org.springframework.core.env.StandardEnvironment;
-import org.springframework.util.Assert;
-
-import com.aliyun.openservices.ons.api.ONSFactory;
-import com.aliyun.openservices.ons.api.Producer;
-import com.aliyun.openservices.ons.api.PropertyKeyConst;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Configuration
-@EnableConfigurationProperties(RocketMQProperties.class)
-@Order
-@Slf4j
-public class AliyunRocketMQAutoConfiguration {
-
- @Bean
- @ConditionalOnClass(RocketMQProperties.Producer.class)
- @ConditionalOnMissingBean(RocketMQProperties.Producer.class)
- @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"environmentPrefix", "producer.group"})
- public Producer mqProducer(RocketMQProperties rocketMQProperties) {
-
- RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer();
- String groupName = producerConfig.getGroup();
- Assert.hasText(groupName, "[spring.rocketmq.producer.group] must not be null");
- String accessKey = rocketMQProperties.getAccessKey();
- Assert.hasText(accessKey, "[spring.rocketmq.accessKey] must not be null");
- String secretKey = rocketMQProperties.getSecretKey();
- Assert.hasText(secretKey, "[spring.rocketmq.secretKey] must not be null");
- String onsAddr = rocketMQProperties.getOnsAddr();
- Assert.hasText(secretKey, "[spring.rocketmq.onsAddr] must not be null");
- String environmentPrefix = rocketMQProperties.getEnvironmentPrefix();
- Assert.hasText(secretKey, "[spring.rocketmq.environmentPrefix] must not be null");
-
- Properties producerProperties = new Properties();
- //生成者ProducerId添加前缀:PID_+环境标识_+groupName
- String pid = "PID_"+environmentPrefix+"_"+groupName;
- log.info("注册生产者PID:"+pid);
- producerProperties.setProperty(PropertyKeyConst.ProducerId, pid);
- producerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
- producerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
- producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, onsAddr);
- log.info("注册生产者producerProperties:"+ JSON.toJSONString(producerProperties));
- //producerProperties.setProperty(PropertyKeyConst.ONSAddr, onsAddr);
- Producer producer = ONSFactory.createProducer(producerProperties);
- log.info("注册生产者完成:"+ JSON.toJSONString(producer));
- return producer;
- }
-
- @Bean
- @ConditionalOnClass(ObjectMapper.class)
- @ConditionalOnMissingBean(name = "rocketMQMessageObjectMapper")
- public ObjectMapper rocketMQMessageObjectMapper() {
- return new ObjectMapper();
- }
-
- @Bean(destroyMethod = "destroy")
- @ConditionalOnBean(Producer.class)
- @ConditionalOnMissingBean(name = "rocketMQTemplate")
- public RocketMQTemplate rocketMQTemplate(Producer mqProducer,RocketMQProperties rocketMQProperties,
- @Autowired(required = false)
- @Qualifier("rocketMQMessageObjectMapper")
- ObjectMapper objectMapper) {
- RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
- rocketMQTemplate.setAliyunProducer(mqProducer);
- rocketMQTemplate.setEnvironmentPrefix(rocketMQProperties.getEnvironmentPrefix());
- if (Objects.nonNull(objectMapper)) {
- rocketMQTemplate.setObjectMapper(objectMapper);
- }
- return rocketMQTemplate;
- }
-
- @Configuration
- @EnableConfigurationProperties(RocketMQProperties.class)
- @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"environmentPrefix", "producer.group"})
- @Order
- public static class ListenerContainerConfiguration implements ApplicationContextAware, InitializingBean {
- private ConfigurableApplicationContext applicationContext;
-
- private AtomicLong counter = new AtomicLong(0);
-
- @Resource
- private StandardEnvironment environment;
-
- @Resource
- private RocketMQProperties rocketMQProperties;
-
- private ObjectMapper objectMapper;
-
- @Autowired
- private RocketMQTemplate rocketMQTemplate;
-
- public ListenerContainerConfiguration() {
- }
-
- @Autowired(required = false)
- public ListenerContainerConfiguration(
- @Qualifier("rocketMQMessageObjectMapper") ObjectMapper objectMapper) {
- this.objectMapper = objectMapper;
- }
-
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- this.applicationContext = (ConfigurableApplicationContext) applicationContext;
- }
-
- @Override
- public void afterPropertiesSet() {
- Map beans = this.applicationContext.getBeansWithAnnotation(RocketMQMessageListener.class);
-
- if (Objects.nonNull(beans)) {
- beans.forEach(this::registerContainer);
- }
- }
-
- private void registerContainer(String beanName, Object bean) {
- String uuid = UUID.randomUUID().toString();
- log.info(uuid+"开始注册消费者,beanName:"+beanName);
- log.info(uuid+"开始注册消费者,rocketMQProperties:"+JSON.toJSONString(rocketMQProperties));
-
- Class> clazz = AopUtils.getTargetClass(bean);
-
- if (!RocketMQListener.class.isAssignableFrom(bean.getClass())) {
- throw new IllegalStateException(clazz + " is not instance of " + RocketMQListener.class.getName());
- }
- RocketMQListener rocketMQListener = (RocketMQListener) bean;
- RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);
- BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(AliyunRocketMQListenerContainer.class);
- // beanBuilder.addPropertyValue(PropertyKeyConst.NAMESRV_ADDR, rocketMQProperties.getOnsAddr());
- beanBuilder.addPropertyValue(PROP_NAMESRV_ADDR, rocketMQProperties.getOnsAddr());
- String topic = rocketMQProperties.getEnvironmentPrefix()+"_"+environment.resolvePlaceholders(annotation.topic());
- log.info(uuid+"订阅的主题topic:"+topic);
- beanBuilder.addPropertyValue(PROP_TOPIC, topic);
- String cid = "GID_"+rocketMQProperties.getEnvironmentPrefix()+"_"+environment.resolvePlaceholders(annotation.consumerGroup());
- log.info(uuid+"消费者CID:"+cid);
- //消费者ConsumerId添加前缀:PID_+环境标识_+groupName
- beanBuilder.addPropertyValue(PROP_CONSUMER_GROUP, cid);
- beanBuilder.addPropertyValue(PROP_CONSUME_MODE, annotation.consumeMode());
- beanBuilder.addPropertyValue(PROP_CONSUME_THREAD_MAX, annotation.consumeThreadMax());
- beanBuilder.addPropertyValue(PROP_MESSAGE_MODEL, annotation.messageModel());
- beanBuilder.addPropertyValue(PROP_SELECTOR_EXPRESS, environment.resolvePlaceholders(annotation.selectorExpress()));
- beanBuilder.addPropertyValue(PROP_SELECTOR_TYPE, annotation.selectorType());
- beanBuilder.addPropertyValue(PROP_ROCKETMQ_LISTENER, rocketMQListener);
- beanBuilder.addPropertyValue(PROP_ROCKETMQ_TEMPLATE, rocketMQTemplate);
- beanBuilder.addPropertyValue(PROP_ENVIRONMENT_PREFIX, rocketMQProperties.getEnvironmentPrefix());
- if (Objects.nonNull(objectMapper)) {
- beanBuilder.addPropertyValue(PROP_OBJECT_MAPPER, objectMapper);
- }
- beanBuilder.setDestroyMethodName(METHOD_DESTROY);
- //增加阿里云key
- beanBuilder.addPropertyValue(PROP_ACCESS_KEY, rocketMQProperties.getAccessKey());
- beanBuilder.addPropertyValue(PROP_SECRET_KEY, rocketMQProperties.getSecretKey());
-
- String containerBeanName = String.format("%s_%s", AliyunRocketMQListenerContainer.class.getName(), counter.incrementAndGet());
- log.info("消费者容器beanName:"+containerBeanName);
- DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
- beanFactory.registerBeanDefinition(containerBeanName, beanBuilder.getBeanDefinition());
-
- AliyunRocketMQListenerContainer container = beanFactory.getBean(containerBeanName, AliyunRocketMQListenerContainer.class);
-
- if (!container.isStarted()) {
- try {
- container.start();
- } catch (Exception e) {
- log.error("started container failed. {}", container, e);
- throw new RuntimeException(e);
- }
- }
-
- log.info("register rocketMQ listener to container, listenerBeanName:{}, containerBeanName:{}", beanName, containerBeanName);
- }
- }
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/RocketMQProperties.java b/src/main/java/org/apache/rocketmq/spring/starter/RocketMQProperties.java
deleted file mode 100644
index c422df1..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/RocketMQProperties.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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.starter;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-@SuppressWarnings("WeakerAccess")
-@ConfigurationProperties(prefix = "spring.rocketmq")
-@Data
-public class RocketMQProperties {
- /**
- * 环境前缀
- */
- private String environmentPrefix;
- /**
- * 消息队列服务接入点
- */
- private String onsAddr;
-
- /**
- * AccessKey, 用于标识、校验用户身份
- */
- private String accessKey;
- /**
- * SecretKey, 用于标识、校验用户身份
- */
- private String secretKey;
-
- private Producer producer;
- @Data
- public static class Producer {
-
- /**
- * name of producer
- */
- private String group;
-
- /**
- * millis of send message timeout
- */
- private int sendMsgTimeout = 3000;
-
- /**
- * Compress message body threshold, namely, message body larger than 4k will be compressed on default.
- */
- private int compressMsgBodyOverHowmuch = 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;
-
- /**
- * Maximum number of retry to perform internally before claiming sending failure in asynchronous mode.
- * 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 retryAnotherBrokerWhenNotStoreOk = false;
-
- /**
- * Maximum allowed message size in bytes.
- */
- private int maxMessageSize = 1024 * 1024 * 4; // 4M
- }
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/annotation/RocketMQMessageListener.java b/src/main/java/org/apache/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
deleted file mode 100644
index 9e768a8..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.starter.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;
-
-import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
-import org.apache.rocketmq.spring.starter.enums.SelectorType;
-
-import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
-
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Documented
-public @interface RocketMQMessageListener {
-
- /**
- * 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 here for further discussion.
- */
- String consumerGroup();
-
- /**
- * Topic name
- */
- String topic();
-
- /**
- * Control how to selector message
- *
- * @see ExpressionType
- */
- SelectorType selectorType() default SelectorType.TAG;
-
- /**
- * Control which message can be select. Grammar please see {@link ExpressionType#TAG} and {@link ExpressionType#SQL92}
- */
- String selectorExpress() 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;
-
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java b/src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
deleted file mode 100644
index b379593..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
+++ /dev/null
@@ -1,440 +0,0 @@
-/*
- * 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.starter.core;
-
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.CONSUMEFAILED_TAG;
-import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.CONSUMEFAILED_TOPIC;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.nio.charset.Charset;
-import java.util.Date;
-import java.util.List;
-import java.util.Objects;
-import java.util.Properties;
-
-import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
-import org.apache.rocketmq.spring.starter.enums.SelectorType;
-import org.apache.rocketmq.spring.starter.exception.ConvertMsgException;
-import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;
-import org.apache.rocketmq.spring.starter.utils.ExceptionUtil;
-import org.apache.rocketmq.spring.starter.utils.IPUtil;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import com.aliyun.openservices.ons.api.Action;
-import com.aliyun.openservices.ons.api.ConsumeContext;
-import com.aliyun.openservices.ons.api.Consumer;
-import com.aliyun.openservices.ons.api.Message;
-import com.aliyun.openservices.ons.api.MessageListener;
-import com.aliyun.openservices.ons.api.ONSFactory;
-import com.aliyun.openservices.ons.api.PropertyKeyConst;
-import com.aliyun.openservices.ons.api.batch.BatchConsumer;
-import com.aliyun.openservices.ons.api.batch.BatchMessageListener;
-import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
-import com.aliyun.openservices.ons.api.order.MessageOrderListener;
-import com.aliyun.openservices.ons.api.order.OrderAction;
-import com.aliyun.openservices.ons.api.order.OrderConsumer;
-import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.consumer.MessageSelector;
-import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.exception.MQClientException;
-import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-
-@SuppressWarnings("WeakerAccess")
-@Slf4j
-public class AliyunRocketMQListenerContainer implements InitializingBean, RocketMQListenerContainer {
- /**
- * 阿里云分配的accesskey
- */
- @Setter
- private String accessKey;
- /**
- * 阿里云分配的secretKey
- */
- @Setter
- private String secretKey;
-
- @Setter
- @Getter
- private String consumerGroup;
- /**
- * 消息队列服务接入点
- */
- @Setter
- @Getter
- private String onsAddr;
-
- @Setter
- @Getter
- private String nameServerAddr;
-
- @Setter
- @Getter
- private String topic;
-
- @Setter
- @Getter
- private ConsumeMode consumeMode = ConsumeMode.CONCURRENTLY;
-
- @Setter
- @Getter
- private SelectorType selectorType = SelectorType.TAG;
-
- @Setter
- @Getter
- private String selectorExpress = "*";
-
- @Setter
- @Getter
- private MessageModel messageModel = MessageModel.CLUSTERING;
-
- @Setter
- @Getter
- private int consumeThreadMax = 64;
-
- @Getter
- @Setter
- private String charset = "UTF-8";
-
- @Setter
- @Getter
- private ObjectMapper objectMapper = new ObjectMapper();
-
- @Setter
- @Getter
- private boolean started;
-
- @Setter
- private RocketMQListener rocketMQListener;
- /**普通消息*/
- private Consumer consumer;
- /**顺序消息*/
- private OrderConsumer orderConsumer;
- /**批量消息*/
- private BatchConsumer batchConsumer;
-
- private Class messageType;
- /**
- * 环境前缀
- */
- @Setter
- private String environmentPrefix;
-
- @Setter
- private RocketMQTemplate rocketMQTemplate;
-
- public void setupMessageListener(RocketMQListener rocketMQListener) {
- this.rocketMQListener = rocketMQListener;
- }
-
- @Override
- public void destroy() {
- this.setStarted(false);
- if (Objects.nonNull(consumer)) {
- consumer.shutdown();
- }
- if (Objects.nonNull(orderConsumer)) {
- orderConsumer.shutdown();
- }
- if (Objects.nonNull(batchConsumer)) {
- batchConsumer.shutdown();
- }
- log.info("container destroyed, {}", this.toString());
- }
-
- public synchronized void start() throws MQClientException {
-
- if (this.isStarted()) {
- throw new IllegalStateException("container already started. " + this.toString());
- }
-
- initRocketMQPushConsumer();
-
- // parse message type
- this.messageType = getMessageType();
- log.debug("msgType: {}", messageType.getName());
-
- if (Objects.nonNull(consumer)) {
- consumer.start();
- }
- if (Objects.nonNull(orderConsumer)) {
- orderConsumer.start();
- }
- if (Objects.nonNull(batchConsumer)) {
- batchConsumer.start();
- }
- this.setStarted(true);
-
- log.info("started container: {}", this.toString());
- }
-
- public class DefaultMessageListenerConcurrently implements MessageListener {
-
- @SuppressWarnings("unchecked")
- public Action consume(final Message message, final ConsumeContext context){
- Date consumeBeginTime = new Date();
- log.debug("received msg: {}", message);
- try {
- long now = consumeBeginTime.getTime();
- rocketMQListener.onMessage(doConvertMessage(message));
- long costTime = System.currentTimeMillis() - now;
- log.debug("consume {} cost: {} ms", message.getMsgID(), costTime);
- } catch (Exception e) {
- log.warn("consume message failed. message:{}", message, e);
- if(message.getTopic().equals(environmentPrefix+"_"+CONSUMEFAILED_TOPIC) && CONSUMEFAILED_TAG.equals(message.getTag())){
- log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
- return Action.CommitMessage;
- }
- if(e instanceof ConvertMsgException){
- log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
- //消息消费失败,发送失败消息
- this.sendConsumeMsgFailed(message,e,consumeBeginTime);
- return Action.CommitMessage;
- }
- this.sendConsumeMsgFailed(message,e,consumeBeginTime);
- return Action.ReconsumeLater;
- }
-
- return Action.CommitMessage;
- }
- /**
- * 发送消息消费失败消息
- * @param message
- * @param e
- * 2018年3月22日 zhaowg
- */
- private void sendConsumeMsgFailed(Message message, Exception e,Date consumeBeginTime) {
- log.info("消费消息失败,开始发送消费失败MQ");
- String topic = CONSUMEFAILED_TOPIC;
- String tag = CONSUMEFAILED_TAG;
- try{
- Date consumeEndTime = new Date();
- ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
- consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
- consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
- consumeFailedMsgVO.setConsumeGroup(consumerGroup);
- consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
- if(e!=null){
- String errMsg = ExceptionUtil.getTrace(e);
- if(!StringUtils.isEmpty(errMsg)){
- //最多保存1024个字符
- consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
- }
- }
- consumeFailedMsgVO.setMsg(new String(message.getBody()));
- consumeFailedMsgVO.setMsgId(message.getMsgID());
- consumeFailedMsgVO.setMsgKeys(message.getKey());
- consumeFailedMsgVO.setReconsumeTimes(message.getReconsumeTimes());
- consumeFailedMsgVO.setTag(message.getTag());
- consumeFailedMsgVO.setTopic(message.getTopic());
- rocketMQTemplate.sendOneWay(topic, tag, consumeFailedMsgVO);
- log.info("发送消息消费失败MQ成功");
- }catch(Exception e1){
- log.info("发送消息消费失败MQ异常",e);
- }
-
- }
- }
-
- public class DefaultMessageListenerOrderly implements MessageOrderListener {
-
- @Override
- public OrderAction consume(Message message, ConsumeOrderContext context) {
- log.debug("received msg: {}", message);
- try {
- long now = System.currentTimeMillis();
- rocketMQListener.onMessage(doConvertMessage(message));
- long costTime = System.currentTimeMillis() - now;
- log.info("consume {} cost: {} ms", message.getMsgID(), costTime);
- } catch (Exception e) {
- log.warn("consume message failed. message:{}", message, e);
- return OrderAction.Suspend;
- }
- return OrderAction.Success;
- }
- }
-
- public class DefaultMessageListenerBatchs implements BatchMessageListener{
-
- @Override
- public Action consume(List messages, ConsumeContext context) {
- for (Message message : messages) {
- Date consumeBeginTime = new Date();
- log.debug("received msg: {}", message);
- try {
- long now = consumeBeginTime.getTime();
- rocketMQListener.onMessage(doConvertMessage(message));
- long costTime = System.currentTimeMillis() - now;
- log.debug("consume {} cost: {} ms", message.getMsgID(), costTime);
- } catch (Exception e) {
- log.warn("consume message failed. message:{}", message, e);
- if(message.getTopic().equals(environmentPrefix+"_"+CONSUMEFAILED_TOPIC) && CONSUMEFAILED_TAG.equals(message.getTag())){
- log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
- continue;
- }
- if(e instanceof ConvertMsgException){
- log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
- //消息消费失败,发送失败消息
- this.sendConsumeMsgFailed(message,e,consumeBeginTime);
- continue;
- }
- this.sendConsumeMsgFailed(message,e,consumeBeginTime);
- return Action.ReconsumeLater;
- }
- }
- return Action.CommitMessage;
- }
-
- /**
- * 发送消息消费失败消息
- * @param message
- * @param e
- * 2018年3月22日 zhaowg
- */
- private void sendConsumeMsgFailed(Message message, Exception e,Date consumeBeginTime) {
- log.info("消费消息失败,开始发送消费失败MQ");
- String topic = environmentPrefix+"_"+CONSUMEFAILED_TOPIC;
- String tag = CONSUMEFAILED_TAG;
- try{
- Date consumeEndTime = new Date();
- ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
- consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
- consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
- consumeFailedMsgVO.setConsumeGroup(consumerGroup);
- consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
- if(e!=null){
- String errMsg = ExceptionUtil.getTrace(e);
- if(!StringUtils.isEmpty(errMsg)){
- //最多保存1024个字符
- consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
- }
- }
- consumeFailedMsgVO.setMsg(new String(message.getBody()));
- consumeFailedMsgVO.setMsgId(message.getMsgID());
- consumeFailedMsgVO.setMsgKeys(message.getKey());
- consumeFailedMsgVO.setReconsumeTimes(message.getReconsumeTimes());
- consumeFailedMsgVO.setTag(message.getTag());
- consumeFailedMsgVO.setTopic(message.getTopic());
- rocketMQTemplate.sendOneWay(topic, tag, consumeFailedMsgVO);
- log.info("发送消息消费失败MQ成功");
- }catch(Exception e1){
- log.info("发送消息消费失败MQ异常",e);
- }
-
- }
- }
- @Override
- public void afterPropertiesSet() throws Exception {
- start();
- }
-
-
- @SuppressWarnings("unchecked")
- private Object doConvertMessage(Message message) {
- if (Objects.equals(messageType, Message.class)) {
- return message;
- } else {
- String str = new String(message.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 ConvertMsgException("cannot convert message to " + messageType, e);
- }
- }
- }
- }
-
- private Class getMessageType() {
- Type[] interfaces = rocketMQListener.getClass().getGenericInterfaces();
- 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(nameServerAddr, "Property 'nameServer' is required");
- Assert.notNull(topic, "Property 'topic' is required");
-
- Properties consumerProperties = new Properties();
- consumerProperties.setProperty(PropertyKeyConst.ConsumerId, consumerGroup);
- consumerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
- consumerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
- consumerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, nameServerAddr);
- consumerProperties.setProperty(PropertyKeyConst.ConsumeThreadNums, consumeThreadMax+"");
- consumerProperties.setProperty(PropertyKeyConst.MessageModel, messageModel.getModeCN());
- //允许用户自己设置该consumer的一些配置
- if (rocketMQListener instanceof AliyunRocketMQPushConsumerLifecycleListener) {
- ((AliyunRocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumerProperties);
- }
- switch (consumeMode) {
- case ORDERLY://顺序消息
- orderConsumer = ONSFactory.createOrderedConsumer(consumerProperties);
- if(selectorType == SelectorType.TAG){
- orderConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerOrderly());
-// }else if(selectorType == SelectorType.SQL92){
-// orderConsumer.subscribe(topic, MessageSelector.bySql(selectorExpress), new DefaultMessageListenerOrderly());
- }
- break;
- case CONCURRENTLY://普通消息
- consumer = ONSFactory.createConsumer(consumerProperties);
- if(selectorType == SelectorType.TAG){
- consumer.subscribe(topic, selectorExpress, new DefaultMessageListenerConcurrently());
-// }else if(selectorType == SelectorType.SQL92){
-// consumer.subscribe(topic, MessageSelector.bySql(selectorExpress), new DefaultMessageListenerConcurrently());
- }
- break;
- case BATCH://批量消息
- batchConsumer = ONSFactory.createBatchConsumer(consumerProperties);
- batchConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerBatchs());
- break;
- default:
- throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
- }
-
- }
-
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java b/src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
deleted file mode 100644
index e0b1860..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * 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.starter.core;
-
-import java.util.Properties;
-
-public interface AliyunRocketMQPushConsumerLifecycleListener extends RocketMQConsumerLifecycleListener {
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java b/src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
deleted file mode 100644
index 9e9889c..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
+++ /dev/null
@@ -1,355 +0,0 @@
-///*
-// * 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.starter.core;
-//
-//import java.lang.reflect.ParameterizedType;
-//import java.lang.reflect.Type;
-//import java.nio.charset.Charset;
-//import java.util.Date;
-//import java.util.List;
-//import java.util.Objects;
-//
-//import org.apache.commons.lang3.StringUtils;
-//import org.apache.commons.lang3.exception.ExceptionUtils;
-//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.exception.MQClientException;
-//import org.apache.rocketmq.common.message.MessageExt;
-//import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
-//import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
-//import org.apache.rocketmq.spring.starter.enums.SelectorType;
-//import org.apache.rocketmq.spring.starter.exception.ConvertMsgException;
-//import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;
-//import org.apache.rocketmq.spring.starter.utils.IPUtil;
-//import org.springframework.beans.factory.InitializingBean;
-//import org.springframework.util.Assert;
-//
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//
-//import lombok.Getter;
-//import lombok.Setter;
-//import lombok.extern.slf4j.Slf4j;
-//
-//@SuppressWarnings("WeakerAccess")
-//@Slf4j
-//public class DefaultRocketMQListenerContainer implements InitializingBean, RocketMQListenerContainer {
-//
-// @Setter
-// @Getter
-// private long suspendCurrentQueueTimeMillis = 1000;
-//
-// /**
-// * Message consume retry strategy
-1,no retry,put into DLQ directly
0,broker control retry frequency
-// * >0,client control retry frequency
-// */
-// @Setter
-// @Getter
-// private int delayLevelWhenNextConsume = 0;
-//
-// @Setter
-// @Getter
-// private String consumerGroup;
-//
-// @Setter
-// @Getter
-// private String nameServer;
-//
-// @Setter
-// @Getter
-// private String topic;
-//
-// @Setter
-// @Getter
-// private ConsumeMode consumeMode = ConsumeMode.CONCURRENTLY;
-//
-// @Setter
-// @Getter
-// private SelectorType selectorType = SelectorType.TAG;
-//
-// @Setter
-// @Getter
-// private String selectorExpress = "*";
-//
-// @Setter
-// @Getter
-// private MessageModel messageModel = MessageModel.CLUSTERING;
-//
-// @Setter
-// @Getter
-// private int consumeThreadMax = 64;
-//
-// @Getter
-// @Setter
-// private String charset = "UTF-8";
-//
-// @Setter
-// @Getter
-// private ObjectMapper objectMapper = new ObjectMapper();
-//
-// @Setter
-// @Getter
-// private boolean started;
-//
-// @Setter
-// private RocketMQListener rocketMQListener;
-//
-// private DefaultMQPushConsumer consumer;
-//
-// private Class messageType;
-//
-// @Setter
-// private RocketMQTemplate rocketMQTemplate;
-//
-// public void setupMessageListener(RocketMQListener rocketMQListener) {
-// this.rocketMQListener = rocketMQListener;
-// }
-//
-// @Override
-// public void destroy() {
-// this.setStarted(false);
-// if (Objects.nonNull(consumer)) {
-// consumer.shutdown();
-// }
-// log.info("container destroyed, {}", this.toString());
-// }
-//
-// public synchronized void start() throws MQClientException {
-//
-// if (this.isStarted()) {
-// throw new IllegalStateException("container already started. " + this.toString());
-// }
-//
-// initRocketMQPushConsumer();
-//
-// // parse message type
-// this.messageType = getMessageType();
-// log.debug("msgType: {}", messageType.getName());
-//
-// consumer.start();
-// this.setStarted(true);
-//
-// log.info("started container: {}", this.toString());
-// }
-//
-// public class DefaultMessageListenerConcurrently implements MessageListenerConcurrently {
-//
-// @SuppressWarnings("unchecked")
-// public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
-// for (MessageExt messageExt : msgs) {
-// Date consumeBeginTime = new Date();
-// 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);
-// if(messageExt.getTopic().equals("DATA_COLLECTION_TOPIC") && "ConsumeMsgFailed".equals(messageExt.getTags())){
-// log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
-// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
-// }
-// if(e instanceof ConvertMsgException){
-// log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
-// //消息消费失败,发送失败消息
-// this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);
-// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
-// }
-// this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);
-// return ConsumeConcurrentlyStatus.RECONSUME_LATER;
-// }
-// }
-//
-// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
-// }
-// /**
-// * 发送消息消费失败消息
-// * @param messageExt
-// * @param e
-// * 2018年3月22日 zhaowg
-// */
-// private void sendConsumeMsgFailed(MessageExt messageExt, Exception e,Date consumeBeginTime) {
-// log.info("消费消息失败,开始发送消费失败MQ");
-// String topic = "DATA_COLLECTION_TOPIC";
-// String tag = "ConsumeMsgFailed";
-// try{
-// Date consumeEndTime = new Date();
-// String destination = topic+":"+tag;
-// ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
-// consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
-// consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
-// consumeFailedMsgVO.setConsumeGroup(consumerGroup);
-// consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
-// if(e!=null){
-// String errMsg = ExceptionUtils.getStackTrace(e);
-// if(StringUtils.isNotBlank(errMsg)){
-// //最多保存1024个字符
-// consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
-// }
-// }
-// consumeFailedMsgVO.setMsg(new String(messageExt.getBody()));
-// consumeFailedMsgVO.setMsgId(messageExt.getMsgId());
-// consumeFailedMsgVO.setMsgKeys(messageExt.getKeys());
-// consumeFailedMsgVO.setReconsumeTimes(messageExt.getReconsumeTimes());
-// consumeFailedMsgVO.setTag(messageExt.getTags());
-// consumeFailedMsgVO.setTopic(messageExt.getTopic());
-// rocketMQTemplate.sendOneWay(destination, consumeFailedMsgVO);
-// log.info("发送消息消费失败MQ成功");
-// }catch(Exception e1){
-// log.info("发送消息消费失败MQ异常",e);
-// }
-//
-// }
-// }
-//
-// public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
-//
-// @SuppressWarnings("unchecked")
-// public ConsumeOrderlyStatus consumeMessage(List 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;
-// }
-// }
-//
-// @Override
-// public void afterPropertiesSet() throws Exception {
-// start();
-// }
-//
-// @Override
-// public String toString() {
-// return "DefaultRocketMQListenerContainer{" +
-// "consumerGroup='" + consumerGroup + '\'' +
-// ", nameServer='" + nameServer + '\'' +
-// ", topic='" + topic + '\'' +
-// ", consumeMode=" + consumeMode +
-// ", selectorType=" + selectorType +
-// ", selectorExpress='" + selectorExpress + '\'' +
-// ", messageModel=" + messageModel +
-// '}';
-// }
-//
-// @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 ConvertMsgException("cannot convert message to " + messageType, e);
-// }
-// }
-// }
-// }
-//
-// private Class getMessageType() {
-// Type[] interfaces = rocketMQListener.getClass().getGenericInterfaces();
-// 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");
-//
-// consumer = new DefaultMQPushConsumer(consumerGroup);
-// consumer.setNamesrvAddr(nameServer);
-// consumer.setConsumeThreadMax(consumeThreadMax);
-// if (consumeThreadMax < consumer.getConsumeThreadMin()) {
-// consumer.setConsumeThreadMin(consumeThreadMax);
-// }
-//
-// consumer.setMessageModel(messageModel);
-//
-// switch (selectorType) {
-// case TAG:
-// consumer.subscribe(topic, selectorExpress);
-// break;
-// case SQL92:
-// consumer.subscribe(topic, MessageSelector.bySql(selectorExpress));
-// 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.");
-// }
-//
-// // provide an entryway to custom setting RocketMQ consumer
-// if (rocketMQListener instanceof AliyunRocketMQPushConsumerLifecycleListener) {
-// ((AliyunRocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumer);
-// }
-//
-// }
-//
-//}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java b/src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
deleted file mode 100644
index 777b951..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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.starter.core;
-
-/**
- * Constants Created by aqlu on 2017/11/16.
- */
-public final class DefaultRocketMQListenerContainerConstants {
- public static final String PROP_NAMESERVER = "nameServer";
- public static final String PROP_TOPIC = "topic";
- public static final String PROP_CONSUMER_GROUP = "consumerGroup";
- public static final String PROP_CONSUME_MODE = "consumeMode";
- public static final String PROP_CONSUME_THREAD_MAX = "consumeThreadMax";
- public static final String PROP_MESSAGE_MODEL = "messageModel";
- public static final String PROP_SELECTOR_EXPRESS = "selectorExpress";
- public static final String PROP_SELECTOR_TYPE = "selectorType";
- public static final String PROP_ROCKETMQ_LISTENER = "rocketMQListener";
- public static final String PROP_OBJECT_MAPPER = "objectMapper";
- public static final String METHOD_DESTROY = "destroy";
- public static final String PROP_ROCKETMQ_TEMPLATE = "rocketMQTemplate";
- public static final String PROP_ONS_Addr = "onsAddr";
- public static final String PROP_ACCESS_KEY = "accessKey";
- public static final String PROP_SECRET_KEY = "secretKey";
- public static final String PROP_NAMESRV_ADDR = "nameServerAddr";
- /**
- * 环境前缀
- */
- public static final String PROP_ENVIRONMENT_PREFIX = "environmentPrefix";
- /**
- * 消息消费失败发送的主题
- */
- public final static String CONSUMEFAILED_TOPIC = "ZTEITS_RNT_CLOUD";
- /**
- * 消息消费失败发送的tag
- */
- public final static String CONSUMEFAILED_TAG = "ConsumeMsgFailed";
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java b/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java
deleted file mode 100644
index 37ebedb..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * 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.starter.core;
-
-public interface RocketMQConsumerLifecycleListener {
- void prepareStart(final T consumer);
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListener.java b/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListener.java
deleted file mode 100644
index 64daa5f..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListener.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * 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.starter.core;
-
-public interface RocketMQListener {
- /**
- * 消费消息接口,由应用来实现
- * 网络抖动等不稳定的情形可能会带来消息重复,对重复消息敏感的业务可对消息做幂等处理
- * 没有异常则表示处理成功,否在处理失败,处理失败时阿里云MQ会重复调用,最多调用16次,如果16次依然失败,则不再调用。
- */
- void onMessage(T message);
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListenerContainer.java b/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListenerContainer.java
deleted file mode 100644
index 7667eed..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQListenerContainer.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.starter.core;
-
-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);
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQTemplate.java b/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQTemplate.java
deleted file mode 100644
index 5d88f62..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQTemplate.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * 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.starter.core;
-
-import java.nio.charset.Charset;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.messaging.MessagingException;
-
-import com.aliyun.openservices.ons.api.Message;
-import com.aliyun.openservices.ons.api.Producer;
-import com.aliyun.openservices.ons.api.SendCallback;
-import com.aliyun.openservices.ons.api.SendResult;
-import com.fasterxml.jackson.databind.ObjectMapper;
-
-import lombok.Getter;
-import lombok.Setter;
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-public class RocketMQTemplate implements InitializingBean, DisposableBean {
-
- @Getter
- @Setter
- private Producer aliyunProducer;
-
- @Setter
- @Getter
- private ObjectMapper objectMapper = new ObjectMapper();
-
- @Getter
- @Setter
- private String charset = "UTF-8";
-
- /**
- * 环境前缀
- */
- @Setter
- private String environmentPrefix;
-
- /**
- * 同步发送消息
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param key 业务主键
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
- * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
- *
- *
- * - 延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
- * - 定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()
- *
- * @return {@link SendResult}
- * 2018年3月23日 zhaowg
- */
- public SendResult syncSend(String topic,String tag,String keys,Object payload,Map userProperties,Long startDeliverTime) {
- if (Objects.isNull(topic) || Objects.isNull(payload)) {
- log.info("同步消息发送失败,主题和消息不能为空");
- throw new IllegalArgumentException("同步消息发送失败,主题和消息不能为空");
- }
-
- try {
- long now = System.currentTimeMillis();
-
- Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
- if(userProperties!=null && !userProperties.isEmpty()){
- for (Entry userProp : userProperties.entrySet()) {
- rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
- }
- }
- if(startDeliverTime!=null){
- //设置定时发送时间
- rocketMsg.setStartDeliverTime(startDeliverTime);
- }
- //阿里云发送
- SendResult sendResult = aliyunProducer.send(rocketMsg);
- long costTime = System.currentTimeMillis() - now;
- log.debug("发送消息耗时: {} ms, msgId:{}", costTime, sendResult.getMessageId());
- return sendResult;
- } catch (Exception e) {
- log.info("同步发送失败. topic:{}, message:{} ", topic, payload);
- throw new MessagingException(e.getMessage(), e);
- }
- }
-
- /**
- * Same to {@link #syncSend(String, String, String, Object, Map, Long)}.
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param key 业务主键
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @return {@link SendResult}
- * 2018年3月23日 zhaowg
- */
- public SendResult syncSend(String topic,String tag,String keys, Object payload) {
- return syncSend(topic, tag, keys, payload, null, null);
- }
- /**
- * Same to {@link #syncSend(String, String, String, Object)}.
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @return {@link SendResult}
- * 2018年3月23日 zhaowg
- */
- public SendResult syncSend(String topic,String tag, Object payload) {
- return syncSend(topic, tag,null, payload);
- }
-
- /**
- * 异步发送消息
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param key 业务主键
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
- * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
- *
- *
- * - 延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
- * - 定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()
- *
- * @param sendCallback 发送完成要执行的回调函数
- * 2018年3月23日 zhaowg
- */
- public void asyncSend(String topic,String tag,String keys,Object payload,Map userProperties,
- Long startDeliverTime,SendCallback sendCallback) {
- if (Objects.isNull(topic) || Objects.isNull(payload)) {
- log.info("异步消息发送失败,主题和消息不能为空");
- throw new IllegalArgumentException("异步消息发送失败,主题和消息不能为空");
- }
- try {
- long now = System.currentTimeMillis();
-
- Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
- if(userProperties!=null && !userProperties.isEmpty()){
- for (Entry userProp : userProperties.entrySet()) {
- rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
- }
- }
- if(startDeliverTime!=null){
- //设置定时发送时间
- rocketMsg.setStartDeliverTime(startDeliverTime);
- }
- //阿里云发送
- aliyunProducer.sendAsync(rocketMsg, sendCallback);
- long costTime = System.currentTimeMillis() - now;
- log.debug("发送消息耗时: {} ms", costTime);
- } catch (Exception e) {
- log.info("异步发送失败. topic:{}, message:{} ", topic, payload);
- throw new MessagingException(e.getMessage(), e);
- }
- }
- /**
- * Same to {@link #asyncSend(String, String, String, Object, Map, Long, SendCallback)}.
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param key 业务主键
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @param sendCallback 发送完成要执行的回调函数
- * @return {@link SendResult}
- * 2018年3月23日 zhaowg
- */
- public void asyncSend(String topic,String tag,String keys, Object payload,SendCallback sendCallback) {
- asyncSend(topic, tag, keys, payload, null, null,sendCallback);
- }
- /**
- * Same to {@link #asyncSend(String, String, String, Object,SendCallback)}.
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @param sendCallback 发送完成要执行的回调函数
- * @return {@link SendResult}
- * 2018年3月23日 zhaowg
- */
- public void asyncSend(String topic,String tag, Object payload,SendCallback sendCallback) {
- asyncSend(topic, tag,null, payload,sendCallback);
- }
- /**
- * 服务器不应答,无法保证消息是否成功到达服务器
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param key 业务主键
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
- * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
- *
- *
- * - 延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
- * - 定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()
- *
- * 2018年3月23日 zhaowg
- */
- public void sendOneWay(String topic,String tag,String keys,Object payload,Map userProperties,
- Long startDeliverTime) {
- if (Objects.isNull(topic) || Objects.isNull(payload)) {
- log.info("sendOneWay消息发送失败,主题和消息不能为空");
- throw new IllegalArgumentException("sendOneWay消息发送失败,主题和消息不能为空");
- }
- try {
- long now = System.currentTimeMillis();
-
- Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
- if(userProperties!=null && !userProperties.isEmpty()){
- for (Entry userProp : userProperties.entrySet()) {
- rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
- }
- }
- if(startDeliverTime!=null){
- //设置定时发送时间
- rocketMsg.setStartDeliverTime(startDeliverTime);
- }
- //阿里云发送
- aliyunProducer.sendOneway(rocketMsg);
- long costTime = System.currentTimeMillis() - now;
- log.debug("发送消息耗时: {} ms", costTime);
- } catch (Exception e) {
- log.info("sendOneWay发送失败. topic:{}, message:{} ", topic, payload);
- throw new MessagingException(e.getMessage(), e);
- }
- }
- /**
- * Same to {@link #sendOneWay(String, String, String, Object, Map, Long)}.
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param key 业务主键
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * 2018年3月23日 zhaowg
- */
- public void sendOneWay(String topic,String tag,String keys, Object payload) {
- sendOneWay(topic, tag, keys, payload, null, null);
- }
- /**
- * Same to {@link #sendOneWay(String, String, String, Object)}.
- * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
- * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
- * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
- * 2018年3月23日 zhaowg
- */
- public void sendOneWay(String topic,String tag, Object payload) {
- sendOneWay(topic, tag,null, payload);
- }
-
- @Override
- public void afterPropertiesSet() throws Exception {
- if(aliyunProducer != null){
- log.info("开始启动阿里云[环境标识:"+environmentPrefix+"]生产者");
- aliyunProducer.start();
- }
- }
-
- /**
- * 转换对象为字节
- * @param msgObj
- * @return
- * 2018年3月23日 zhaowg
- */
- private byte[] convertToRocketMsg(Object msgObj) {
- byte[] payloads;
-
- if (msgObj instanceof String) {
- payloads = ((String) msgObj).getBytes(Charset.forName(charset));
- } else {
- try {
- String jsonObj = this.objectMapper.writeValueAsString(msgObj);
- payloads = jsonObj.getBytes(Charset.forName(charset));
- } catch (Exception e) {
- throw new RuntimeException("convert to RocketMQ message failed.", e);
- }
- }
- return payloads;
- }
-
-
- @Override
- public void destroy() {
- if(Objects.nonNull(aliyunProducer)){
- log.info("开始关闭阿里云[环境标识:"+environmentPrefix+"]生产者");
- aliyunProducer.shutdown();
- }
- }
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/enums/ConsumeMode.java b/src/main/java/org/apache/rocketmq/spring/starter/enums/ConsumeMode.java
deleted file mode 100644
index 04a0349..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/enums/ConsumeMode.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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.starter.enums;
-
-public enum ConsumeMode {
- /**
- * 同时接收异步发送的消息
- */
- CONCURRENTLY,
-
- /**
- * 顺序接收消息,一个队列,一个线程
- */
- ORDERLY,
-
- /**
- * 批量接收发送的消息,允许自定义范围为[1, 32], 实际消费数量可能小于该值
- */
- BATCH
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/enums/SelectorType.java b/src/main/java/org/apache/rocketmq/spring/starter/enums/SelectorType.java
deleted file mode 100644
index 1923713..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/enums/SelectorType.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.starter.enums;
-
-import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.filter.ExpressionType;
-
-public enum SelectorType {
-
- /**
- * @see ExpressionType#TAG
- */
- TAG,
-
- /**
- * @see ExpressionType#SQL92
- * 注释by zwg 暂时不支持,原因:阿里云提供的ons-client最新版本1.7.4支持,但是该包有问题,引入后工程无法打包,目前使用的1.7.1,该版本不支持SQL92过滤
- */
- //SQL92
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/exception/ConvertMsgException.java b/src/main/java/org/apache/rocketmq/spring/starter/exception/ConvertMsgException.java
deleted file mode 100644
index 503ba1a..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/exception/ConvertMsgException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package org.apache.rocketmq.spring.starter.exception;
-
-public class ConvertMsgException extends RuntimeException{
-
- private static final long serialVersionUID = 1L;
-
- public ConvertMsgException() {
- super();
- }
-
- public ConvertMsgException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
- super(message, cause, enableSuppression, writableStackTrace);
- }
-
- public ConvertMsgException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public ConvertMsgException(String message) {
- super(message);
- }
-
- public ConvertMsgException(Throwable cause) {
- super(cause);
- }
-
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java b/src/main/java/org/apache/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java
deleted file mode 100644
index 8224133..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java
+++ /dev/null
@@ -1,149 +0,0 @@
-package org.apache.rocketmq.spring.starter.msgvo;
-
-import java.io.Serializable;
-import java.util.Date;
-
-public class ConsumeFailedMsgVO implements Serializable{
-
- private static final long serialVersionUID = 1L;
-
- /**消息ID*/
- private String msgId;
-
- /**消息主题*/
- private String topic;
-
- /**消息标签描述*/
- private String tag;
-
- /**消费组*/
- private String consumeGroup;
-
- /**消费者ip*/
- private String consumeIp;
-
- /**消费开始时间*/
- private Date consumeBeginTime;
-
- /**消费结束时间*/
- private Date consumeEndTime;
-
- /**消息关键字*/
- private String msgKeys;
-
- /**重复消费次数*/
- private Integer reconsumeTimes;
-
- /**消费失败错误信息*/
- private String cunsumerErrMsg;
-
- /**消息内容*/
- private String msg;
-
- public String getCunsumerErrMsg() {
- return cunsumerErrMsg;
- }
-
- public void setCunsumerErrMsg(String cunsumerErrMsg) {
- this.cunsumerErrMsg = cunsumerErrMsg;
- }
-
- public String getMsg() {
- return msg;
- }
-
- public void setMsg(String msg) {
- this.msg = msg;
- }
-
- /**获取消息ID*/
- public String getMsgId() {
- return msgId;
- }
-
- /**设置消息ID*/
- public void setMsgId(String msgId) {
- this.msgId = msgId == null ? null : msgId.trim();
- }
-
- /**获取消息主题*/
- public String getTopic() {
- return topic;
- }
-
- /**设置消息主题*/
- public void setTopic(String topic) {
- this.topic = topic == null ? null : topic.trim();
- }
-
- /**获取消息标签描述*/
- public String getTag() {
- return tag;
- }
-
- /**设置消息标签描述*/
- public void setTag(String tag) {
- this.tag = tag == null ? null : tag.trim();
- }
-
- /**获取消费组*/
- public String getConsumeGroup() {
- return consumeGroup;
- }
-
- /**设置消费组*/
- public void setConsumeGroup(String consumeGroup) {
- this.consumeGroup = consumeGroup == null ? null : consumeGroup.trim();
- }
-
- /**获取消费者ip*/
- public String getConsumeIp() {
- return consumeIp;
- }
-
- /**设置消费者ip*/
- public void setConsumeIp(String consumeIp) {
- this.consumeIp = consumeIp == null ? null : consumeIp.trim();
- }
-
- /**获取消费开始时间*/
- public Date getConsumeBeginTime() {
- return consumeBeginTime;
- }
-
- /**设置消费开始时间*/
- public void setConsumeBeginTime(Date consumeBeginTime) {
- this.consumeBeginTime = consumeBeginTime;
- }
-
- /**获取消费结束时间*/
- public Date getConsumeEndTime() {
- return consumeEndTime;
- }
-
- /**设置消费结束时间*/
- public void setConsumeEndTime(Date consumeEndTime) {
- this.consumeEndTime = consumeEndTime;
- }
-
- /**获取消息关键字*/
- public String getMsgKeys() {
- return msgKeys;
- }
-
- /**设置消息关键字*/
- public void setMsgKeys(String msgKeys) {
- this.msgKeys = msgKeys == null ? null : msgKeys.trim();
- }
-
- /**获取重复消费次数*/
- public Integer getReconsumeTimes() {
- return reconsumeTimes;
- }
-
- /**设置重复消费次数*/
- public void setReconsumeTimes(Integer reconsumeTimes) {
- this.reconsumeTimes = reconsumeTimes;
- }
-
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/utils/ExceptionUtil.java b/src/main/java/org/apache/rocketmq/spring/starter/utils/ExceptionUtil.java
deleted file mode 100644
index e97da1c..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/utils/ExceptionUtil.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package org.apache.rocketmq.spring.starter.utils;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
-public class ExceptionUtil {
-
- public static String getTrace(Throwable t) {
- StringBuffer buffer = new StringBuffer();
- if(t==null){
- return "";
- }
- StringWriter stringWriter = new StringWriter();
- PrintWriter writer = new PrintWriter(stringWriter);
- t.printStackTrace(writer);
- //设置堆栈信息
- buffer.append("堆栈信息为:" + stringWriter.getBuffer().toString());
- return buffer.toString();
- }
-
-}
diff --git a/src/main/java/org/apache/rocketmq/spring/starter/utils/IPUtil.java b/src/main/java/org/apache/rocketmq/spring/starter/utils/IPUtil.java
deleted file mode 100644
index b40739c..0000000
--- a/src/main/java/org/apache/rocketmq/spring/starter/utils/IPUtil.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package org.apache.rocketmq.spring.starter.utils;
-
-import java.net.InetAddress;
-
-import org.springframework.util.StringUtils;
-
-/**
- * Copyright: Copyright (c) 2017 zteits
- *
- * @ClassName: com.clouds.constants.utils
- * @Description: IP地址工具类
- * @version: v1.0.0
- * @author: atao
- * @date: 2017/4/26 上午9:25
- * Modification History:
- * Date Author Version Description
- * ---------------------------------------------------------*
- * 2017/4/26 atao v1.0.0 创建
- */
-public class IPUtil {
- private static String localHost;
- private static String localHostName;
-
- public static String getLocalHost() {
- if (StringUtils.isEmpty(localHost)) {
- getLocalHostInfo();
- }
- return localHost;
- }
-
- public static String getLocalHostNome() {
- if (StringUtils.isEmpty(localHostName)) {
- getLocalHostInfo();
- }
- return localHostName;
- }
-
- private static void getLocalHostInfo() {
- try {
- InetAddress ia = InetAddress.getLocalHost();
- localHostName = ia.getHostName();
- localHost = ia.getHostAddress();
- } catch (Exception e) {
- //获取当前地址失败
- e.printStackTrace();
- }
- }
-
-}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java b/src/main/java/zteits/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
new file mode 100644
index 0000000..7b3052f
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
@@ -0,0 +1,233 @@
+/*
+ * 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 zteits.rocketmq.spring.starter;
+
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.METHOD_DESTROY;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUMER_GROUP;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_MODE;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_THREAD_MAX;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_MESSAGE_MODEL;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_OBJECT_MAPPER;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_LISTENER;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_TEMPLATE;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_EXPRESS;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_TYPE;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.*;
+
+import java.util.Map;
+import java.util.Objects;
+import java.util.Properties;
+import java.util.UUID;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.annotation.Resource;
+
+import com.aliyun.openservices.shade.com.alibaba.fastjson.JSONObject;
+import zteits.rocketmq.spring.starter.annotation.RocketMQMessageListener;
+import zteits.rocketmq.spring.starter.core.AliyunRocketMQListenerContainer;
+import zteits.rocketmq.spring.starter.core.RocketMQListener;
+import zteits.rocketmq.spring.starter.core.RocketMQTemplate;
+import org.springframework.aop.support.AopUtils;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.DefaultListableBeanFactory;
+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.context.properties.EnableConfigurationProperties;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.core.env.StandardEnvironment;
+import org.springframework.util.Assert;
+
+import com.aliyun.openservices.ons.api.ONSFactory;
+import com.aliyun.openservices.ons.api.Producer;
+import com.aliyun.openservices.ons.api.PropertyKeyConst;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Configuration
+@EnableConfigurationProperties(RocketMQProperties.class)
+@Order
+@Slf4j
+public class AliyunRocketMQAutoConfiguration {
+
+ @Bean
+ @ConditionalOnClass(RocketMQProperties.Producer.class)
+ @ConditionalOnMissingBean(RocketMQProperties.Producer.class)
+ @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"environmentPrefix", "producer.group"})
+ public Producer mqProducer(RocketMQProperties rocketMQProperties) {
+ log.info("注册生产者mqProducer:"+ JSONObject.toJSON(rocketMQProperties));
+
+ RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer();
+ String groupName = producerConfig.getGroup();
+ Assert.hasText(groupName, "[spring.rocketmq.producer.group] must not be null");
+ String accessKey = rocketMQProperties.getAccessKey();
+ Assert.hasText(accessKey, "[spring.rocketmq.accessKey] must not be null");
+ String secretKey = rocketMQProperties.getSecretKey();
+ Assert.hasText(secretKey, "[spring.rocketmq.secretKey] must not be null");
+ // String onsAddr = rocketMQProperties.getOnsAddr();
+ String namesrvAddr = rocketMQProperties.getNameSrvAddr();
+ Assert.hasText(namesrvAddr, "[spring.rocketmq.nameSrvAddr] must not be null");
+ String environmentPrefix = rocketMQProperties.getEnvironmentPrefix();
+ Assert.hasText(secretKey, "[spring.rocketmq.environmentPrefix] must not be null");
+
+ Properties producerProperties = new Properties();
+ //生成者ProducerId添加前缀:PID_+环境标识_+groupName
+ String pid = "PID_"+environmentPrefix+"_"+groupName;
+ log.info("注册生产者PID:"+pid);
+ producerProperties.setProperty(PropertyKeyConst.ProducerId, pid);
+ producerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
+ producerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
+ producerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, namesrvAddr);
+ //producerProperties.setProperty(PropertyKeyConst.ONSAddr, onsAddr);
+ Producer producer = ONSFactory.createProducer(producerProperties);
+ return producer;
+ }
+
+ @Bean
+ @ConditionalOnClass(ObjectMapper.class)
+ @ConditionalOnMissingBean(name = "rocketMQMessageObjectMapper")
+ public ObjectMapper rocketMQMessageObjectMapper() {
+ return new ObjectMapper();
+ }
+
+ @Bean(destroyMethod = "destroy")
+ @ConditionalOnBean(Producer.class)
+ @ConditionalOnMissingBean(name = "rocketMQTemplate")
+ public RocketMQTemplate rocketMQTemplate(Producer mqProducer,RocketMQProperties rocketMQProperties,
+ @Autowired(required = false)
+ @Qualifier("rocketMQMessageObjectMapper")
+ ObjectMapper objectMapper) {
+ RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
+ rocketMQTemplate.setAliyunProducer(mqProducer);
+ rocketMQTemplate.setEnvironmentPrefix(rocketMQProperties.getEnvironmentPrefix());
+ if (Objects.nonNull(objectMapper)) {
+ rocketMQTemplate.setObjectMapper(objectMapper);
+ }
+ return rocketMQTemplate;
+ }
+
+ @Configuration
+ @EnableConfigurationProperties(RocketMQProperties.class)
+ @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"environmentPrefix", "producer.group"})
+ @Order
+ public static class ListenerContainerConfiguration implements ApplicationContextAware, InitializingBean {
+ private ConfigurableApplicationContext applicationContext;
+
+ private AtomicLong counter = new AtomicLong(0);
+
+ @Resource
+ private StandardEnvironment environment;
+
+ @Resource
+ private RocketMQProperties rocketMQProperties;
+
+ private ObjectMapper objectMapper;
+
+ @Autowired
+ private RocketMQTemplate rocketMQTemplate;
+
+ public ListenerContainerConfiguration() {
+ }
+
+ @Autowired(required = false)
+ public ListenerContainerConfiguration(
+ @Qualifier("rocketMQMessageObjectMapper") ObjectMapper objectMapper) {
+ this.objectMapper = objectMapper;
+ }
+
+ @Override
+ public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+ this.applicationContext = (ConfigurableApplicationContext) applicationContext;
+ }
+
+ @Override
+ public void afterPropertiesSet() {
+ Map beans = this.applicationContext.getBeansWithAnnotation(RocketMQMessageListener.class);
+
+ if (Objects.nonNull(beans)) {
+ beans.forEach(this::registerContainer);
+ }
+ }
+
+ private void registerContainer(String beanName, Object bean) {
+ String uuid = UUID.randomUUID().toString();
+ log.info(uuid+"开始注册消费者,beanName:"+beanName);
+ Class> clazz = AopUtils.getTargetClass(bean);
+
+ if (!RocketMQListener.class.isAssignableFrom(bean.getClass())) {
+ throw new IllegalStateException(clazz + " is not instance of " + RocketMQListener.class.getName());
+ }
+ RocketMQListener rocketMQListener = (RocketMQListener) bean;
+ RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);
+ BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(AliyunRocketMQListenerContainer.class);
+ beanBuilder.addPropertyValue(PROP_NAMESRV_Addr, rocketMQProperties.getNameSrvAddr());
+ // beanBuilder.addPropertyValue(PROP_ONS_Addr, rocketMQProperties.getOnsAddr());
+ String topic = rocketMQProperties.getEnvironmentPrefix()+"_"+environment.resolvePlaceholders(annotation.topic());
+ log.info(uuid+"订阅的主题topic:"+topic);
+ beanBuilder.addPropertyValue(PROP_TOPIC, topic);
+ String cid = "GID_"+rocketMQProperties.getEnvironmentPrefix()+"_"+environment.resolvePlaceholders(annotation.consumerGroup());
+ log.info(uuid+"消费者CID:"+cid);
+ //消费者ConsumerId添加前缀:PID_+环境标识_+groupName
+ beanBuilder.addPropertyValue(PROP_CONSUMER_GROUP, cid);
+ beanBuilder.addPropertyValue(PROP_CONSUME_MODE, annotation.consumeMode());
+ beanBuilder.addPropertyValue(PROP_CONSUME_THREAD_MAX, annotation.consumeThreadMax());
+ beanBuilder.addPropertyValue(PROP_MESSAGE_MODEL, annotation.messageModel());
+ beanBuilder.addPropertyValue(PROP_SELECTOR_EXPRESS, environment.resolvePlaceholders(annotation.selectorExpress()));
+ beanBuilder.addPropertyValue(PROP_SELECTOR_TYPE, annotation.selectorType());
+ beanBuilder.addPropertyValue(PROP_ROCKETMQ_LISTENER, rocketMQListener);
+ beanBuilder.addPropertyValue(PROP_ROCKETMQ_TEMPLATE, rocketMQTemplate);
+ beanBuilder.addPropertyValue(PROP_ENVIRONMENT_PREFIX, rocketMQProperties.getEnvironmentPrefix());
+ if (Objects.nonNull(objectMapper)) {
+ beanBuilder.addPropertyValue(PROP_OBJECT_MAPPER, objectMapper);
+ }
+ beanBuilder.setDestroyMethodName(METHOD_DESTROY);
+ //增加阿里云key
+ beanBuilder.addPropertyValue(PROP_ACCESS_KEY, rocketMQProperties.getAccessKey());
+ beanBuilder.addPropertyValue(PROP_SECRET_KEY, rocketMQProperties.getSecretKey());
+
+ String containerBeanName = String.format("%s_%s", AliyunRocketMQListenerContainer.class.getName(), counter.incrementAndGet());
+ log.info("消费者容器beanName:"+containerBeanName);
+ DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
+ beanFactory.registerBeanDefinition(containerBeanName, beanBuilder.getBeanDefinition());
+
+ AliyunRocketMQListenerContainer container = beanFactory.getBean(containerBeanName, AliyunRocketMQListenerContainer.class);
+
+ if (!container.isStarted()) {
+ try {
+ container.start();
+ } catch (Exception e) {
+ log.error("started container failed. {}", container, e);
+ throw new RuntimeException(e);
+ }
+ }
+
+ log.info("register rocketMQ listener to container, listenerBeanName:{}, containerBeanName:{}", beanName, containerBeanName);
+ }
+ }
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/RocketMQProperties.java b/src/main/java/zteits/rocketmq/spring/starter/RocketMQProperties.java
new file mode 100644
index 0000000..94fa432
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/RocketMQProperties.java
@@ -0,0 +1,115 @@
+/*
+ * 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 zteits.rocketmq.spring.starter;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+@SuppressWarnings("WeakerAccess")
+@ConfigurationProperties(prefix = "spring.rocketmq")
+@Data
+public class RocketMQProperties {
+ /**
+ * 环境前缀
+ */
+ private String environmentPrefix;
+ /**
+ * 消息队列服务接入点
+ */
+ private String onsAddr;
+
+ private String nameSrvAddr;
+
+ /**
+ * AccessKey, 用于标识、校验用户身份
+ */
+ private String accessKey;
+ /**
+ * SecretKey, 用于标识、校验用户身份
+ */
+ private String secretKey;
+
+ private Producer producer;
+ @Data
+ public static class Producer {
+
+ /**
+ * name of producer
+ */
+ private String group;
+
+ /**
+ * millis of send message timeout
+ */
+ private int sendMsgTimeout = 3000;
+
+ /**
+ * Compress message body threshold, namely, message body larger than 4k will be compressed on default.
+ */
+ private int compressMsgBodyOverHowmuch = 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;
+
+ /**
+ * Maximum number of retry to perform internally before claiming sending failure in asynchronous mode.
+ * 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 retryAnotherBrokerWhenNotStoreOk = false;
+
+ /**
+ * Maximum allowed message size in bytes.
+ */
+ private int maxMessageSize = 1024 * 1024 * 4; // 4M
+
+ /**
+ * 消费失败消息主题
+ */
+ private String consumeFailedTopic = "ZTEITS_RNT_CLOUD";
+
+ /**
+ * 消费失败消息标签
+ */
+ private String consumeFailedTag = "ConsumeMsgFailed";
+
+ // 对应的getter和setter方法
+ public String getConsumeFailedTopic() {
+ return consumeFailedTopic;
+ }
+
+ public void setConsumeFailedTopic(String consumeFailedTopic) {
+ this.consumeFailedTopic = consumeFailedTopic;
+ }
+
+ public String getConsumeFailedTag() {
+ return consumeFailedTag;
+ }
+
+ public void setConsumeFailedTag(String consumeFailedTag) {
+ this.consumeFailedTag = consumeFailedTag;
+ }
+ }
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/annotation/RocketMQMessageListener.java b/src/main/java/zteits/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
new file mode 100644
index 0000000..79b4ea9
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
@@ -0,0 +1,77 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.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;
+
+import zteits.rocketmq.spring.starter.enums.ConsumeMode;
+import zteits.rocketmq.spring.starter.enums.SelectorType;
+
+import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
+
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface RocketMQMessageListener {
+
+ /**
+ * 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 here for further discussion.
+ */
+ String consumerGroup();
+
+ /**
+ * Topic name
+ */
+ String topic();
+
+ /**
+ * Control how to selector message
+ *
+ * @see ExpressionType
+ */
+ SelectorType selectorType() default SelectorType.TAG;
+
+ /**
+ * Control which message can be select. Grammar please see {@link ExpressionType#TAG} and {@link ExpressionType#SQL92}
+ */
+ String selectorExpress() 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;
+
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java b/src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
new file mode 100644
index 0000000..39b761d
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
@@ -0,0 +1,441 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.core;
+
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.CONSUMEFAILED_TAG;
+import static zteits.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.CONSUMEFAILED_TOPIC;
+
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.nio.charset.Charset;
+import java.util.Date;
+import java.util.List;
+import java.util.Objects;
+import java.util.Properties;
+
+import zteits.rocketmq.spring.starter.enums.ConsumeMode;
+import zteits.rocketmq.spring.starter.enums.SelectorType;
+import zteits.rocketmq.spring.starter.exception.ConvertMsgException;
+import zteits.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;
+import zteits.rocketmq.spring.starter.utils.ExceptionUtil;
+import zteits.rocketmq.spring.starter.utils.IPUtil;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+import com.aliyun.openservices.ons.api.Action;
+import com.aliyun.openservices.ons.api.ConsumeContext;
+import com.aliyun.openservices.ons.api.Consumer;
+import com.aliyun.openservices.ons.api.Message;
+import com.aliyun.openservices.ons.api.MessageListener;
+import com.aliyun.openservices.ons.api.ONSFactory;
+import com.aliyun.openservices.ons.api.PropertyKeyConst;
+import com.aliyun.openservices.ons.api.batch.BatchConsumer;
+import com.aliyun.openservices.ons.api.batch.BatchMessageListener;
+import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
+import com.aliyun.openservices.ons.api.order.MessageOrderListener;
+import com.aliyun.openservices.ons.api.order.OrderAction;
+import com.aliyun.openservices.ons.api.order.OrderConsumer;
+import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.exception.MQClientException;
+import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@SuppressWarnings("WeakerAccess")
+@Slf4j
+public class AliyunRocketMQListenerContainer implements InitializingBean, RocketMQListenerContainer {
+ /**
+ * 阿里云分配的accesskey
+ */
+ @Setter
+ private String accessKey;
+ /**
+ * 阿里云分配的secretKey
+ */
+ @Setter
+ private String secretKey;
+
+ @Setter
+ @Getter
+ private String consumerGroup;
+ /**
+ * 消息队列服务接入点
+ */
+ @Setter
+ @Getter
+ private String onsAddr;
+
+// @Setter
+// @Getter
+// private String nameServerAddr;
+
+ @Setter
+ @Getter
+ private String nameSrvAddr;
+
+ @Setter
+ @Getter
+ private String topic;
+
+ @Setter
+ @Getter
+ private ConsumeMode consumeMode = ConsumeMode.CONCURRENTLY;
+
+ @Setter
+ @Getter
+ private SelectorType selectorType = SelectorType.TAG;
+
+ @Setter
+ @Getter
+ private String selectorExpress = "*";
+
+ @Setter
+ @Getter
+ private MessageModel messageModel = MessageModel.CLUSTERING;
+
+ @Setter
+ @Getter
+ private int consumeThreadMax = 64;
+
+ @Getter
+ @Setter
+ private String charset = "UTF-8";
+
+ @Setter
+ @Getter
+ private ObjectMapper objectMapper = new ObjectMapper();
+
+ @Setter
+ @Getter
+ private boolean started;
+
+ @Setter
+ private RocketMQListener rocketMQListener;
+ /**普通消息*/
+ private Consumer consumer;
+ /**顺序消息*/
+ private OrderConsumer orderConsumer;
+ /**批量消息*/
+ private BatchConsumer batchConsumer;
+
+ private Class messageType;
+ /**
+ * 环境前缀
+ */
+ @Setter
+ private String environmentPrefix;
+
+ @Setter
+ private RocketMQTemplate rocketMQTemplate;
+
+ public void setupMessageListener(RocketMQListener rocketMQListener) {
+ this.rocketMQListener = rocketMQListener;
+ }
+
+ @Override
+ public void destroy() {
+ this.setStarted(false);
+ if (Objects.nonNull(consumer)) {
+ consumer.shutdown();
+ }
+ if (Objects.nonNull(orderConsumer)) {
+ orderConsumer.shutdown();
+ }
+ if (Objects.nonNull(batchConsumer)) {
+ batchConsumer.shutdown();
+ }
+ log.info("container destroyed, {}", this.toString());
+ }
+
+ public synchronized void start() throws MQClientException {
+
+ if (this.isStarted()) {
+ throw new IllegalStateException("container already started. " + this.toString());
+ }
+
+ initRocketMQPushConsumer();
+
+ // parse message type
+ this.messageType = getMessageType();
+ log.debug("msgType: {}", messageType.getName());
+
+ if (Objects.nonNull(consumer)) {
+ consumer.start();
+ }
+ if (Objects.nonNull(orderConsumer)) {
+ orderConsumer.start();
+ }
+ if (Objects.nonNull(batchConsumer)) {
+ batchConsumer.start();
+ }
+ this.setStarted(true);
+
+ log.info("started container: {}", this.toString());
+ }
+
+ public class DefaultMessageListenerConcurrently implements MessageListener {
+
+ @SuppressWarnings("unchecked")
+ public Action consume(final Message message, final ConsumeContext context){
+ Date consumeBeginTime = new Date();
+ log.debug("received msg: {}", message);
+ try {
+ long now = consumeBeginTime.getTime();
+ rocketMQListener.onMessage(doConvertMessage(message));
+ long costTime = System.currentTimeMillis() - now;
+ log.debug("consume {} cost: {} ms", message.getMsgID(), costTime);
+ } catch (Exception e) {
+ log.warn("consume message failed. message:{}", message, e);
+ if(message.getTopic().equals(environmentPrefix+"_"+CONSUMEFAILED_TOPIC) && CONSUMEFAILED_TAG.equals(message.getTag())){
+ log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
+ return Action.CommitMessage;
+ }
+ if(e instanceof ConvertMsgException){
+ log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
+ //消息消费失败,发送失败消息
+ this.sendConsumeMsgFailed(message,e,consumeBeginTime);
+ return Action.CommitMessage;
+ }
+ this.sendConsumeMsgFailed(message,e,consumeBeginTime);
+ return Action.ReconsumeLater;
+ }
+
+ return Action.CommitMessage;
+ }
+ /**
+ * 发送消息消费失败消息
+ * @param message
+ * @param e
+ * 2018年3月22日 zhaowg
+ */
+ private void sendConsumeMsgFailed(Message message, Exception e,Date consumeBeginTime) {
+ log.info("消费消息失败,开始发送消费失败MQ");
+ String topic = environmentPrefix+"_"+CONSUMEFAILED_TOPIC;
+ String tag = CONSUMEFAILED_TAG;
+ try{
+ Date consumeEndTime = new Date();
+ ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
+ consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
+ consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
+ consumeFailedMsgVO.setConsumeGroup(consumerGroup);
+ consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
+ if(e!=null){
+ String errMsg = ExceptionUtil.getTrace(e);
+ if(!StringUtils.isEmpty(errMsg)){
+ //最多保存1024个字符
+ consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
+ }
+ }
+ consumeFailedMsgVO.setMsg(new String(message.getBody()));
+ consumeFailedMsgVO.setMsgId(message.getMsgID());
+ consumeFailedMsgVO.setMsgKeys(message.getKey());
+ consumeFailedMsgVO.setReconsumeTimes(message.getReconsumeTimes());
+ consumeFailedMsgVO.setTag(message.getTag());
+ consumeFailedMsgVO.setTopic(message.getTopic());
+ rocketMQTemplate.sendOneWay(topic, tag, consumeFailedMsgVO);
+ log.info("发送消息消费失败MQ成功");
+ }catch(Exception e1){
+ log.error("发送消息消费失败MQ异常", e1);
+ }
+ }
+ }
+
+ public class DefaultMessageListenerOrderly implements MessageOrderListener {
+
+ @Override
+ public OrderAction consume(Message message, ConsumeOrderContext context) {
+ log.debug("received msg: {}", message);
+ try {
+ long now = System.currentTimeMillis();
+ rocketMQListener.onMessage(doConvertMessage(message));
+ long costTime = System.currentTimeMillis() - now;
+ log.info("consume {} cost: {} ms", message.getMsgID(), costTime);
+ } catch (Exception e) {
+ log.warn("consume message failed. message:{}", message, e);
+ return OrderAction.Suspend;
+ }
+ return OrderAction.Success;
+ }
+ }
+
+ public class DefaultMessageListenerBatchs implements BatchMessageListener{
+
+ @Override
+ public Action consume(List messages, ConsumeContext context) {
+ for (Message message : messages) {
+ Date consumeBeginTime = new Date();
+ log.debug("received msg: {}", message);
+ try {
+ long now = consumeBeginTime.getTime();
+ rocketMQListener.onMessage(doConvertMessage(message));
+ long costTime = System.currentTimeMillis() - now;
+ log.debug("consume {} cost: {} ms", message.getMsgID(), costTime);
+ } catch (Exception e) {
+ log.warn("consume message failed. message:{}", message, e);
+ if(message.getTopic().equals(environmentPrefix+"_"+CONSUMEFAILED_TOPIC) && CONSUMEFAILED_TAG.equals(message.getTag())){
+ log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
+ continue;
+ }
+ if(e instanceof ConvertMsgException){
+ log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
+ //消息消费失败,发送失败消息
+ this.sendConsumeMsgFailed(message,e,consumeBeginTime);
+ continue;
+ }
+ this.sendConsumeMsgFailed(message,e,consumeBeginTime);
+ return Action.ReconsumeLater;
+ }
+ }
+ return Action.CommitMessage;
+ }
+
+ /**
+ * 发送消息消费失败消息
+ * @param message
+ * @param e
+ * 2018年3月22日 zhaowg
+ */
+ private void sendConsumeMsgFailed(Message message, Exception e,Date consumeBeginTime) {
+ log.info("消费消息失败,开始发送消费失败MQ");
+ String topic = environmentPrefix+"_"+CONSUMEFAILED_TOPIC;
+ String tag = CONSUMEFAILED_TAG;
+ try{
+ Date consumeEndTime = new Date();
+ ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
+ consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
+ consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
+ consumeFailedMsgVO.setConsumeGroup(consumerGroup);
+ consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
+ if(e!=null){
+ String errMsg = ExceptionUtil.getTrace(e);
+ if(!StringUtils.isEmpty(errMsg)){
+ //最多保存1024个字符
+ consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
+ }
+ }
+ consumeFailedMsgVO.setMsg(new String(message.getBody()));
+ consumeFailedMsgVO.setMsgId(message.getMsgID());
+ consumeFailedMsgVO.setMsgKeys(message.getKey());
+ consumeFailedMsgVO.setReconsumeTimes(message.getReconsumeTimes());
+ consumeFailedMsgVO.setTag(message.getTag());
+ consumeFailedMsgVO.setTopic(message.getTopic());
+ rocketMQTemplate.sendOneWay(topic, tag, consumeFailedMsgVO);
+ log.info("发送消息消费失败MQ成功");
+ }catch(Exception e1){
+ log.error("发送消息消费失败MQ异常", e1);
+ }
+ }
+ }
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ start();
+ }
+
+
+ @SuppressWarnings("unchecked")
+ private Object doConvertMessage(Message message) {
+ if (Objects.equals(messageType, Message.class)) {
+ return message;
+ } else {
+ String str = new String(message.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 ConvertMsgException("cannot convert message to " + messageType, e);
+ }
+ }
+ }
+ }
+
+ private Class getMessageType() {
+ Type[] interfaces = rocketMQListener.getClass().getGenericInterfaces();
+ 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(nameSrvAddr, "Property 'nameServer' is required");
+ Assert.notNull(topic, "Property 'topic' is required");
+
+ Properties consumerProperties = new Properties();
+ consumerProperties.setProperty(PropertyKeyConst.ConsumerId, consumerGroup);
+ consumerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
+ consumerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
+ consumerProperties.setProperty(PropertyKeyConst.NAMESRV_ADDR, nameSrvAddr);
+ consumerProperties.setProperty(PropertyKeyConst.ConsumeThreadNums, consumeThreadMax+"");
+ consumerProperties.setProperty(PropertyKeyConst.MessageModel, messageModel.getModeCN());
+ //允许用户自己设置该consumer的一些配置
+ if (rocketMQListener instanceof AliyunRocketMQPushConsumerLifecycleListener) {
+ ((AliyunRocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumerProperties);
+ }
+ switch (consumeMode) {
+ case ORDERLY://顺序消息
+ orderConsumer = ONSFactory.createOrderedConsumer(consumerProperties);
+ if(selectorType == SelectorType.TAG){
+ orderConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerOrderly());
+// }else if(selectorType == SelectorType.SQL92){
+// orderConsumer.subscribe(topic, MessageSelector.bySql(selectorExpress), new DefaultMessageListenerOrderly());
+ }
+ break;
+ case CONCURRENTLY://普通消息
+ consumer = ONSFactory.createConsumer(consumerProperties);
+ if(selectorType == SelectorType.TAG){
+ consumer.subscribe(topic, selectorExpress, new DefaultMessageListenerConcurrently());
+// }else if(selectorType == SelectorType.SQL92){
+// consumer.subscribe(topic, MessageSelector.bySql(selectorExpress), new DefaultMessageListenerConcurrently());
+ }
+ break;
+ case BATCH://批量消息
+ batchConsumer = ONSFactory.createBatchConsumer(consumerProperties);
+ batchConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerBatchs());
+ break;
+ default:
+ throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
+ }
+
+ }
+
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java b/src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
new file mode 100644
index 0000000..ebb5a23
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
@@ -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.
+ */
+
+package zteits.rocketmq.spring.starter.core;
+
+import java.util.Properties;
+
+public interface AliyunRocketMQPushConsumerLifecycleListener extends RocketMQConsumerLifecycleListener {
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java b/src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
new file mode 100644
index 0000000..9e9889c
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
@@ -0,0 +1,355 @@
+///*
+// * 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.starter.core;
+//
+//import java.lang.reflect.ParameterizedType;
+//import java.lang.reflect.Type;
+//import java.nio.charset.Charset;
+//import java.util.Date;
+//import java.util.List;
+//import java.util.Objects;
+//
+//import org.apache.commons.lang3.StringUtils;
+//import org.apache.commons.lang3.exception.ExceptionUtils;
+//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.exception.MQClientException;
+//import org.apache.rocketmq.common.message.MessageExt;
+//import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+//import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
+//import org.apache.rocketmq.spring.starter.enums.SelectorType;
+//import org.apache.rocketmq.spring.starter.exception.ConvertMsgException;
+//import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;
+//import org.apache.rocketmq.spring.starter.utils.IPUtil;
+//import org.springframework.beans.factory.InitializingBean;
+//import org.springframework.util.Assert;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//
+//import lombok.Getter;
+//import lombok.Setter;
+//import lombok.extern.slf4j.Slf4j;
+//
+//@SuppressWarnings("WeakerAccess")
+//@Slf4j
+//public class DefaultRocketMQListenerContainer implements InitializingBean, RocketMQListenerContainer {
+//
+// @Setter
+// @Getter
+// private long suspendCurrentQueueTimeMillis = 1000;
+//
+// /**
+// * Message consume retry strategy
-1,no retry,put into DLQ directly
0,broker control retry frequency
+// * >0,client control retry frequency
+// */
+// @Setter
+// @Getter
+// private int delayLevelWhenNextConsume = 0;
+//
+// @Setter
+// @Getter
+// private String consumerGroup;
+//
+// @Setter
+// @Getter
+// private String nameServer;
+//
+// @Setter
+// @Getter
+// private String topic;
+//
+// @Setter
+// @Getter
+// private ConsumeMode consumeMode = ConsumeMode.CONCURRENTLY;
+//
+// @Setter
+// @Getter
+// private SelectorType selectorType = SelectorType.TAG;
+//
+// @Setter
+// @Getter
+// private String selectorExpress = "*";
+//
+// @Setter
+// @Getter
+// private MessageModel messageModel = MessageModel.CLUSTERING;
+//
+// @Setter
+// @Getter
+// private int consumeThreadMax = 64;
+//
+// @Getter
+// @Setter
+// private String charset = "UTF-8";
+//
+// @Setter
+// @Getter
+// private ObjectMapper objectMapper = new ObjectMapper();
+//
+// @Setter
+// @Getter
+// private boolean started;
+//
+// @Setter
+// private RocketMQListener rocketMQListener;
+//
+// private DefaultMQPushConsumer consumer;
+//
+// private Class messageType;
+//
+// @Setter
+// private RocketMQTemplate rocketMQTemplate;
+//
+// public void setupMessageListener(RocketMQListener rocketMQListener) {
+// this.rocketMQListener = rocketMQListener;
+// }
+//
+// @Override
+// public void destroy() {
+// this.setStarted(false);
+// if (Objects.nonNull(consumer)) {
+// consumer.shutdown();
+// }
+// log.info("container destroyed, {}", this.toString());
+// }
+//
+// public synchronized void start() throws MQClientException {
+//
+// if (this.isStarted()) {
+// throw new IllegalStateException("container already started. " + this.toString());
+// }
+//
+// initRocketMQPushConsumer();
+//
+// // parse message type
+// this.messageType = getMessageType();
+// log.debug("msgType: {}", messageType.getName());
+//
+// consumer.start();
+// this.setStarted(true);
+//
+// log.info("started container: {}", this.toString());
+// }
+//
+// public class DefaultMessageListenerConcurrently implements MessageListenerConcurrently {
+//
+// @SuppressWarnings("unchecked")
+// public ConsumeConcurrentlyStatus consumeMessage(List msgs, ConsumeConcurrentlyContext context) {
+// for (MessageExt messageExt : msgs) {
+// Date consumeBeginTime = new Date();
+// 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);
+// if(messageExt.getTopic().equals("DATA_COLLECTION_TOPIC") && "ConsumeMsgFailed".equals(messageExt.getTags())){
+// log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
+// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+// }
+// if(e instanceof ConvertMsgException){
+// log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
+// //消息消费失败,发送失败消息
+// this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);
+// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+// }
+// this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);
+// return ConsumeConcurrentlyStatus.RECONSUME_LATER;
+// }
+// }
+//
+// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+// }
+// /**
+// * 发送消息消费失败消息
+// * @param messageExt
+// * @param e
+// * 2018年3月22日 zhaowg
+// */
+// private void sendConsumeMsgFailed(MessageExt messageExt, Exception e,Date consumeBeginTime) {
+// log.info("消费消息失败,开始发送消费失败MQ");
+// String topic = "DATA_COLLECTION_TOPIC";
+// String tag = "ConsumeMsgFailed";
+// try{
+// Date consumeEndTime = new Date();
+// String destination = topic+":"+tag;
+// ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
+// consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
+// consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
+// consumeFailedMsgVO.setConsumeGroup(consumerGroup);
+// consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
+// if(e!=null){
+// String errMsg = ExceptionUtils.getStackTrace(e);
+// if(StringUtils.isNotBlank(errMsg)){
+// //最多保存1024个字符
+// consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
+// }
+// }
+// consumeFailedMsgVO.setMsg(new String(messageExt.getBody()));
+// consumeFailedMsgVO.setMsgId(messageExt.getMsgId());
+// consumeFailedMsgVO.setMsgKeys(messageExt.getKeys());
+// consumeFailedMsgVO.setReconsumeTimes(messageExt.getReconsumeTimes());
+// consumeFailedMsgVO.setTag(messageExt.getTags());
+// consumeFailedMsgVO.setTopic(messageExt.getTopic());
+// rocketMQTemplate.sendOneWay(destination, consumeFailedMsgVO);
+// log.info("发送消息消费失败MQ成功");
+// }catch(Exception e1){
+// log.info("发送消息消费失败MQ异常",e);
+// }
+//
+// }
+// }
+//
+// public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
+//
+// @SuppressWarnings("unchecked")
+// public ConsumeOrderlyStatus consumeMessage(List 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;
+// }
+// }
+//
+// @Override
+// public void afterPropertiesSet() throws Exception {
+// start();
+// }
+//
+// @Override
+// public String toString() {
+// return "DefaultRocketMQListenerContainer{" +
+// "consumerGroup='" + consumerGroup + '\'' +
+// ", nameServer='" + nameServer + '\'' +
+// ", topic='" + topic + '\'' +
+// ", consumeMode=" + consumeMode +
+// ", selectorType=" + selectorType +
+// ", selectorExpress='" + selectorExpress + '\'' +
+// ", messageModel=" + messageModel +
+// '}';
+// }
+//
+// @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 ConvertMsgException("cannot convert message to " + messageType, e);
+// }
+// }
+// }
+// }
+//
+// private Class getMessageType() {
+// Type[] interfaces = rocketMQListener.getClass().getGenericInterfaces();
+// 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");
+//
+// consumer = new DefaultMQPushConsumer(consumerGroup);
+// consumer.setNamesrvAddr(nameServer);
+// consumer.setConsumeThreadMax(consumeThreadMax);
+// if (consumeThreadMax < consumer.getConsumeThreadMin()) {
+// consumer.setConsumeThreadMin(consumeThreadMax);
+// }
+//
+// consumer.setMessageModel(messageModel);
+//
+// switch (selectorType) {
+// case TAG:
+// consumer.subscribe(topic, selectorExpress);
+// break;
+// case SQL92:
+// consumer.subscribe(topic, MessageSelector.bySql(selectorExpress));
+// 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.");
+// }
+//
+// // provide an entryway to custom setting RocketMQ consumer
+// if (rocketMQListener instanceof AliyunRocketMQPushConsumerLifecycleListener) {
+// ((AliyunRocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumer);
+// }
+//
+// }
+//
+//}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java b/src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
new file mode 100644
index 0000000..f535eff
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
@@ -0,0 +1,53 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.core;
+
+/**
+ * Constants Created by aqlu on 2017/11/16.
+ */
+public final class DefaultRocketMQListenerContainerConstants {
+ public static final String PROP_NAMESERVER = "nameServer";
+ public static final String PROP_TOPIC = "topic";
+ public static final String PROP_CONSUMER_GROUP = "consumerGroup";
+ public static final String PROP_CONSUME_MODE = "consumeMode";
+ public static final String PROP_CONSUME_THREAD_MAX = "consumeThreadMax";
+ public static final String PROP_MESSAGE_MODEL = "messageModel";
+ public static final String PROP_SELECTOR_EXPRESS = "selectorExpress";
+ public static final String PROP_SELECTOR_TYPE = "selectorType";
+ public static final String PROP_ROCKETMQ_LISTENER = "rocketMQListener";
+ public static final String PROP_OBJECT_MAPPER = "objectMapper";
+ public static final String METHOD_DESTROY = "destroy";
+ public static final String PROP_ROCKETMQ_TEMPLATE = "rocketMQTemplate";
+ public static final String PROP_ONS_Addr = "onsAddr";
+ public static final String PROP_ACCESS_KEY = "accessKey";
+ public static final String PROP_SECRET_KEY = "secretKey";
+ public static final String PROP_NAMESRV_Addr = "nameSrvAddr";
+
+ /**
+ * 环境前缀
+ */
+ public static final String PROP_ENVIRONMENT_PREFIX = "environmentPrefix";
+ /**
+ * 消息消费失败发送的主题
+ */
+ public final static String CONSUMEFAILED_TOPIC = "ZTEITS_RNT_CLOUD";
+ /**
+ * 消息消费失败发送的tag
+ */
+ public final static String CONSUMEFAILED_TAG = "ConsumeMsgFailed";
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQConsumerLifecycleListener.java
new file mode 100644
index 0000000..c2a4f54
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/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 zteits.rocketmq.spring.starter.core;
+
+public interface RocketMQConsumerLifecycleListener {
+ void prepareStart(final T consumer);
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListener.java b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListener.java
new file mode 100644
index 0000000..6e20c8b
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListener.java
@@ -0,0 +1,27 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.core;
+
+public interface RocketMQListener {
+ /**
+ * 消费消息接口,由应用来实现
+ * 网络抖动等不稳定的情形可能会带来消息重复,对重复消息敏感的业务可对消息做幂等处理
+ * 没有异常则表示处理成功,否在处理失败,处理失败时阿里云MQ会重复调用,最多调用16次,如果16次依然失败,则不再调用。
+ */
+ void onMessage(T message);
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListenerContainer.java b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListenerContainer.java
new file mode 100644
index 0000000..a986167
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQListenerContainer.java
@@ -0,0 +1,29 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.core;
+
+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);
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQTemplate.java b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQTemplate.java
new file mode 100644
index 0000000..6004d64
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/core/RocketMQTemplate.java
@@ -0,0 +1,302 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.core;
+
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.messaging.MessagingException;
+
+import com.aliyun.openservices.ons.api.Message;
+import com.aliyun.openservices.ons.api.Producer;
+import com.aliyun.openservices.ons.api.SendCallback;
+import com.aliyun.openservices.ons.api.SendResult;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+import lombok.Getter;
+import lombok.Setter;
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+public class RocketMQTemplate implements InitializingBean, DisposableBean {
+
+ @Getter
+ @Setter
+ private Producer aliyunProducer;
+
+ @Setter
+ @Getter
+ private ObjectMapper objectMapper = new ObjectMapper();
+
+ @Getter
+ @Setter
+ private String charset = "UTF-8";
+
+ /**
+ * 环境前缀
+ */
+ @Setter
+ private String environmentPrefix;
+
+ /**
+ * 同步发送消息
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param key 业务主键
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
+ * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
+ *
+ *
+ * - 延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
+ * - 定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()
+ *
+ * @return {@link SendResult}
+ * 2018年3月23日 zhaowg
+ */
+ public SendResult syncSend(String topic,String tag,String keys,Object payload,Map userProperties,Long startDeliverTime) {
+ if (Objects.isNull(topic) || Objects.isNull(payload)) {
+ log.info("同步消息发送失败,主题和消息不能为空");
+ throw new IllegalArgumentException("同步消息发送失败,主题和消息不能为空");
+ }
+
+ try {
+ long now = System.currentTimeMillis();
+
+ Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
+ if(userProperties!=null && !userProperties.isEmpty()){
+ for (Entry userProp : userProperties.entrySet()) {
+ rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
+ }
+ }
+ if(startDeliverTime!=null){
+ //设置定时发送时间
+ rocketMsg.setStartDeliverTime(startDeliverTime);
+ }
+ //阿里云发送
+ SendResult sendResult = aliyunProducer.send(rocketMsg);
+ long costTime = System.currentTimeMillis() - now;
+ log.debug("发送消息耗时: {} ms, msgId:{}", costTime, sendResult.getMessageId());
+ return sendResult;
+ } catch (Exception e) {
+ log.info("同步发送失败. topic:{}, message:{} ", topic, payload);
+ throw new MessagingException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Same to {@link #syncSend(String, String, String, Object, Map, Long)}.
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param key 业务主键
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @return {@link SendResult}
+ * 2018年3月23日 zhaowg
+ */
+ public SendResult syncSend(String topic,String tag,String keys, Object payload) {
+ return syncSend(topic, tag, keys, payload, null, null);
+ }
+ /**
+ * Same to {@link #syncSend(String, String, String, Object)}.
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @return {@link SendResult}
+ * 2018年3月23日 zhaowg
+ */
+ public SendResult syncSend(String topic,String tag, Object payload) {
+ return syncSend(topic, tag,null, payload);
+ }
+
+ /**
+ * 异步发送消息
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param key 业务主键
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
+ * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
+ *
+ *
+ * - 延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
+ * - 定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()
+ *
+ * @param sendCallback 发送完成要执行的回调函数
+ * 2018年3月23日 zhaowg
+ */
+ public void asyncSend(String topic,String tag,String keys,Object payload,Map userProperties,
+ Long startDeliverTime,SendCallback sendCallback) {
+ if (Objects.isNull(topic) || Objects.isNull(payload)) {
+ log.info("异步消息发送失败,主题和消息不能为空");
+ throw new IllegalArgumentException("异步消息发送失败,主题和消息不能为空");
+ }
+ try {
+ long now = System.currentTimeMillis();
+
+ Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
+ if(userProperties!=null && !userProperties.isEmpty()){
+ for (Entry userProp : userProperties.entrySet()) {
+ rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
+ }
+ }
+ if(startDeliverTime!=null){
+ //设置定时发送时间
+ rocketMsg.setStartDeliverTime(startDeliverTime);
+ }
+ //阿里云发送
+ aliyunProducer.sendAsync(rocketMsg, sendCallback);
+ long costTime = System.currentTimeMillis() - now;
+ log.debug("发送消息耗时: {} ms", costTime);
+ } catch (Exception e) {
+ log.info("异步发送失败. topic:{}, message:{} ", topic, payload);
+ throw new MessagingException(e.getMessage(), e);
+ }
+ }
+ /**
+ * Same to {@link #asyncSend(String, String, String, Object, Map, Long, SendCallback)}.
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param key 业务主键
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @param sendCallback 发送完成要执行的回调函数
+ * @return {@link SendResult}
+ * 2018年3月23日 zhaowg
+ */
+ public void asyncSend(String topic,String tag,String keys, Object payload,SendCallback sendCallback) {
+ asyncSend(topic, tag, keys, payload, null, null,sendCallback);
+ }
+ /**
+ * Same to {@link #asyncSend(String, String, String, Object,SendCallback)}.
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @param sendCallback 发送完成要执行的回调函数
+ * @return {@link SendResult}
+ * 2018年3月23日 zhaowg
+ */
+ public void asyncSend(String topic,String tag, Object payload,SendCallback sendCallback) {
+ asyncSend(topic, tag,null, payload,sendCallback);
+ }
+ /**
+ * 服务器不应答,无法保证消息是否成功到达服务器
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param key 业务主键
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
+ * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
+ *
+ *
+ * - 延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;
+ * - 定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()
+ *
+ * 2018年3月23日 zhaowg
+ */
+ public void sendOneWay(String topic,String tag,String keys,Object payload,Map userProperties,
+ Long startDeliverTime) {
+ if (Objects.isNull(topic) || Objects.isNull(payload)) {
+ log.info("sendOneWay消息发送失败,主题和消息不能为空");
+ throw new IllegalArgumentException("sendOneWay消息发送失败,主题和消息不能为空");
+ }
+ try {
+ long now = System.currentTimeMillis();
+
+ Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
+ if(userProperties!=null && !userProperties.isEmpty()){
+ for (Entry userProp : userProperties.entrySet()) {
+ rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
+ }
+ }
+ if(startDeliverTime!=null){
+ //设置定时发送时间
+ rocketMsg.setStartDeliverTime(startDeliverTime);
+ }
+ //阿里云发送
+ aliyunProducer.sendOneway(rocketMsg);
+ long costTime = System.currentTimeMillis() - now;
+ log.debug("发送消息耗时: {} ms", costTime);
+ } catch (Exception e) {
+ log.info("sendOneWay发送失败. topic:{}, message:{} ", topic, payload);
+ throw new MessagingException(e.getMessage(), e);
+ }
+ }
+ /**
+ * Same to {@link #sendOneWay(String, String, String, Object, Map, Long)}.
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param key 业务主键
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * 2018年3月23日 zhaowg
+ */
+ public void sendOneWay(String topic,String tag,String keys, Object payload) {
+ sendOneWay(topic, tag, keys, payload, null, null);
+ }
+ /**
+ * Same to {@link #sendOneWay(String, String, String, Object)}.
+ * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
+ * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
+ * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
+ * 2018年3月23日 zhaowg
+ */
+ public void sendOneWay(String topic,String tag, Object payload) {
+ sendOneWay(topic, tag,null, payload);
+ }
+
+ @Override
+ public void afterPropertiesSet() throws Exception {
+ if(aliyunProducer != null){
+ log.info("开始启动阿里云[环境标识:"+environmentPrefix+"]生产者");
+ aliyunProducer.start();
+ }
+ }
+
+ /**
+ * 转换对象为字节
+ * @param msgObj
+ * @return
+ * 2018年3月23日 zhaowg
+ */
+ private byte[] convertToRocketMsg(Object msgObj) {
+ byte[] payloads;
+
+ if (msgObj instanceof String) {
+ payloads = ((String) msgObj).getBytes(Charset.forName(charset));
+ } else {
+ try {
+ String jsonObj = this.objectMapper.writeValueAsString(msgObj);
+ payloads = jsonObj.getBytes(Charset.forName(charset));
+ } catch (Exception e) {
+ throw new RuntimeException("convert to RocketMQ message failed.", e);
+ }
+ }
+ return payloads;
+ }
+
+
+ @Override
+ public void destroy() {
+ if(Objects.nonNull(aliyunProducer)){
+ log.info("开始关闭阿里云[环境标识:"+environmentPrefix+"]生产者");
+ aliyunProducer.shutdown();
+ }
+ }
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/enums/ConsumeMode.java b/src/main/java/zteits/rocketmq/spring/starter/enums/ConsumeMode.java
new file mode 100644
index 0000000..3795b7d
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/enums/ConsumeMode.java
@@ -0,0 +1,35 @@
+/*
+ * 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 zteits.rocketmq.spring.starter.enums;
+
+public enum ConsumeMode {
+ /**
+ * 同时接收异步发送的消息
+ */
+ CONCURRENTLY,
+
+ /**
+ * 顺序接收消息,一个队列,一个线程
+ */
+ ORDERLY,
+
+ /**
+ * 批量接收发送的消息,允许自定义范围为[1, 32], 实际消费数量可能小于该值
+ */
+ BATCH
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/enums/SelectorType.java b/src/main/java/zteits/rocketmq/spring/starter/enums/SelectorType.java
new file mode 100644
index 0000000..0b5b4f4
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/enums/SelectorType.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 zteits.rocketmq.spring.starter.enums;
+
+import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.filter.ExpressionType;
+
+public enum SelectorType {
+
+ /**
+ * @see ExpressionType#TAG
+ */
+ TAG,
+
+ /**
+ * @see ExpressionType#SQL92
+ * 注释by zwg 暂时不支持,原因:阿里云提供的ons-client最新版本1.7.4支持,但是该包有问题,引入后工程无法打包,目前使用的1.7.1,该版本不支持SQL92过滤
+ */
+ //SQL92
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/exception/ConvertMsgException.java b/src/main/java/zteits/rocketmq/spring/starter/exception/ConvertMsgException.java
new file mode 100644
index 0000000..4e75358
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/exception/ConvertMsgException.java
@@ -0,0 +1,27 @@
+package zteits.rocketmq.spring.starter.exception;
+
+public class ConvertMsgException extends RuntimeException{
+
+ private static final long serialVersionUID = 1L;
+
+ public ConvertMsgException() {
+ super();
+ }
+
+ public ConvertMsgException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+
+ public ConvertMsgException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public ConvertMsgException(String message) {
+ super(message);
+ }
+
+ public ConvertMsgException(Throwable cause) {
+ super(cause);
+ }
+
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java b/src/main/java/zteits/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java
new file mode 100644
index 0000000..ec22372
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/msgvo/ConsumeFailedMsgVO.java
@@ -0,0 +1,149 @@
+package zteits.rocketmq.spring.starter.msgvo;
+
+import java.io.Serializable;
+import java.util.Date;
+
+public class ConsumeFailedMsgVO implements Serializable{
+
+ private static final long serialVersionUID = 1L;
+
+ /**消息ID*/
+ private String msgId;
+
+ /**消息主题*/
+ private String topic;
+
+ /**消息标签描述*/
+ private String tag;
+
+ /**消费组*/
+ private String consumeGroup;
+
+ /**消费者ip*/
+ private String consumeIp;
+
+ /**消费开始时间*/
+ private Date consumeBeginTime;
+
+ /**消费结束时间*/
+ private Date consumeEndTime;
+
+ /**消息关键字*/
+ private String msgKeys;
+
+ /**重复消费次数*/
+ private Integer reconsumeTimes;
+
+ /**消费失败错误信息*/
+ private String cunsumerErrMsg;
+
+ /**消息内容*/
+ private String msg;
+
+ public String getCunsumerErrMsg() {
+ return cunsumerErrMsg;
+ }
+
+ public void setCunsumerErrMsg(String cunsumerErrMsg) {
+ this.cunsumerErrMsg = cunsumerErrMsg;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+
+ /**获取消息ID*/
+ public String getMsgId() {
+ return msgId;
+ }
+
+ /**设置消息ID*/
+ public void setMsgId(String msgId) {
+ this.msgId = msgId == null ? null : msgId.trim();
+ }
+
+ /**获取消息主题*/
+ public String getTopic() {
+ return topic;
+ }
+
+ /**设置消息主题*/
+ public void setTopic(String topic) {
+ this.topic = topic == null ? null : topic.trim();
+ }
+
+ /**获取消息标签描述*/
+ public String getTag() {
+ return tag;
+ }
+
+ /**设置消息标签描述*/
+ public void setTag(String tag) {
+ this.tag = tag == null ? null : tag.trim();
+ }
+
+ /**获取消费组*/
+ public String getConsumeGroup() {
+ return consumeGroup;
+ }
+
+ /**设置消费组*/
+ public void setConsumeGroup(String consumeGroup) {
+ this.consumeGroup = consumeGroup == null ? null : consumeGroup.trim();
+ }
+
+ /**获取消费者ip*/
+ public String getConsumeIp() {
+ return consumeIp;
+ }
+
+ /**设置消费者ip*/
+ public void setConsumeIp(String consumeIp) {
+ this.consumeIp = consumeIp == null ? null : consumeIp.trim();
+ }
+
+ /**获取消费开始时间*/
+ public Date getConsumeBeginTime() {
+ return consumeBeginTime;
+ }
+
+ /**设置消费开始时间*/
+ public void setConsumeBeginTime(Date consumeBeginTime) {
+ this.consumeBeginTime = consumeBeginTime;
+ }
+
+ /**获取消费结束时间*/
+ public Date getConsumeEndTime() {
+ return consumeEndTime;
+ }
+
+ /**设置消费结束时间*/
+ public void setConsumeEndTime(Date consumeEndTime) {
+ this.consumeEndTime = consumeEndTime;
+ }
+
+ /**获取消息关键字*/
+ public String getMsgKeys() {
+ return msgKeys;
+ }
+
+ /**设置消息关键字*/
+ public void setMsgKeys(String msgKeys) {
+ this.msgKeys = msgKeys == null ? null : msgKeys.trim();
+ }
+
+ /**获取重复消费次数*/
+ public Integer getReconsumeTimes() {
+ return reconsumeTimes;
+ }
+
+ /**设置重复消费次数*/
+ public void setReconsumeTimes(Integer reconsumeTimes) {
+ this.reconsumeTimes = reconsumeTimes;
+ }
+
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/utils/ExceptionUtil.java b/src/main/java/zteits/rocketmq/spring/starter/utils/ExceptionUtil.java
new file mode 100644
index 0000000..70818ea
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/utils/ExceptionUtil.java
@@ -0,0 +1,21 @@
+package zteits.rocketmq.spring.starter.utils;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public class ExceptionUtil {
+
+ public static String getTrace(Throwable t) {
+ StringBuffer buffer = new StringBuffer();
+ if(t==null){
+ return "";
+ }
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter writer = new PrintWriter(stringWriter);
+ t.printStackTrace(writer);
+ //设置堆栈信息
+ buffer.append("堆栈信息为:" + stringWriter.getBuffer().toString());
+ return buffer.toString();
+ }
+
+}
diff --git a/src/main/java/zteits/rocketmq/spring/starter/utils/IPUtil.java b/src/main/java/zteits/rocketmq/spring/starter/utils/IPUtil.java
new file mode 100644
index 0000000..f9b4e80
--- /dev/null
+++ b/src/main/java/zteits/rocketmq/spring/starter/utils/IPUtil.java
@@ -0,0 +1,49 @@
+package zteits.rocketmq.spring.starter.utils;
+
+import java.net.InetAddress;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * Copyright: Copyright (c) 2017 zteits
+ *
+ * @ClassName: com.clouds.constants.utils
+ * @Description: IP地址工具类
+ * @version: v1.0.0
+ * @author: atao
+ * @date: 2017/4/26 上午9:25
+ * Modification History:
+ * Date Author Version Description
+ * ---------------------------------------------------------*
+ * 2017/4/26 atao v1.0.0 创建
+ */
+public class IPUtil {
+ private static String localHost;
+ private static String localHostName;
+
+ public static String getLocalHost() {
+ if (StringUtils.isEmpty(localHost)) {
+ getLocalHostInfo();
+ }
+ return localHost;
+ }
+
+ public static String getLocalHostNome() {
+ if (StringUtils.isEmpty(localHostName)) {
+ getLocalHostInfo();
+ }
+ return localHostName;
+ }
+
+ private static void getLocalHostInfo() {
+ try {
+ InetAddress ia = InetAddress.getLocalHost();
+ localHostName = ia.getHostName();
+ localHost = ia.getHostAddress();
+ } catch (Exception e) {
+ //获取当前地址失败
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/src/main/resources/META-INF/spring.factories b/src/main/resources/META-INF/spring.factories
index 6ab3023..7247f53 100644
--- a/src/main/resources/META-INF/spring.factories
+++ b/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-org.apache.rocketmq.spring.starter.AliyunRocketMQAutoConfiguration
\ No newline at end of file
+zteits.rocketmq.spring.starter.AliyunRocketMQAutoConfiguration
diff --git a/src/test/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java b/src/test/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
deleted file mode 100644
index e4e2c41..0000000
--- a/src/test/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
+++ /dev/null
@@ -1,184 +0,0 @@
-///*
-// * 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.starter;
-//
-//import com.fasterxml.jackson.databind.ObjectMapper;
-//import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;
-//import org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainer;
-//import org.apache.rocketmq.spring.starter.core.RocketMQListener;
-//import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;
-//import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
-//import org.apache.rocketmq.spring.starter.enums.SelectorType;
-//import org.apache.rocketmq.client.producer.DefaultMQProducer;
-//import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
-//import org.junit.After;
-//import org.junit.Test;
-//import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-//import org.springframework.boot.test.util.EnvironmentTestUtils;
-//import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-//
-//import static org.assertj.core.api.Assertions.assertThat;
-//
-//public class RocketMQAutoConfigurationTests {
-//
-// private static final String TEST_CONSUMER_GROUP = "my_consumer";
-//
-// private static final String TEST_TOPIC = "test-topic";
-//
-// private AnnotationConfigApplicationContext context;
-//
-// @Test
-// public void rocketMQTemplate() {
-//
-// load("spring.rocketmq.nameServer=127.0.0.1:9876",
-// "spring.rocketmq.producer.group=my_group",
-// "spring.rocketmq.producer.send-msg-timeout=30000",
-// "spring.rocketmq.producer.retry-times-when-send-async-failed=1",
-// "spring.rocketmq.producer.compress-msg-body-over-howmuch=1024",
-// "spring.rocketmq.producer.max-message-size=10240",
-// "spring.rocketmq.producer.retry-another-broker-when-not-store-ok=true",
-// "spring.rocketmq.producer.retry-times-when-send-failed=1");
-//
-// assertThat(this.context.containsBean("rocketMQMessageObjectMapper")).isTrue();
-// assertThat(this.context.containsBean("mqProducer")).isTrue();
-// assertThat(this.context.containsBean("rocketMQTemplate")).isTrue();
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
-//
-// RocketMQTemplate rocketMQTemplate = this.context.getBean(RocketMQTemplate.class);
-// ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);
-// assertThat(rocketMQTemplate.getObjectMapper()).isEqualTo(objectMapper);
-//
-// DefaultMQProducer defaultMQProducer = rocketMQTemplate.getProducer();
-//
-// assertThat(defaultMQProducer.getNamesrvAddr()).isEqualTo("127.0.0.1:9876");
-// assertThat(defaultMQProducer.getProducerGroup()).isEqualTo("my_group");
-// assertThat(defaultMQProducer.getSendMsgTimeout()).isEqualTo(30000);
-// assertThat(defaultMQProducer.getRetryTimesWhenSendAsyncFailed()).isEqualTo(1);
-// assertThat(defaultMQProducer.getCompressMsgBodyOverHowmuch()).isEqualTo(1024);
-// assertThat(defaultMQProducer.getMaxMessageSize()).isEqualTo(10240);
-// assertThat(defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()).isTrue();
-// assertThat(defaultMQProducer.getRetryTimesWhenSendFailed()).isEqualTo(1);
-// }
-//
-// @Test
-// public void enableProducer() {
-// load();
-// assertThat(this.context.containsBean("mqProducer")).isFalse();
-// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
-// closeContext();
-//
-// load("spring.rocketmq.nameServer=127.0.0.1:9876");
-// assertThat(this.context.containsBean("mqProducer")).isFalse();
-// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
-// closeContext();
-//
-// load("spring.rocketmq.producer.group=my_group");
-// assertThat(this.context.containsBean("mqProducer")).isFalse();
-// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
-// closeContext();
-//
-// load("spring.rocketmq.nameServer=127.0.0.1:9876", "spring.rocketmq.producer.group=my_group");
-// assertThat(this.context.containsBean("mqProducer")).isTrue();
-// assertThat(this.context.containsBean("rocketMQTemplate")).isEqualTo(true);
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
-// }
-//
-// @Test
-// public void enableConsumer() {
-// load();
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
-// closeContext();
-//
-// load("spring.rocketmq.nameServer=127.0.0.1:9876");
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
-// closeContext();
-//
-// load(false);
-// this.context.registerBeanDefinition("myListener",
-// BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());
-// this.context.refresh();
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
-// closeContext();
-//
-// load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");
-// this.context.registerBeanDefinition("myListener",
-// BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());
-// this.context.refresh();
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();
-// assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();
-// assertThat(this.context.containsBean("mqProducer")).isFalse();
-// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
-//
-// }
-//
-// @Test
-// public void listenerContainer() {
-// load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");
-// BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(MyListener.class);
-// this.context.registerBeanDefinition("myListener", beanBuilder.getBeanDefinition());
-// this.context.refresh();
-//
-// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();
-// assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();
-//
-// DefaultRocketMQListenerContainer listenerContainer =
-// this.context.getBean(DefaultRocketMQListenerContainer.class.getName() + "_1",
-// DefaultRocketMQListenerContainer.class);
-// ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);
-// assertThat(listenerContainer.getObjectMapper()).isEqualTo(objectMapper);
-// assertThat(listenerContainer.getConsumeMode()).isEqualTo(ConsumeMode.CONCURRENTLY);
-// assertThat(listenerContainer.getSelectorType()).isEqualTo(SelectorType.TAG);
-// assertThat(listenerContainer.getSelectorExpress()).isEqualTo("*");
-// assertThat(listenerContainer.getConsumerGroup()).isEqualTo(TEST_CONSUMER_GROUP);
-// assertThat(listenerContainer.getTopic()).isEqualTo(TEST_TOPIC);
-// assertThat(listenerContainer.getNameServer()).isEqualTo("127.0.0.1:9876");
-// assertThat(listenerContainer.getMessageModel()).isEqualTo(MessageModel.CLUSTERING);
-// assertThat(listenerContainer.getConsumeThreadMax()).isEqualTo(1);
-// }
-//
-// @After
-// public void closeContext() {
-// if (this.context != null) {
-// this.context.close();
-// }
-// }
-//
-// @RocketMQMessageListener(consumerGroup = TEST_CONSUMER_GROUP, topic = TEST_TOPIC, consumeThreadMax = 1)
-// private static class MyListener implements RocketMQListener {
-//
-// @Override
-// public void onMessage(String message) {
-// System.out.println(message);
-// }
-// }
-//
-// private void load(boolean refresh, String... environment) {
-// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
-// ctx.register(RocketMQAutoConfiguration.class);
-// EnvironmentTestUtils.addEnvironment(ctx, environment);
-// if (refresh) {
-// ctx.refresh();
-// }
-// this.context = ctx;
-// }
-//
-// private void load(String... environment) {
-// load(true, environment);
-// }
-//}
-//
diff --git a/src/test/java/zteits/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java b/src/test/java/zteits/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
new file mode 100644
index 0000000..e4e2c41
--- /dev/null
+++ b/src/test/java/zteits/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
@@ -0,0 +1,184 @@
+///*
+// * 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.starter;
+//
+//import com.fasterxml.jackson.databind.ObjectMapper;
+//import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;
+//import org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainer;
+//import org.apache.rocketmq.spring.starter.core.RocketMQListener;
+//import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;
+//import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
+//import org.apache.rocketmq.spring.starter.enums.SelectorType;
+//import org.apache.rocketmq.client.producer.DefaultMQProducer;
+//import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+//import org.junit.After;
+//import org.junit.Test;
+//import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+//import org.springframework.boot.test.util.EnvironmentTestUtils;
+//import org.springframework.context.annotation.AnnotationConfigApplicationContext;
+//
+//import static org.assertj.core.api.Assertions.assertThat;
+//
+//public class RocketMQAutoConfigurationTests {
+//
+// private static final String TEST_CONSUMER_GROUP = "my_consumer";
+//
+// private static final String TEST_TOPIC = "test-topic";
+//
+// private AnnotationConfigApplicationContext context;
+//
+// @Test
+// public void rocketMQTemplate() {
+//
+// load("spring.rocketmq.nameServer=127.0.0.1:9876",
+// "spring.rocketmq.producer.group=my_group",
+// "spring.rocketmq.producer.send-msg-timeout=30000",
+// "spring.rocketmq.producer.retry-times-when-send-async-failed=1",
+// "spring.rocketmq.producer.compress-msg-body-over-howmuch=1024",
+// "spring.rocketmq.producer.max-message-size=10240",
+// "spring.rocketmq.producer.retry-another-broker-when-not-store-ok=true",
+// "spring.rocketmq.producer.retry-times-when-send-failed=1");
+//
+// assertThat(this.context.containsBean("rocketMQMessageObjectMapper")).isTrue();
+// assertThat(this.context.containsBean("mqProducer")).isTrue();
+// assertThat(this.context.containsBean("rocketMQTemplate")).isTrue();
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
+//
+// RocketMQTemplate rocketMQTemplate = this.context.getBean(RocketMQTemplate.class);
+// ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);
+// assertThat(rocketMQTemplate.getObjectMapper()).isEqualTo(objectMapper);
+//
+// DefaultMQProducer defaultMQProducer = rocketMQTemplate.getProducer();
+//
+// assertThat(defaultMQProducer.getNamesrvAddr()).isEqualTo("127.0.0.1:9876");
+// assertThat(defaultMQProducer.getProducerGroup()).isEqualTo("my_group");
+// assertThat(defaultMQProducer.getSendMsgTimeout()).isEqualTo(30000);
+// assertThat(defaultMQProducer.getRetryTimesWhenSendAsyncFailed()).isEqualTo(1);
+// assertThat(defaultMQProducer.getCompressMsgBodyOverHowmuch()).isEqualTo(1024);
+// assertThat(defaultMQProducer.getMaxMessageSize()).isEqualTo(10240);
+// assertThat(defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()).isTrue();
+// assertThat(defaultMQProducer.getRetryTimesWhenSendFailed()).isEqualTo(1);
+// }
+//
+// @Test
+// public void enableProducer() {
+// load();
+// assertThat(this.context.containsBean("mqProducer")).isFalse();
+// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
+// closeContext();
+//
+// load("spring.rocketmq.nameServer=127.0.0.1:9876");
+// assertThat(this.context.containsBean("mqProducer")).isFalse();
+// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
+// closeContext();
+//
+// load("spring.rocketmq.producer.group=my_group");
+// assertThat(this.context.containsBean("mqProducer")).isFalse();
+// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
+// closeContext();
+//
+// load("spring.rocketmq.nameServer=127.0.0.1:9876", "spring.rocketmq.producer.group=my_group");
+// assertThat(this.context.containsBean("mqProducer")).isTrue();
+// assertThat(this.context.containsBean("rocketMQTemplate")).isEqualTo(true);
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
+// }
+//
+// @Test
+// public void enableConsumer() {
+// load();
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
+// closeContext();
+//
+// load("spring.rocketmq.nameServer=127.0.0.1:9876");
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
+// closeContext();
+//
+// load(false);
+// this.context.registerBeanDefinition("myListener",
+// BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());
+// this.context.refresh();
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
+// closeContext();
+//
+// load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");
+// this.context.registerBeanDefinition("myListener",
+// BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());
+// this.context.refresh();
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();
+// assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();
+// assertThat(this.context.containsBean("mqProducer")).isFalse();
+// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
+//
+// }
+//
+// @Test
+// public void listenerContainer() {
+// load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");
+// BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(MyListener.class);
+// this.context.registerBeanDefinition("myListener", beanBuilder.getBeanDefinition());
+// this.context.refresh();
+//
+// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();
+// assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();
+//
+// DefaultRocketMQListenerContainer listenerContainer =
+// this.context.getBean(DefaultRocketMQListenerContainer.class.getName() + "_1",
+// DefaultRocketMQListenerContainer.class);
+// ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);
+// assertThat(listenerContainer.getObjectMapper()).isEqualTo(objectMapper);
+// assertThat(listenerContainer.getConsumeMode()).isEqualTo(ConsumeMode.CONCURRENTLY);
+// assertThat(listenerContainer.getSelectorType()).isEqualTo(SelectorType.TAG);
+// assertThat(listenerContainer.getSelectorExpress()).isEqualTo("*");
+// assertThat(listenerContainer.getConsumerGroup()).isEqualTo(TEST_CONSUMER_GROUP);
+// assertThat(listenerContainer.getTopic()).isEqualTo(TEST_TOPIC);
+// assertThat(listenerContainer.getNameServer()).isEqualTo("127.0.0.1:9876");
+// assertThat(listenerContainer.getMessageModel()).isEqualTo(MessageModel.CLUSTERING);
+// assertThat(listenerContainer.getConsumeThreadMax()).isEqualTo(1);
+// }
+//
+// @After
+// public void closeContext() {
+// if (this.context != null) {
+// this.context.close();
+// }
+// }
+//
+// @RocketMQMessageListener(consumerGroup = TEST_CONSUMER_GROUP, topic = TEST_TOPIC, consumeThreadMax = 1)
+// private static class MyListener implements RocketMQListener {
+//
+// @Override
+// public void onMessage(String message) {
+// System.out.println(message);
+// }
+// }
+//
+// private void load(boolean refresh, String... environment) {
+// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
+// ctx.register(RocketMQAutoConfiguration.class);
+// EnvironmentTestUtils.addEnvironment(ctx, environment);
+// if (refresh) {
+// ctx.refresh();
+// }
+// this.context = ctx;
+// }
+//
+// private void load(String... environment) {
+// load(true, environment);
+// }
+//}
+//
--
libgit2 0.21.4