Commit a2aff61fe3ccbdaa2745868c1334a579bec519f2

Authored by zhaowg
1 parent b2ebdd73

整合阿里云RocketMQ SDK

@@ -60,17 +60,6 @@ @@ -60,17 +60,6 @@
60 <artifactId>spring-boot-starter</artifactId> 60 <artifactId>spring-boot-starter</artifactId>
61 </dependency> 61 </dependency>
62 <dependency> 62 <dependency>
63 - <groupId>org.apache.rocketmq</groupId>  
64 - <artifactId>rocketmq-client</artifactId>  
65 - <version>${rocketmq-version}</version>  
66 - <exclusions>  
67 - <exclusion>  
68 - <groupId>org.slf4j</groupId>  
69 - <artifactId>slf4j-api</artifactId>  
70 - </exclusion>  
71 - </exclusions>  
72 - </dependency>  
73 - <dependency>  
74 <groupId>com.aliyun.openservices</groupId> 63 <groupId>com.aliyun.openservices</groupId>
75 <artifactId>ons-client</artifactId> 64 <artifactId>ons-client</artifactId>
76 <version>1.7.2.Final</version> 65 <version>1.7.2.Final</version>
src/main/java/org/apache/rocketmq/spring/starter/AliyunRocketMQAutoConfiguration.java
@@ -22,13 +22,12 @@ import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerCon @@ -22,13 +22,12 @@ import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerCon
22 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_MODE; 22 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_MODE;
23 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_THREAD_MAX; 23 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_CONSUME_THREAD_MAX;
24 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_MESSAGE_MODEL; 24 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_MESSAGE_MODEL;
25 -import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_NAMESERVER;  
26 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_OBJECT_MAPPER; 25 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_OBJECT_MAPPER;
27 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_LISTENER; 26 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_LISTENER;
28 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_TEMPLATE; 27 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_ROCKETMQ_TEMPLATE;
29 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_EXPRESS; 28 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_EXPRESS;
30 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_TYPE; 29 import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_SELECTOR_TYPE;
31 -import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.PROP_TOPIC; 30 +import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.*;
32 31
33 import java.util.Map; 32 import java.util.Map;
34 import java.util.Objects; 33 import java.util.Objects;
@@ -39,7 +38,6 @@ import javax.annotation.Resource; @@ -39,7 +38,6 @@ import javax.annotation.Resource;
39 38
40 import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener; 39 import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;
41 import org.apache.rocketmq.spring.starter.core.AliyunRocketMQListenerContainer; 40 import org.apache.rocketmq.spring.starter.core.AliyunRocketMQListenerContainer;
42 -import org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainer;  
43 import org.apache.rocketmq.spring.starter.core.RocketMQListener; 41 import org.apache.rocketmq.spring.starter.core.RocketMQListener;
44 import org.apache.rocketmq.spring.starter.core.RocketMQTemplate; 42 import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;
45 import org.springframework.aop.support.AopUtils; 43 import org.springframework.aop.support.AopUtils;
@@ -72,7 +70,6 @@ import lombok.extern.slf4j.Slf4j; @@ -72,7 +70,6 @@ import lombok.extern.slf4j.Slf4j;
72 70
73 @Configuration 71 @Configuration
74 @EnableConfigurationProperties(RocketMQProperties.class) 72 @EnableConfigurationProperties(RocketMQProperties.class)
75 -@ConditionalOnProperty(name = "spring.rocketmq.aliyun",havingValue="true")  
76 @Order 73 @Order
77 @Slf4j 74 @Slf4j
78 public class AliyunRocketMQAutoConfiguration { 75 public class AliyunRocketMQAutoConfiguration {
@@ -80,23 +77,27 @@ public class AliyunRocketMQAutoConfiguration { @@ -80,23 +77,27 @@ public class AliyunRocketMQAutoConfiguration {
80 @Bean 77 @Bean
81 @ConditionalOnClass(Producer.class) 78 @ConditionalOnClass(Producer.class)
82 @ConditionalOnMissingBean(Producer.class) 79 @ConditionalOnMissingBean(Producer.class)
83 - @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"nameServer", "producer.group"}) 80 + @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"environmentPrefix", "producer.group"})
84 public Producer mqProducer(RocketMQProperties rocketMQProperties) { 81 public Producer mqProducer(RocketMQProperties rocketMQProperties) {
85 82
86 RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer(); 83 RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer();
87 String groupName = producerConfig.getGroup(); 84 String groupName = producerConfig.getGroup();
88 Assert.hasText(groupName, "[spring.rocketmq.producer.group] must not be null"); 85 Assert.hasText(groupName, "[spring.rocketmq.producer.group] must not be null");
89 String accessKey = rocketMQProperties.getAccessKey(); 86 String accessKey = rocketMQProperties.getAccessKey();
90 - Assert.hasText(accessKey, "[spring.rocketmq.producer.accessKey] must not be null"); 87 + Assert.hasText(accessKey, "[spring.rocketmq.accessKey] must not be null");
91 String secretKey = rocketMQProperties.getSecretKey(); 88 String secretKey = rocketMQProperties.getSecretKey();
92 - Assert.hasText(secretKey, "[spring.rocketmq.producer.secretKey] must not be null"); 89 + Assert.hasText(secretKey, "[spring.rocketmq.secretKey] must not be null");
  90 + String onsAddr = rocketMQProperties.getOnsAddr();
  91 + Assert.hasText(secretKey, "[spring.rocketmq.onsAddr] must not be null");
  92 + String environmentPrefix = rocketMQProperties.getEnvironmentPrefix();
  93 + Assert.hasText(secretKey, "[spring.rocketmq.environmentPrefix] must not be null");
93 94
94 Properties producerProperties = new Properties(); 95 Properties producerProperties = new Properties();
95 - producerProperties.setProperty(PropertyKeyConst.ProducerId, "PID_"+groupName); 96 + //生成者ProducerId添加前缀:PID_+环境标识_+groupName
  97 + producerProperties.setProperty(PropertyKeyConst.ProducerId, "PID_"+environmentPrefix+"_"+groupName);
96 producerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey); 98 producerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
97 producerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey); 99 producerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
98 - producerProperties.setProperty(PropertyKeyConst.ONSAddr, rocketMQProperties.getNameServer());  
99 - 100 + producerProperties.setProperty(PropertyKeyConst.ONSAddr, onsAddr);
100 Producer producer = ONSFactory.createProducer(producerProperties); 101 Producer producer = ONSFactory.createProducer(producerProperties);
101 return producer; 102 return producer;
102 } 103 }
@@ -111,12 +112,13 @@ public class AliyunRocketMQAutoConfiguration { @@ -111,12 +112,13 @@ public class AliyunRocketMQAutoConfiguration {
111 @Bean(destroyMethod = "destroy") 112 @Bean(destroyMethod = "destroy")
112 @ConditionalOnBean(Producer.class) 113 @ConditionalOnBean(Producer.class)
113 @ConditionalOnMissingBean(name = "rocketMQTemplate") 114 @ConditionalOnMissingBean(name = "rocketMQTemplate")
114 - public RocketMQTemplate rocketMQTemplate(Producer mqProducer, 115 + public RocketMQTemplate rocketMQTemplate(Producer mqProducer,RocketMQProperties rocketMQProperties,
115 @Autowired(required = false) 116 @Autowired(required = false)
116 @Qualifier("rocketMQMessageObjectMapper") 117 @Qualifier("rocketMQMessageObjectMapper")
117 ObjectMapper objectMapper) { 118 ObjectMapper objectMapper) {
118 RocketMQTemplate rocketMQTemplate = new RocketMQTemplate(); 119 RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
119 rocketMQTemplate.setAliyunProducer(mqProducer); 120 rocketMQTemplate.setAliyunProducer(mqProducer);
  121 + rocketMQTemplate.setEnvironmentPrefix(rocketMQProperties.getEnvironmentPrefix());
120 if (Objects.nonNull(objectMapper)) { 122 if (Objects.nonNull(objectMapper)) {
121 rocketMQTemplate.setObjectMapper(objectMapper); 123 rocketMQTemplate.setObjectMapper(objectMapper);
122 } 124 }
@@ -176,10 +178,11 @@ public class AliyunRocketMQAutoConfiguration { @@ -176,10 +178,11 @@ public class AliyunRocketMQAutoConfiguration {
176 RocketMQListener rocketMQListener = (RocketMQListener) bean; 178 RocketMQListener rocketMQListener = (RocketMQListener) bean;
177 RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class); 179 RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);
178 BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(AliyunRocketMQListenerContainer.class); 180 BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(AliyunRocketMQListenerContainer.class);
179 - beanBuilder.addPropertyValue(PROP_NAMESERVER, rocketMQProperties.getNameServer());  
180 - beanBuilder.addPropertyValue(PROP_TOPIC, environment.resolvePlaceholders(annotation.topic())); 181 + beanBuilder.addPropertyValue(PROP_ONS_Addr, rocketMQProperties.getOnsAddr());
  182 + beanBuilder.addPropertyValue(PROP_TOPIC, rocketMQProperties.getEnvironmentPrefix()+"_"+environment.resolvePlaceholders(annotation.topic()));
181 183
182 - beanBuilder.addPropertyValue(PROP_CONSUMER_GROUP, environment.resolvePlaceholders(annotation.consumerGroup())); 184 + //消费者ConsumerId添加前缀:PID_+环境标识_+groupName
  185 + beanBuilder.addPropertyValue(PROP_CONSUMER_GROUP, "CID_"+rocketMQProperties.getEnvironmentPrefix()+"_"+environment.resolvePlaceholders(annotation.consumerGroup()));
183 beanBuilder.addPropertyValue(PROP_CONSUME_MODE, annotation.consumeMode()); 186 beanBuilder.addPropertyValue(PROP_CONSUME_MODE, annotation.consumeMode());
184 beanBuilder.addPropertyValue(PROP_CONSUME_THREAD_MAX, annotation.consumeThreadMax()); 187 beanBuilder.addPropertyValue(PROP_CONSUME_THREAD_MAX, annotation.consumeThreadMax());
185 beanBuilder.addPropertyValue(PROP_MESSAGE_MODEL, annotation.messageModel()); 188 beanBuilder.addPropertyValue(PROP_MESSAGE_MODEL, annotation.messageModel());
@@ -187,13 +190,14 @@ public class AliyunRocketMQAutoConfiguration { @@ -187,13 +190,14 @@ public class AliyunRocketMQAutoConfiguration {
187 beanBuilder.addPropertyValue(PROP_SELECTOR_TYPE, annotation.selectorType()); 190 beanBuilder.addPropertyValue(PROP_SELECTOR_TYPE, annotation.selectorType());
188 beanBuilder.addPropertyValue(PROP_ROCKETMQ_LISTENER, rocketMQListener); 191 beanBuilder.addPropertyValue(PROP_ROCKETMQ_LISTENER, rocketMQListener);
189 beanBuilder.addPropertyValue(PROP_ROCKETMQ_TEMPLATE, rocketMQTemplate); 192 beanBuilder.addPropertyValue(PROP_ROCKETMQ_TEMPLATE, rocketMQTemplate);
  193 + beanBuilder.addPropertyValue(PROP_ENVIRONMENT_PREFIX, rocketMQProperties.getEnvironmentPrefix());
190 if (Objects.nonNull(objectMapper)) { 194 if (Objects.nonNull(objectMapper)) {
191 beanBuilder.addPropertyValue(PROP_OBJECT_MAPPER, objectMapper); 195 beanBuilder.addPropertyValue(PROP_OBJECT_MAPPER, objectMapper);
192 } 196 }
193 beanBuilder.setDestroyMethodName(METHOD_DESTROY); 197 beanBuilder.setDestroyMethodName(METHOD_DESTROY);
194 //增加阿里云key 198 //增加阿里云key
195 - beanBuilder.addPropertyValue("accessKey", rocketMQProperties.getAccessKey());  
196 - beanBuilder.addPropertyValue("secretKey", rocketMQProperties.getSecretKey()); 199 + beanBuilder.addPropertyValue(PROP_ACCESS_KEY, rocketMQProperties.getAccessKey());
  200 + beanBuilder.addPropertyValue(PROP_SECRET_KEY, rocketMQProperties.getSecretKey());
197 201
198 String containerBeanName = String.format("%s_%s", AliyunRocketMQListenerContainer.class.getName(), counter.incrementAndGet()); 202 String containerBeanName = String.format("%s_%s", AliyunRocketMQListenerContainer.class.getName(), counter.incrementAndGet());
199 DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory(); 203 DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
src/main/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfiguration.java deleted
1 -/*  
2 - * Licensed to the Apache Software Foundation (ASF) under one or more  
3 - * contributor license agreements. See the NOTICE file distributed with  
4 - * this work for additional information regarding copyright ownership.  
5 - * The ASF licenses this file to You under the Apache License, Version 2.0  
6 - * (the "License"); you may not use this file except in compliance with  
7 - * the License. You may obtain a copy of the License at  
8 - *  
9 - * http://www.apache.org/licenses/LICENSE-2.0  
10 - *  
11 - * Unless required by applicable law or agreed to in writing, software  
12 - * distributed under the License is distributed on an "AS IS" BASIS,  
13 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
14 - * See the License for the specific language governing permissions and  
15 - * limitations under the License.  
16 - */  
17 -  
18 -package org.apache.rocketmq.spring.starter;  
19 -  
20 -import com.fasterxml.jackson.databind.ObjectMapper;  
21 -import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;  
22 -import org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainer;  
23 -import org.apache.rocketmq.spring.starter.core.RocketMQListener;  
24 -import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;  
25 -import java.util.Map;  
26 -import java.util.Objects;  
27 -import java.util.concurrent.atomic.AtomicLong;  
28 -import javax.annotation.Resource;  
29 -import lombok.extern.slf4j.Slf4j;  
30 -import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;  
31 -import org.apache.rocketmq.client.impl.MQClientAPIImpl;  
32 -import org.apache.rocketmq.client.producer.DefaultMQProducer;  
33 -import org.springframework.aop.support.AopUtils;  
34 -import org.springframework.beans.BeansException;  
35 -import org.springframework.beans.factory.InitializingBean;  
36 -import org.springframework.beans.factory.annotation.Autowired;  
37 -import org.springframework.beans.factory.annotation.Qualifier;  
38 -import org.springframework.beans.factory.support.BeanDefinitionBuilder;  
39 -import org.springframework.beans.factory.support.DefaultListableBeanFactory;  
40 -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;  
41 -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;  
42 -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;  
43 -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;  
44 -import org.springframework.boot.context.properties.EnableConfigurationProperties;  
45 -import org.springframework.context.ApplicationContext;  
46 -import org.springframework.context.ApplicationContextAware;  
47 -import org.springframework.context.ConfigurableApplicationContext;  
48 -import org.springframework.context.annotation.Bean;  
49 -import org.springframework.context.annotation.Configuration;  
50 -import org.springframework.core.annotation.Order;  
51 -import org.springframework.core.env.StandardEnvironment;  
52 -import org.springframework.util.Assert;  
53 -  
54 -import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.*;  
55 -  
56 -@Configuration  
57 -@ConditionalOnProperty(name = "spring.rocketmq.aliyun",havingValue="false")  
58 -@EnableConfigurationProperties(RocketMQProperties.class)  
59 -@ConditionalOnClass(MQClientAPIImpl.class)  
60 -@Order  
61 -@Slf4j  
62 -public class RocketMQAutoConfiguration {  
63 -  
64 - @Bean  
65 - @ConditionalOnClass(DefaultMQProducer.class)  
66 - @ConditionalOnMissingBean(DefaultMQProducer.class)  
67 - @ConditionalOnProperty(prefix = "spring.rocketmq", value = {"nameServer", "producer.group"})  
68 - public DefaultMQProducer mqProducer(RocketMQProperties rocketMQProperties) {  
69 -  
70 - RocketMQProperties.Producer producerConfig = rocketMQProperties.getProducer();  
71 - String groupName = producerConfig.getGroup();  
72 - Assert.hasText(groupName, "[spring.rocketmq.producer.group] must not be null");  
73 -  
74 - DefaultMQProducer producer = new DefaultMQProducer(producerConfig.getGroup());  
75 - producer.setNamesrvAddr(rocketMQProperties.getNameServer());  
76 - producer.setSendMsgTimeout(producerConfig.getSendMsgTimeout());  
77 - producer.setRetryTimesWhenSendFailed(producerConfig.getRetryTimesWhenSendFailed());  
78 - producer.setRetryTimesWhenSendAsyncFailed(producerConfig.getRetryTimesWhenSendAsyncFailed());  
79 - producer.setMaxMessageSize(producerConfig.getMaxMessageSize());  
80 - producer.setCompressMsgBodyOverHowmuch(producerConfig.getCompressMsgBodyOverHowmuch());  
81 - producer.setRetryAnotherBrokerWhenNotStoreOK(producerConfig.isRetryAnotherBrokerWhenNotStoreOk());  
82 -  
83 - return producer;  
84 - }  
85 -  
86 - @Bean  
87 - @ConditionalOnClass(ObjectMapper.class)  
88 - @ConditionalOnMissingBean(name = "rocketMQMessageObjectMapper")  
89 - public ObjectMapper rocketMQMessageObjectMapper() {  
90 - return new ObjectMapper();  
91 - }  
92 -  
93 - @Bean(destroyMethod = "destroy")  
94 - @ConditionalOnBean(DefaultMQProducer.class)  
95 - @ConditionalOnMissingBean(name = "rocketMQTemplate")  
96 - public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer,  
97 - @Autowired(required = false)  
98 - @Qualifier("rocketMQMessageObjectMapper")  
99 - ObjectMapper objectMapper) {  
100 - RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();  
101 - rocketMQTemplate.setDefaultProducer(mqProducer);  
102 - if (Objects.nonNull(objectMapper)) {  
103 - rocketMQTemplate.setObjectMapper(objectMapper);  
104 - }  
105 -  
106 - return rocketMQTemplate;  
107 - }  
108 -  
109 - @Configuration  
110 - @ConditionalOnClass(DefaultMQPushConsumer.class)  
111 - @EnableConfigurationProperties(RocketMQProperties.class)  
112 - @ConditionalOnProperty(prefix = "spring.rocketmq", value = "nameServer")  
113 - @Order  
114 - public static class ListenerContainerConfiguration implements ApplicationContextAware, InitializingBean {  
115 - private ConfigurableApplicationContext applicationContext;  
116 -  
117 - private AtomicLong counter = new AtomicLong(0);  
118 -  
119 - @Resource  
120 - private StandardEnvironment environment;  
121 -  
122 - @Resource  
123 - private RocketMQProperties rocketMQProperties;  
124 -  
125 - private ObjectMapper objectMapper;  
126 -  
127 - @Autowired  
128 - private RocketMQTemplate rocketMQTemplate;  
129 -  
130 - public ListenerContainerConfiguration() {  
131 - }  
132 -  
133 - @Autowired(required = false)  
134 - public ListenerContainerConfiguration(  
135 - @Qualifier("rocketMQMessageObjectMapper") ObjectMapper objectMapper) {  
136 - this.objectMapper = objectMapper;  
137 - }  
138 -  
139 - @Override  
140 - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {  
141 - this.applicationContext = (ConfigurableApplicationContext) applicationContext;  
142 - }  
143 -  
144 - @Override  
145 - public void afterPropertiesSet() {  
146 - Map<String, Object> beans = this.applicationContext.getBeansWithAnnotation(RocketMQMessageListener.class);  
147 -  
148 - if (Objects.nonNull(beans)) {  
149 - beans.forEach(this::registerContainer);  
150 - }  
151 - }  
152 -  
153 - private void registerContainer(String beanName, Object bean) {  
154 - Class<?> clazz = AopUtils.getTargetClass(bean);  
155 -  
156 - if (!RocketMQListener.class.isAssignableFrom(bean.getClass())) {  
157 - throw new IllegalStateException(clazz + " is not instance of " + RocketMQListener.class.getName());  
158 - }  
159 -  
160 - RocketMQListener rocketMQListener = (RocketMQListener) bean;  
161 - RocketMQMessageListener annotation = clazz.getAnnotation(RocketMQMessageListener.class);  
162 - BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(DefaultRocketMQListenerContainer.class);  
163 - beanBuilder.addPropertyValue(PROP_NAMESERVER, rocketMQProperties.getNameServer());  
164 - beanBuilder.addPropertyValue(PROP_TOPIC, environment.resolvePlaceholders(annotation.topic()));  
165 -  
166 - beanBuilder.addPropertyValue(PROP_CONSUMER_GROUP, environment.resolvePlaceholders(annotation.consumerGroup()));  
167 - beanBuilder.addPropertyValue(PROP_CONSUME_MODE, annotation.consumeMode());  
168 - beanBuilder.addPropertyValue(PROP_CONSUME_THREAD_MAX, annotation.consumeThreadMax());  
169 - beanBuilder.addPropertyValue(PROP_MESSAGE_MODEL, annotation.messageModel());  
170 - beanBuilder.addPropertyValue(PROP_SELECTOR_EXPRESS, environment.resolvePlaceholders(annotation.selectorExpress()));  
171 - beanBuilder.addPropertyValue(PROP_SELECTOR_TYPE, annotation.selectorType());  
172 - beanBuilder.addPropertyValue(PROP_ROCKETMQ_LISTENER, rocketMQListener);  
173 - beanBuilder.addPropertyValue(PROP_ROCKETMQ_TEMPLATE, rocketMQTemplate);  
174 - if (Objects.nonNull(objectMapper)) {  
175 - beanBuilder.addPropertyValue(PROP_OBJECT_MAPPER, objectMapper);  
176 - }  
177 - beanBuilder.setDestroyMethodName(METHOD_DESTROY);  
178 -  
179 - String containerBeanName = String.format("%s_%s", DefaultRocketMQListenerContainer.class.getName(), counter.incrementAndGet());  
180 - DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();  
181 - beanFactory.registerBeanDefinition(containerBeanName, beanBuilder.getBeanDefinition());  
182 -  
183 - DefaultRocketMQListenerContainer container = beanFactory.getBean(containerBeanName, DefaultRocketMQListenerContainer.class);  
184 -  
185 - if (!container.isStarted()) {  
186 - try {  
187 - container.start();  
188 - } catch (Exception e) {  
189 - log.error("started container failed. {}", container, e);  
190 - throw new RuntimeException(e);  
191 - }  
192 - }  
193 -  
194 - log.info("register rocketMQ listener to container, listenerBeanName:{}, containerBeanName:{}", beanName, containerBeanName);  
195 - }  
196 - }  
197 -}  
src/main/java/org/apache/rocketmq/spring/starter/RocketMQProperties.java
@@ -24,22 +24,25 @@ import org.springframework.boot.context.properties.ConfigurationProperties; @@ -24,22 +24,25 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
24 @ConfigurationProperties(prefix = "spring.rocketmq") 24 @ConfigurationProperties(prefix = "spring.rocketmq")
25 @Data 25 @Data
26 public class RocketMQProperties { 26 public class RocketMQProperties {
27 -  
28 - /**  
29 - * name server for rocketMQ, formats: `host:port;host:port` 27 + /**
  28 + * 环境前缀
  29 + */
  30 + private String environmentPrefix;
  31 + /**
  32 + * 消息队列服务接入点
30 */ 33 */
31 - private String nameServer; 34 + private String onsAddr;
32 35
33 - private Producer producer;  
34 - /**  
35 - * 阿里云分配的accesskey 36 + /**
  37 + * AccessKey, 用于标识、校验用户身份
36 */ 38 */
37 private String accessKey; 39 private String accessKey;
38 /** 40 /**
39 - * 阿里云分配的secretKey 41 + * SecretKey, 用于标识、校验用户身份
40 */ 42 */
41 private String secretKey; 43 private String secretKey;
42 44
  45 + private Producer producer;
43 @Data 46 @Data
44 public static class Producer { 47 public static class Producer {
45 48
src/main/java/org/apache/rocketmq/spring/starter/annotation/RocketMQMessageListener.java
@@ -17,15 +17,17 @@ @@ -17,15 +17,17 @@
17 17
18 package org.apache.rocketmq.spring.starter.annotation; 18 package org.apache.rocketmq.spring.starter.annotation;
19 19
20 -import org.apache.rocketmq.common.filter.ExpressionType;  
21 -import org.apache.rocketmq.spring.starter.enums.ConsumeMode;  
22 -import org.apache.rocketmq.spring.starter.enums.SelectorType;  
23 import java.lang.annotation.Documented; 20 import java.lang.annotation.Documented;
24 import java.lang.annotation.ElementType; 21 import java.lang.annotation.ElementType;
25 import java.lang.annotation.Retention; 22 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy; 23 import java.lang.annotation.RetentionPolicy;
27 import java.lang.annotation.Target; 24 import java.lang.annotation.Target;
28 -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel; 25 +
  26 +import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
  27 +import org.apache.rocketmq.spring.starter.enums.SelectorType;
  28 +
  29 +import com.aliyun.openservices.ons.api.ExpressionType;
  30 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
29 31
30 @Target(ElementType.TYPE) 32 @Target(ElementType.TYPE)
31 @Retention(RetentionPolicy.RUNTIME) 33 @Retention(RetentionPolicy.RUNTIME)
src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQListenerContainer.java
@@ -25,38 +25,39 @@ import java.util.List; @@ -25,38 +25,39 @@ import java.util.List;
25 import java.util.Objects; 25 import java.util.Objects;
26 import java.util.Properties; 26 import java.util.Properties;
27 27
28 -import org.apache.commons.lang3.StringUtils;  
29 -import org.apache.commons.lang3.exception.ExceptionUtils;  
30 -import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;  
31 -import org.apache.rocketmq.client.consumer.MessageSelector;  
32 -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;  
33 -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;  
34 -import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;  
35 -import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;  
36 -import org.apache.rocketmq.client.exception.MQClientException;  
37 -import org.apache.rocketmq.common.message.MessageExt;  
38 -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;  
39 import org.apache.rocketmq.spring.starter.enums.ConsumeMode; 28 import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
40 import org.apache.rocketmq.spring.starter.enums.SelectorType; 29 import org.apache.rocketmq.spring.starter.enums.SelectorType;
41 import org.apache.rocketmq.spring.starter.exception.ConvertMsgException; 30 import org.apache.rocketmq.spring.starter.exception.ConvertMsgException;
42 import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO; 31 import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;
  32 +import org.apache.rocketmq.spring.starter.utils.ExceptionUtil;
43 import org.apache.rocketmq.spring.starter.utils.IPUtil; 33 import org.apache.rocketmq.spring.starter.utils.IPUtil;
44 import org.springframework.beans.factory.InitializingBean; 34 import org.springframework.beans.factory.InitializingBean;
45 import org.springframework.util.Assert; 35 import org.springframework.util.Assert;
  36 +import org.springframework.util.StringUtils;
46 37
47 import com.aliyun.openservices.ons.api.Action; 38 import com.aliyun.openservices.ons.api.Action;
48 import com.aliyun.openservices.ons.api.ConsumeContext; 39 import com.aliyun.openservices.ons.api.ConsumeContext;
49 import com.aliyun.openservices.ons.api.Consumer; 40 import com.aliyun.openservices.ons.api.Consumer;
50 import com.aliyun.openservices.ons.api.Message; 41 import com.aliyun.openservices.ons.api.Message;
51 import com.aliyun.openservices.ons.api.MessageListener; 42 import com.aliyun.openservices.ons.api.MessageListener;
  43 +import com.aliyun.openservices.ons.api.MessageSelector;
52 import com.aliyun.openservices.ons.api.ONSFactory; 44 import com.aliyun.openservices.ons.api.ONSFactory;
53 import com.aliyun.openservices.ons.api.PropertyKeyConst; 45 import com.aliyun.openservices.ons.api.PropertyKeyConst;
54 import com.aliyun.openservices.ons.api.batch.BatchConsumer; 46 import com.aliyun.openservices.ons.api.batch.BatchConsumer;
55 -import com.aliyun.openservices.ons.api.bean.BatchConsumerBean; 47 +import com.aliyun.openservices.ons.api.batch.BatchMessageListener;
  48 +import com.aliyun.openservices.ons.api.order.ConsumeOrderContext;
56 import com.aliyun.openservices.ons.api.order.MessageOrderListener; 49 import com.aliyun.openservices.ons.api.order.MessageOrderListener;
  50 +import com.aliyun.openservices.ons.api.order.OrderAction;
57 import com.aliyun.openservices.ons.api.order.OrderConsumer; 51 import com.aliyun.openservices.ons.api.order.OrderConsumer;
  52 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
  53 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
  54 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
  55 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
  56 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.client.exception.MQClientException;
  57 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.message.MessageExt;
  58 +import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
58 import com.fasterxml.jackson.databind.ObjectMapper; 59 import com.fasterxml.jackson.databind.ObjectMapper;
59 - 60 +import static org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainerConstants.*;
60 import lombok.Getter; 61 import lombok.Getter;
61 import lombok.Setter; 62 import lombok.Setter;
62 import lombok.extern.slf4j.Slf4j; 63 import lombok.extern.slf4j.Slf4j;
@@ -77,23 +78,13 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket @@ -77,23 +78,13 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket
77 78
78 @Setter 79 @Setter
79 @Getter 80 @Getter
80 - private long suspendCurrentQueueTimeMillis = 1000;  
81 - 81 + private String consumerGroup;
82 /** 82 /**
83 - * Message consume retry strategy<br> -1,no retry,put into DLQ directly<br> 0,broker control retry frequency<br>  
84 - * >0,client control retry frequency 83 + * 消息队列服务接入点
85 */ 84 */
86 @Setter 85 @Setter
87 @Getter 86 @Getter
88 - private int delayLevelWhenNextConsume = 0;  
89 -  
90 - @Setter  
91 - @Getter  
92 - private String consumerGroup;  
93 -  
94 - @Setter  
95 - @Getter  
96 - private String nameServer; 87 + private String onsAddr;
97 88
98 @Setter 89 @Setter
99 @Getter 90 @Getter
@@ -141,6 +132,11 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket @@ -141,6 +132,11 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket
141 private BatchConsumer batchConsumer; 132 private BatchConsumer batchConsumer;
142 133
143 private Class messageType; 134 private Class messageType;
  135 + /**
  136 + * 环境前缀
  137 + */
  138 + @Setter
  139 + private String environmentPrefix;
144 140
145 @Setter 141 @Setter
146 private RocketMQTemplate rocketMQTemplate; 142 private RocketMQTemplate rocketMQTemplate;
@@ -180,66 +176,62 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket @@ -180,66 +176,62 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket
180 176
181 @SuppressWarnings("unchecked") 177 @SuppressWarnings("unchecked")
182 public Action consume(final Message message, final ConsumeContext context){ 178 public Action consume(final Message message, final ConsumeContext context){
183 - for (MessageExt messageExt : msgs) {  
184 - Date consumeBeginTime = new Date();  
185 - log.debug("received msg: {}", messageExt);  
186 - try {  
187 - long now = System.currentTimeMillis();  
188 - rocketMQListener.onMessage(doConvertMessage(messageExt));  
189 - long costTime = System.currentTimeMillis() - now;  
190 - log.debug("consume {} cost: {} ms", messageExt.getMsgId(), costTime);  
191 - } catch (Exception e) {  
192 - log.warn("consume message failed. messageExt:{}", messageExt, e);  
193 - context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);  
194 - if(messageExt.getTopic().equals("DATA_COLLECTION_TOPIC") && "ConsumeMsgFailed".equals(messageExt.getTags())){  
195 - log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");  
196 - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;  
197 - }  
198 - if(e instanceof ConvertMsgException){  
199 - log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");  
200 - //消息消费失败,发送失败消息  
201 - this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);  
202 - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;  
203 - }  
204 - this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);  
205 - return ConsumeConcurrentlyStatus.RECONSUME_LATER; 179 + Date consumeBeginTime = new Date();
  180 + log.debug("received msg: {}", message);
  181 + try {
  182 + long now = consumeBeginTime.getTime();
  183 + rocketMQListener.onMessage(doConvertMessage(message));
  184 + long costTime = System.currentTimeMillis() - now;
  185 + log.debug("consume {} cost: {} ms", message.getMsgID(), costTime);
  186 + } catch (Exception e) {
  187 + log.warn("consume message failed. message:{}", message, e);
  188 + if(message.getTopic().equals(environmentPrefix+"_"+CONSUMEFAILED_TOPIC) && CONSUMEFAILED_TAG.equals(message.getTag())){
  189 + log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
  190 + return Action.CommitMessage;
  191 + }
  192 + if(e instanceof ConvertMsgException){
  193 + log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
  194 + //消息消费失败,发送失败消息
  195 + this.sendConsumeMsgFailed(message,e,consumeBeginTime);
  196 + return Action.CommitMessage;
206 } 197 }
  198 + this.sendConsumeMsgFailed(message,e,consumeBeginTime);
  199 + return Action.ReconsumeLater;
207 } 200 }
208 -  
209 - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; 201 +
  202 + return Action.CommitMessage;
210 } 203 }
211 /** 204 /**
212 * 发送消息消费失败消息 205 * 发送消息消费失败消息
213 - * @param messageExt 206 + * @param message
214 * @param e 207 * @param e
215 * 2018年3月22日 zhaowg 208 * 2018年3月22日 zhaowg
216 */ 209 */
217 - private void sendConsumeMsgFailed(MessageExt messageExt, Exception e,Date consumeBeginTime) { 210 + private void sendConsumeMsgFailed(Message message, Exception e,Date consumeBeginTime) {
218 log.info("消费消息失败,开始发送消费失败MQ"); 211 log.info("消费消息失败,开始发送消费失败MQ");
219 - String topic = "DATA_COLLECTION_TOPIC";  
220 - String tag = "ConsumeMsgFailed"; 212 + String topic = environmentPrefix+"_"+CONSUMEFAILED_TOPIC;
  213 + String tag = CONSUMEFAILED_TAG;
221 try{ 214 try{
222 Date consumeEndTime = new Date(); 215 Date consumeEndTime = new Date();
223 - String destination = topic+":"+tag;  
224 ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO(); 216 ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
225 consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime); 217 consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
226 consumeFailedMsgVO.setConsumeEndTime(consumeEndTime); 218 consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
227 consumeFailedMsgVO.setConsumeGroup(consumerGroup); 219 consumeFailedMsgVO.setConsumeGroup(consumerGroup);
228 consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost()); 220 consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
229 if(e!=null){ 221 if(e!=null){
230 - String errMsg = ExceptionUtils.getStackTrace(e);  
231 - if(StringUtils.isNotBlank(errMsg)){ 222 + String errMsg = ExceptionUtil.getTrace(e);
  223 + if(!StringUtils.isEmpty(errMsg)){
232 //最多保存1024个字符 224 //最多保存1024个字符
233 consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024)); 225 consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
234 } 226 }
235 } 227 }
236 - consumeFailedMsgVO.setMsg(new String(messageExt.getBody()));  
237 - consumeFailedMsgVO.setMsgId(messageExt.getMsgId());  
238 - consumeFailedMsgVO.setMsgKeys(messageExt.getKeys());  
239 - consumeFailedMsgVO.setReconsumeTimes(messageExt.getReconsumeTimes());  
240 - consumeFailedMsgVO.setTag(messageExt.getTags());  
241 - consumeFailedMsgVO.setTopic(messageExt.getTopic());  
242 - rocketMQTemplate.sendOneWay(destination, consumeFailedMsgVO); 228 + consumeFailedMsgVO.setMsg(new String(message.getBody()));
  229 + consumeFailedMsgVO.setMsgId(message.getMsgID());
  230 + consumeFailedMsgVO.setMsgKeys(message.getKey());
  231 + consumeFailedMsgVO.setReconsumeTimes(message.getReconsumeTimes());
  232 + consumeFailedMsgVO.setTag(message.getTag());
  233 + consumeFailedMsgVO.setTopic(message.getTopic());
  234 + rocketMQTemplate.sendOneWay(topic, tag, consumeFailedMsgVO);
243 log.info("发送消息消费失败MQ成功"); 235 log.info("发送消息消费失败MQ成功");
244 }catch(Exception e1){ 236 }catch(Exception e1){
245 log.info("发送消息消费失败MQ异常",e); 237 log.info("发送消息消费失败MQ异常",e);
@@ -250,50 +242,103 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket @@ -250,50 +242,103 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket
250 242
251 public class DefaultMessageListenerOrderly implements MessageOrderListener { 243 public class DefaultMessageListenerOrderly implements MessageOrderListener {
252 244
253 - @SuppressWarnings("unchecked")  
254 - public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {  
255 - for (MessageExt messageExt : msgs) {  
256 - log.debug("received msg: {}", messageExt);  
257 - try {  
258 - long now = System.currentTimeMillis();  
259 - rocketMQListener.onMessage(doConvertMessage(messageExt));  
260 - long costTime = System.currentTimeMillis() - now;  
261 - log.info("consume {} cost: {} ms", messageExt.getMsgId(), costTime);  
262 - } catch (Exception e) {  
263 - log.warn("consume message failed. messageExt:{}", messageExt, e);  
264 - context.setSuspendCurrentQueueTimeMillis(suspendCurrentQueueTimeMillis);  
265 - return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;  
266 - } 245 + @Override
  246 + public OrderAction consume(Message message, ConsumeOrderContext context) {
  247 + log.debug("received msg: {}", message);
  248 + try {
  249 + long now = System.currentTimeMillis();
  250 + rocketMQListener.onMessage(doConvertMessage(message));
  251 + long costTime = System.currentTimeMillis() - now;
  252 + log.info("consume {} cost: {} ms", message.getMsgID(), costTime);
  253 + } catch (Exception e) {
  254 + log.warn("consume message failed. message:{}", message, e);
  255 + return OrderAction.Suspend;
267 } 256 }
268 -  
269 - return ConsumeOrderlyStatus.SUCCESS;  
270 - } 257 + return OrderAction.Success;
  258 + }
  259 + }
  260 +
  261 + public class DefaultMessageListenerBatchs implements BatchMessageListener{
  262 +
  263 + @Override
  264 + public Action consume(List<Message> messages, ConsumeContext context) {
  265 + for (Message message : messages) {
  266 + Date consumeBeginTime = new Date();
  267 + log.debug("received msg: {}", message);
  268 + try {
  269 + long now = consumeBeginTime.getTime();
  270 + rocketMQListener.onMessage(doConvertMessage(message));
  271 + long costTime = System.currentTimeMillis() - now;
  272 + log.debug("consume {} cost: {} ms", message.getMsgID(), costTime);
  273 + } catch (Exception e) {
  274 + log.warn("consume message failed. message:{}", message, e);
  275 + if(message.getTopic().equals(environmentPrefix+"_"+CONSUMEFAILED_TOPIC) && CONSUMEFAILED_TAG.equals(message.getTag())){
  276 + log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
  277 + continue;
  278 + }
  279 + if(e instanceof ConvertMsgException){
  280 + log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
  281 + //消息消费失败,发送失败消息
  282 + this.sendConsumeMsgFailed(message,e,consumeBeginTime);
  283 + continue;
  284 + }
  285 + this.sendConsumeMsgFailed(message,e,consumeBeginTime);
  286 + return Action.ReconsumeLater;
  287 + }
  288 + }
  289 + return Action.CommitMessage;
  290 + }
  291 +
  292 + /**
  293 + * 发送消息消费失败消息
  294 + * @param message
  295 + * @param e
  296 + * 2018年3月22日 zhaowg
  297 + */
  298 + private void sendConsumeMsgFailed(Message message, Exception e,Date consumeBeginTime) {
  299 + log.info("消费消息失败,开始发送消费失败MQ");
  300 + String topic = environmentPrefix+"_"+CONSUMEFAILED_TOPIC;
  301 + String tag = CONSUMEFAILED_TAG;
  302 + try{
  303 + Date consumeEndTime = new Date();
  304 + ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
  305 + consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
  306 + consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
  307 + consumeFailedMsgVO.setConsumeGroup(consumerGroup);
  308 + consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
  309 + if(e!=null){
  310 + String errMsg = ExceptionUtil.getTrace(e);
  311 + if(!StringUtils.isEmpty(errMsg)){
  312 + //最多保存1024个字符
  313 + consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
  314 + }
  315 + }
  316 + consumeFailedMsgVO.setMsg(new String(message.getBody()));
  317 + consumeFailedMsgVO.setMsgId(message.getMsgID());
  318 + consumeFailedMsgVO.setMsgKeys(message.getKey());
  319 + consumeFailedMsgVO.setReconsumeTimes(message.getReconsumeTimes());
  320 + consumeFailedMsgVO.setTag(message.getTag());
  321 + consumeFailedMsgVO.setTopic(message.getTopic());
  322 + rocketMQTemplate.sendOneWay(topic, tag, consumeFailedMsgVO);
  323 + log.info("发送消息消费失败MQ成功");
  324 + }catch(Exception e1){
  325 + log.info("发送消息消费失败MQ异常",e);
  326 + }
  327 +
  328 + }
271 } 329 }
272 -  
273 @Override 330 @Override
274 public void afterPropertiesSet() throws Exception { 331 public void afterPropertiesSet() throws Exception {
275 start(); 332 start();
276 } 333 }
277 334
278 - @Override  
279 - public String toString() {  
280 - return "DefaultRocketMQListenerContainer{" +  
281 - "consumerGroup='" + consumerGroup + '\'' +  
282 - ", nameServer='" + nameServer + '\'' +  
283 - ", topic='" + topic + '\'' +  
284 - ", consumeMode=" + consumeMode +  
285 - ", selectorType=" + selectorType +  
286 - ", selectorExpress='" + selectorExpress + '\'' +  
287 - ", messageModel=" + messageModel +  
288 - '}';  
289 - }  
290 335
291 @SuppressWarnings("unchecked") 336 @SuppressWarnings("unchecked")
292 - private Object doConvertMessage(MessageExt messageExt) {  
293 - if (Objects.equals(messageType, MessageExt.class)) {  
294 - return messageExt; 337 + private Object doConvertMessage(Message message) {
  338 + if (Objects.equals(messageType, Message.class)) {
  339 + return message;
295 } else { 340 } else {
296 - String str = new String(messageExt.getBody(), Charset.forName(charset)); 341 + String str = new String(message.getBody(), Charset.forName(charset));
297 if (Objects.equals(messageType, String.class)) { 342 if (Objects.equals(messageType, String.class)) {
298 return str; 343 return str;
299 } else { 344 } else {
@@ -335,72 +380,45 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket @@ -335,72 +380,45 @@ public class AliyunRocketMQListenerContainer implements InitializingBean, Rocket
335 380
336 Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required"); 381 Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
337 Assert.notNull(consumerGroup, "Property 'consumerGroup' is required"); 382 Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
338 - Assert.notNull(nameServer, "Property 'nameServer' is required"); 383 + Assert.notNull(onsAddr, "Property 'nameServer' is required");
339 Assert.notNull(topic, "Property 'topic' is required"); 384 Assert.notNull(topic, "Property 'topic' is required");
340 385
341 Properties consumerProperties = new Properties(); 386 Properties consumerProperties = new Properties();
342 - consumerProperties.setProperty(PropertyKeyConst.ConsumerId, "CID_"+consumerGroup); 387 + consumerProperties.setProperty(PropertyKeyConst.ConsumerId, consumerGroup);
343 consumerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey); 388 consumerProperties.setProperty(PropertyKeyConst.AccessKey, accessKey);
344 consumerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey); 389 consumerProperties.setProperty(PropertyKeyConst.SecretKey, secretKey);
345 - consumerProperties.setProperty(PropertyKeyConst.ONSAddr, nameServer); 390 + consumerProperties.setProperty(PropertyKeyConst.ONSAddr, onsAddr);
346 consumerProperties.setProperty(PropertyKeyConst.ConsumeThreadNums, consumeThreadMax+""); 391 consumerProperties.setProperty(PropertyKeyConst.ConsumeThreadNums, consumeThreadMax+"");
347 consumerProperties.setProperty(PropertyKeyConst.MessageModel, messageModel.getModeCN()); 392 consumerProperties.setProperty(PropertyKeyConst.MessageModel, messageModel.getModeCN());
348 - //判断是否为批量消费者  
349 - boolean isBatchConsume = false;  
350 //允许用户自己设置该consumer的一些配置 393 //允许用户自己设置该consumer的一些配置
351 - DefaultMQPushConsumer defaultMQPushConsumer = new DefaultMQPushConsumer();  
352 - if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {  
353 - ((RocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(defaultMQPushConsumer);  
354 - isBatchConsume = defaultMQPushConsumer.getConsumeMessageBatchMaxSize()>1; 394 + if (rocketMQListener instanceof AliyunRocketMQPushConsumerLifecycleListener) {
  395 + ((AliyunRocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumerProperties);
355 } 396 }
356 -  
357 switch (consumeMode) { 397 switch (consumeMode) {
358 case ORDERLY://顺序消息 398 case ORDERLY://顺序消息
359 orderConsumer = ONSFactory.createOrderedConsumer(consumerProperties); 399 orderConsumer = ONSFactory.createOrderedConsumer(consumerProperties);
360 if(selectorType == SelectorType.TAG){ 400 if(selectorType == SelectorType.TAG){
361 orderConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerOrderly()); 401 orderConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerOrderly());
362 }else if(selectorType == SelectorType.SQL92){ 402 }else if(selectorType == SelectorType.SQL92){
363 - orderConsumer.subscribe(topic, com.aliyun.openservices.ons.api.MessageSelector.bySql(selectorExpress), new DefaultMessageListenerOrderly()); 403 + orderConsumer.subscribe(topic, MessageSelector.bySql(selectorExpress), new DefaultMessageListenerOrderly());
364 } 404 }
365 break; 405 break;
366 case CONCURRENTLY://普通消息 406 case CONCURRENTLY://普通消息
367 - if(isBatchConsume){  
368 - //批量消息  
369 -  
370 - }  
371 -  
372 consumer = ONSFactory.createConsumer(consumerProperties); 407 consumer = ONSFactory.createConsumer(consumerProperties);
373 if(selectorType == SelectorType.TAG){ 408 if(selectorType == SelectorType.TAG){
374 consumer.subscribe(topic, selectorExpress, new DefaultMessageListenerConcurrently()); 409 consumer.subscribe(topic, selectorExpress, new DefaultMessageListenerConcurrently());
375 }else if(selectorType == SelectorType.SQL92){ 410 }else if(selectorType == SelectorType.SQL92){
376 - consumer.subscribe(topic, com.aliyun.openservices.ons.api.MessageSelector.bySql(selectorExpress), new DefaultMessageListenerConcurrently()); 411 + consumer.subscribe(topic, MessageSelector.bySql(selectorExpress), new DefaultMessageListenerConcurrently());
377 } 412 }
378 break; 413 break;
  414 + case BATCH://批量消息
  415 + batchConsumer = ONSFactory.createBatchConsumer(consumerProperties);
  416 + batchConsumer.subscribe(topic, selectorExpress, new DefaultMessageListenerBatchs());
  417 + break;
379 default: 418 default:
380 throw new IllegalArgumentException("Property 'consumeMode' was wrong."); 419 throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
381 } 420 }
382 421
383 -  
384 -  
385 -  
386 -  
387 - consumer.subscribe(MqConfig.TOPIC, MqConfig.TAG, new MessageListenerImpl());  
388 - consumer.start();  
389 -  
390 - switch (selectorType) {  
391 - case TAG:  
392 - consumer.subscribe(topic, selectorExpress);  
393 - break;  
394 - case SQL92:  
395 - consumer.subscribe(topic, MessageSelector.bySql(selectorExpress));  
396 - break;  
397 - default:  
398 - throw new IllegalArgumentException("Property 'selectorType' was wrong.");  
399 - }  
400 -  
401 -  
402 -  
403 -  
404 } 422 }
405 423
406 } 424 }
src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQPushConsumerLifecycleListener.java renamed to src/main/java/org/apache/rocketmq/spring/starter/core/AliyunRocketMQPushConsumerLifecycleListener.java
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 17
18 package org.apache.rocketmq.spring.starter.core; 18 package org.apache.rocketmq.spring.starter.core;
19 19
20 -import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; 20 +import java.util.Properties;
21 21
22 -public interface RocketMQPushConsumerLifecycleListener extends RocketMQConsumerLifecycleListener<DefaultMQPushConsumer> { 22 +public interface AliyunRocketMQPushConsumerLifecycleListener extends RocketMQConsumerLifecycleListener<Properties> {
23 } 23 }
src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainer.java
1 -/*  
2 - * Licensed to the Apache Software Foundation (ASF) under one or more  
3 - * contributor license agreements. See the NOTICE file distributed with  
4 - * this work for additional information regarding copyright ownership.  
5 - * The ASF licenses this file to You under the Apache License, Version 2.0  
6 - * (the "License"); you may not use this file except in compliance with  
7 - * the License. You may obtain a copy of the License at  
8 - *  
9 - * http://www.apache.org/licenses/LICENSE-2.0  
10 - *  
11 - * Unless required by applicable law or agreed to in writing, software  
12 - * distributed under the License is distributed on an "AS IS" BASIS,  
13 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
14 - * See the License for the specific language governing permissions and  
15 - * limitations under the License.  
16 - */  
17 -  
18 -package org.apache.rocketmq.spring.starter.core;  
19 -  
20 -import java.lang.reflect.ParameterizedType;  
21 -import java.lang.reflect.Type;  
22 -import java.nio.charset.Charset;  
23 -import java.util.Date;  
24 -import java.util.List;  
25 -import java.util.Objects;  
26 -  
27 -import org.apache.commons.lang3.StringUtils;  
28 -import org.apache.commons.lang3.exception.ExceptionUtils;  
29 -import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;  
30 -import org.apache.rocketmq.client.consumer.MessageSelector;  
31 -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;  
32 -import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;  
33 -import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;  
34 -import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;  
35 -import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;  
36 -import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;  
37 -import org.apache.rocketmq.client.exception.MQClientException;  
38 -import org.apache.rocketmq.common.message.MessageExt;  
39 -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;  
40 -import org.apache.rocketmq.spring.starter.enums.ConsumeMode;  
41 -import org.apache.rocketmq.spring.starter.enums.SelectorType;  
42 -import org.apache.rocketmq.spring.starter.exception.ConvertMsgException;  
43 -import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;  
44 -import org.apache.rocketmq.spring.starter.utils.IPUtil;  
45 -import org.springframework.beans.factory.InitializingBean;  
46 -import org.springframework.util.Assert;  
47 -  
48 -import com.fasterxml.jackson.databind.ObjectMapper;  
49 -  
50 -import lombok.Getter;  
51 -import lombok.Setter;  
52 -import lombok.extern.slf4j.Slf4j;  
53 -  
54 -@SuppressWarnings("WeakerAccess")  
55 -@Slf4j  
56 -public class DefaultRocketMQListenerContainer implements InitializingBean, RocketMQListenerContainer {  
57 -  
58 - @Setter  
59 - @Getter  
60 - private long suspendCurrentQueueTimeMillis = 1000;  
61 -  
62 - /**  
63 - * Message consume retry strategy<br> -1,no retry,put into DLQ directly<br> 0,broker control retry frequency<br>  
64 - * >0,client control retry frequency  
65 - */  
66 - @Setter  
67 - @Getter  
68 - private int delayLevelWhenNextConsume = 0;  
69 -  
70 - @Setter  
71 - @Getter  
72 - private String consumerGroup;  
73 -  
74 - @Setter  
75 - @Getter  
76 - private String nameServer;  
77 -  
78 - @Setter  
79 - @Getter  
80 - private String topic;  
81 -  
82 - @Setter  
83 - @Getter  
84 - private ConsumeMode consumeMode = ConsumeMode.CONCURRENTLY;  
85 -  
86 - @Setter  
87 - @Getter  
88 - private SelectorType selectorType = SelectorType.TAG;  
89 -  
90 - @Setter  
91 - @Getter  
92 - private String selectorExpress = "*";  
93 -  
94 - @Setter  
95 - @Getter  
96 - private MessageModel messageModel = MessageModel.CLUSTERING;  
97 -  
98 - @Setter  
99 - @Getter  
100 - private int consumeThreadMax = 64;  
101 -  
102 - @Getter  
103 - @Setter  
104 - private String charset = "UTF-8";  
105 -  
106 - @Setter  
107 - @Getter  
108 - private ObjectMapper objectMapper = new ObjectMapper();  
109 -  
110 - @Setter  
111 - @Getter  
112 - private boolean started;  
113 -  
114 - @Setter  
115 - private RocketMQListener rocketMQListener;  
116 -  
117 - private DefaultMQPushConsumer consumer;  
118 -  
119 - private Class messageType;  
120 -  
121 - @Setter  
122 - private RocketMQTemplate rocketMQTemplate;  
123 -  
124 - public void setupMessageListener(RocketMQListener rocketMQListener) {  
125 - this.rocketMQListener = rocketMQListener;  
126 - }  
127 -  
128 - @Override  
129 - public void destroy() {  
130 - this.setStarted(false);  
131 - if (Objects.nonNull(consumer)) {  
132 - consumer.shutdown();  
133 - }  
134 - log.info("container destroyed, {}", this.toString());  
135 - }  
136 -  
137 - public synchronized void start() throws MQClientException {  
138 -  
139 - if (this.isStarted()) {  
140 - throw new IllegalStateException("container already started. " + this.toString());  
141 - }  
142 -  
143 - initRocketMQPushConsumer();  
144 -  
145 - // parse message type  
146 - this.messageType = getMessageType();  
147 - log.debug("msgType: {}", messageType.getName());  
148 -  
149 - consumer.start();  
150 - this.setStarted(true);  
151 -  
152 - log.info("started container: {}", this.toString());  
153 - }  
154 -  
155 - public class DefaultMessageListenerConcurrently implements MessageListenerConcurrently {  
156 -  
157 - @SuppressWarnings("unchecked")  
158 - public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {  
159 - for (MessageExt messageExt : msgs) {  
160 - Date consumeBeginTime = new Date();  
161 - log.debug("received msg: {}", messageExt);  
162 - try {  
163 - long now = System.currentTimeMillis();  
164 - rocketMQListener.onMessage(doConvertMessage(messageExt));  
165 - long costTime = System.currentTimeMillis() - now;  
166 - log.debug("consume {} cost: {} ms", messageExt.getMsgId(), costTime);  
167 - } catch (Exception e) {  
168 - log.warn("consume message failed. messageExt:{}", messageExt, e);  
169 - context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);  
170 - if(messageExt.getTopic().equals("DATA_COLLECTION_TOPIC") && "ConsumeMsgFailed".equals(messageExt.getTags())){  
171 - log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");  
172 - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;  
173 - }  
174 - if(e instanceof ConvertMsgException){  
175 - log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");  
176 - //消息消费失败,发送失败消息  
177 - this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);  
178 - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;  
179 - }  
180 - this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);  
181 - return ConsumeConcurrentlyStatus.RECONSUME_LATER;  
182 - }  
183 - }  
184 -  
185 - return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;  
186 - }  
187 - /**  
188 - * 发送消息消费失败消息  
189 - * @param messageExt  
190 - * @param e  
191 - * 2018年3月22日 zhaowg  
192 - */  
193 - private void sendConsumeMsgFailed(MessageExt messageExt, Exception e,Date consumeBeginTime) {  
194 - log.info("消费消息失败,开始发送消费失败MQ");  
195 - String topic = "DATA_COLLECTION_TOPIC";  
196 - String tag = "ConsumeMsgFailed";  
197 - try{  
198 - Date consumeEndTime = new Date();  
199 - String destination = topic+":"+tag;  
200 - ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();  
201 - consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);  
202 - consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);  
203 - consumeFailedMsgVO.setConsumeGroup(consumerGroup);  
204 - consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());  
205 - if(e!=null){  
206 - String errMsg = ExceptionUtils.getStackTrace(e);  
207 - if(StringUtils.isNotBlank(errMsg)){  
208 - //最多保存1024个字符  
209 - consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));  
210 - }  
211 - }  
212 - consumeFailedMsgVO.setMsg(new String(messageExt.getBody()));  
213 - consumeFailedMsgVO.setMsgId(messageExt.getMsgId());  
214 - consumeFailedMsgVO.setMsgKeys(messageExt.getKeys());  
215 - consumeFailedMsgVO.setReconsumeTimes(messageExt.getReconsumeTimes());  
216 - consumeFailedMsgVO.setTag(messageExt.getTags());  
217 - consumeFailedMsgVO.setTopic(messageExt.getTopic());  
218 - rocketMQTemplate.sendOneWay(destination, consumeFailedMsgVO);  
219 - log.info("发送消息消费失败MQ成功");  
220 - }catch(Exception e1){  
221 - log.info("发送消息消费失败MQ异常",e);  
222 - }  
223 -  
224 - }  
225 - }  
226 -  
227 - public class DefaultMessageListenerOrderly implements MessageListenerOrderly {  
228 -  
229 - @SuppressWarnings("unchecked")  
230 - public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {  
231 - for (MessageExt messageExt : msgs) {  
232 - log.debug("received msg: {}", messageExt);  
233 - try {  
234 - long now = System.currentTimeMillis();  
235 - rocketMQListener.onMessage(doConvertMessage(messageExt));  
236 - long costTime = System.currentTimeMillis() - now;  
237 - log.info("consume {} cost: {} ms", messageExt.getMsgId(), costTime);  
238 - } catch (Exception e) {  
239 - log.warn("consume message failed. messageExt:{}", messageExt, e);  
240 - context.setSuspendCurrentQueueTimeMillis(suspendCurrentQueueTimeMillis);  
241 - return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;  
242 - }  
243 - }  
244 -  
245 - return ConsumeOrderlyStatus.SUCCESS;  
246 - }  
247 - }  
248 -  
249 - @Override  
250 - public void afterPropertiesSet() throws Exception {  
251 - start();  
252 - }  
253 -  
254 - @Override  
255 - public String toString() {  
256 - return "DefaultRocketMQListenerContainer{" +  
257 - "consumerGroup='" + consumerGroup + '\'' +  
258 - ", nameServer='" + nameServer + '\'' +  
259 - ", topic='" + topic + '\'' +  
260 - ", consumeMode=" + consumeMode +  
261 - ", selectorType=" + selectorType +  
262 - ", selectorExpress='" + selectorExpress + '\'' +  
263 - ", messageModel=" + messageModel +  
264 - '}';  
265 - }  
266 -  
267 - @SuppressWarnings("unchecked")  
268 - private Object doConvertMessage(MessageExt messageExt) {  
269 - if (Objects.equals(messageType, MessageExt.class)) {  
270 - return messageExt;  
271 - } else {  
272 - String str = new String(messageExt.getBody(), Charset.forName(charset));  
273 - if (Objects.equals(messageType, String.class)) {  
274 - return str;  
275 - } else {  
276 - // if msgType not string, use objectMapper change it.  
277 - try {  
278 - return objectMapper.readValue(str, messageType);  
279 - } catch (Exception e) {  
280 - log.info("convert failed. str:{}, msgType:{}", str, messageType);  
281 - throw new ConvertMsgException("cannot convert message to " + messageType, e);  
282 - }  
283 - }  
284 - }  
285 - }  
286 -  
287 - private Class getMessageType() {  
288 - Type[] interfaces = rocketMQListener.getClass().getGenericInterfaces();  
289 - if (Objects.nonNull(interfaces)) {  
290 - for (Type type : interfaces) {  
291 - if (type instanceof ParameterizedType) {  
292 - ParameterizedType parameterizedType = (ParameterizedType) type;  
293 - if (Objects.equals(parameterizedType.getRawType(), RocketMQListener.class)) {  
294 - Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();  
295 - if (Objects.nonNull(actualTypeArguments) && actualTypeArguments.length > 0) {  
296 - return (Class) actualTypeArguments[0];  
297 - } else {  
298 - return Object.class;  
299 - }  
300 - }  
301 - }  
302 - }  
303 -  
304 - return Object.class;  
305 - } else {  
306 - return Object.class;  
307 - }  
308 - }  
309 -  
310 - private void initRocketMQPushConsumer() throws MQClientException {  
311 -  
312 - Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");  
313 - Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");  
314 - Assert.notNull(nameServer, "Property 'nameServer' is required");  
315 - Assert.notNull(topic, "Property 'topic' is required");  
316 -  
317 - consumer = new DefaultMQPushConsumer(consumerGroup);  
318 - consumer.setNamesrvAddr(nameServer);  
319 - consumer.setConsumeThreadMax(consumeThreadMax);  
320 - if (consumeThreadMax < consumer.getConsumeThreadMin()) {  
321 - consumer.setConsumeThreadMin(consumeThreadMax);  
322 - }  
323 -  
324 - consumer.setMessageModel(messageModel);  
325 -  
326 - switch (selectorType) {  
327 - case TAG:  
328 - consumer.subscribe(topic, selectorExpress);  
329 - break;  
330 - case SQL92:  
331 - consumer.subscribe(topic, MessageSelector.bySql(selectorExpress));  
332 - break;  
333 - default:  
334 - throw new IllegalArgumentException("Property 'selectorType' was wrong.");  
335 - }  
336 -  
337 - switch (consumeMode) {  
338 - case ORDERLY:  
339 - consumer.setMessageListener(new DefaultMessageListenerOrderly());  
340 - break;  
341 - case CONCURRENTLY:  
342 - consumer.setMessageListener(new DefaultMessageListenerConcurrently());  
343 - break;  
344 - default:  
345 - throw new IllegalArgumentException("Property 'consumeMode' was wrong.");  
346 - }  
347 -  
348 - // provide an entryway to custom setting RocketMQ consumer  
349 - if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {  
350 - ((RocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumer);  
351 - }  
352 -  
353 - }  
354 -  
355 -} 1 +///*
  2 +// * Licensed to the Apache Software Foundation (ASF) under one or more
  3 +// * contributor license agreements. See the NOTICE file distributed with
  4 +// * this work for additional information regarding copyright ownership.
  5 +// * The ASF licenses this file to You under the Apache License, Version 2.0
  6 +// * (the "License"); you may not use this file except in compliance with
  7 +// * the License. You may obtain a copy of the License at
  8 +// *
  9 +// * http://www.apache.org/licenses/LICENSE-2.0
  10 +// *
  11 +// * Unless required by applicable law or agreed to in writing, software
  12 +// * distributed under the License is distributed on an "AS IS" BASIS,
  13 +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +// * See the License for the specific language governing permissions and
  15 +// * limitations under the License.
  16 +// */
  17 +//
  18 +//package org.apache.rocketmq.spring.starter.core;
  19 +//
  20 +//import java.lang.reflect.ParameterizedType;
  21 +//import java.lang.reflect.Type;
  22 +//import java.nio.charset.Charset;
  23 +//import java.util.Date;
  24 +//import java.util.List;
  25 +//import java.util.Objects;
  26 +//
  27 +//import org.apache.commons.lang3.StringUtils;
  28 +//import org.apache.commons.lang3.exception.ExceptionUtils;
  29 +//import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
  30 +//import org.apache.rocketmq.client.consumer.MessageSelector;
  31 +//import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
  32 +//import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
  33 +//import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
  34 +//import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
  35 +//import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
  36 +//import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
  37 +//import org.apache.rocketmq.client.exception.MQClientException;
  38 +//import org.apache.rocketmq.common.message.MessageExt;
  39 +//import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
  40 +//import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
  41 +//import org.apache.rocketmq.spring.starter.enums.SelectorType;
  42 +//import org.apache.rocketmq.spring.starter.exception.ConvertMsgException;
  43 +//import org.apache.rocketmq.spring.starter.msgvo.ConsumeFailedMsgVO;
  44 +//import org.apache.rocketmq.spring.starter.utils.IPUtil;
  45 +//import org.springframework.beans.factory.InitializingBean;
  46 +//import org.springframework.util.Assert;
  47 +//
  48 +//import com.fasterxml.jackson.databind.ObjectMapper;
  49 +//
  50 +//import lombok.Getter;
  51 +//import lombok.Setter;
  52 +//import lombok.extern.slf4j.Slf4j;
  53 +//
  54 +//@SuppressWarnings("WeakerAccess")
  55 +//@Slf4j
  56 +//public class DefaultRocketMQListenerContainer implements InitializingBean, RocketMQListenerContainer {
  57 +//
  58 +// @Setter
  59 +// @Getter
  60 +// private long suspendCurrentQueueTimeMillis = 1000;
  61 +//
  62 +// /**
  63 +// * Message consume retry strategy<br> -1,no retry,put into DLQ directly<br> 0,broker control retry frequency<br>
  64 +// * >0,client control retry frequency
  65 +// */
  66 +// @Setter
  67 +// @Getter
  68 +// private int delayLevelWhenNextConsume = 0;
  69 +//
  70 +// @Setter
  71 +// @Getter
  72 +// private String consumerGroup;
  73 +//
  74 +// @Setter
  75 +// @Getter
  76 +// private String nameServer;
  77 +//
  78 +// @Setter
  79 +// @Getter
  80 +// private String topic;
  81 +//
  82 +// @Setter
  83 +// @Getter
  84 +// private ConsumeMode consumeMode = ConsumeMode.CONCURRENTLY;
  85 +//
  86 +// @Setter
  87 +// @Getter
  88 +// private SelectorType selectorType = SelectorType.TAG;
  89 +//
  90 +// @Setter
  91 +// @Getter
  92 +// private String selectorExpress = "*";
  93 +//
  94 +// @Setter
  95 +// @Getter
  96 +// private MessageModel messageModel = MessageModel.CLUSTERING;
  97 +//
  98 +// @Setter
  99 +// @Getter
  100 +// private int consumeThreadMax = 64;
  101 +//
  102 +// @Getter
  103 +// @Setter
  104 +// private String charset = "UTF-8";
  105 +//
  106 +// @Setter
  107 +// @Getter
  108 +// private ObjectMapper objectMapper = new ObjectMapper();
  109 +//
  110 +// @Setter
  111 +// @Getter
  112 +// private boolean started;
  113 +//
  114 +// @Setter
  115 +// private RocketMQListener rocketMQListener;
  116 +//
  117 +// private DefaultMQPushConsumer consumer;
  118 +//
  119 +// private Class messageType;
  120 +//
  121 +// @Setter
  122 +// private RocketMQTemplate rocketMQTemplate;
  123 +//
  124 +// public void setupMessageListener(RocketMQListener rocketMQListener) {
  125 +// this.rocketMQListener = rocketMQListener;
  126 +// }
  127 +//
  128 +// @Override
  129 +// public void destroy() {
  130 +// this.setStarted(false);
  131 +// if (Objects.nonNull(consumer)) {
  132 +// consumer.shutdown();
  133 +// }
  134 +// log.info("container destroyed, {}", this.toString());
  135 +// }
  136 +//
  137 +// public synchronized void start() throws MQClientException {
  138 +//
  139 +// if (this.isStarted()) {
  140 +// throw new IllegalStateException("container already started. " + this.toString());
  141 +// }
  142 +//
  143 +// initRocketMQPushConsumer();
  144 +//
  145 +// // parse message type
  146 +// this.messageType = getMessageType();
  147 +// log.debug("msgType: {}", messageType.getName());
  148 +//
  149 +// consumer.start();
  150 +// this.setStarted(true);
  151 +//
  152 +// log.info("started container: {}", this.toString());
  153 +// }
  154 +//
  155 +// public class DefaultMessageListenerConcurrently implements MessageListenerConcurrently {
  156 +//
  157 +// @SuppressWarnings("unchecked")
  158 +// public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
  159 +// for (MessageExt messageExt : msgs) {
  160 +// Date consumeBeginTime = new Date();
  161 +// log.debug("received msg: {}", messageExt);
  162 +// try {
  163 +// long now = System.currentTimeMillis();
  164 +// rocketMQListener.onMessage(doConvertMessage(messageExt));
  165 +// long costTime = System.currentTimeMillis() - now;
  166 +// log.debug("consume {} cost: {} ms", messageExt.getMsgId(), costTime);
  167 +// } catch (Exception e) {
  168 +// log.warn("consume message failed. messageExt:{}", messageExt, e);
  169 +// context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);
  170 +// if(messageExt.getTopic().equals("DATA_COLLECTION_TOPIC") && "ConsumeMsgFailed".equals(messageExt.getTags())){
  171 +// log.error("消费失败的消息为“保存消费失败日志消息”,不需要记录日志,不需要重新消费,直接返回成功");
  172 +// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  173 +// }
  174 +// if(e instanceof ConvertMsgException){
  175 +// log.error("消费失败的原因为转换对象失败,需要记录日志,不需要重新消费,返回消费成功");
  176 +// //消息消费失败,发送失败消息
  177 +// this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);
  178 +// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  179 +// }
  180 +// this.sendConsumeMsgFailed(messageExt,e,consumeBeginTime);
  181 +// return ConsumeConcurrentlyStatus.RECONSUME_LATER;
  182 +// }
  183 +// }
  184 +//
  185 +// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
  186 +// }
  187 +// /**
  188 +// * 发送消息消费失败消息
  189 +// * @param messageExt
  190 +// * @param e
  191 +// * 2018年3月22日 zhaowg
  192 +// */
  193 +// private void sendConsumeMsgFailed(MessageExt messageExt, Exception e,Date consumeBeginTime) {
  194 +// log.info("消费消息失败,开始发送消费失败MQ");
  195 +// String topic = "DATA_COLLECTION_TOPIC";
  196 +// String tag = "ConsumeMsgFailed";
  197 +// try{
  198 +// Date consumeEndTime = new Date();
  199 +// String destination = topic+":"+tag;
  200 +// ConsumeFailedMsgVO consumeFailedMsgVO = new ConsumeFailedMsgVO();
  201 +// consumeFailedMsgVO.setConsumeBeginTime(consumeBeginTime);
  202 +// consumeFailedMsgVO.setConsumeEndTime(consumeEndTime);
  203 +// consumeFailedMsgVO.setConsumeGroup(consumerGroup);
  204 +// consumeFailedMsgVO.setConsumeIp(IPUtil.getLocalHost());
  205 +// if(e!=null){
  206 +// String errMsg = ExceptionUtils.getStackTrace(e);
  207 +// if(StringUtils.isNotBlank(errMsg)){
  208 +// //最多保存1024个字符
  209 +// consumeFailedMsgVO.setCunsumerErrMsg(errMsg.substring(0, 1024));
  210 +// }
  211 +// }
  212 +// consumeFailedMsgVO.setMsg(new String(messageExt.getBody()));
  213 +// consumeFailedMsgVO.setMsgId(messageExt.getMsgId());
  214 +// consumeFailedMsgVO.setMsgKeys(messageExt.getKeys());
  215 +// consumeFailedMsgVO.setReconsumeTimes(messageExt.getReconsumeTimes());
  216 +// consumeFailedMsgVO.setTag(messageExt.getTags());
  217 +// consumeFailedMsgVO.setTopic(messageExt.getTopic());
  218 +// rocketMQTemplate.sendOneWay(destination, consumeFailedMsgVO);
  219 +// log.info("发送消息消费失败MQ成功");
  220 +// }catch(Exception e1){
  221 +// log.info("发送消息消费失败MQ异常",e);
  222 +// }
  223 +//
  224 +// }
  225 +// }
  226 +//
  227 +// public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
  228 +//
  229 +// @SuppressWarnings("unchecked")
  230 +// public ConsumeOrderlyStatus consumeMessage(List<MessageExt> msgs, ConsumeOrderlyContext context) {
  231 +// for (MessageExt messageExt : msgs) {
  232 +// log.debug("received msg: {}", messageExt);
  233 +// try {
  234 +// long now = System.currentTimeMillis();
  235 +// rocketMQListener.onMessage(doConvertMessage(messageExt));
  236 +// long costTime = System.currentTimeMillis() - now;
  237 +// log.info("consume {} cost: {} ms", messageExt.getMsgId(), costTime);
  238 +// } catch (Exception e) {
  239 +// log.warn("consume message failed. messageExt:{}", messageExt, e);
  240 +// context.setSuspendCurrentQueueTimeMillis(suspendCurrentQueueTimeMillis);
  241 +// return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
  242 +// }
  243 +// }
  244 +//
  245 +// return ConsumeOrderlyStatus.SUCCESS;
  246 +// }
  247 +// }
  248 +//
  249 +// @Override
  250 +// public void afterPropertiesSet() throws Exception {
  251 +// start();
  252 +// }
  253 +//
  254 +// @Override
  255 +// public String toString() {
  256 +// return "DefaultRocketMQListenerContainer{" +
  257 +// "consumerGroup='" + consumerGroup + '\'' +
  258 +// ", nameServer='" + nameServer + '\'' +
  259 +// ", topic='" + topic + '\'' +
  260 +// ", consumeMode=" + consumeMode +
  261 +// ", selectorType=" + selectorType +
  262 +// ", selectorExpress='" + selectorExpress + '\'' +
  263 +// ", messageModel=" + messageModel +
  264 +// '}';
  265 +// }
  266 +//
  267 +// @SuppressWarnings("unchecked")
  268 +// private Object doConvertMessage(MessageExt messageExt) {
  269 +// if (Objects.equals(messageType, MessageExt.class)) {
  270 +// return messageExt;
  271 +// } else {
  272 +// String str = new String(messageExt.getBody(), Charset.forName(charset));
  273 +// if (Objects.equals(messageType, String.class)) {
  274 +// return str;
  275 +// } else {
  276 +// // if msgType not string, use objectMapper change it.
  277 +// try {
  278 +// return objectMapper.readValue(str, messageType);
  279 +// } catch (Exception e) {
  280 +// log.info("convert failed. str:{}, msgType:{}", str, messageType);
  281 +// throw new ConvertMsgException("cannot convert message to " + messageType, e);
  282 +// }
  283 +// }
  284 +// }
  285 +// }
  286 +//
  287 +// private Class getMessageType() {
  288 +// Type[] interfaces = rocketMQListener.getClass().getGenericInterfaces();
  289 +// if (Objects.nonNull(interfaces)) {
  290 +// for (Type type : interfaces) {
  291 +// if (type instanceof ParameterizedType) {
  292 +// ParameterizedType parameterizedType = (ParameterizedType) type;
  293 +// if (Objects.equals(parameterizedType.getRawType(), RocketMQListener.class)) {
  294 +// Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
  295 +// if (Objects.nonNull(actualTypeArguments) && actualTypeArguments.length > 0) {
  296 +// return (Class) actualTypeArguments[0];
  297 +// } else {
  298 +// return Object.class;
  299 +// }
  300 +// }
  301 +// }
  302 +// }
  303 +//
  304 +// return Object.class;
  305 +// } else {
  306 +// return Object.class;
  307 +// }
  308 +// }
  309 +//
  310 +// private void initRocketMQPushConsumer() throws MQClientException {
  311 +//
  312 +// Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
  313 +// Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
  314 +// Assert.notNull(nameServer, "Property 'nameServer' is required");
  315 +// Assert.notNull(topic, "Property 'topic' is required");
  316 +//
  317 +// consumer = new DefaultMQPushConsumer(consumerGroup);
  318 +// consumer.setNamesrvAddr(nameServer);
  319 +// consumer.setConsumeThreadMax(consumeThreadMax);
  320 +// if (consumeThreadMax < consumer.getConsumeThreadMin()) {
  321 +// consumer.setConsumeThreadMin(consumeThreadMax);
  322 +// }
  323 +//
  324 +// consumer.setMessageModel(messageModel);
  325 +//
  326 +// switch (selectorType) {
  327 +// case TAG:
  328 +// consumer.subscribe(topic, selectorExpress);
  329 +// break;
  330 +// case SQL92:
  331 +// consumer.subscribe(topic, MessageSelector.bySql(selectorExpress));
  332 +// break;
  333 +// default:
  334 +// throw new IllegalArgumentException("Property 'selectorType' was wrong.");
  335 +// }
  336 +//
  337 +// switch (consumeMode) {
  338 +// case ORDERLY:
  339 +// consumer.setMessageListener(new DefaultMessageListenerOrderly());
  340 +// break;
  341 +// case CONCURRENTLY:
  342 +// consumer.setMessageListener(new DefaultMessageListenerConcurrently());
  343 +// break;
  344 +// default:
  345 +// throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
  346 +// }
  347 +//
  348 +// // provide an entryway to custom setting RocketMQ consumer
  349 +// if (rocketMQListener instanceof AliyunRocketMQPushConsumerLifecycleListener) {
  350 +// ((AliyunRocketMQPushConsumerLifecycleListener) rocketMQListener).prepareStart(consumer);
  351 +// }
  352 +//
  353 +// }
  354 +//
  355 +//}
src/main/java/org/apache/rocketmq/spring/starter/core/DefaultRocketMQListenerContainerConstants.java
@@ -32,6 +32,20 @@ public final class DefaultRocketMQListenerContainerConstants { @@ -32,6 +32,20 @@ public final class DefaultRocketMQListenerContainerConstants {
32 public static final String PROP_ROCKETMQ_LISTENER = "rocketMQListener"; 32 public static final String PROP_ROCKETMQ_LISTENER = "rocketMQListener";
33 public static final String PROP_OBJECT_MAPPER = "objectMapper"; 33 public static final String PROP_OBJECT_MAPPER = "objectMapper";
34 public static final String METHOD_DESTROY = "destroy"; 34 public static final String METHOD_DESTROY = "destroy";
35 - /**生产者 add zwg*/  
36 - public static final String PROP_ROCKETMQ_TEMPLATE = "rocketMQTemplate"; 35 + public static final String PROP_ROCKETMQ_TEMPLATE = "rocketMQTemplate";
  36 + public static final String PROP_ONS_Addr = "onsAddr";
  37 + public static final String PROP_ACCESS_KEY = "accessKey";
  38 + public static final String PROP_SECRET_KEY = "secretKey";
  39 + /**
  40 + * 环境前缀
  41 + */
  42 + public static final String PROP_ENVIRONMENT_PREFIX = "environmentPrefix";
  43 + /**
  44 + * 消息消费失败发送的主题
  45 + */
  46 + public final static String CONSUMEFAILED_TOPIC = "ZTEITS_RNT_CLOUD";
  47 + /**
  48 + * 消息消费失败发送的tag
  49 + */
  50 + public final static String CONSUMEFAILED_TAG = "ConsumeMsgFailed";
37 } 51 }
src/main/java/org/apache/rocketmq/spring/starter/core/RocketMQTemplate.java
@@ -17,54 +17,30 @@ @@ -17,54 +17,30 @@
17 17
18 package org.apache.rocketmq.spring.starter.core; 18 package org.apache.rocketmq.spring.starter.core;
19 19
20 -import com.aliyun.openservices.ons.api.MessageAccessor;  
21 -import com.aliyun.openservices.ons.api.OnExceptionContext;  
22 -import com.aliyun.openservices.ons.api.Producer;  
23 -import com.aliyun.openservices.ons.api.PropertyKeyConst;  
24 -import com.aliyun.openservices.ons.api.exception.ONSClientException;  
25 -import com.aliyun.openservices.shade.com.alibaba.rocketmq.common.message.MessageExt;  
26 -import com.fasterxml.jackson.core.JsonProcessingException;  
27 -import com.fasterxml.jackson.databind.ObjectMapper;  
28 import java.nio.charset.Charset; 20 import java.nio.charset.Charset;
29 -import java.util.Iterator;  
30 import java.util.Map; 21 import java.util.Map;
31 -import java.util.Objects;  
32 -import java.util.Properties;  
33 import java.util.Map.Entry; 22 import java.util.Map.Entry;
  23 +import java.util.Objects;
34 24
35 -import lombok.Getter;  
36 -import lombok.Setter;  
37 -import lombok.extern.slf4j.Slf4j;  
38 -import org.apache.rocketmq.client.producer.DefaultMQProducer;  
39 -import org.apache.rocketmq.client.producer.MessageQueueSelector;  
40 -import org.apache.rocketmq.client.producer.SendCallback;  
41 -import org.apache.rocketmq.client.producer.SendResult;  
42 -import org.apache.rocketmq.client.producer.SendStatus;  
43 -import org.apache.rocketmq.client.producer.selector.SelectMessageQueueByHash;  
44 -import org.apache.rocketmq.common.message.MessageConst;  
45 -import org.apache.rocketmq.common.message.MessageQueue;  
46 import org.springframework.beans.factory.DisposableBean; 25 import org.springframework.beans.factory.DisposableBean;
47 import org.springframework.beans.factory.InitializingBean; 26 import org.springframework.beans.factory.InitializingBean;
48 -import org.springframework.messaging.Message;  
49 -import org.springframework.messaging.MessageHeaders;  
50 import org.springframework.messaging.MessagingException; 27 import org.springframework.messaging.MessagingException;
51 -import org.springframework.messaging.core.AbstractMessageSendingTemplate;  
52 -import org.springframework.messaging.core.MessagePostProcessor;  
53 -import org.springframework.messaging.support.MessageBuilder;  
54 -import org.springframework.util.Assert;  
55 -import org.springframework.util.MimeTypeUtils;  
56 -import org.springframework.util.StringUtils;  
57 28
58 -@SuppressWarnings({"WeakerAccess", "unused"}) 29 +import com.aliyun.openservices.ons.api.Message;
  30 +import com.aliyun.openservices.ons.api.Producer;
  31 +import com.aliyun.openservices.ons.api.SendCallback;
  32 +import com.aliyun.openservices.ons.api.SendResult;
  33 +import com.fasterxml.jackson.databind.ObjectMapper;
  34 +
  35 +import lombok.Getter;
  36 +import lombok.Setter;
  37 +import lombok.extern.slf4j.Slf4j;
  38 +
59 @Slf4j 39 @Slf4j
60 -public class RocketMQTemplate extends AbstractMessageSendingTemplate<String> implements InitializingBean, DisposableBean { 40 +public class RocketMQTemplate implements InitializingBean, DisposableBean {
61 41
62 @Getter 42 @Getter
63 @Setter 43 @Setter
64 - private DefaultMQProducer defaultProducer;  
65 -  
66 - @Getter  
67 - @Setter  
68 private Producer aliyunProducer; 44 private Producer aliyunProducer;
69 45
70 @Setter 46 @Setter
@@ -74,479 +50,252 @@ public class RocketMQTemplate extends AbstractMessageSendingTemplate&lt;String&gt; imp @@ -74,479 +50,252 @@ public class RocketMQTemplate extends AbstractMessageSendingTemplate&lt;String&gt; imp
74 @Getter 50 @Getter
75 @Setter 51 @Setter
76 private String charset = "UTF-8"; 52 private String charset = "UTF-8";
77 -  
78 - @Getter 53 +
  54 + /**
  55 + * 环境前缀
  56 + */
79 @Setter 57 @Setter
80 - private MessageQueueSelector messageQueueSelector = new SelectMessageQueueByHash(); 58 + private String environmentPrefix;
81 59
82 /** 60 /**
83 - * <p> Send message in synchronous mode. This method returns only when the sending procedure totally completes.  
84 - * Reliable synchronous transmission is used in extensive scenes, such as important notification messages, SMS  
85 - * notification, SMS marketing system, etc.. </p>  
86 - *  
87 - * <strong>Warn:</strong> this method has internal retry-mechanism, that is, internal implementation will retry  
88 - * {@link DefaultMQProducer#getRetryTimesWhenSendFailed} times before claiming failure. As a result, multiple  
89 - * messages may potentially delivered to broker(s). It's up to the application developers to resolve potential  
90 - * duplication issue.  
91 - *  
92 - * @param destination formats: `topicName:tags`  
93 - * @param message {@link org.springframework.messaging.Message} 61 + * 同步发送消息
  62 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  63 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  64 + * @param key 业务主键
  65 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  66 + * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
  67 + * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
  68 + * </p>
  69 + * <ol>
  70 + * <li>延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;</li>
  71 + * <li>定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()</li>
  72 + * </ol>
94 * @return {@link SendResult} 73 * @return {@link SendResult}
  74 + * 2018年3月23日 zhaowg
95 */ 75 */
96 - public SendResult syncSend(String destination, Message<?> message) {  
97 - if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {  
98 - log.info("syncSend failed. destination:{}, message is null ", destination);  
99 - throw new IllegalArgumentException("`message` and `message.payload` cannot be null"); 76 + public SendResult syncSend(String topic,String tag,String keys,Object payload,Map<String, String> userProperties,Long startDeliverTime) {
  77 + if (Objects.isNull(topic) || Objects.isNull(payload)) {
  78 + log.info("同步消息发送失败,主题和消息不能为空");
  79 + throw new IllegalArgumentException("同步消息发送失败,主题和消息不能为空");
100 } 80 }
101 81
102 try { 82 try {
103 - SendResult sendResult = new SendResult();  
104 - long now = System.currentTimeMillis();  
105 - if(aliyunProducer != null){  
106 - //阿里云发送  
107 - com.aliyun.openservices.ons.api.Message aliyunMsg = convertToAliyunRocketMsg(destination,message);  
108 - com.aliyun.openservices.ons.api.SendResult aliyunSendResult = aliyunProducer.send(aliyunMsg);  
109 - sendResult = convertAliyunSendResult(aliyunSendResult);  
110 - }else if(defaultProducer != null){  
111 - org.apache.rocketmq.common.message.Message rocketMsg = convertToRocketMsg(destination, message);  
112 - sendResult = defaultProducer.send(rocketMsg);  
113 - }else{  
114 - throw new RuntimeException("product为空,请检查配置文件是否配置:spring.rocketmq.aliyun,且值为true或false");  
115 - } 83 + long now = System.currentTimeMillis();
  84 +
  85 + Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
  86 + if(userProperties!=null && !userProperties.isEmpty()){
  87 + for (Entry<String, String> userProp : userProperties.entrySet()) {
  88 + rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
  89 + }
  90 + }
  91 + if(startDeliverTime!=null){
  92 + //设置定时发送时间
  93 + rocketMsg.setStartDeliverTime(startDeliverTime);
  94 + }
  95 + //阿里云发送
  96 + SendResult sendResult = aliyunProducer.send(rocketMsg);
116 long costTime = System.currentTimeMillis() - now; 97 long costTime = System.currentTimeMillis() - now;
117 - log.debug("send message cost: {} ms, msgId:{}", costTime, sendResult.getMsgId()); 98 + log.debug("发送消息耗时: {} ms, msgId:{}", costTime, sendResult.getMessageId());
118 return sendResult; 99 return sendResult;
119 } catch (Exception e) { 100 } catch (Exception e) {
120 - log.info("syncSend failed. destination:{}, message:{} ", destination, message); 101 + log.info("同步发送失败. topic:{}, message:{} ", topic, payload);
121 throw new MessagingException(e.getMessage(), e); 102 throw new MessagingException(e.getMessage(), e);
122 } 103 }
123 } 104 }
124 105
125 /** 106 /**
126 - * Same to {@link #syncSend(String, Message)}.  
127 - *  
128 - * @param destination formats: `topicName:tags`  
129 - * @param payload the Object to use as payload 107 + * Same to {@link #syncSend(String, String, String, Object, Map, Long)}.
  108 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  109 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  110 + * @param key 业务主键
  111 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
130 * @return {@link SendResult} 112 * @return {@link SendResult}
  113 + * 2018年3月23日 zhaowg
131 */ 114 */
132 - public SendResult syncSend(String destination, Object payload) {  
133 - Message<?> message = this.doConvert(payload, null, null);  
134 - return syncSend(destination, message); 115 + public SendResult syncSend(String topic,String tag,String keys, Object payload) {
  116 + return syncSend(topic, tag, keys, payload, null, null);
135 } 117 }
136 -  
137 -  
138 - /**  
139 - * Same to {@link #syncSend(String, Message)} with send orderly with hashKey by specified.  
140 - *  
141 - * @param destination formats: `topicName:tags`  
142 - * @param message {@link org.springframework.messaging.Message}  
143 - * @param hashKey use this key to select queue. for example: orderId, productId ...  
144 - * @return {@link SendResult}  
145 - */  
146 - /*public SendResult syncSendOrderly(String destination, Message<?> message, String hashKey) {  
147 - if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {  
148 - log.info("syncSendOrderly failed. destination:{}, message is null ", destination);  
149 - throw new IllegalArgumentException("`message` and `message.payload` cannot be null");  
150 - }  
151 -  
152 - try {  
153 - long now = System.currentTimeMillis();  
154 - org.apache.rocketmq.common.message.Message rocketMsg = convertToRocketMsg(destination, message);  
155 - //TODO  
156 - throw new RuntimeException("暂时未整合阿里云Producer,不要使用");  
157 -// SendResult sendResult = producer.send(rocketMsg, messageQueueSelector, hashKey, timeout);  
158 -// long costTime = System.currentTimeMillis() - now;  
159 -// log.debug("send message cost: {} ms, msgId:{}", costTime, sendResult.getMsgId());  
160 -// return sendResult;  
161 - } catch (Exception e) {  
162 - log.info("syncSendOrderly failed. destination:{}, message:{} ", destination, message);  
163 - throw new MessagingException(e.getMessage(), e);  
164 - }  
165 - }*/  
166 -  
167 -  
168 /** 118 /**
169 - * Same to {@link #syncSend(String, Object)} with send orderly with hashKey by specified.  
170 - *  
171 - * @param destination formats: `topicName:tags`  
172 - * @param payload the Object to use as payload  
173 - * @param hashKey use this key to select queue. for example: orderId, productId ... 119 + * Same to {@link #syncSend(String, String, String, Object)}.
  120 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  121 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  122 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
174 * @return {@link SendResult} 123 * @return {@link SendResult}
  124 + * 2018年3月23日 zhaowg
175 */ 125 */
176 -// public SendResult syncSendOrderly(String destination, Object payload, String hashKey) {  
177 -// Message<?> message = this.doConvert(payload, null, null);  
178 -// return syncSendOrderly(destination, message, hashKey);  
179 -// } 126 + public SendResult syncSend(String topic,String tag, Object payload) {
  127 + return syncSend(topic, tag,null, payload);
  128 + }
180 129
181 /** 130 /**
182 - * 将公共的sendCallBack转换为阿里云的sendCallBack  
183 - * @param sendCallback  
184 - * @return 131 + * 异步发送消息
  132 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  133 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  134 + * @param key 业务主键
  135 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  136 + * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
  137 + * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
  138 + * </p>
  139 + * <ol>
  140 + * <li>延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;</li>
  141 + * <li>定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()</li>
  142 + * </ol>
  143 + * @param sendCallback 发送完成要执行的回调函数
185 * 2018年3月23日 zhaowg 144 * 2018年3月23日 zhaowg
186 */ 145 */
187 - private com.aliyun.openservices.ons.api.SendCallback aliyunSendCallBackConvert(final SendCallback sendCallback) {  
188 - com.aliyun.openservices.ons.api.SendCallback aliyunSendCallBack = new com.aliyun.openservices.ons.api.SendCallback() {  
189 -  
190 - @Override  
191 - public void onSuccess(com.aliyun.openservices.ons.api.SendResult sendResult) {  
192 - sendCallback.onSuccess(convertAliyunSendResult(sendResult));  
193 - }  
194 -  
195 - @Override  
196 - public void onException(OnExceptionContext context) {  
197 - sendCallback.onException(context.getException());  
198 - }  
199 - };  
200 - return aliyunSendCallBack;  
201 - }  
202 - /**  
203 - * <p> Send message to broker asynchronously. asynchronous transmission is generally used in response time sensitive  
204 - * business scenarios. </p>  
205 - *  
206 - * This method returns immediately. On sending completion, <code>sendCallback</code> will be executed.  
207 - *  
208 - * Similar to {@link #syncSend(String, Object)}, internal implementation would potentially retry up to {@link  
209 - * DefaultMQProducer#getRetryTimesWhenSendAsyncFailed} times before claiming sending failure, which may yield  
210 - * message duplication and application developers are the one to resolve this potential issue.  
211 - *  
212 - * @param destination formats: `topicName:tags`  
213 - * @param message {@link org.springframework.messaging.Message}  
214 - * @param sendCallback {@link SendCallback}  
215 - */  
216 - public void asyncSend(String destination, Message<?> message, SendCallback sendCallback) {  
217 - if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {  
218 - log.info("asyncSend failed. destination:{}, message is null ", destination);  
219 - throw new IllegalArgumentException("`message` and `message.payload` cannot be null"); 146 + public void asyncSend(String topic,String tag,String keys,Object payload,Map<String, String> userProperties,
  147 + Long startDeliverTime,SendCallback sendCallback) {
  148 + if (Objects.isNull(topic) || Objects.isNull(payload)) {
  149 + log.info("异步消息发送失败,主题和消息不能为空");
  150 + throw new IllegalArgumentException("异步消息发送失败,主题和消息不能为空");
220 } 151 }
221 -  
222 try { 152 try {
223 - if(aliyunProducer != null){  
224 - com.aliyun.openservices.ons.api.Message aliyunMsg = this.convertToAliyunRocketMsg(destination, message);  
225 - aliyunProducer.sendAsync(aliyunMsg, aliyunSendCallBackConvert(sendCallback));  
226 - }else if(defaultProducer != null){  
227 - org.apache.rocketmq.common.message.Message rocketMsg = convertToRocketMsg(destination, message);  
228 - defaultProducer.send(rocketMsg, sendCallback);  
229 - }else{  
230 - throw new RuntimeException("product为空,请检查配置文件是否配置:spring.rocketmq.aliyun,且值为true或false"); 153 + long now = System.currentTimeMillis();
  154 +
  155 + Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
  156 + if(userProperties!=null && !userProperties.isEmpty()){
  157 + for (Entry<String, String> userProp : userProperties.entrySet()) {
  158 + rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
  159 + }
  160 + }
  161 + if(startDeliverTime!=null){
  162 + //设置定时发送时间
  163 + rocketMsg.setStartDeliverTime(startDeliverTime);
231 } 164 }
  165 + //阿里云发送
  166 + aliyunProducer.sendAsync(rocketMsg, sendCallback);
  167 + long costTime = System.currentTimeMillis() - now;
  168 + log.debug("发送消息耗时: {} ms", costTime);
232 } catch (Exception e) { 169 } catch (Exception e) {
233 - log.info("asyncSend failed. destination:{}, message:{} ", destination, message); 170 + log.info("异步发送失败. topic:{}, message:{} ", topic, payload);
234 throw new MessagingException(e.getMessage(), e); 171 throw new MessagingException(e.getMessage(), e);
235 } 172 }
236 } 173 }
237 -  
238 - /**  
239 - * Same to {@link #asyncSend(String, Message, SendCallback)}.  
240 - *  
241 - * @param destination formats: `topicName:tags`  
242 - * @param payload the Object to use as payload  
243 - * @param sendCallback {@link SendCallback} 174 + /**
  175 + * Same to {@link #asyncSend(String, String, String, Object, Map, Long, SendCallback)}.
  176 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  177 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  178 + * @param key 业务主键
  179 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  180 + * @param sendCallback 发送完成要执行的回调函数
  181 + * @return {@link SendResult}
  182 + * 2018年3月23日 zhaowg
244 */ 183 */
245 - public void asyncSend(String destination, Object payload, SendCallback sendCallback) {  
246 - Message<?> message = this.doConvert(payload, null, null);  
247 - asyncSend(destination, message, sendCallback); 184 + public void asyncSend(String topic,String tag,String keys, Object payload,SendCallback sendCallback) {
  185 + asyncSend(topic, tag, keys, payload, null, null,sendCallback);
248 } 186 }
249 -  
250 -  
251 /** 187 /**
252 - * Same to {@link #asyncSend(String, Message, SendCallback)} with send orderly with hashKey by specified.  
253 - *  
254 - * @param destination formats: `topicName:tags`  
255 - * @param message {@link org.springframework.messaging.Message}  
256 - * @param hashKey use this key to select queue. for example: orderId, productId ...  
257 - * @param sendCallback {@link SendCallback}  
258 - */  
259 -// public void asyncSendOrderly(String destination, Message<?> message, String hashKey, SendCallback sendCallback) {  
260 -// if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {  
261 -// log.info("asyncSendOrderly failed. destination:{}, message is null ", destination);  
262 -// throw new IllegalArgumentException("`message` and `message.payload` cannot be null");  
263 -// }  
264 -//  
265 -// try {  
266 -// org.apache.rocketmq.common.message.Message rocketMsg = convertToRocketMsg(destination, message);  
267 -// //TODO zwg  
268 -// throw new RuntimeException("暂时未整合阿里云Producer,不要使用");  
269 -// //producer.send(rocketMsg, messageQueueSelector, hashKey, sendCallback, timeout);  
270 -// } catch (Exception e) {  
271 -// log.info("asyncSendOrderly failed. destination:{}, message:{} ", destination, message);  
272 -// throw new MessagingException(e.getMessage(), e);  
273 -// }  
274 -// }  
275 -  
276 - /**  
277 - * Same to {@link #asyncSendOrderly(String, Message, String, SendCallback)}.  
278 - *  
279 - * @param destination formats: `topicName:tags`  
280 - * @param payload the Object to use as payload  
281 - * @param hashKey use this key to select queue. for example: orderId, productId ...  
282 - * @param sendCallback {@link SendCallback} 188 + * Same to {@link #asyncSend(String, String, String, Object,SendCallback)}.
  189 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  190 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  191 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  192 + * @param sendCallback 发送完成要执行的回调函数
  193 + * @return {@link SendResult}
  194 + * 2018年3月23日 zhaowg
283 */ 195 */
284 -// public void asyncSendOrderly(String destination, Object payload, String hashKey, SendCallback sendCallback) {  
285 -// Message<?> message = this.doConvert(payload, null, null);  
286 -// asyncSendOrderly(destination, message, hashKey, sendCallback);  
287 -// }  
288 - 196 + public void asyncSend(String topic,String tag, Object payload,SendCallback sendCallback) {
  197 + asyncSend(topic, tag,null, payload,sendCallback);
  198 + }
289 /** 199 /**
290 - * Similar to <a href="https://en.wikipedia.org/wiki/User_Datagram_Protocol">UDP</a>, this method won't wait for  
291 - * acknowledgement from broker before return. Obviously, it has maximums throughput yet potentials of message loss.  
292 - *  
293 - * One-way transmission is used for cases requiring moderate reliability, such as log collection.  
294 - *  
295 - * @param destination formats: `topicName:tags`  
296 - * @param message {@link org.springframework.messaging.Message} 200 + * 服务器不应答,无法保证消息是否成功到达服务器
  201 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  202 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  203 + * @param key 业务主键
  204 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  205 + * @param userProperties 添加用户自定义属性键值对; 该键值对在消费消费时可被获取.也可用于做SQL属性过滤
  206 + * @param startDeliverTime 设置消息的定时投递时间(绝对时间),最大延迟时间为7天.
  207 + * </p>
  208 + * <ol>
  209 + * <li>延迟投递: 延迟3s投递, 设置为: System.currentTimeMillis() + 3000;</li>
  210 + * <li>定时投递: 2016-02-01 11:30:00投递, 设置为: new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2016-02-01 11:30:00").getTime()</li>
  211 + * </ol>
  212 + * 2018年3月23日 zhaowg
297 */ 213 */
298 - public void sendOneWay(String destination, Message<?> message) {  
299 - if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {  
300 - log.info("sendOneWay failed. destination:{}, message is null ", destination);  
301 - throw new IllegalArgumentException("`message` and `message.payload` cannot be null"); 214 + public void sendOneWay(String topic,String tag,String keys,Object payload,Map<String, String> userProperties,
  215 + Long startDeliverTime) {
  216 + if (Objects.isNull(topic) || Objects.isNull(payload)) {
  217 + log.info("sendOneWay消息发送失败,主题和消息不能为空");
  218 + throw new IllegalArgumentException("sendOneWay消息发送失败,主题和消息不能为空");
302 } 219 }
303 -  
304 try { 220 try {
305 - if(aliyunProducer !=null){  
306 - //阿里云环境  
307 - com.aliyun.openservices.ons.api.Message aliyunMsg = convertToAliyunRocketMsg(destination, message);  
308 - aliyunProducer.sendOneway(aliyunMsg);  
309 - }else if(defaultProducer != null){  
310 - org.apache.rocketmq.common.message.Message rocketMsg = convertToRocketMsg(destination, message);  
311 - defaultProducer.sendOneway(rocketMsg);  
312 - }else{  
313 - throw new RuntimeException("product为空,请检查配置文件是否配置:spring.rocketmq.aliyun,且值为true或false");  
314 - } 221 + long now = System.currentTimeMillis();
315 222
  223 + Message rocketMsg = new Message(environmentPrefix+"_"+topic, tag, keys, convertToRocketMsg(payload));
  224 + if(userProperties!=null && !userProperties.isEmpty()){
  225 + for (Entry<String, String> userProp : userProperties.entrySet()) {
  226 + rocketMsg.putUserProperties(userProp.getKey(), userProp.getValue());
  227 + }
  228 + }
  229 + if(startDeliverTime!=null){
  230 + //设置定时发送时间
  231 + rocketMsg.setStartDeliverTime(startDeliverTime);
  232 + }
  233 + //阿里云发送
  234 + aliyunProducer.sendOneway(rocketMsg);
  235 + long costTime = System.currentTimeMillis() - now;
  236 + log.debug("发送消息耗时: {} ms", costTime);
316 } catch (Exception e) { 237 } catch (Exception e) {
317 - log.info("sendOneWay failed. destination:{}, message:{} ", destination, message); 238 + log.info("sendOneWay发送失败. topic:{}, message:{} ", topic, payload);
318 throw new MessagingException(e.getMessage(), e); 239 throw new MessagingException(e.getMessage(), e);
319 } 240 }
320 } 241 }
321 -  
322 - /**  
323 - * Same to {@link #sendOneWay(String, Message)}  
324 - *  
325 - * @param destination formats: `topicName:tags`  
326 - * @param payload the Object to use as payload 242 + /**
  243 + * Same to {@link #sendOneWay(String, String, String, Object, Map, Long)}.
  244 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  245 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  246 + * @param key 业务主键
  247 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  248 + * 2018年3月23日 zhaowg
327 */ 249 */
328 - public void sendOneWay(String destination, Object payload) {  
329 - Message<?> message = this.doConvert(payload, null, null);  
330 - sendOneWay(destination, message); 250 + public void sendOneWay(String topic,String tag,String keys, Object payload) {
  251 + sendOneWay(topic, tag, keys, payload, null, null);
331 } 252 }
332 -  
333 /** 253 /**
334 - * Same to {@link #sendOneWay(String, Message)} with send orderly with hashKey by specified.  
335 - *  
336 - * @param destination formats: `topicName:tags`  
337 - * @param message {@link org.springframework.messaging.Message}  
338 - * @param hashKey use this key to select queue. for example: orderId, productId ... 254 + * Same to {@link #sendOneWay(String, String, String, Object)}.
  255 + * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
  256 + * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
  257 + * @param payload 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
  258 + * 2018年3月23日 zhaowg
339 */ 259 */
340 -// public void sendOneWayOrderly(String destination, Message<?> message, String hashKey) {  
341 -// if (Objects.isNull(message) || Objects.isNull(message.getPayload())) {  
342 -// log.info("sendOneWayOrderly failed. destination:{}, message is null ", destination);  
343 -// throw new IllegalArgumentException("`message` and `message.payload` cannot be null");  
344 -// }  
345 -//  
346 -// try {  
347 -// //TODO zwg  
348 -// throw new RuntimeException("暂时未整合阿里云Producer,不要使用");  
349 -// //org.apache.rocketmq.common.message.Message rocketMsg = convertToRocketMsg(destination, message);  
350 -// //producer.sendOneway(rocketMsg, messageQueueSelector, hashKey);  
351 -// } catch (Exception e) {  
352 -// log.info("sendOneWayOrderly failed. destination:{}, message:{}", destination, message);  
353 -// throw new MessagingException(e.getMessage(), e);  
354 -// }  
355 -// } 260 + public void sendOneWay(String topic,String tag, Object payload) {
  261 + sendOneWay(topic, tag,null, payload);
  262 + }
356 263
357 - /**  
358 - * Same to {@link #sendOneWayOrderly(String, Message, String)}  
359 - *  
360 - * @param destination formats: `topicName:tags`  
361 - * @param payload the Object to use as payload  
362 - */  
363 -// public void sendOneWayOrderly(String destination, Object payload, String hashKey) {  
364 -// Message<?> message = this.doConvert(payload, null, null);  
365 -// sendOneWayOrderly(destination, message, hashKey);  
366 -// }  
367 -  
368 @Override 264 @Override
369 public void afterPropertiesSet() throws Exception { 265 public void afterPropertiesSet() throws Exception {
370 if(aliyunProducer != null){ 266 if(aliyunProducer != null){
371 - log.info("开始启动阿里云环境生产者"); 267 + log.info("开始启动阿里云[环境标识:"+environmentPrefix+"]生产者");
372 aliyunProducer.start(); 268 aliyunProducer.start();
373 - }else if(defaultProducer != null){  
374 - log.info("开始启动非阿里云环境生产者");  
375 - defaultProducer.start();  
376 - }else{  
377 - throw new RuntimeException("product为空,请检查配置文件是否配置:spring.rocketmq.aliyun,且值为true或false");  
378 } 269 }
379 } 270 }
380 271
381 - protected void doSend(String destination, Message<?> message) {  
382 - SendResult sendResult = syncSend(destination, message);  
383 - log.debug("send message to `{}` finished. result:{}", destination, sendResult);  
384 - }  
385 /** 272 /**
386 - * 转换阿里云返回对象  
387 - * @param aliyunSendResult 273 + * 转换对象为字节
  274 + * @param msgObj
388 * @return 275 * @return
389 * 2018年3月23日 zhaowg 276 * 2018年3月23日 zhaowg
390 */ 277 */
391 - private SendResult convertAliyunSendResult(com.aliyun.openservices.ons.api.SendResult aliyunSendResult) {  
392 - SendResult sendResult = new SendResult();  
393 - sendResult.setMsgId(aliyunSendResult.getMessageId());  
394 - MessageQueue messageQueue = new MessageQueue(aliyunSendResult.getTopic(), null, 0);  
395 - sendResult.setMessageQueue(messageQueue);  
396 - sendResult.setSendStatus(SendStatus.SEND_OK);  
397 - return sendResult;  
398 - }  
399 - /**  
400 - * 转换为阿里云发送的消息对象  
401 - * @param destination formats: `topicName:tags`  
402 - * @param message {@link org.springframework.messaging.Message}  
403 - * @return  
404 - * 2018年3月23日 zhaowg  
405 - */  
406 - private com.aliyun.openservices.ons.api.Message convertToAliyunRocketMsg(String destination, Message<?> message) {  
407 - Object payloadObj = message.getPayload();  
408 - byte[] payloads;  
409 -  
410 - if (payloadObj instanceof String) {  
411 - payloads = ((String) payloadObj).getBytes(Charset.forName(charset));  
412 - } else {  
413 - try {  
414 - String jsonObj = this.objectMapper.writeValueAsString(payloadObj);  
415 - payloads = jsonObj.getBytes(Charset.forName(charset));  
416 - } catch (Exception e) {  
417 - throw new RuntimeException("convert to RocketMQ message failed.", e);  
418 - }  
419 - }  
420 -  
421 - String[] tempArr = destination.split(":", 2);  
422 - String topic = tempArr[0];  
423 - String tags = "";  
424 - if (tempArr.length > 1) {  
425 - tags = tempArr[1];  
426 - }  
427 -  
428 - com.aliyun.openservices.ons.api.Message rocketMsg = new com.aliyun.openservices.ons.api.Message(topic, tags, payloads);  
429 -  
430 - MessageHeaders headers = message.getHeaders();  
431 - if (Objects.nonNull(headers) && !headers.isEmpty()) {  
432 - Object keys = headers.get(MessageConst.PROPERTY_KEYS);  
433 - if (!StringUtils.isEmpty(keys)) { // if headers has 'KEYS', set rocketMQ message key  
434 - rocketMsg.setKey(keys.toString());  
435 - }  
436 -  
437 - headers.entrySet().stream()  
438 - .filter(entry -> !Objects.equals(entry.getKey(), MessageConst.PROPERTY_KEYS)  
439 - && !Objects.equals(entry.getKey(), "FLAG")  
440 - && !Objects.equals(entry.getKey(), "WAIT_STORE_MSG_OK")) // exclude "KEYS", "FLAG", "WAIT_STORE_MSG_OK"  
441 - .forEach(entry -> {  
442 - rocketMsg.putUserProperties("USERS_" + entry.getKey(), String.valueOf(entry.getValue())); // add other properties with prefix "USERS_"  
443 - });  
444 -  
445 - }  
446 -  
447 - return rocketMsg;  
448 - }  
449 - /**  
450 - * Convert spring message to rocketMQ message  
451 - *  
452 - * @param destination formats: `topicName:tags`  
453 - * @param message {@link org.springframework.messaging.Message}  
454 - * @return instance of {@link org.apache.rocketmq.common.message.Message}  
455 - */  
456 - private org.apache.rocketmq.common.message.Message convertToRocketMsg(String destination, Message<?> message) {  
457 - Object payloadObj = message.getPayload(); 278 + private byte[] convertToRocketMsg(Object msgObj) {
458 byte[] payloads; 279 byte[] payloads;
459 280
460 - if (payloadObj instanceof String) {  
461 - payloads = ((String) payloadObj).getBytes(Charset.forName(charset)); 281 + if (msgObj instanceof String) {
  282 + payloads = ((String) msgObj).getBytes(Charset.forName(charset));
462 } else { 283 } else {
463 try { 284 try {
464 - String jsonObj = this.objectMapper.writeValueAsString(payloadObj); 285 + String jsonObj = this.objectMapper.writeValueAsString(msgObj);
465 payloads = jsonObj.getBytes(Charset.forName(charset)); 286 payloads = jsonObj.getBytes(Charset.forName(charset));
466 } catch (Exception e) { 287 } catch (Exception e) {
467 throw new RuntimeException("convert to RocketMQ message failed.", e); 288 throw new RuntimeException("convert to RocketMQ message failed.", e);
468 } 289 }
469 } 290 }
470 -  
471 - String[] tempArr = destination.split(":", 2);  
472 - String topic = tempArr[0];  
473 - String tags = "";  
474 - if (tempArr.length > 1) {  
475 - tags = tempArr[1];  
476 - }  
477 -  
478 - org.apache.rocketmq.common.message.Message rocketMsg = new org.apache.rocketmq.common.message.Message(topic, tags, payloads);  
479 -  
480 - MessageHeaders headers = message.getHeaders();  
481 - if (Objects.nonNull(headers) && !headers.isEmpty()) {  
482 - Object keys = headers.get(MessageConst.PROPERTY_KEYS);  
483 - if (!StringUtils.isEmpty(keys)) { // if headers has 'KEYS', set rocketMQ message key  
484 - rocketMsg.setKeys(keys.toString());  
485 - }  
486 -  
487 - // set rocketMQ message flag  
488 - Object flagObj = headers.getOrDefault("FLAG", "0");  
489 - int flag = 0;  
490 - try {  
491 - flag = Integer.parseInt(flagObj.toString());  
492 - } catch (NumberFormatException e) {  
493 - // ignore  
494 - log.info("flag must be integer, flagObj:{}", flagObj);  
495 - }  
496 - rocketMsg.setFlag(flag);  
497 -  
498 - // set rocketMQ message waitStoreMsgOkObj  
499 - Object waitStoreMsgOkObj = headers.getOrDefault("WAIT_STORE_MSG_OK", "true");  
500 - boolean waitStoreMsgOK = Boolean.TRUE.equals(waitStoreMsgOkObj);  
501 - rocketMsg.setWaitStoreMsgOK(waitStoreMsgOK);  
502 -  
503 - headers.entrySet().stream()  
504 - .filter(entry -> !Objects.equals(entry.getKey(), MessageConst.PROPERTY_KEYS)  
505 - && !Objects.equals(entry.getKey(), "FLAG")  
506 - && !Objects.equals(entry.getKey(), "WAIT_STORE_MSG_OK")) // exclude "KEYS", "FLAG", "WAIT_STORE_MSG_OK"  
507 - .forEach(entry -> {  
508 - rocketMsg.putUserProperty("USERS_" + entry.getKey(), String.valueOf(entry.getValue())); // add other properties with prefix "USERS_"  
509 - });  
510 -  
511 - }  
512 -  
513 - return rocketMsg; 291 + return payloads;
514 } 292 }
515 293
516 - @Override  
517 - protected Message<?> doConvert(Object payload, Map<String, Object> headers, MessagePostProcessor postProcessor) {  
518 - String content;  
519 - if (payload instanceof String) {  
520 - content = (String) payload;  
521 - } else {  
522 - // if payload not as string, use objectMapper change it.  
523 - try {  
524 - content = objectMapper.writeValueAsString(payload);  
525 - } catch (JsonProcessingException e) {  
526 - log.info("convert payload to String failed. payload:{}", payload);  
527 - throw new RuntimeException("convert to payload to String failed.", e);  
528 - }  
529 - }  
530 -  
531 - MessageBuilder<?> builder = MessageBuilder.withPayload(content);  
532 - if (headers != null) {  
533 - builder.copyHeaders(headers);  
534 - }  
535 - builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN);  
536 -  
537 - Message<?> message = builder.build();  
538 - if (postProcessor != null) {  
539 - message = postProcessor.postProcessMessage(message);  
540 - }  
541 - return message;  
542 - }  
543 294
544 @Override 295 @Override
545 public void destroy() { 296 public void destroy() {
546 - if (Objects.nonNull(defaultProducer)) {  
547 - defaultProducer.shutdown();  
548 - }  
549 if(Objects.nonNull(aliyunProducer)){ 297 if(Objects.nonNull(aliyunProducer)){
  298 + log.info("开始关闭阿里云[环境标识:"+environmentPrefix+"]生产者");
550 aliyunProducer.shutdown(); 299 aliyunProducer.shutdown();
551 } 300 }
552 } 301 }
src/main/java/org/apache/rocketmq/spring/starter/enums/ConsumeMode.java
@@ -19,12 +19,17 @@ package org.apache.rocketmq.spring.starter.enums; @@ -19,12 +19,17 @@ package org.apache.rocketmq.spring.starter.enums;
19 19
20 public enum ConsumeMode { 20 public enum ConsumeMode {
21 /** 21 /**
22 - * receive asynchronously delivered messages concurrently 22 + * 同时接收异步发送的消息
23 */ 23 */
24 CONCURRENTLY, 24 CONCURRENTLY,
25 25
26 /** 26 /**
27 - * receive asynchronously delivered messages orderly. one queue, one thread 27 + * 顺序接收消息,一个队列,一个线程
28 */ 28 */
29 - ORDERLY 29 + ORDERLY,
  30 +
  31 + /**
  32 + * 批量接收发送的消息,允许自定义范围为[1, 32], 实际消费数量可能小于该值
  33 + */
  34 + BATCH
30 } 35 }
src/main/java/org/apache/rocketmq/spring/starter/enums/SelectorType.java
@@ -17,7 +17,7 @@ @@ -17,7 +17,7 @@
17 17
18 package org.apache.rocketmq.spring.starter.enums; 18 package org.apache.rocketmq.spring.starter.enums;
19 19
20 -import org.apache.rocketmq.common.filter.ExpressionType; 20 +import com.aliyun.openservices.ons.api.ExpressionType;
21 21
22 public enum SelectorType { 22 public enum SelectorType {
23 23
src/main/java/org/apache/rocketmq/spring/starter/utils/ExceptionUtil.java 0 → 100644
  1 +package org.apache.rocketmq.spring.starter.utils;
  2 +
  3 +import java.io.PrintWriter;
  4 +import java.io.StringWriter;
  5 +
  6 +public class ExceptionUtil {
  7 +
  8 + public static String getTrace(Throwable t) {
  9 + StringBuffer buffer = new StringBuffer();
  10 + if(t==null){
  11 + return "";
  12 + }
  13 + StringWriter stringWriter = new StringWriter();
  14 + PrintWriter writer = new PrintWriter(stringWriter);
  15 + t.printStackTrace(writer);
  16 + //设置堆栈信息
  17 + buffer.append("堆栈信息为:" + stringWriter.getBuffer().toString());
  18 + return buffer.toString();
  19 + }
  20 +
  21 +}
src/test/java/org/apache/rocketmq/spring/starter/RocketMQAutoConfigurationTests.java
1 -/*  
2 - * Licensed to the Apache Software Foundation (ASF) under one or more  
3 - * contributor license agreements. See the NOTICE file distributed with  
4 - * this work for additional information regarding copyright ownership.  
5 - * The ASF licenses this file to You under the Apache License, Version 2.0  
6 - * (the "License"); you may not use this file except in compliance with  
7 - * the License. You may obtain a copy of the License at  
8 - *  
9 - * http://www.apache.org/licenses/LICENSE-2.0  
10 - *  
11 - * Unless required by applicable law or agreed to in writing, software  
12 - * distributed under the License is distributed on an "AS IS" BASIS,  
13 - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
14 - * See the License for the specific language governing permissions and  
15 - * limitations under the License.  
16 - */  
17 -  
18 -package org.apache.rocketmq.spring.starter;  
19 -  
20 -import com.fasterxml.jackson.databind.ObjectMapper;  
21 -import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;  
22 -import org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainer;  
23 -import org.apache.rocketmq.spring.starter.core.RocketMQListener;  
24 -import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;  
25 -import org.apache.rocketmq.spring.starter.enums.ConsumeMode;  
26 -import org.apache.rocketmq.spring.starter.enums.SelectorType;  
27 -import org.apache.rocketmq.client.producer.DefaultMQProducer;  
28 -import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;  
29 -import org.junit.After;  
30 -import org.junit.Test;  
31 -import org.springframework.beans.factory.support.BeanDefinitionBuilder;  
32 -import org.springframework.boot.test.util.EnvironmentTestUtils;  
33 -import org.springframework.context.annotation.AnnotationConfigApplicationContext;  
34 -  
35 -import static org.assertj.core.api.Assertions.assertThat;  
36 -  
37 -public class RocketMQAutoConfigurationTests {  
38 -  
39 - private static final String TEST_CONSUMER_GROUP = "my_consumer";  
40 -  
41 - private static final String TEST_TOPIC = "test-topic";  
42 -  
43 - private AnnotationConfigApplicationContext context;  
44 -  
45 - @Test  
46 - public void rocketMQTemplate() {  
47 -  
48 - load("spring.rocketmq.nameServer=127.0.0.1:9876",  
49 - "spring.rocketmq.producer.group=my_group",  
50 - "spring.rocketmq.producer.send-msg-timeout=30000",  
51 - "spring.rocketmq.producer.retry-times-when-send-async-failed=1",  
52 - "spring.rocketmq.producer.compress-msg-body-over-howmuch=1024",  
53 - "spring.rocketmq.producer.max-message-size=10240",  
54 - "spring.rocketmq.producer.retry-another-broker-when-not-store-ok=true",  
55 - "spring.rocketmq.producer.retry-times-when-send-failed=1");  
56 -  
57 - assertThat(this.context.containsBean("rocketMQMessageObjectMapper")).isTrue();  
58 - assertThat(this.context.containsBean("mqProducer")).isTrue();  
59 - assertThat(this.context.containsBean("rocketMQTemplate")).isTrue();  
60 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();  
61 -  
62 - RocketMQTemplate rocketMQTemplate = this.context.getBean(RocketMQTemplate.class);  
63 - ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);  
64 - assertThat(rocketMQTemplate.getObjectMapper()).isEqualTo(objectMapper);  
65 -  
66 - DefaultMQProducer defaultMQProducer = rocketMQTemplate.getProducer();  
67 -  
68 - assertThat(defaultMQProducer.getNamesrvAddr()).isEqualTo("127.0.0.1:9876");  
69 - assertThat(defaultMQProducer.getProducerGroup()).isEqualTo("my_group");  
70 - assertThat(defaultMQProducer.getSendMsgTimeout()).isEqualTo(30000);  
71 - assertThat(defaultMQProducer.getRetryTimesWhenSendAsyncFailed()).isEqualTo(1);  
72 - assertThat(defaultMQProducer.getCompressMsgBodyOverHowmuch()).isEqualTo(1024);  
73 - assertThat(defaultMQProducer.getMaxMessageSize()).isEqualTo(10240);  
74 - assertThat(defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()).isTrue();  
75 - assertThat(defaultMQProducer.getRetryTimesWhenSendFailed()).isEqualTo(1);  
76 - }  
77 -  
78 - @Test  
79 - public void enableProducer() {  
80 - load();  
81 - assertThat(this.context.containsBean("mqProducer")).isFalse();  
82 - assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();  
83 - closeContext();  
84 -  
85 - load("spring.rocketmq.nameServer=127.0.0.1:9876");  
86 - assertThat(this.context.containsBean("mqProducer")).isFalse();  
87 - assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();  
88 - closeContext();  
89 -  
90 - load("spring.rocketmq.producer.group=my_group");  
91 - assertThat(this.context.containsBean("mqProducer")).isFalse();  
92 - assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();  
93 - closeContext();  
94 -  
95 - load("spring.rocketmq.nameServer=127.0.0.1:9876", "spring.rocketmq.producer.group=my_group");  
96 - assertThat(this.context.containsBean("mqProducer")).isTrue();  
97 - assertThat(this.context.containsBean("rocketMQTemplate")).isEqualTo(true);  
98 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();  
99 - }  
100 -  
101 - @Test  
102 - public void enableConsumer() {  
103 - load();  
104 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();  
105 - closeContext();  
106 -  
107 - load("spring.rocketmq.nameServer=127.0.0.1:9876");  
108 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();  
109 - closeContext();  
110 -  
111 - load(false);  
112 - this.context.registerBeanDefinition("myListener",  
113 - BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());  
114 - this.context.refresh();  
115 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();  
116 - closeContext();  
117 -  
118 - load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");  
119 - this.context.registerBeanDefinition("myListener",  
120 - BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());  
121 - this.context.refresh();  
122 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();  
123 - assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();  
124 - assertThat(this.context.containsBean("mqProducer")).isFalse();  
125 - assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();  
126 -  
127 - }  
128 -  
129 - @Test  
130 - public void listenerContainer() {  
131 - load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");  
132 - BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(MyListener.class);  
133 - this.context.registerBeanDefinition("myListener", beanBuilder.getBeanDefinition());  
134 - this.context.refresh();  
135 -  
136 - assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();  
137 - assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();  
138 -  
139 - DefaultRocketMQListenerContainer listenerContainer =  
140 - this.context.getBean(DefaultRocketMQListenerContainer.class.getName() + "_1",  
141 - DefaultRocketMQListenerContainer.class);  
142 - ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);  
143 - assertThat(listenerContainer.getObjectMapper()).isEqualTo(objectMapper);  
144 - assertThat(listenerContainer.getConsumeMode()).isEqualTo(ConsumeMode.CONCURRENTLY);  
145 - assertThat(listenerContainer.getSelectorType()).isEqualTo(SelectorType.TAG);  
146 - assertThat(listenerContainer.getSelectorExpress()).isEqualTo("*");  
147 - assertThat(listenerContainer.getConsumerGroup()).isEqualTo(TEST_CONSUMER_GROUP);  
148 - assertThat(listenerContainer.getTopic()).isEqualTo(TEST_TOPIC);  
149 - assertThat(listenerContainer.getNameServer()).isEqualTo("127.0.0.1:9876");  
150 - assertThat(listenerContainer.getMessageModel()).isEqualTo(MessageModel.CLUSTERING);  
151 - assertThat(listenerContainer.getConsumeThreadMax()).isEqualTo(1);  
152 - }  
153 -  
154 - @After  
155 - public void closeContext() {  
156 - if (this.context != null) {  
157 - this.context.close();  
158 - }  
159 - }  
160 -  
161 - @RocketMQMessageListener(consumerGroup = TEST_CONSUMER_GROUP, topic = TEST_TOPIC, consumeThreadMax = 1)  
162 - private static class MyListener implements RocketMQListener<String> {  
163 -  
164 - @Override  
165 - public void onMessage(String message) {  
166 - System.out.println(message);  
167 - }  
168 - }  
169 -  
170 - private void load(boolean refresh, String... environment) {  
171 - AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();  
172 - ctx.register(RocketMQAutoConfiguration.class);  
173 - EnvironmentTestUtils.addEnvironment(ctx, environment);  
174 - if (refresh) {  
175 - ctx.refresh();  
176 - }  
177 - this.context = ctx;  
178 - }  
179 -  
180 - private void load(String... environment) {  
181 - load(true, environment);  
182 - }  
183 -}  
184 - 1 +///*
  2 +// * Licensed to the Apache Software Foundation (ASF) under one or more
  3 +// * contributor license agreements. See the NOTICE file distributed with
  4 +// * this work for additional information regarding copyright ownership.
  5 +// * The ASF licenses this file to You under the Apache License, Version 2.0
  6 +// * (the "License"); you may not use this file except in compliance with
  7 +// * the License. You may obtain a copy of the License at
  8 +// *
  9 +// * http://www.apache.org/licenses/LICENSE-2.0
  10 +// *
  11 +// * Unless required by applicable law or agreed to in writing, software
  12 +// * distributed under the License is distributed on an "AS IS" BASIS,
  13 +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14 +// * See the License for the specific language governing permissions and
  15 +// * limitations under the License.
  16 +// */
  17 +//
  18 +//package org.apache.rocketmq.spring.starter;
  19 +//
  20 +//import com.fasterxml.jackson.databind.ObjectMapper;
  21 +//import org.apache.rocketmq.spring.starter.annotation.RocketMQMessageListener;
  22 +//import org.apache.rocketmq.spring.starter.core.DefaultRocketMQListenerContainer;
  23 +//import org.apache.rocketmq.spring.starter.core.RocketMQListener;
  24 +//import org.apache.rocketmq.spring.starter.core.RocketMQTemplate;
  25 +//import org.apache.rocketmq.spring.starter.enums.ConsumeMode;
  26 +//import org.apache.rocketmq.spring.starter.enums.SelectorType;
  27 +//import org.apache.rocketmq.client.producer.DefaultMQProducer;
  28 +//import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
  29 +//import org.junit.After;
  30 +//import org.junit.Test;
  31 +//import org.springframework.beans.factory.support.BeanDefinitionBuilder;
  32 +//import org.springframework.boot.test.util.EnvironmentTestUtils;
  33 +//import org.springframework.context.annotation.AnnotationConfigApplicationContext;
  34 +//
  35 +//import static org.assertj.core.api.Assertions.assertThat;
  36 +//
  37 +//public class RocketMQAutoConfigurationTests {
  38 +//
  39 +// private static final String TEST_CONSUMER_GROUP = "my_consumer";
  40 +//
  41 +// private static final String TEST_TOPIC = "test-topic";
  42 +//
  43 +// private AnnotationConfigApplicationContext context;
  44 +//
  45 +// @Test
  46 +// public void rocketMQTemplate() {
  47 +//
  48 +// load("spring.rocketmq.nameServer=127.0.0.1:9876",
  49 +// "spring.rocketmq.producer.group=my_group",
  50 +// "spring.rocketmq.producer.send-msg-timeout=30000",
  51 +// "spring.rocketmq.producer.retry-times-when-send-async-failed=1",
  52 +// "spring.rocketmq.producer.compress-msg-body-over-howmuch=1024",
  53 +// "spring.rocketmq.producer.max-message-size=10240",
  54 +// "spring.rocketmq.producer.retry-another-broker-when-not-store-ok=true",
  55 +// "spring.rocketmq.producer.retry-times-when-send-failed=1");
  56 +//
  57 +// assertThat(this.context.containsBean("rocketMQMessageObjectMapper")).isTrue();
  58 +// assertThat(this.context.containsBean("mqProducer")).isTrue();
  59 +// assertThat(this.context.containsBean("rocketMQTemplate")).isTrue();
  60 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
  61 +//
  62 +// RocketMQTemplate rocketMQTemplate = this.context.getBean(RocketMQTemplate.class);
  63 +// ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);
  64 +// assertThat(rocketMQTemplate.getObjectMapper()).isEqualTo(objectMapper);
  65 +//
  66 +// DefaultMQProducer defaultMQProducer = rocketMQTemplate.getProducer();
  67 +//
  68 +// assertThat(defaultMQProducer.getNamesrvAddr()).isEqualTo("127.0.0.1:9876");
  69 +// assertThat(defaultMQProducer.getProducerGroup()).isEqualTo("my_group");
  70 +// assertThat(defaultMQProducer.getSendMsgTimeout()).isEqualTo(30000);
  71 +// assertThat(defaultMQProducer.getRetryTimesWhenSendAsyncFailed()).isEqualTo(1);
  72 +// assertThat(defaultMQProducer.getCompressMsgBodyOverHowmuch()).isEqualTo(1024);
  73 +// assertThat(defaultMQProducer.getMaxMessageSize()).isEqualTo(10240);
  74 +// assertThat(defaultMQProducer.isRetryAnotherBrokerWhenNotStoreOK()).isTrue();
  75 +// assertThat(defaultMQProducer.getRetryTimesWhenSendFailed()).isEqualTo(1);
  76 +// }
  77 +//
  78 +// @Test
  79 +// public void enableProducer() {
  80 +// load();
  81 +// assertThat(this.context.containsBean("mqProducer")).isFalse();
  82 +// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
  83 +// closeContext();
  84 +//
  85 +// load("spring.rocketmq.nameServer=127.0.0.1:9876");
  86 +// assertThat(this.context.containsBean("mqProducer")).isFalse();
  87 +// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
  88 +// closeContext();
  89 +//
  90 +// load("spring.rocketmq.producer.group=my_group");
  91 +// assertThat(this.context.containsBean("mqProducer")).isFalse();
  92 +// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
  93 +// closeContext();
  94 +//
  95 +// load("spring.rocketmq.nameServer=127.0.0.1:9876", "spring.rocketmq.producer.group=my_group");
  96 +// assertThat(this.context.containsBean("mqProducer")).isTrue();
  97 +// assertThat(this.context.containsBean("rocketMQTemplate")).isEqualTo(true);
  98 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
  99 +// }
  100 +//
  101 +// @Test
  102 +// public void enableConsumer() {
  103 +// load();
  104 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
  105 +// closeContext();
  106 +//
  107 +// load("spring.rocketmq.nameServer=127.0.0.1:9876");
  108 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
  109 +// closeContext();
  110 +//
  111 +// load(false);
  112 +// this.context.registerBeanDefinition("myListener",
  113 +// BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());
  114 +// this.context.refresh();
  115 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isEmpty();
  116 +// closeContext();
  117 +//
  118 +// load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");
  119 +// this.context.registerBeanDefinition("myListener",
  120 +// BeanDefinitionBuilder.rootBeanDefinition(MyListener.class).getBeanDefinition());
  121 +// this.context.refresh();
  122 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();
  123 +// assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();
  124 +// assertThat(this.context.containsBean("mqProducer")).isFalse();
  125 +// assertThat(this.context.containsBean("rocketMQTemplate")).isFalse();
  126 +//
  127 +// }
  128 +//
  129 +// @Test
  130 +// public void listenerContainer() {
  131 +// load(false, "spring.rocketmq.nameServer=127.0.0.1:9876");
  132 +// BeanDefinitionBuilder beanBuilder = BeanDefinitionBuilder.rootBeanDefinition(MyListener.class);
  133 +// this.context.registerBeanDefinition("myListener", beanBuilder.getBeanDefinition());
  134 +// this.context.refresh();
  135 +//
  136 +// assertThat(this.context.getBeansOfType(DefaultRocketMQListenerContainer.class)).isNotEmpty();
  137 +// assertThat(this.context.containsBean(DefaultRocketMQListenerContainer.class.getName() + "_1")).isTrue();
  138 +//
  139 +// DefaultRocketMQListenerContainer listenerContainer =
  140 +// this.context.getBean(DefaultRocketMQListenerContainer.class.getName() + "_1",
  141 +// DefaultRocketMQListenerContainer.class);
  142 +// ObjectMapper objectMapper = this.context.getBean("rocketMQMessageObjectMapper", ObjectMapper.class);
  143 +// assertThat(listenerContainer.getObjectMapper()).isEqualTo(objectMapper);
  144 +// assertThat(listenerContainer.getConsumeMode()).isEqualTo(ConsumeMode.CONCURRENTLY);
  145 +// assertThat(listenerContainer.getSelectorType()).isEqualTo(SelectorType.TAG);
  146 +// assertThat(listenerContainer.getSelectorExpress()).isEqualTo("*");
  147 +// assertThat(listenerContainer.getConsumerGroup()).isEqualTo(TEST_CONSUMER_GROUP);
  148 +// assertThat(listenerContainer.getTopic()).isEqualTo(TEST_TOPIC);
  149 +// assertThat(listenerContainer.getNameServer()).isEqualTo("127.0.0.1:9876");
  150 +// assertThat(listenerContainer.getMessageModel()).isEqualTo(MessageModel.CLUSTERING);
  151 +// assertThat(listenerContainer.getConsumeThreadMax()).isEqualTo(1);
  152 +// }
  153 +//
  154 +// @After
  155 +// public void closeContext() {
  156 +// if (this.context != null) {
  157 +// this.context.close();
  158 +// }
  159 +// }
  160 +//
  161 +// @RocketMQMessageListener(consumerGroup = TEST_CONSUMER_GROUP, topic = TEST_TOPIC, consumeThreadMax = 1)
  162 +// private static class MyListener implements RocketMQListener<String> {
  163 +//
  164 +// @Override
  165 +// public void onMessage(String message) {
  166 +// System.out.println(message);
  167 +// }
  168 +// }
  169 +//
  170 +// private void load(boolean refresh, String... environment) {
  171 +// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
  172 +// ctx.register(RocketMQAutoConfiguration.class);
  173 +// EnvironmentTestUtils.addEnvironment(ctx, environment);
  174 +// if (refresh) {
  175 +// ctx.refresh();
  176 +// }
  177 +// this.context = ctx;
  178 +// }
  179 +//
  180 +// private void load(String... environment) {
  181 +// load(true, environment);
  182 +// }
  183 +//}
  184 +//