From a42bd2e3a9f8e3080630dbe242f8d807fa092a60 Mon Sep 17 00:00:00 2001
From: Roger3581321
Date: Wed, 7 Oct 2020 12:15:08 +0800
Subject: [PATCH 01/99] explicitly use standalone mode in windows
explicitly use standalone mode otherwise cluster mode in windows batch environment
---
.../nacos-example/nacos-config-example/readme.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme.md b/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme.md
index 797c09cc1..d93464ece 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme.md
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/readme.md
@@ -46,7 +46,7 @@ Before we start the demo, let's learn how to connect Nacos Config to a Spring Cl
2. Unzip the downloaded file and go to the nacos/bin folder(), And according to the actual situation of the operating system, execute the following command。[see reference for more detail](https://nacos.io/en-us/docs/quick-start.html)。
1. Linux/Unix/Mac , execute `sh startup.sh -m standalone`
- 2. Windows , execute `cmd startup.cmd`
+ 2. Windows , execute `cmd startup.cmd -m standalone`
3. Execute the following command to add a configuration to Nacos Server.
From 3e5d5a98e1d9bfe1c54d87a9a917db9abcda9033 Mon Sep 17 00:00:00 2001
From: roger
Date: Thu, 8 Oct 2020 19:31:22 +0800
Subject: [PATCH 02/99] explicitly add nacos service discovery option, handle
divide zero error case
---
.../cloud/examples/ProviderApplication.java | 156 +++++++++---------
.../src/main/resources/application.properties | 21 +--
2 files changed, 91 insertions(+), 86 deletions(-)
mode change 100644 => 100755 spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/resources/application.properties
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java
index 94a842598..0325055c2 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/java/com/alibaba/cloud/examples/ProviderApplication.java
@@ -1,76 +1,80 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.examples;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
-import org.springframework.http.HttpStatus;
-import org.springframework.http.ResponseEntity;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PathVariable;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
-/**
- * @author xiaojing
- */
-@EnableDiscoveryClient
-@SpringBootApplication
-public class ProviderApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(ProviderApplication.class, args);
- }
-
- @RestController
- class EchoController {
-
- @GetMapping("/")
- public ResponseEntity index() {
- return new ResponseEntity("index error", HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- @GetMapping("/test")
- public ResponseEntity test() {
- return new ResponseEntity("error", HttpStatus.INTERNAL_SERVER_ERROR);
- }
-
- @GetMapping("/sleep")
- public String sleep() {
- try {
- Thread.sleep(1000L);
- }
- catch (InterruptedException e) {
- e.printStackTrace();
- }
- return "ok";
- }
-
- @GetMapping("/echo/{string}")
- public String echo(@PathVariable String string) {
- return "hello Nacos Discovery " + string;
- }
-
- @GetMapping("/divide")
- public String divide(@RequestParam Integer a, @RequestParam Integer b) {
- return String.valueOf(a / b);
- }
-
- }
-
-}
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.examples;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author xiaojing
+ */
+@EnableDiscoveryClient
+@SpringBootApplication
+public class ProviderApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(ProviderApplication.class, args);
+ }
+
+ @RestController
+ class EchoController {
+
+ @GetMapping("/")
+ public ResponseEntity index() {
+ return new ResponseEntity("index error", HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @GetMapping("/test")
+ public ResponseEntity test() {
+ return new ResponseEntity("error", HttpStatus.INTERNAL_SERVER_ERROR);
+ }
+
+ @GetMapping("/sleep")
+ public String sleep() {
+ try {
+ Thread.sleep(1000L);
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return "ok";
+ }
+
+ @GetMapping("/echo/{string}")
+ public String echo(@PathVariable String string) {
+ return "hello Nacos Discovery " + string;
+ }
+
+ @GetMapping("/divide")
+ public String divide(@RequestParam Integer a, @RequestParam Integer b) {
+ if(b == 0) {
+ return String.valueOf(0);
+ } else {
+ return String.valueOf(a / b);
+ }
+ }
+
+ }
+
+}
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/resources/application.properties
old mode 100644
new mode 100755
index 16c0acc9d..e967cd12f
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-provider-example/src/main/resources/application.properties
@@ -1,10 +1,11 @@
-server.port=18082
-spring.application.name=service-provider
-spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
-#spring.cloud.nacos.discovery.instance-enabled=true
-
-spring.cloud.nacos.username=nacos
-spring.cloud.nacos.password=nacos
-
-management.endpoints.web.exposure.include=*
-management.endpoint.health.show-details=always
+server.port=18082
+spring.application.name=service-provider
+spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
+spring.cloud.nacos.discovery.enabled=true
+#spring.cloud.nacos.discovery.instance-enabled=true
+
+spring.cloud.nacos.username=nacos
+spring.cloud.nacos.password=nacos
+
+management.endpoints.web.exposure.include=*
+management.endpoint.health.show-details=always
From 770382b36afd5180f4c77b02830683f4283bd659 Mon Sep 17 00:00:00 2001
From: wangmin
Date: Tue, 8 Dec 2020 20:04:19 +0800
Subject: [PATCH 03/99] Fix ConcurrentModificationException while
EventDispatcher.run after 'received push data' from Nacos
---
.../metadata/repository/DubboServiceMetadataRepository.java | 3 ---
1 file changed, 3 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
index a5be34df8..81751a618 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
@@ -237,9 +237,6 @@ public class DubboServiceMetadataRepository
dispatchEvent(new SubscribedServicesChangedEvent(this, oldSubscribedServices,
newSubscribedServices));
- // clear old one, help GC
- oldSubscribedServices.clear();
-
return newSubscribedServices.stream();
}
From 1ecf526b5cfb85b06d181281bd76623cc6f37a34 Mon Sep 17 00:00:00 2001
From: yangying <2505594512@qq.com>
Date: Tue, 15 Dec 2020 15:18:06 +0800
Subject: [PATCH 04/99] =?UTF-8?q?sentinel=E7=A4=BA=E4=BE=8B=EF=BC=8C?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0sentinel=E9=85=8D=E7=BD=AE=EF=BC=8C=E5=AE=9E?=
=?UTF-8?q?=E7=8E=B0sentinel=E7=A4=BA=E4=BE=8B=E5=8A=9F=E8=83=BD=EF=BC=8C?=
=?UTF-8?q?=E4=BB=A5=E5=8F=8A=E8=BF=90=E8=A1=8C=E8=AF=B4=E6=98=8E=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../sentinel-example/sentinel-feign-example/readme-zh.md | 4 ++++
.../src/main/resources/application.yml | 3 +++
2 files changed, 7 insertions(+)
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/readme-zh.md b/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/readme-zh.md
index 542d9ef78..06bc694e7 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/readme-zh.md
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/readme-zh.md
@@ -114,6 +114,8 @@ public class EchoController {
- 启动nacos 注册中心
+- 启动sentinel
+
- 启动服务提供方:
1. IDE直接启动:找到主类 `ProviderApplication`,执行 main 方法启动应用。
@@ -123,3 +125,5 @@ public class EchoController {
1. IDE直接启动:找到主类 `ConsumerApplication`,执行 main 方法启动应用。
2. 打包编译后启动:首先执行 `mvn clean package` 将工程编译打包,然后执行 `java -jar sentinel-feign-consumer-example.jar`启动应用。
+
+- 启动之后,Sentinel Dashboard可能看不见service-consumer服务的详细信息,多请求几次接口即可。
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/sentinel-feign-consumer-example/src/main/resources/application.yml b/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/sentinel-feign-consumer-example/src/main/resources/application.yml
index 219c38d02..c981dca1e 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/sentinel-feign-consumer-example/src/main/resources/application.yml
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-feign-example/sentinel-feign-consumer-example/src/main/resources/application.yml
@@ -8,6 +8,9 @@ spring:
nacos:
discovery:
server-addr: 127.0.0.1:8848
+ sentinel:
+ transport:
+ dashboard: 127.0.0.1:8081
feign:
sentinel:
From 441bcb9124098f781e9c24535945f1e0c4d7b6fb Mon Sep 17 00:00:00 2001
From: "mai.jh"
Date: Tue, 19 Jan 2021 15:45:45 +0800
Subject: [PATCH 05/99] for: #1931 ,Add a reset Nacos Log Config listener.
---
.../nacos/logging/NacosLoggingListener.java | 54 +++++++++++++++++++
.../main/resources/META-INF/spring.factories | 4 +-
.../logging/NacosLoggingListener.java | 54 +++++++++++++++++++
.../main/resources/META-INF/spring.factories | 2 +
4 files changed, 113 insertions(+), 1 deletion(-)
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/logging/NacosLoggingListener.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/logging/NacosLoggingListener.java
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/logging/NacosLoggingListener.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/logging/NacosLoggingListener.java
new file mode 100644
index 000000000..41d5842ec
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/logging/NacosLoggingListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.nacos.logging;
+
+import com.alibaba.nacos.client.logging.NacosLogging;
+
+import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.event.GenericApplicationListener;
+import org.springframework.core.Ordered;
+import org.springframework.core.ResolvableType;
+
+/**
+ * Reload nacos log configuration file, after
+ * {@link org.springframework.boot.context.logging.LoggingApplicationListener}.
+ *
+ * @author mai.jh
+ */
+public class NacosLoggingListener implements GenericApplicationListener {
+
+ @Override
+ public boolean supportsEventType(ResolvableType resolvableType) {
+ Class> type = resolvableType.getRawClass();
+ if (type != null) {
+ return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(type);
+ }
+ return false;
+ }
+
+ @Override
+ public void onApplicationEvent(ApplicationEvent applicationEvent) {
+ NacosLogging.getInstance().loadConfiguration();
+ }
+
+ @Override
+ public int getOrder() {
+ return Ordered.HIGHEST_PRECEDENCE + 21;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/spring.factories
index aa6bf0d92..a7ee06a44 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/resources/META-INF/spring.factories
@@ -7,4 +7,6 @@ org.springframework.boot.diagnostics.FailureAnalyzer=\
com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer
org.springframework.boot.env.PropertySourceLoader=\
com.alibaba.cloud.nacos.parser.NacosJsonPropertySourceLoader,\
-com.alibaba.cloud.nacos.parser.NacosXmlPropertySourceLoader
\ No newline at end of file
+com.alibaba.cloud.nacos.parser.NacosXmlPropertySourceLoader
+org.springframework.context.ApplicationListener=\
+com.alibaba.cloud.nacos.logging.NacosLoggingListener
\ No newline at end of file
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/logging/NacosLoggingListener.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/logging/NacosLoggingListener.java
new file mode 100644
index 000000000..91822ace6
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/logging/NacosLoggingListener.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.nacos.discovery.logging;
+
+import com.alibaba.nacos.client.logging.NacosLogging;
+
+import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
+import org.springframework.context.ApplicationEvent;
+import org.springframework.context.event.GenericApplicationListener;
+import org.springframework.core.Ordered;
+import org.springframework.core.ResolvableType;
+
+/**
+ * Reload nacos log configuration file, after
+ * {@link org.springframework.boot.context.logging.LoggingApplicationListener}.
+ *
+ * @author mai.jh
+ */
+public class NacosLoggingListener implements GenericApplicationListener {
+
+ @Override
+ public boolean supportsEventType(ResolvableType resolvableType) {
+ Class> type = resolvableType.getRawClass();
+ if (type != null) {
+ return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(type);
+ }
+ return false;
+ }
+
+ @Override
+ public void onApplicationEvent(ApplicationEvent applicationEvent) {
+ NacosLogging.getInstance().loadConfiguration();
+ }
+
+ @Override
+ public int getOrder() {
+ return Ordered.HIGHEST_PRECEDENCE + 21;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories
index 80befe757..dad08529a 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/resources/META-INF/spring.factories
@@ -9,3 +9,5 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.NacosServiceAutoConfiguration
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.discovery.configclient.NacosDiscoveryClientConfigServiceBootstrapConfiguration
+org.springframework.context.ApplicationListener=\
+ com.alibaba.cloud.nacos.discovery.logging.NacosLoggingListener
From cbd64061cecc394a9467a7c98b4dd52c1f4c2061 Mon Sep 17 00:00:00 2001
From: zkzlx
Date: Mon, 1 Feb 2021 11:23:10 +0800
Subject: [PATCH 06/99] Code refactoring and some new feature support
---
pom.xml | 15 +-
.../pom.xml | 7 +-
.../binder/rocketmq/RocketMQBinderUtils.java | 89 --
.../RocketMQMessageChannelBinder.java | 295 ++----
.../RocketMQBinderHealthIndicator.java | 10 +-
.../RocketMQListenerBindingContainer.java | 935 +++++++++---------
.../RocketMQInboundChannelAdapter.java | 176 ----
.../integration/RocketMQMessageHandler.java | 302 ------
.../integration/RocketMQMessageSource.java | 382 -------
.../rocketmq/metrics/Instrumentation.java | 21 +
.../metrics/InstrumentationManager.java | 35 +-
...RocketMQBinderConfigurationProperties.java | 81 +-
.../properties/RocketMQBindingProperties.java | 49 -
.../RocketMQConsumerProperties.java | 429 ++++++--
.../RocketMQExtendedBindingProperties.java | 12 +-
.../RocketMQProducerProperties.java | 201 ++--
.../PartitionMessageQueueSelector.java | 2 +-
17 files changed, 1111 insertions(+), 1930 deletions(-)
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/RocketMQMessageHandler.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/RocketMQMessageSource.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBindingProperties.java
diff --git a/pom.xml b/pom.xml
index 7f9f0f88b..3fd389aca 100644
--- a/pom.xml
+++ b/pom.xml
@@ -98,6 +98,7 @@
4.0.1
+ 4.6.12.0.2
@@ -258,10 +259,20 @@
+
+
+
+
+
org.apache.rocketmq
- rocketmq-spring-boot-starter
- ${rocketmq.starter.version}
+ rocketmq-client
+ ${rocketmq.version}
+
+
+ org.apache.rocketmq
+ rocketmq-acl
+ ${rocketmq.version}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/pom.xml b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/pom.xml
index ec44c9d7a..ca5c22391 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/pom.xml
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/pom.xml
@@ -50,9 +50,12 @@
org.apache.rocketmq
- rocketmq-spring-boot-starter
+ rocketmq-client
+
+
+ org.apache.rocketmq
+ rocketmq-acl
-
org.springframework.bootspring-boot-starter-test
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
deleted file mode 100644
index c7daff0ef..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq;
-
-import java.util.Arrays;
-import java.util.List;
-
-import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
-import org.apache.rocketmq.spring.autoconfigure.RocketMQProperties;
-
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.StringUtils;
-
-/**
- * @author Jim
- */
-public final class RocketMQBinderUtils {
-
- private RocketMQBinderUtils() {
-
- }
-
- public static RocketMQBinderConfigurationProperties mergeProperties(
- RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
- RocketMQProperties rocketMQProperties) {
- RocketMQBinderConfigurationProperties result = new RocketMQBinderConfigurationProperties();
- if (StringUtils.isEmpty(rocketMQProperties.getNameServer())) {
- result.setNameServer(rocketBinderConfigurationProperties.getNameServer());
- }
- else {
- result.setNameServer(
- Arrays.asList(rocketMQProperties.getNameServer().split(";")));
- }
- if (rocketMQProperties.getProducer() == null
- || StringUtils.isEmpty(rocketMQProperties.getProducer().getAccessKey())) {
- result.setAccessKey(rocketBinderConfigurationProperties.getAccessKey());
- }
- else {
- result.setAccessKey(rocketMQProperties.getProducer().getAccessKey());
- }
- if (rocketMQProperties.getProducer() == null
- || StringUtils.isEmpty(rocketMQProperties.getProducer().getSecretKey())) {
- result.setSecretKey(rocketBinderConfigurationProperties.getSecretKey());
- }
- else {
- result.setSecretKey(rocketMQProperties.getProducer().getSecretKey());
- }
- if (rocketMQProperties.getProducer() == null || StringUtils
- .isEmpty(rocketMQProperties.getProducer().getCustomizedTraceTopic())) {
- result.setCustomizedTraceTopic(
- rocketBinderConfigurationProperties.getCustomizedTraceTopic());
- }
- else {
- result.setCustomizedTraceTopic(
- rocketMQProperties.getProducer().getCustomizedTraceTopic());
- }
- if (rocketMQProperties.getProducer() != null
- && rocketMQProperties.getProducer().isEnableMsgTrace()) {
- result.setEnableMsgTrace(Boolean.TRUE);
- }
- else {
- result.setEnableMsgTrace(
- rocketBinderConfigurationProperties.isEnableMsgTrace());
- }
- return result;
- }
-
- public static String getNameServerStr(List nameServerList) {
- if (CollectionUtils.isEmpty(nameServerList)) {
- return null;
- }
- return String.join(";", nameServerList);
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
index e5a2e24b1..5683bff68 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013-2018 the original author or authors.
+ * Copyright (C) 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * https://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,34 +16,18 @@
package com.alibaba.cloud.stream.binder.rocketmq;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-import com.alibaba.cloud.stream.binder.rocketmq.consuming.RocketMQListenerBindingContainer;
-import com.alibaba.cloud.stream.binder.rocketmq.integration.RocketMQInboundChannelAdapter;
-import com.alibaba.cloud.stream.binder.rocketmq.integration.RocketMQMessageHandler;
-import com.alibaba.cloud.stream.binder.rocketmq.integration.RocketMQMessageSource;
-import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQBeanContainerCache;
+import com.alibaba.cloud.stream.binder.rocketmq.extend.ErrorAcknowledgeHandler;
+import com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.RocketMQInboundChannelAdapter;
+import com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.pull.DefaultErrorAcknowledgeHandler;
+import com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.pull.RocketMQMessageSource;
+import com.alibaba.cloud.stream.binder.rocketmq.integration.outbound.RocketMQProducerMessageHandler;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties;
import com.alibaba.cloud.stream.binder.rocketmq.provisioning.RocketMQTopicProvisioner;
-import com.alibaba.cloud.stream.binder.rocketmq.provisioning.selector.PartitionMessageQueueSelector;
-import com.alibaba.cloud.stream.binder.rocketmq.support.JacksonRocketMQHeaderMapper;
-import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQHeaderMapper;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.rocketmq.acl.common.AclClientRPCHook;
-import org.apache.rocketmq.acl.common.SessionCredentials;
-import org.apache.rocketmq.client.producer.DefaultMQProducer;
-import org.apache.rocketmq.common.UtilAll;
-import org.apache.rocketmq.remoting.RPCHook;
-import org.apache.rocketmq.spring.autoconfigure.RocketMQProperties;
-import org.apache.rocketmq.spring.core.RocketMQTemplate;
-import org.apache.rocketmq.spring.support.RocketMQUtil;
+import com.alibaba.cloud.stream.binder.rocketmq.utils.RocketMQUtils;
import org.springframework.cloud.stream.binder.AbstractMessageChannelBinder;
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
@@ -55,15 +39,19 @@ import org.springframework.cloud.stream.provisioning.ConsumerDestination;
import org.springframework.cloud.stream.provisioning.ProducerDestination;
import org.springframework.integration.StaticMessageHeaderAccessor;
import org.springframework.integration.acks.AcknowledgmentCallback;
-import org.springframework.integration.acks.AcknowledgmentCallback.Status;
import org.springframework.integration.channel.AbstractMessageChannel;
import org.springframework.integration.core.MessageProducer;
+import org.springframework.integration.support.DefaultErrorMessageStrategy;
+import org.springframework.integration.support.ErrorMessageStrategy;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHandler;
import org.springframework.messaging.MessagingException;
import org.springframework.util.StringUtils;
/**
+ * A {@link org.springframework.cloud.stream.binder.Binder} that uses RocketMQ as the
+ * underlying middleware.
+ *
* @author Jim
*/
public class RocketMQMessageChannelBinder extends
@@ -71,120 +59,44 @@ public class RocketMQMessageChannelBinder extends
implements
ExtendedPropertiesBinder {
- private RocketMQExtendedBindingProperties extendedBindingProperties = new RocketMQExtendedBindingProperties();
-
- private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
-
- private final RocketMQProperties rocketMQProperties;
-
- private final InstrumentationManager instrumentationManager;
-
- private Map topicInUse = new HashMap<>();
+ private final RocketMQExtendedBindingProperties extendedBindingProperties;
+ private final RocketMQBinderConfigurationProperties binderConfigurationProperties;
- public RocketMQMessageChannelBinder(RocketMQTopicProvisioner provisioningProvider,
+ public RocketMQMessageChannelBinder(
+ RocketMQBinderConfigurationProperties binderConfigurationProperties,
RocketMQExtendedBindingProperties extendedBindingProperties,
- RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
- RocketMQProperties rocketMQProperties,
- InstrumentationManager instrumentationManager) {
- super(null, provisioningProvider);
+ RocketMQTopicProvisioner provisioningProvider) {
+ super(new String[0], provisioningProvider);
this.extendedBindingProperties = extendedBindingProperties;
- this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
- this.rocketMQProperties = rocketMQProperties;
- this.instrumentationManager = instrumentationManager;
+ this.binderConfigurationProperties = binderConfigurationProperties;
}
@Override
protected MessageHandler createProducerMessageHandler(ProducerDestination destination,
- ExtendedProducerProperties producerProperties,
+ ExtendedProducerProperties extendedProducerProperties,
MessageChannel channel, MessageChannel errorChannel) throws Exception {
- if (producerProperties.getExtension().getEnabled()) {
-
- // if producerGroup is empty, using destination
- String extendedProducerGroup = producerProperties.getExtension().getGroup();
- String producerGroup = StringUtils.isEmpty(extendedProducerGroup)
- ? destination.getName() : extendedProducerGroup;
-
- RocketMQBinderConfigurationProperties mergedProperties = RocketMQBinderUtils
- .mergeProperties(rocketBinderConfigurationProperties,
- rocketMQProperties);
-
- RocketMQTemplate rocketMQTemplate;
- if (producerProperties.getExtension().getTransactional()) {
- Map rocketMQTemplates = getBeanFactory()
- .getBeansOfType(RocketMQTemplate.class);
- if (rocketMQTemplates.size() == 0) {
- throw new IllegalStateException(
- "there is no RocketMQTemplate in Spring BeanFactory");
- }
- else if (rocketMQTemplates.size() > 1) {
- throw new IllegalStateException(
- "there is more than 1 RocketMQTemplates in Spring BeanFactory");
- }
- rocketMQTemplate = rocketMQTemplates.values().iterator().next();
- }
- else {
- rocketMQTemplate = new RocketMQTemplate();
- rocketMQTemplate.setObjectMapper(this.getApplicationContext()
- .getBeansOfType(ObjectMapper.class).values().iterator().next());
- DefaultMQProducer producer;
- String ak = mergedProperties.getAccessKey();
- String sk = mergedProperties.getSecretKey();
- if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
- RPCHook rpcHook = new AclClientRPCHook(
- new SessionCredentials(ak, sk));
- producer = new DefaultMQProducer(producerGroup, rpcHook,
- mergedProperties.isEnableMsgTrace(),
- mergedProperties.getCustomizedTraceTopic());
- producer.setVipChannelEnabled(false);
- producer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook,
- destination.getName() + "|" + UtilAll.getPid()));
- }
- else {
- producer = new DefaultMQProducer(producerGroup);
- producer.setVipChannelEnabled(
- producerProperties.getExtension().getVipChannelEnabled());
- }
- producer.setNamesrvAddr(RocketMQBinderUtils
- .getNameServerStr(mergedProperties.getNameServer()));
- producer.setSendMsgTimeout(
- producerProperties.getExtension().getSendMessageTimeout());
- producer.setRetryTimesWhenSendFailed(
- producerProperties.getExtension().getRetryTimesWhenSendFailed());
- producer.setRetryTimesWhenSendAsyncFailed(producerProperties
- .getExtension().getRetryTimesWhenSendAsyncFailed());
- producer.setCompressMsgBodyOverHowmuch(producerProperties.getExtension()
- .getCompressMessageBodyThreshold());
- producer.setRetryAnotherBrokerWhenNotStoreOK(
- producerProperties.getExtension().isRetryNextServer());
- producer.setMaxMessageSize(
- producerProperties.getExtension().getMaxMessageSize());
- rocketMQTemplate.setProducer(producer);
- if (producerProperties.isPartitioned()) {
- rocketMQTemplate
- .setMessageQueueSelector(new PartitionMessageQueueSelector());
- }
- }
-
- RocketMQMessageHandler messageHandler = new RocketMQMessageHandler(
- rocketMQTemplate, destination.getName(), producerGroup,
- producerProperties.getExtension().getTransactional(),
- instrumentationManager, producerProperties,
- ((AbstractMessageChannel) channel).getInterceptors().stream().filter(
- channelInterceptor -> channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor)
- .map(channelInterceptor -> ((MessageConverterConfigurer.PartitioningInterceptor) channelInterceptor))
- .findFirst().orElse(null));
- messageHandler.setBeanFactory(this.getApplicationContext().getBeanFactory());
- messageHandler.setSync(producerProperties.getExtension().getSync());
- messageHandler.setHeaderMapper(createHeaderMapper(producerProperties));
- if (errorChannel != null) {
- messageHandler.setSendFailureChannel(errorChannel);
- }
- return messageHandler;
- }
- else {
+ if (!extendedProducerProperties.getExtension().getEnabled()) {
throw new RuntimeException("Binding for channel " + destination.getName()
+ " has been disabled, message can't be delivered");
}
+ RocketMQProducerProperties mqProducerProperties = RocketMQUtils
+ .mergeRocketMQProperties(binderConfigurationProperties,
+ extendedProducerProperties.getExtension());
+ RocketMQProducerMessageHandler messageHandler = new RocketMQProducerMessageHandler(
+ destination, extendedProducerProperties, mqProducerProperties);
+ messageHandler.setApplicationContext(this.getApplicationContext());
+ if (errorChannel != null) {
+ messageHandler.setSendFailureChannel(errorChannel);
+ }
+ MessageConverterConfigurer.PartitioningInterceptor partitioningInterceptor = ((AbstractMessageChannel) channel)
+ .getInterceptors().stream()
+ .filter(channelInterceptor -> channelInterceptor instanceof MessageConverterConfigurer.PartitioningInterceptor)
+ .map(channelInterceptor -> ((MessageConverterConfigurer.PartitioningInterceptor) channelInterceptor))
+ .findFirst().orElse(null);
+ messageHandler.setPartitioningInterceptor(partitioningInterceptor);
+ messageHandler.setBeanFactory(this.getApplicationContext().getBeanFactory());
+ messageHandler.setErrorMessageStrategy(this.getErrorMessageStrategy());
+ return messageHandler;
}
@Override
@@ -198,56 +110,43 @@ public class RocketMQMessageChannelBinder extends
@Override
protected MessageProducer createConsumerEndpoint(ConsumerDestination destination,
String group,
- ExtendedConsumerProperties consumerProperties)
+ ExtendedConsumerProperties extendedConsumerProperties)
throws Exception {
- if (group == null || "".equals(group)) {
+ // todo support anymous consumer
+ if (StringUtils.isEmpty(group)) {
throw new RuntimeException(
"'group must be configured for channel " + destination.getName());
}
+ RocketMQUtils.mergeRocketMQProperties(binderConfigurationProperties,
+ extendedConsumerProperties.getExtension());
+ extendedConsumerProperties.getExtension().setGroup(group);
- RocketMQListenerBindingContainer listenerContainer = new RocketMQListenerBindingContainer(
- consumerProperties, rocketBinderConfigurationProperties, this);
- listenerContainer.setConsumerGroup(group);
- listenerContainer.setTopic(destination.getName());
- listenerContainer.setConsumeThreadMax(consumerProperties.getConcurrency());
- listenerContainer.setSuspendCurrentQueueTimeMillis(
- consumerProperties.getExtension().getSuspendCurrentQueueTimeMillis());
- listenerContainer.setDelayLevelWhenNextConsume(
- consumerProperties.getExtension().getDelayLevelWhenNextConsume());
- listenerContainer
- .setNameServer(rocketBinderConfigurationProperties.getNameServer());
- listenerContainer.setHeaderMapper(createHeaderMapper(consumerProperties));
-
- RocketMQInboundChannelAdapter rocketInboundChannelAdapter = new RocketMQInboundChannelAdapter(
- listenerContainer, consumerProperties, instrumentationManager);
-
- topicInUse.put(destination.getName(), group);
-
+ RocketMQInboundChannelAdapter inboundChannelAdapter = new RocketMQInboundChannelAdapter(
+ destination.getName(), extendedConsumerProperties);
ErrorInfrastructure errorInfrastructure = registerErrorInfrastructure(destination,
- group, consumerProperties);
- if (consumerProperties.getMaxAttempts() > 1) {
- rocketInboundChannelAdapter
- .setRetryTemplate(buildRetryTemplate(consumerProperties));
- rocketInboundChannelAdapter
- .setRecoveryCallback(errorInfrastructure.getRecoverer());
+ group, extendedConsumerProperties);
+ if (extendedConsumerProperties.getMaxAttempts() > 1) {
+ inboundChannelAdapter
+ .setRetryTemplate(buildRetryTemplate(extendedConsumerProperties));
+ inboundChannelAdapter.setRecoveryCallback(errorInfrastructure.getRecoverer());
}
else {
- rocketInboundChannelAdapter
- .setErrorChannel(errorInfrastructure.getErrorChannel());
+ inboundChannelAdapter.setErrorChannel(errorInfrastructure.getErrorChannel());
}
-
- return rocketInboundChannelAdapter;
+ return inboundChannelAdapter;
}
@Override
protected PolledConsumerResources createPolledConsumerResources(String name,
String group, ConsumerDestination destination,
- ExtendedConsumerProperties consumerProperties) {
- RocketMQMessageSource rocketMQMessageSource = new RocketMQMessageSource(
- rocketBinderConfigurationProperties, consumerProperties, name, group);
- return new PolledConsumerResources(rocketMQMessageSource,
- registerErrorInfrastructure(destination, group, consumerProperties,
- true));
+ ExtendedConsumerProperties extendedConsumerProperties) {
+ RocketMQUtils.mergeRocketMQProperties(binderConfigurationProperties,
+ extendedConsumerProperties.getExtension());
+ extendedConsumerProperties.getExtension().setGroup(group);
+ RocketMQMessageSource messageSource = new RocketMQMessageSource(name,
+ extendedConsumerProperties);
+ return new PolledConsumerResources(messageSource, registerErrorInfrastructure(
+ destination, group, extendedConsumerProperties, true));
}
@Override
@@ -261,67 +160,47 @@ public class RocketMQMessageChannelBinder extends
((MessagingException) message.getPayload())
.getFailedMessage());
if (ack != null) {
- if (properties.getExtension().shouldRequeue()) {
- ack.acknowledge(Status.REQUEUE);
- }
- else {
- ack.acknowledge(Status.REJECT);
- }
+ ErrorAcknowledgeHandler handler = RocketMQBeanContainerCache.getBean(
+ properties.getExtension().getPull().getErrAcknowledge(),
+ ErrorAcknowledgeHandler.class,
+ new DefaultErrorAcknowledgeHandler());
+ ack.acknowledge(
+ handler.handler(((MessagingException) message.getPayload())
+ .getFailedMessage()));
}
}
};
}
+ /**
+ * Binders can return an {@link ErrorMessageStrategy} for building error messages;
+ * binder implementations typically might add extra headers to the error message.
+ *
+ * @return the implementation - may be null.
+ */
@Override
- public RocketMQConsumerProperties getExtendedConsumerProperties(String channelName) {
- return extendedBindingProperties.getExtendedConsumerProperties(channelName);
+ protected ErrorMessageStrategy getErrorMessageStrategy() {
+ // It can be extended to custom if necessary.
+ return new DefaultErrorMessageStrategy();
}
@Override
- public RocketMQProducerProperties getExtendedProducerProperties(String channelName) {
- return extendedBindingProperties.getExtendedProducerProperties(channelName);
+ public RocketMQConsumerProperties getExtendedConsumerProperties(String channelName) {
+ return this.extendedBindingProperties.getExtendedConsumerProperties(channelName);
}
- public Map getTopicInUse() {
- return topicInUse;
+ @Override
+ public RocketMQProducerProperties getExtendedProducerProperties(String channelName) {
+ return this.extendedBindingProperties.getExtendedProducerProperties(channelName);
}
@Override
public String getDefaultsPrefix() {
- return extendedBindingProperties.getDefaultsPrefix();
+ return this.extendedBindingProperties.getDefaultsPrefix();
}
@Override
public Class extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
- return extendedBindingProperties.getExtendedPropertiesEntryClass();
+ return this.extendedBindingProperties.getExtendedPropertiesEntryClass();
}
-
- public void setExtendedBindingProperties(
- RocketMQExtendedBindingProperties extendedBindingProperties) {
- this.extendedBindingProperties = extendedBindingProperties;
- }
-
- private RocketMQHeaderMapper createHeaderMapper(
- final ExtendedConsumerProperties extendedConsumerProperties) {
- Set trustedPackages = extendedConsumerProperties.getExtension()
- .getTrustedPackages();
- return createHeaderMapper(trustedPackages);
- }
-
- private RocketMQHeaderMapper createHeaderMapper(
- final ExtendedProducerProperties producerProperties) {
- return createHeaderMapper(Collections.emptyList());
- }
-
- private RocketMQHeaderMapper createHeaderMapper(Collection trustedPackages) {
- ObjectMapper objectMapper = this.getApplicationContext()
- .getBeansOfType(ObjectMapper.class).values().iterator().next();
- JacksonRocketMQHeaderMapper headerMapper = new JacksonRocketMQHeaderMapper(
- objectMapper);
- if (!StringUtils.isEmpty(trustedPackages)) {
- headerMapper.addTrustedPackages(trustedPackages);
- }
- return headerMapper;
- }
-
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/actuator/RocketMQBinderHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/actuator/RocketMQBinderHealthIndicator.java
index 1c49359ea..6e704250a 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/actuator/RocketMQBinderHealthIndicator.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/actuator/RocketMQBinderHealthIndicator.java
@@ -19,7 +19,6 @@ package com.alibaba.cloud.stream.binder.rocketmq.actuator;
import com.alibaba.cloud.stream.binder.rocketmq.metrics.Instrumentation;
import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
@@ -29,23 +28,20 @@ import org.springframework.boot.actuate.health.Health;
*/
public class RocketMQBinderHealthIndicator extends AbstractHealthIndicator {
- @Autowired
- private InstrumentationManager instrumentationManager;
-
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
- if (instrumentationManager.getHealthInstrumentations().stream()
+ if (InstrumentationManager.getHealthInstrumentations().stream()
.allMatch(Instrumentation::isUp)) {
builder.up();
return;
}
- if (instrumentationManager.getHealthInstrumentations().stream()
+ if (InstrumentationManager.getHealthInstrumentations().stream()
.allMatch(Instrumentation::isOutOfService)) {
builder.outOfService();
return;
}
builder.down();
- instrumentationManager.getHealthInstrumentations().stream()
+ InstrumentationManager.getHealthInstrumentations().stream()
.filter(instrumentation -> !instrumentation.isStarted())
.forEach(instrumentation1 -> builder
.withException(instrumentation1.getStartException()));
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
index fb167c697..7bd875f33 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
@@ -1,465 +1,470 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq.consuming;
-
-import java.util.List;
-import java.util.Objects;
-
-import com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderUtils;
-import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
-import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
-import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
-import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQHeaderMapper;
-import org.apache.rocketmq.acl.common.AclClientRPCHook;
-import org.apache.rocketmq.acl.common.SessionCredentials;
-import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
-import org.apache.rocketmq.client.consumer.MessageSelector;
-import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
-import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
-import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
-import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
-import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
-import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
-import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
-import org.apache.rocketmq.client.exception.MQClientException;
-import org.apache.rocketmq.common.UtilAll;
-import org.apache.rocketmq.common.message.MessageExt;
-import org.apache.rocketmq.remoting.RPCHook;
-import org.apache.rocketmq.spring.annotation.ConsumeMode;
-import org.apache.rocketmq.spring.annotation.MessageModel;
-import org.apache.rocketmq.spring.annotation.SelectorType;
-import org.apache.rocketmq.spring.core.RocketMQListener;
-import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
-import org.apache.rocketmq.spring.support.RocketMQListenerContainer;
-import org.apache.rocketmq.spring.support.RocketMQUtil;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
-import org.springframework.context.SmartLifecycle;
-import org.springframework.integration.support.MessageBuilder;
-import org.springframework.messaging.Message;
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import static com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ROCKETMQ_RECONSUME_TIMES;
-
-/**
- * A class that Listen on rocketmq message.
- *
- * this class will delegate {@link RocketMQListener} to handle message
- *
- * @author Jim
- * @author Xiejiashuai
- * @see RocketMQListener
- */
-public class RocketMQListenerBindingContainer
- implements InitializingBean, RocketMQListenerContainer, SmartLifecycle {
-
- private final static Logger log = LoggerFactory
- .getLogger(RocketMQListenerBindingContainer.class);
-
- private long suspendCurrentQueueTimeMillis = 1000;
-
- /**
- * Message consume retry strategy
- * -1,no retry,put into DLQ directly
- * 0,broker control retry frequency
- * >0,client control retry frequency.
- */
- private int delayLevelWhenNextConsume = 0;
-
- private List nameServer;
-
- private String consumerGroup;
-
- private String topic;
-
- private int consumeThreadMax = 64;
-
- private String charset = "UTF-8";
-
- private RocketMQListener rocketMQListener;
-
- private RocketMQHeaderMapper headerMapper;
-
- private DefaultMQPushConsumer consumer;
-
- private boolean running;
-
- private final ExtendedConsumerProperties rocketMQConsumerProperties;
-
- private final RocketMQMessageChannelBinder rocketMQMessageChannelBinder;
-
- private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
-
- // The following properties came from RocketMQConsumerProperties.
- private ConsumeMode consumeMode;
-
- private SelectorType selectorType;
-
- private String selectorExpression;
-
- private MessageModel messageModel;
-
- public RocketMQListenerBindingContainer(
- ExtendedConsumerProperties rocketMQConsumerProperties,
- RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
- RocketMQMessageChannelBinder rocketMQMessageChannelBinder) {
- this.rocketMQConsumerProperties = rocketMQConsumerProperties;
- this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
- this.rocketMQMessageChannelBinder = rocketMQMessageChannelBinder;
- this.consumeMode = rocketMQConsumerProperties.getExtension().getOrderly()
- ? ConsumeMode.ORDERLY : ConsumeMode.CONCURRENTLY;
- if (StringUtils.isEmpty(rocketMQConsumerProperties.getExtension().getSql())) {
- this.selectorType = SelectorType.TAG;
- this.selectorExpression = rocketMQConsumerProperties.getExtension().getTags();
- }
- else {
- this.selectorType = SelectorType.SQL92;
- this.selectorExpression = rocketMQConsumerProperties.getExtension().getSql();
- }
- this.messageModel = rocketMQConsumerProperties.getExtension().getBroadcasting()
- ? MessageModel.BROADCASTING : MessageModel.CLUSTERING;
- }
-
- @Override
- public void setupMessageListener(RocketMQListener> rocketMQListener) {
- this.rocketMQListener = rocketMQListener;
- }
-
- @Override
- public void destroy() throws Exception {
- this.setRunning(false);
- if (Objects.nonNull(consumer)) {
- consumer.shutdown();
- }
- log.info("container destroyed, {}", this.toString());
- }
-
- @Override
- public void afterPropertiesSet() throws Exception {
- initRocketMQPushConsumer();
- }
-
- @Override
- public boolean isAutoStartup() {
- return true;
- }
-
- @Override
- public void stop(Runnable callback) {
- stop();
- callback.run();
- }
-
- @Override
- public void start() {
- if (this.isRunning()) {
- throw new IllegalStateException(
- "container already running. " + this.toString());
- }
-
- try {
- consumer.start();
- }
- catch (MQClientException e) {
- throw new IllegalStateException("Failed to start RocketMQ push consumer", e);
- }
- this.setRunning(true);
-
- log.info("running container: {}", this.toString());
- }
-
- @Override
- public void stop() {
- if (this.isRunning()) {
- if (Objects.nonNull(consumer)) {
- consumer.shutdown();
- }
- setRunning(false);
- }
- }
-
- @Override
- public boolean isRunning() {
- return running;
- }
-
- private void setRunning(boolean running) {
- this.running = running;
- }
-
- @Override
- public int getPhase() {
- return Integer.MAX_VALUE;
- }
-
- private void initRocketMQPushConsumer() throws MQClientException {
- Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
- Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
- Assert.notNull(nameServer, "Property 'nameServer' is required");
- Assert.notNull(topic, "Property 'topic' is required");
-
- String ak = rocketBinderConfigurationProperties.getAccessKey();
- String sk = rocketBinderConfigurationProperties.getSecretKey();
- if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
- RPCHook rpcHook = new AclClientRPCHook(new SessionCredentials(ak, sk));
- consumer = new DefaultMQPushConsumer(consumerGroup, rpcHook,
- new AllocateMessageQueueAveragely(),
- rocketBinderConfigurationProperties.isEnableMsgTrace(),
- rocketBinderConfigurationProperties.getCustomizedTraceTopic());
- consumer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook,
- topic + "|" + UtilAll.getPid()));
- consumer.setVipChannelEnabled(false);
- }
- else {
- consumer = new DefaultMQPushConsumer(consumerGroup,
- rocketBinderConfigurationProperties.isEnableMsgTrace(),
- rocketBinderConfigurationProperties.getCustomizedTraceTopic());
- }
-
- consumer.setNamesrvAddr(RocketMQBinderUtils.getNameServerStr(nameServer));
- consumer.setConsumeThreadMax(rocketMQConsumerProperties.getConcurrency());
- consumer.setConsumeThreadMin(rocketMQConsumerProperties.getConcurrency());
-
- switch (messageModel) {
- case BROADCASTING:
- consumer.setMessageModel(
- org.apache.rocketmq.common.protocol.heartbeat.MessageModel.BROADCASTING);
- break;
- case CLUSTERING:
- consumer.setMessageModel(
- org.apache.rocketmq.common.protocol.heartbeat.MessageModel.CLUSTERING);
- break;
- default:
- throw new IllegalArgumentException("Property 'messageModel' was wrong.");
- }
-
- switch (selectorType) {
- case TAG:
- consumer.subscribe(topic, selectorExpression);
- break;
- case SQL92:
- consumer.subscribe(topic, MessageSelector.bySql(selectorExpression));
- break;
- default:
- throw new IllegalArgumentException("Property 'selectorType' was wrong.");
- }
-
- switch (consumeMode) {
- case ORDERLY:
- consumer.setMessageListener(new DefaultMessageListenerOrderly());
- break;
- case CONCURRENTLY:
- consumer.setMessageListener(new DefaultMessageListenerConcurrently());
- break;
- default:
- throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
- }
-
- if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {
- ((RocketMQPushConsumerLifecycleListener) rocketMQListener)
- .prepareStart(consumer);
- }
-
- }
-
- @Override
- public String toString() {
- return "RocketMQListenerBindingContainer{" + "consumerGroup='" + consumerGroup
- + '\'' + ", nameServer='" + nameServer + '\'' + ", topic='" + topic + '\''
- + ", consumeMode=" + consumeMode + ", selectorType=" + selectorType
- + ", selectorExpression='" + selectorExpression + '\'' + ", messageModel="
- + messageModel + '}';
- }
-
- public long getSuspendCurrentQueueTimeMillis() {
- return suspendCurrentQueueTimeMillis;
- }
-
- public void setSuspendCurrentQueueTimeMillis(long suspendCurrentQueueTimeMillis) {
- this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
- }
-
- public int getDelayLevelWhenNextConsume() {
- return delayLevelWhenNextConsume;
- }
-
- public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
- this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
- }
-
- public List getNameServer() {
- return nameServer;
- }
-
- public void setNameServer(List nameServer) {
- this.nameServer = nameServer;
- }
-
- public String getConsumerGroup() {
- return consumerGroup;
- }
-
- public void setConsumerGroup(String consumerGroup) {
- this.consumerGroup = consumerGroup;
- }
-
- public String getTopic() {
- return topic;
- }
-
- public void setTopic(String topic) {
- this.topic = topic;
- }
-
- public int getConsumeThreadMax() {
- return consumeThreadMax;
- }
-
- public void setConsumeThreadMax(int consumeThreadMax) {
- this.consumeThreadMax = consumeThreadMax;
- }
-
- public String getCharset() {
- return charset;
- }
-
- public void setCharset(String charset) {
- this.charset = charset;
- }
-
- public RocketMQListener getRocketMQListener() {
- return rocketMQListener;
- }
-
- public void setRocketMQListener(RocketMQListener rocketMQListener) {
- this.rocketMQListener = rocketMQListener;
- }
-
- public DefaultMQPushConsumer getConsumer() {
- return consumer;
- }
-
- public void setConsumer(DefaultMQPushConsumer consumer) {
- this.consumer = consumer;
- }
-
- public ExtendedConsumerProperties getRocketMQConsumerProperties() {
- return rocketMQConsumerProperties;
- }
-
- public ConsumeMode getConsumeMode() {
- return consumeMode;
- }
-
- public SelectorType getSelectorType() {
- return selectorType;
- }
-
- public String getSelectorExpression() {
- return selectorExpression;
- }
-
- public MessageModel getMessageModel() {
- return messageModel;
- }
-
- public RocketMQHeaderMapper getHeaderMapper() {
- return headerMapper;
- }
-
- public void setHeaderMapper(RocketMQHeaderMapper headerMapper) {
- this.headerMapper = headerMapper;
- }
-
- /**
- * Convert rocketmq {@link MessageExt} to Spring {@link Message}.
- * @param messageExt the rocketmq message
- * @return the converted Spring {@link Message}
- */
- @SuppressWarnings("unchecked")
- private Message convertToSpringMessage(MessageExt messageExt) {
-
- // add reconsume-times header to messageExt
- int reconsumeTimes = messageExt.getReconsumeTimes();
- messageExt.putUserProperty(ROCKETMQ_RECONSUME_TIMES,
- String.valueOf(reconsumeTimes));
- Message message = RocketMQUtil.convertToSpringMessage(messageExt);
- return MessageBuilder.fromMessage(message)
- .copyHeaders(headerMapper.toHeaders(messageExt.getProperties())).build();
- }
-
- public class DefaultMessageListenerConcurrently
- implements MessageListenerConcurrently {
-
- @SuppressWarnings({ "unchecked", "Duplicates" })
- @Override
- public ConsumeConcurrentlyStatus consumeMessage(List msgs,
- ConsumeConcurrentlyContext context) {
- for (MessageExt messageExt : msgs) {
- log.debug("received msg: {}", messageExt);
- try {
- long now = System.currentTimeMillis();
- rocketMQListener.onMessage(convertToSpringMessage(messageExt));
- long costTime = System.currentTimeMillis() - now;
- log.debug("consume {} message key:[{}] cost: {} ms",
- messageExt.getMsgId(), messageExt.getKeys(), costTime);
- }
- catch (Exception e) {
- log.warn("consume message failed. messageExt:{}", messageExt, e);
- context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);
- return ConsumeConcurrentlyStatus.RECONSUME_LATER;
- }
- }
-
- return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
- }
-
- }
-
- public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
-
- @SuppressWarnings({ "unchecked", "Duplicates" })
- @Override
- public ConsumeOrderlyStatus consumeMessage(List msgs,
- ConsumeOrderlyContext context) {
- for (MessageExt messageExt : msgs) {
- log.debug("received msg: {}", messageExt);
- try {
- long now = System.currentTimeMillis();
- rocketMQListener.onMessage(convertToSpringMessage(messageExt));
- long costTime = System.currentTimeMillis() - now;
- log.info("consume {} message key:[{}] cost: {} ms",
- messageExt.getMsgId(), messageExt.getKeys(), costTime);
- }
- catch (Exception e) {
- log.warn("consume message failed. messageExt:{}", messageExt, e);
- context.setSuspendCurrentQueueTimeMillis(
- suspendCurrentQueueTimeMillis);
- return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
- }
- }
-
- return ConsumeOrderlyStatus.SUCCESS;
- }
-
- }
-
-}
+/// *
+// * Copyright 2013-2018 the original author or authors.
+// *
+// * Licensed under the Apache License, Version 2.0 (the "License");
+// * you may not use this file except in compliance with the License.
+// * You may obtain a copy of the License at
+// *
+// * https://www.apache.org/licenses/LICENSE-2.0
+// *
+// * Unless required by applicable law or agreed to in writing, software
+// * distributed under the License is distributed on an "AS IS" BASIS,
+// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// * See the License for the specific language governing permissions and
+// * limitations under the License.
+// */
+//
+// package com.alibaba.cloud.stream.binder.rocketmq.consuming;
+//
+// import java.util.List;
+// import java.util.Objects;
+//
+// import com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderUtils;
+// import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
+// import
+/// com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
+// import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
+// import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQHeaderMapper;
+// import org.apache.rocketmq.acl.common.AclClientRPCHook;
+// import org.apache.rocketmq.acl.common.SessionCredentials;
+// import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+// import org.apache.rocketmq.client.consumer.MessageSelector;
+// import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
+// import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+// import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
+// import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
+// import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+// import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
+// import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
+// import org.apache.rocketmq.client.exception.MQClientException;
+// import org.apache.rocketmq.common.UtilAll;
+// import org.apache.rocketmq.common.message.MessageExt;
+// import org.apache.rocketmq.remoting.RPCHook;
+// import org.apache.rocketmq.spring.annotation.ConsumeMode;
+// import org.apache.rocketmq.spring.annotation.MessageModel;
+// import org.apache.rocketmq.spring.annotation.SelectorType;
+// import org.apache.rocketmq.spring.core.RocketMQListener;
+// import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
+// import org.apache.rocketmq.spring.support.RocketMQListenerContainer;
+// import org.apache.rocketmq.spring.support.RocketMQUtil;
+// import org.slf4j.Logger;
+// import org.slf4j.LoggerFactory;
+//
+// import org.springframework.beans.factory.InitializingBean;
+// import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
+// import org.springframework.context.SmartLifecycle;
+// import org.springframework.integration.support.MessageBuilder;
+// import org.springframework.messaging.Message;
+// import org.springframework.util.Assert;
+// import org.springframework.util.StringUtils;
+//
+// import static
+/// com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ROCKETMQ_RECONSUME_TIMES;
+//
+/// **
+// * A class that Listen on rocketmq message.
+// *
+// * this class will delegate {@link RocketMQListener} to handle message
+// *
+// * @author Jim
+// * @author Xiejiashuai
+// * @see RocketMQListener
+// */
+// public class RocketMQListenerBindingContainer
+// implements InitializingBean, RocketMQListenerContainer, SmartLifecycle {
+//
+// private final static Logger log = LoggerFactory
+// .getLogger(RocketMQListenerBindingContainer.class);
+//
+// private long suspendCurrentQueueTimeMillis = 1000;
+//
+// /**
+// * Message consume retry strategy
+// * -1,no retry,put into DLQ directly
+// * 0,broker control retry frequency
+// * >0,client control retry frequency.
+// */
+// private int delayLevelWhenNextConsume = 0;
+//
+// private List nameServer;
+//
+// private String consumerGroup;
+//
+// private String topic;
+//
+// private int consumeThreadMax = 64;
+//
+// private String charset = "UTF-8";
+//
+// private RocketMQListener rocketMQListener;
+//
+// private RocketMQHeaderMapper headerMapper;
+//
+// private DefaultMQPushConsumer consumer;
+//
+// private boolean running;
+//
+// private final ExtendedConsumerProperties
+/// rocketMQConsumerProperties;
+//
+// private final RocketMQMessageChannelBinder rocketMQMessageChannelBinder;
+//
+// private final RocketMQBinderConfigurationProperties
+/// rocketBinderConfigurationProperties;
+//
+// // The following properties came from RocketMQConsumerProperties.
+// private ConsumeMode consumeMode;
+//
+// private SelectorType selectorType;
+//
+// private String selectorExpression;
+//
+// private MessageModel messageModel;
+//
+// public RocketMQListenerBindingContainer(
+// ExtendedConsumerProperties rocketMQConsumerProperties,
+// RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
+// RocketMQMessageChannelBinder rocketMQMessageChannelBinder) {
+// this.rocketMQConsumerProperties = rocketMQConsumerProperties;
+// this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
+// this.rocketMQMessageChannelBinder = rocketMQMessageChannelBinder;
+// this.consumeMode = rocketMQConsumerProperties.getExtension().getOrderly()
+// ? ConsumeMode.ORDERLY : ConsumeMode.CONCURRENTLY;
+// if (StringUtils.isEmpty(rocketMQConsumerProperties.getExtension().getSql())) {
+// this.selectorType = SelectorType.TAG;
+// this.selectorExpression = rocketMQConsumerProperties.getExtension().getTags();
+// }
+// else {
+// this.selectorType = SelectorType.SQL92;
+// this.selectorExpression = rocketMQConsumerProperties.getExtension().getSql();
+// }
+// this.messageModel = rocketMQConsumerProperties.getExtension().getBroadcasting()
+// ? MessageModel.BROADCASTING : MessageModel.CLUSTERING;
+// }
+//
+// @Override
+// public void setupMessageListener(RocketMQListener> rocketMQListener) {
+// this.rocketMQListener = rocketMQListener;
+// }
+//
+// @Override
+// public void destroy() throws Exception {
+// this.setRunning(false);
+// if (Objects.nonNull(consumer)) {
+// consumer.shutdown();
+// }
+// log.info("container destroyed, {}", this.toString());
+// }
+//
+// @Override
+// public void afterPropertiesSet() throws Exception {
+// initRocketMQPushConsumer();
+// }
+//
+// @Override
+// public boolean isAutoStartup() {
+// return true;
+// }
+//
+// @Override
+// public void stop(Runnable callback) {
+// stop();
+// callback.run();
+// }
+//
+// @Override
+// public void start() {
+// if (this.isRunning()) {
+// throw new IllegalStateException(
+// "container already running. " + this.toString());
+// }
+//
+// try {
+// consumer.start();
+// }
+// catch (MQClientException e) {
+// throw new IllegalStateException("Failed to start RocketMQ push consumer", e);
+// }
+// this.setRunning(true);
+//
+// log.info("running container: {}", this.toString());
+// }
+//
+// @Override
+// public void stop() {
+// if (this.isRunning()) {
+// if (Objects.nonNull(consumer)) {
+// consumer.shutdown();
+// }
+// setRunning(false);
+// }
+// }
+//
+// @Override
+// public boolean isRunning() {
+// return running;
+// }
+//
+// private void setRunning(boolean running) {
+// this.running = running;
+// }
+//
+// @Override
+// public int getPhase() {
+// return Integer.MAX_VALUE;
+// }
+//
+// private void initRocketMQPushConsumer() throws MQClientException {
+// Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
+// Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
+// Assert.notNull(nameServer, "Property 'nameServer' is required");
+// Assert.notNull(topic, "Property 'topic' is required");
+//
+// String ak = rocketBinderConfigurationProperties.getAccessKey();
+// String sk = rocketBinderConfigurationProperties.getSecretKey();
+// if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
+// RPCHook rpcHook = new AclClientRPCHook(new SessionCredentials(ak, sk));
+// consumer = new DefaultMQPushConsumer(consumerGroup, rpcHook,
+// new AllocateMessageQueueAveragely(),
+// rocketBinderConfigurationProperties.isEnableMsgTrace(),
+// rocketBinderConfigurationProperties.getCustomizedTraceTopic());
+// consumer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook,
+// topic + "|" + UtilAll.getPid()));
+// consumer.setVipChannelEnabled(false);
+// }
+// else {
+// consumer = new DefaultMQPushConsumer(consumerGroup,
+// rocketBinderConfigurationProperties.isEnableMsgTrace(),
+// rocketBinderConfigurationProperties.getCustomizedTraceTopic());
+// }
+//
+// consumer.setNamesrvAddr(RocketMQBinderUtils.getNameServerStr(nameServer));
+// consumer.setConsumeThreadMax(rocketMQConsumerProperties.getConcurrency());
+// consumer.setConsumeThreadMin(rocketMQConsumerProperties.getConcurrency());
+//
+// switch (messageModel) {
+// case BROADCASTING:
+// consumer.setMessageModel(
+// org.apache.rocketmq.common.protocol.heartbeat.MessageModel.BROADCASTING);
+// break;
+// case CLUSTERING:
+// consumer.setMessageModel(
+// org.apache.rocketmq.common.protocol.heartbeat.MessageModel.CLUSTERING);
+// break;
+// default:
+// throw new IllegalArgumentException("Property 'messageModel' was wrong.");
+// }
+//
+// switch (selectorType) {
+// case TAG:
+// consumer.subscribe(topic, selectorExpression);
+// break;
+// case SQL92:
+// consumer.subscribe(topic, MessageSelector.bySql(selectorExpression));
+// break;
+// default:
+// throw new IllegalArgumentException("Property 'selectorType' was wrong.");
+// }
+//
+// switch (consumeMode) {
+// case ORDERLY:
+// consumer.setMessageListener(new DefaultMessageListenerOrderly());
+// break;
+// case CONCURRENTLY:
+// consumer.setMessageListener(new DefaultMessageListenerConcurrently());
+// break;
+// default:
+// throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
+// }
+//
+// if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {
+// ((RocketMQPushConsumerLifecycleListener) rocketMQListener)
+// .prepareStart(consumer);
+// }
+//
+// }
+//
+// @Override
+// public String toString() {
+// return "RocketMQListenerBindingContainer{" + "consumerGroup='" + consumerGroup
+// + '\'' + ", nameServer='" + nameServer + '\'' + ", topic='" + topic + '\''
+// + ", consumeMode=" + consumeMode + ", selectorType=" + selectorType
+// + ", selectorExpression='" + selectorExpression + '\'' + ", messageModel="
+// + messageModel + '}';
+// }
+//
+// public long getSuspendCurrentQueueTimeMillis() {
+// return suspendCurrentQueueTimeMillis;
+// }
+//
+// public void setSuspendCurrentQueueTimeMillis(long suspendCurrentQueueTimeMillis) {
+// this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
+// }
+//
+// public int getDelayLevelWhenNextConsume() {
+// return delayLevelWhenNextConsume;
+// }
+//
+// public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
+// this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
+// }
+//
+// public List getNameServer() {
+// return nameServer;
+// }
+//
+// public void setNameServer(List nameServer) {
+// this.nameServer = nameServer;
+// }
+//
+// public String getConsumerGroup() {
+// return consumerGroup;
+// }
+//
+// public void setConsumerGroup(String consumerGroup) {
+// this.consumerGroup = consumerGroup;
+// }
+//
+// public String getTopic() {
+// return topic;
+// }
+//
+// public void setTopic(String topic) {
+// this.topic = topic;
+// }
+//
+// public int getConsumeThreadMax() {
+// return consumeThreadMax;
+// }
+//
+// public void setConsumeThreadMax(int consumeThreadMax) {
+// this.consumeThreadMax = consumeThreadMax;
+// }
+//
+// public String getCharset() {
+// return charset;
+// }
+//
+// public void setCharset(String charset) {
+// this.charset = charset;
+// }
+//
+// public RocketMQListener getRocketMQListener() {
+// return rocketMQListener;
+// }
+//
+// public void setRocketMQListener(RocketMQListener rocketMQListener) {
+// this.rocketMQListener = rocketMQListener;
+// }
+//
+// public DefaultMQPushConsumer getConsumer() {
+// return consumer;
+// }
+//
+// public void setConsumer(DefaultMQPushConsumer consumer) {
+// this.consumer = consumer;
+// }
+//
+// public ExtendedConsumerProperties
+/// getRocketMQConsumerProperties() {
+// return rocketMQConsumerProperties;
+// }
+//
+// public ConsumeMode getConsumeMode() {
+// return consumeMode;
+// }
+//
+// public SelectorType getSelectorType() {
+// return selectorType;
+// }
+//
+// public String getSelectorExpression() {
+// return selectorExpression;
+// }
+//
+// public MessageModel getMessageModel() {
+// return messageModel;
+// }
+//
+// public RocketMQHeaderMapper getHeaderMapper() {
+// return headerMapper;
+// }
+//
+// public void setHeaderMapper(RocketMQHeaderMapper headerMapper) {
+// this.headerMapper = headerMapper;
+// }
+//
+// /**
+// * Convert rocketmq {@link MessageExt} to Spring {@link Message}.
+// * @param messageExt the rocketmq message
+// * @return the converted Spring {@link Message}
+// */
+// @SuppressWarnings("unchecked")
+// private Message convertToSpringMessage(MessageExt messageExt) {
+//
+// // add reconsume-times header to messageExt
+// int reconsumeTimes = messageExt.getReconsumeTimes();
+// messageExt.putUserProperty(ROCKETMQ_RECONSUME_TIMES,
+// String.valueOf(reconsumeTimes));
+// Message message = RocketMQUtil.convertToSpringMessage(messageExt);
+// return MessageBuilder.fromMessage(message)
+// .copyHeaders(headerMapper.toHeaders(messageExt.getProperties())).build();
+// }
+//
+// public class DefaultMessageListenerConcurrently
+// implements MessageListenerConcurrently {
+//
+// @SuppressWarnings({ "unchecked", "Duplicates" })
+// @Override
+// public ConsumeConcurrentlyStatus consumeMessage(List msgs,
+// ConsumeConcurrentlyContext context) {
+// for (MessageExt messageExt : msgs) {
+// log.debug("received msg: {}", messageExt);
+// try {
+// long now = System.currentTimeMillis();
+// rocketMQListener.onMessage(convertToSpringMessage(messageExt));
+// long costTime = System.currentTimeMillis() - now;
+// log.debug("consume {} message key:[{}] cost: {} ms",
+// messageExt.getMsgId(), messageExt.getKeys(), costTime);
+// }
+// catch (Exception e) {
+// log.warn("consume message failed. messageExt:{}", messageExt, e);
+// context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);
+// return ConsumeConcurrentlyStatus.RECONSUME_LATER;
+// }
+// }
+//
+// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
+// }
+//
+// }
+//
+// public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
+//
+// @SuppressWarnings({ "unchecked", "Duplicates" })
+// @Override
+// public ConsumeOrderlyStatus consumeMessage(List msgs,
+// ConsumeOrderlyContext context) {
+// for (MessageExt messageExt : msgs) {
+// log.debug("received msg: {}", messageExt);
+// try {
+// long now = System.currentTimeMillis();
+// rocketMQListener.onMessage(convertToSpringMessage(messageExt));
+// long costTime = System.currentTimeMillis() - now;
+// log.info("consume {} message key:[{}] cost: {} ms",
+// messageExt.getMsgId(), messageExt.getKeys(), costTime);
+// }
+// catch (Exception e) {
+// log.warn("consume message failed. messageExt:{}", messageExt, e);
+// context.setSuspendCurrentQueueTimeMillis(
+// suspendCurrentQueueTimeMillis);
+// return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
+// }
+// }
+//
+// return ConsumeOrderlyStatus.SUCCESS;
+// }
+//
+// }
+//
+// }
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java
deleted file mode 100644
index a3b680419..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/RocketMQInboundChannelAdapter.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq.integration;
-
-import com.alibaba.cloud.stream.binder.rocketmq.consuming.RocketMQListenerBindingContainer;
-import com.alibaba.cloud.stream.binder.rocketmq.metrics.Instrumentation;
-import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
-import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
-import org.apache.rocketmq.spring.core.RocketMQListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
-import org.springframework.integration.endpoint.MessageProducerSupport;
-import org.springframework.integration.support.MessageBuilder;
-import org.springframework.messaging.Message;
-import org.springframework.messaging.MessagingException;
-import org.springframework.retry.RecoveryCallback;
-import org.springframework.retry.RetryCallback;
-import org.springframework.retry.RetryContext;
-import org.springframework.retry.RetryListener;
-import org.springframework.retry.support.RetryTemplate;
-import org.springframework.util.Assert;
-
-/**
- * @author Jim
- */
-public class RocketMQInboundChannelAdapter extends MessageProducerSupport {
-
- private static final Logger log = LoggerFactory
- .getLogger(RocketMQInboundChannelAdapter.class);
-
- private RetryTemplate retryTemplate;
-
- private RecoveryCallback extends Object> recoveryCallback;
-
- private RocketMQListenerBindingContainer rocketMQListenerContainer;
-
- private final ExtendedConsumerProperties consumerProperties;
-
- private final InstrumentationManager instrumentationManager;
-
- public RocketMQInboundChannelAdapter(
- RocketMQListenerBindingContainer rocketMQListenerContainer,
- ExtendedConsumerProperties consumerProperties,
- InstrumentationManager instrumentationManager) {
- this.rocketMQListenerContainer = rocketMQListenerContainer;
- this.consumerProperties = consumerProperties;
- this.instrumentationManager = instrumentationManager;
- }
-
- @Override
- protected void onInit() {
- if (consumerProperties == null
- || !consumerProperties.getExtension().getEnabled()) {
- return;
- }
- super.onInit();
- if (this.retryTemplate != null) {
- Assert.state(getErrorChannel() == null,
- "Cannot have an 'errorChannel' property when a 'RetryTemplate' is "
- + "provided; use an 'ErrorMessageSendingRecoverer' in the 'recoveryCallback' property to "
- + "send an error message when retries are exhausted");
- }
-
- BindingRocketMQListener listener = new BindingRocketMQListener();
- rocketMQListenerContainer.setRocketMQListener(listener);
-
- if (retryTemplate != null) {
- this.retryTemplate.registerListener(listener);
- }
-
- try {
- rocketMQListenerContainer.afterPropertiesSet();
-
- }
- catch (Exception e) {
- log.error("rocketMQListenerContainer init error: " + e.getMessage(), e);
- throw new IllegalArgumentException(
- "rocketMQListenerContainer init error: " + e.getMessage(), e);
- }
-
- instrumentationManager.addHealthInstrumentation(
- new Instrumentation(rocketMQListenerContainer.getTopic()
- + rocketMQListenerContainer.getConsumerGroup()));
- }
-
- @Override
- protected void doStart() {
- if (consumerProperties == null
- || !consumerProperties.getExtension().getEnabled()) {
- return;
- }
- try {
- rocketMQListenerContainer.start();
- instrumentationManager
- .getHealthInstrumentation(rocketMQListenerContainer.getTopic()
- + rocketMQListenerContainer.getConsumerGroup())
- .markStartedSuccessfully();
- }
- catch (Exception e) {
- instrumentationManager
- .getHealthInstrumentation(rocketMQListenerContainer.getTopic()
- + rocketMQListenerContainer.getConsumerGroup())
- .markStartFailed(e);
- log.error("RocketMQTemplate startup failed, Caused by " + e.getMessage());
- throw new MessagingException(MessageBuilder.withPayload(
- "RocketMQTemplate startup failed, Caused by " + e.getMessage())
- .build(), e);
- }
- }
-
- @Override
- protected void doStop() {
- rocketMQListenerContainer.stop();
- }
-
- public void setRetryTemplate(RetryTemplate retryTemplate) {
- this.retryTemplate = retryTemplate;
- }
-
- public void setRecoveryCallback(RecoveryCallback extends Object> recoveryCallback) {
- this.recoveryCallback = recoveryCallback;
- }
-
- protected class BindingRocketMQListener
- implements RocketMQListener, RetryListener {
-
- @Override
- public void onMessage(Message message) {
- boolean enableRetry = RocketMQInboundChannelAdapter.this.retryTemplate != null;
- if (enableRetry) {
- RocketMQInboundChannelAdapter.this.retryTemplate.execute(context -> {
- RocketMQInboundChannelAdapter.this.sendMessage(message);
- return null;
- }, (RecoveryCallback
+ *
+ * This field defaults to clustering.
*/
- private String tags;
+ private String messageModel = MessageModel.CLUSTERING.getModeCN();
/**
- * {@link MQPushConsumer#subscribe(String, MessageSelector)}
- * {@link MessageSelector#bySql(String)}.
+ * Queue allocation algorithm specifying how message queues are allocated to each
+ * consumer clients.
*/
- private String sql;
+ private String allocateMessageQueueStrategy;
/**
- * {@link MessageModel#BROADCASTING}.
+ * The expressions include tags or SQL,as follow:
+ *
+ * tag: {@code tag1||tag2||tag3 }; sql: {@code 'color'='blue' AND 'price'>100 } .
+ *
+ * Determines whether there are specific characters "{@code ||}" in the expression to
+ * determine how the message is filtered,tags or SQL.
*/
- private Boolean broadcasting = false;
+ private String subscription;
/**
- * if orderly is true, using {@link MessageListenerOrderly} else if orderly if false,
- * using {@link MessageListenerConcurrently}.
+ * Delay some time when exception occur
*/
- private Boolean orderly = false;
+ private long pullTimeDelayMillsWhenException = 1000;
/**
- * for concurrently listener. message consume retry strategy. see
- * {@link ConsumeConcurrentlyContext#delayLevelWhenNextConsume}. -1 means dlq(or
- * discard, see {@link this#shouldRequeue}), others means requeue.
+ * Consuming point on consumer booting.
+ *
+ *
+ * There are three consuming points:
+ *
+ *
CONSUME_FROM_LAST_OFFSET: consumer clients pick up where it
+ * stopped previously. If it were a newly booting up consumer client, according aging
+ * of the consumer group, there are two cases:
+ *
+ *
if the consumer group is created so recently that the earliest message being
+ * subscribed has yet expired, which means the consumer group represents a lately
+ * launched business, consuming will start from the very beginning;
+ *
if the earliest message being subscribed has expired, consuming will start from
+ * the latest messages, meaning messages born prior to the booting timestamp would be
+ * ignored.
+ *
+ *
+ *
CONSUME_FROM_FIRST_OFFSET: Consumer client will start from
+ * earliest messages available.
+ *
CONSUME_FROM_TIMESTAMP: Consumer client will start from specified
+ * timestamp, which means messages born prior to {@link #consumeTimestamp} will be
+ * ignored
+ *
+ */
+ private ConsumeFromWhere consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET;
+ /**
+ * Backtracking consumption time with second precision. Time format is
+ * 20131223171201
+ * Implying Seventeen twelve and 01 seconds on December 23, 2013 year
+ * Default backtracking consumption time Half an hour ago.
*/
- private int delayLevelWhenNextConsume = 0;
+ private String consumeTimestamp = UtilAll
+ .timeMillisToHumanString3(System.currentTimeMillis() - (1000 * 60 * 30));
/**
- * for orderly listener. next retry delay time.
+ * Flow control threshold on queue level, each message queue will cache at most 1000
+ * messages by default, Consider the {@link #pullBatchSize}, the instantaneous value
+ * may exceed the limit
*/
- private long suspendCurrentQueueTimeMillis = 1000;
+ private int pullThresholdForQueue = 1000;
+ /**
+ * Limit the cached message size on queue level, each message queue will cache at most
+ * 100 MiB messages by default, Consider the {@link #pullBatchSize}, the instantaneous
+ * value may exceed the limit
+ *
+ *
+ * The size of a message only measured by message body, so it's not accurate
+ */
+ private int pullThresholdSizeForQueue = 100;
- private Boolean enabled = true;
+ /**
+ * Maximum number of messages pulled each time.
+ */
+ private int pullBatchSize = 10;
/**
- * {@link JacksonRocketMQHeaderMapper#addTrustedPackages(String...)}.
+ * Consume max span offset.it has no effect on sequential consumption.
*/
- private Set trustedPackages;
+ private int consumeMaxSpan = 2000;
- // ------------ For Pull Consumer ------------
+ private Push push = new Push();
+ private Pull pull = new Pull();
- private long pullTimeout = 10 * 1000;
+ public String getMessageModel() {
+ return messageModel;
+ }
+
+ public RocketMQConsumerProperties setMessageModel(String messageModel) {
+ this.messageModel = messageModel;
+ return this;
+ }
- private boolean fromStore;
+ public String getAllocateMessageQueueStrategy() {
+ return allocateMessageQueueStrategy;
+ }
- // ------------ For Pull Consumer ------------
+ public void setAllocateMessageQueueStrategy(String allocateMessageQueueStrategy) {
+ this.allocateMessageQueueStrategy = allocateMessageQueueStrategy;
+ }
+
+ public String getSubscription() {
+ return subscription;
+ }
- public String getTags() {
- return tags;
+ public void setSubscription(String subscription) {
+ this.subscription = subscription;
}
- public void setTags(String tags) {
- this.tags = tags;
+ public Push getPush() {
+ return push;
}
- public String getSql() {
- return sql;
+ public void setPush(Push push) {
+ this.push = push;
}
- public void setSql(String sql) {
- this.sql = sql;
+ public long getPullTimeDelayMillsWhenException() {
+ return pullTimeDelayMillsWhenException;
}
- public Boolean getOrderly() {
- return orderly;
+ public RocketMQConsumerProperties setPullTimeDelayMillsWhenException(
+ long pullTimeDelayMillsWhenException) {
+ this.pullTimeDelayMillsWhenException = pullTimeDelayMillsWhenException;
+ return this;
}
- public void setOrderly(Boolean orderly) {
- this.orderly = orderly;
+ public ConsumeFromWhere getConsumeFromWhere() {
+ return consumeFromWhere;
}
- public Boolean getEnabled() {
- return enabled;
+ public RocketMQConsumerProperties setConsumeFromWhere(
+ ConsumeFromWhere consumeFromWhere) {
+ this.consumeFromWhere = consumeFromWhere;
+ return this;
}
- public void setEnabled(Boolean enabled) {
- this.enabled = enabled;
+ public String getConsumeTimestamp() {
+ return consumeTimestamp;
}
- public Boolean getBroadcasting() {
- return broadcasting;
+ public RocketMQConsumerProperties setConsumeTimestamp(String consumeTimestamp) {
+ this.consumeTimestamp = consumeTimestamp;
+ return this;
}
- public void setBroadcasting(Boolean broadcasting) {
- this.broadcasting = broadcasting;
+ public int getPullThresholdForQueue() {
+ return pullThresholdForQueue;
}
- public int getDelayLevelWhenNextConsume() {
- return delayLevelWhenNextConsume;
+ public RocketMQConsumerProperties setPullThresholdForQueue(
+ int pullThresholdForQueue) {
+ this.pullThresholdForQueue = pullThresholdForQueue;
+ return this;
}
- public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
- this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
+ public int getPullThresholdSizeForQueue() {
+ return pullThresholdSizeForQueue;
}
- public long getSuspendCurrentQueueTimeMillis() {
- return suspendCurrentQueueTimeMillis;
+ public RocketMQConsumerProperties setPullThresholdSizeForQueue(
+ int pullThresholdSizeForQueue) {
+ this.pullThresholdSizeForQueue = pullThresholdSizeForQueue;
+ return this;
}
- public void setSuspendCurrentQueueTimeMillis(long suspendCurrentQueueTimeMillis) {
- this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
+ public int getPullBatchSize() {
+ return pullBatchSize;
}
- public long getPullTimeout() {
- return pullTimeout;
+ public RocketMQConsumerProperties setPullBatchSize(int pullBatchSize) {
+ this.pullBatchSize = pullBatchSize;
+ return this;
}
- public void setPullTimeout(long pullTimeout) {
- this.pullTimeout = pullTimeout;
+ public Pull getPull() {
+ return pull;
}
- public boolean isFromStore() {
- return fromStore;
+ public RocketMQConsumerProperties setPull(Pull pull) {
+ this.pull = pull;
+ return this;
}
- public void setFromStore(boolean fromStore) {
- this.fromStore = fromStore;
+ public int getConsumeMaxSpan() {
+ return consumeMaxSpan;
}
- public boolean shouldRequeue() {
- return delayLevelWhenNextConsume != -1;
+ public RocketMQConsumerProperties setConsumeMaxSpan(int consumeMaxSpan) {
+ this.consumeMaxSpan = consumeMaxSpan;
+ return this;
}
- public Set getTrustedPackages() {
- return trustedPackages;
+ public static class Push implements Serializable {
+ private static final long serialVersionUID = -7398468554978817630L;
+
+ /**
+ * if orderly is true, using {@link MessageListenerOrderly} else if orderly if
+ * false, using {@link MessageListenerConcurrently}.
+ */
+ private boolean orderly = false;
+ /**
+ * Suspending pulling time for cases requiring slow pulling like flow-control
+ * scenario. see{@link ConsumeMessageOrderlyService#processConsumeResult}.
+ * see{@link ConsumeOrderlyContext#getSuspendCurrentQueueTimeMillis}.
+ */
+ private int suspendCurrentQueueTimeMillis = 1000;
+
+ /**
+ * https://github.com/alibaba/spring-cloud-alibaba/issues/1866 Max re-consume
+ * times. -1 means 16 times.
+ *
+ * If messages are re-consumed more than {@link #maxReconsumeTimes} before
+ * success, it's be directed to a deletion queue waiting.
+ */
+ private int maxReconsumeTimes;
+
+ /**
+ * for concurrently listener. message consume retry strategy. -1 means dlq(or
+ * discard. see {@link ConsumeMessageConcurrentlyService#processConsumeResult}.
+ * see {@link ConsumeConcurrentlyContext#getDelayLevelWhenNextConsume}.
+ */
+ private int delayLevelWhenNextConsume = 0;
+
+ /**
+ * Flow control threshold on topic level, default value is -1(Unlimited)
+ *
+ * The value of {@code pullThresholdForQueue} will be overwrote and calculated
+ * based on {@code pullThresholdForTopic} if it is't unlimited
+ *
+ * For example, if the value of pullThresholdForTopic is 1000 and 10 message
+ * queues are assigned to this consumer, then pullThresholdForQueue will be set to
+ * 100.
+ */
+ private int pullThresholdForTopic = -1;
+
+ /**
+ * Limit the cached message size on topic level, default value is -1
+ * MiB(Unlimited)
+ *
+ * The value of {@code pullThresholdSizeForQueue} will be overwrote and calculated
+ * based on {@code pullThresholdSizeForTopic} if it is't unlimited
+ *
+ * For example, if the value of pullThresholdSizeForTopic is 1000 MiB and 10
+ * message queues are assigned to this consumer, then pullThresholdSizeForQueue
+ * will be set to 100 MiB
+ */
+ private int pullThresholdSizeForTopic = -1;
+
+ /**
+ * Message pull Interval
+ */
+ private long pullInterval = 0;
+
+ /**
+ * Batch consumption size
+ */
+ private int consumeMessageBatchMaxSize = 1;
+
+ public boolean getOrderly() {
+ return orderly;
+ }
+
+ public void setOrderly(boolean orderly) {
+ this.orderly = orderly;
+ }
+
+ public int getSuspendCurrentQueueTimeMillis() {
+ return suspendCurrentQueueTimeMillis;
+ }
+
+ public void setSuspendCurrentQueueTimeMillis(int suspendCurrentQueueTimeMillis) {
+ this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
+ }
+
+ public int getMaxReconsumeTimes() {
+ return maxReconsumeTimes;
+ }
+
+ public void setMaxReconsumeTimes(int maxReconsumeTimes) {
+ this.maxReconsumeTimes = maxReconsumeTimes;
+ }
+
+ public int getDelayLevelWhenNextConsume() {
+ return delayLevelWhenNextConsume;
+ }
+
+ public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
+ this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
+ }
+
+ public int getPullThresholdForTopic() {
+ return pullThresholdForTopic;
+ }
+
+ public void setPullThresholdForTopic(int pullThresholdForTopic) {
+ this.pullThresholdForTopic = pullThresholdForTopic;
+ }
+
+ public int getPullThresholdSizeForTopic() {
+ return pullThresholdSizeForTopic;
+ }
+
+ public void setPullThresholdSizeForTopic(int pullThresholdSizeForTopic) {
+ this.pullThresholdSizeForTopic = pullThresholdSizeForTopic;
+ }
+
+ public long getPullInterval() {
+ return pullInterval;
+ }
+
+ public void setPullInterval(long pullInterval) {
+ this.pullInterval = pullInterval;
+ }
+
+ public int getConsumeMessageBatchMaxSize() {
+ return consumeMessageBatchMaxSize;
+ }
+
+ public void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) {
+ this.consumeMessageBatchMaxSize = consumeMessageBatchMaxSize;
+ }
}
- public void setTrustedPackages(Set trustedPackages) {
- this.trustedPackages = trustedPackages;
+ public static class Pull implements Serializable {
+ /**
+ * The poll timeout in milliseconds
+ */
+ private long pollTimeoutMillis = 1000 * 5;
+ /**
+ * Pull thread number
+ */
+ private int pullThreadNums = 20;
+
+ /**
+ * Interval time in in milliseconds for checking changes in topic metadata.
+ */
+ private long topicMetadataCheckIntervalMillis = 30 * 1000;
+
+ /**
+ * Long polling mode, the Consumer connection timeout(must greater than
+ * brokerSuspendMaxTimeMillis), it is not recommended to modify
+ */
+ private long consumerTimeoutMillisWhenSuspend = 1000 * 30;
+
+ /**
+ * Ack state handling, including receive, reject, and retry, when a consumption
+ * exception occurs. see {@link }
+ */
+ private String errAcknowledge;
+
+ private long pullThresholdForAll = 1000L;
+
+ public long getPollTimeoutMillis() {
+ return pollTimeoutMillis;
+ }
+
+ public void setPollTimeoutMillis(long pollTimeoutMillis) {
+ this.pollTimeoutMillis = pollTimeoutMillis;
+ }
+
+ public int getPullThreadNums() {
+ return pullThreadNums;
+ }
+
+ public void setPullThreadNums(int pullThreadNums) {
+ this.pullThreadNums = pullThreadNums;
+ }
+
+ public long getTopicMetadataCheckIntervalMillis() {
+ return topicMetadataCheckIntervalMillis;
+ }
+
+ public void setTopicMetadataCheckIntervalMillis(
+ long topicMetadataCheckIntervalMillis) {
+ this.topicMetadataCheckIntervalMillis = topicMetadataCheckIntervalMillis;
+ }
+
+ public long getConsumerTimeoutMillisWhenSuspend() {
+ return consumerTimeoutMillisWhenSuspend;
+ }
+
+ public void setConsumerTimeoutMillisWhenSuspend(
+ long consumerTimeoutMillisWhenSuspend) {
+ this.consumerTimeoutMillisWhenSuspend = consumerTimeoutMillisWhenSuspend;
+ }
+
+ public String getErrAcknowledge() {
+ return errAcknowledge;
+ }
+
+ public void setErrAcknowledge(String errAcknowledge) {
+ this.errAcknowledge = errAcknowledge;
+ }
+
+ public long getPullThresholdForAll() {
+ return pullThresholdForAll;
+ }
+
+ public void setPullThresholdForAll(long pullThresholdForAll) {
+ this.pullThresholdForAll = pullThresholdForAll;
+ }
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java
index 890d22500..5fc34ed08 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013-2018 the original author or authors.
+ * Copyright (C) 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * https://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -21,12 +21,14 @@ import org.springframework.cloud.stream.binder.AbstractExtendedBindingProperties
import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
/**
- * @author Timur Valiev
+ * rocketMQ specific extended binding properties class that extends from
+ * {@link AbstractExtendedBindingProperties}.
+ *
* @author Jim
*/
@ConfigurationProperties("spring.cloud.stream.rocketmq")
public class RocketMQExtendedBindingProperties extends
- AbstractExtendedBindingProperties {
+ AbstractExtendedBindingProperties {
private static final String DEFAULTS_PREFIX = "spring.cloud.stream.rocketmq.default";
@@ -37,7 +39,7 @@ public class RocketMQExtendedBindingProperties extends
@Override
public Class extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
- return RocketMQBindingProperties.class;
+ return RocketMQSpecificPropertiesProvider.class;
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java
index ab2a92a3a..8f73cf93f 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright 2013-2018 the original author or authors.
+ * Copyright (C) 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * https://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -16,55 +16,39 @@
package com.alibaba.cloud.stream.binder.rocketmq.properties;
-import org.apache.rocketmq.client.producer.DefaultMQProducer;
-
/**
- * @author Timur Valiev
+ * Extended producer properties for RocketMQ binder.
+ *
* @author Jim
*/
-public class RocketMQProducerProperties {
-
- private Boolean enabled = true;
+public class RocketMQProducerProperties extends RocketMQCommonProperties {
/**
- * Name of producer.
+ * Timeout for sending messages.
*/
- private String group;
-
- /**
- * Maximum allowed message size in bytes {@link DefaultMQProducer#maxMessageSize}.
- */
- private Integer maxMessageSize = 1024 * 1024 * 4;
-
- private Boolean transactional = false;
-
- private Boolean sync = false;
-
- private Boolean vipChannelEnabled = true;
-
- /**
- * Millis of send message timeout.
- */
- private int sendMessageTimeout = 3000;
+ private int sendMsgTimeout = 3000;
/**
* Compress message body threshold, namely, message body larger than 4k will be
* compressed on default.
*/
- private int compressMessageBodyThreshold = 1024 * 4;
+ private int compressMsgBodyThreshold = 1024 * 4;
/**
* Maximum number of retry to perform internally before claiming sending failure in
- * synchronous mode. This may potentially cause message duplication which is up to
- * application developers to resolve.
+ * synchronous mode.
+ *
+ *
+ * This may potentially cause message duplication which is up to application
+ * developers to resolve.
*/
private int retryTimesWhenSendFailed = 2;
/**
- *
* Maximum number of retry to perform internally before claiming sending failure in
* asynchronous mode.
*
+ *
* This may potentially cause message duplication which is up to application
* developers to resolve.
*/
@@ -73,94 +57,165 @@ public class RocketMQProducerProperties {
/**
* Indicate whether to retry another broker on sending failure internally.
*/
- private boolean retryNextServer = false;
+ private boolean retryAnotherBroker = false;
- public String getGroup() {
- return group;
+ /**
+ * Maximum allowed message size in bytes.
+ */
+ private int maxMessageSize = 1024 * 1024 * 4;
+
+ private String producerType = ProducerType.Normal.name();
+
+ private String sendType = SendType.Sync.name();
+
+ private String sendCallBack;
+
+ private String transactionListener;
+
+ private String messageQueueSelector;
+
+ private String errorMessageStrategy;
+
+ private String sendFailureChannel;
+
+ private String checkForbiddenHook;
+
+ private String sendMessageHook;
+
+ public int getSendMsgTimeout() {
+ return sendMsgTimeout;
+ }
+
+ public void setSendMsgTimeout(int sendMsgTimeout) {
+ this.sendMsgTimeout = sendMsgTimeout;
}
- public void setGroup(String group) {
- this.group = group;
+ public int getCompressMsgBodyThreshold() {
+ return compressMsgBodyThreshold;
}
- public Boolean getEnabled() {
- return enabled;
+ public void setCompressMsgBodyThreshold(int compressMsgBodyThreshold) {
+ this.compressMsgBodyThreshold = compressMsgBodyThreshold;
}
- public void setEnabled(Boolean enabled) {
- this.enabled = enabled;
+ public int getRetryTimesWhenSendFailed() {
+ return retryTimesWhenSendFailed;
}
- public Integer getMaxMessageSize() {
+ public void setRetryTimesWhenSendFailed(int retryTimesWhenSendFailed) {
+ this.retryTimesWhenSendFailed = retryTimesWhenSendFailed;
+ }
+
+ public int getRetryTimesWhenSendAsyncFailed() {
+ return retryTimesWhenSendAsyncFailed;
+ }
+
+ public void setRetryTimesWhenSendAsyncFailed(int retryTimesWhenSendAsyncFailed) {
+ this.retryTimesWhenSendAsyncFailed = retryTimesWhenSendAsyncFailed;
+ }
+
+ public boolean getRetryAnotherBroker() {
+ return retryAnotherBroker;
+ }
+
+ public void setRetryAnotherBroker(boolean retryAnotherBroker) {
+ this.retryAnotherBroker = retryAnotherBroker;
+ }
+
+ public int getMaxMessageSize() {
return maxMessageSize;
}
- public void setMaxMessageSize(Integer maxMessageSize) {
+ public void setMaxMessageSize(int maxMessageSize) {
this.maxMessageSize = maxMessageSize;
}
- public Boolean getTransactional() {
- return transactional;
+ public String getProducerType() {
+ return producerType;
}
- public void setTransactional(Boolean transactional) {
- this.transactional = transactional;
+ public void setProducerType(String producerType) {
+ this.producerType = producerType;
}
- public Boolean getSync() {
- return sync;
+ public String getSendType() {
+ return sendType;
}
- public void setSync(Boolean sync) {
- this.sync = sync;
+ public void setSendType(String sendType) {
+ this.sendType = sendType;
}
- public Boolean getVipChannelEnabled() {
- return vipChannelEnabled;
+ public String getSendCallBack() {
+ return sendCallBack;
}
- public void setVipChannelEnabled(Boolean vipChannelEnabled) {
- this.vipChannelEnabled = vipChannelEnabled;
+ public void setSendCallBack(String sendCallBack) {
+ this.sendCallBack = sendCallBack;
}
- public int getSendMessageTimeout() {
- return sendMessageTimeout;
+ public String getTransactionListener() {
+ return transactionListener;
}
- public void setSendMessageTimeout(int sendMessageTimeout) {
- this.sendMessageTimeout = sendMessageTimeout;
+ public void setTransactionListener(String transactionListener) {
+ this.transactionListener = transactionListener;
}
- public int getCompressMessageBodyThreshold() {
- return compressMessageBodyThreshold;
+ public String getMessageQueueSelector() {
+ return messageQueueSelector;
}
- public void setCompressMessageBodyThreshold(int compressMessageBodyThreshold) {
- this.compressMessageBodyThreshold = compressMessageBodyThreshold;
+ public void setMessageQueueSelector(String messageQueueSelector) {
+ this.messageQueueSelector = messageQueueSelector;
}
- public int getRetryTimesWhenSendFailed() {
- return retryTimesWhenSendFailed;
+ public String getErrorMessageStrategy() {
+ return errorMessageStrategy;
}
- public void setRetryTimesWhenSendFailed(int retryTimesWhenSendFailed) {
- this.retryTimesWhenSendFailed = retryTimesWhenSendFailed;
+ public void setErrorMessageStrategy(String errorMessageStrategy) {
+ this.errorMessageStrategy = errorMessageStrategy;
}
- public int getRetryTimesWhenSendAsyncFailed() {
- return retryTimesWhenSendAsyncFailed;
+ public String getSendFailureChannel() {
+ return sendFailureChannel;
}
- public void setRetryTimesWhenSendAsyncFailed(int retryTimesWhenSendAsyncFailed) {
- this.retryTimesWhenSendAsyncFailed = retryTimesWhenSendAsyncFailed;
+ public void setSendFailureChannel(String sendFailureChannel) {
+ this.sendFailureChannel = sendFailureChannel;
+ }
+
+ public String getCheckForbiddenHook() {
+ return checkForbiddenHook;
}
- public boolean isRetryNextServer() {
- return retryNextServer;
+ public void setCheckForbiddenHook(String checkForbiddenHook) {
+ this.checkForbiddenHook = checkForbiddenHook;
}
- public void setRetryNextServer(boolean retryNextServer) {
- this.retryNextServer = retryNextServer;
+ public String getSendMessageHook() {
+ return sendMessageHook;
+ }
+
+ public void setSendMessageHook(String sendMessageHook) {
+ this.sendMessageHook = sendMessageHook;
+ }
+
+ public enum ProducerType {
+ Normal, Trans;
+
+ public boolean equalsName(String name) {
+ return this.name().equalsIgnoreCase(name);
+ }
+ }
+
+ public enum SendType {
+ OneWay, Async, Sync,;
+
+ public boolean equalsName(String name) {
+ return this.name().equalsIgnoreCase(name);
+ }
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/provisioning/selector/PartitionMessageQueueSelector.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/provisioning/selector/PartitionMessageQueueSelector.java
index 694dcdc96..0580fe859 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/provisioning/selector/PartitionMessageQueueSelector.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/provisioning/selector/PartitionMessageQueueSelector.java
@@ -36,7 +36,7 @@ public class PartitionMessageQueueSelector implements MessageQueueSelector {
@Override
public MessageQueue select(List mqs, Message msg, Object arg) {
- Integer partition = 0;
+ int partition = 0;
try {
partition = Math.abs(
Integer.parseInt(msg.getProperty(BinderHeaders.PARTITION_HEADER)));
From a6e01c998417669fcd4d4b053db454d37725fe7a Mon Sep 17 00:00:00 2001
From: zkzlx
Date: Mon, 1 Feb 2021 11:24:25 +0800
Subject: [PATCH 07/99] Code refactoring and some new feature support
---
...gHandlerMappingsProviderConfiguration.java | 45 +++
.../RocketMQBinderAutoConfiguration.java | 81 +++++
.../rocketmq/contants/RocketMQConst.java | 90 ++++++
.../convert/RocketMQMessageConverter.java | 84 +++++
.../custom/RocketMQBeanContainerCache.java | 75 +++++
.../RocketMQConfigBeanPostProcessor.java | 43 +++
.../extend/ErrorAcknowledgeHandler.java | 35 +++
.../inbound/RocketMQConsumerFactory.java | 156 ++++++++++
.../RocketMQInboundChannelAdapter.java | 228 ++++++++++++++
.../pull/DefaultErrorAcknowledgeHandler.java | 43 +++
.../inbound/pull/RocketMQAckCallback.java | 112 +++++++
.../inbound/pull/RocketMQMessageSource.java | 161 ++++++++++
.../outbound/RocketMQProduceFactory.java | 131 ++++++++
.../RocketMQProducerMessageHandler.java | 286 ++++++++++++++++++
.../properties/RocketMQCommonProperties.java | 201 ++++++++++++
.../RocketMQSpecificPropertiesProvider.java | 66 ++++
.../RocketMQMessageConverterSupport.java | 185 +++++++++++
.../binder/rocketmq/utils/RocketMQUtils.java | 98 ++++++
18 files changed, 2120 insertions(+)
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
new file mode 100644
index 000000000..eb6e6ce52
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
+import org.springframework.cloud.stream.config.BindingHandlerAdvise.MappingsProvider;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ExtendedBindingHandlerMappingsProviderConfiguration {
+
+ @Bean
+ public MappingsProvider rocketExtendedPropertiesDefaultMappingsProvider() {
+ return () -> {
+ Map mappings = new HashMap<>();
+ mappings.put(
+ ConfigurationPropertyName.of("spring.cloud.stream.rocketmq.bindings"),
+ ConfigurationPropertyName.of("spring.cloud.stream.rocketmq.default"));
+ mappings.put(
+ ConfigurationPropertyName.of("spring.cloud.stream.rocketmq.streams"),
+ ConfigurationPropertyName
+ .of("spring.cloud.stream.rocketmq.streams.default"));
+ return mappings;
+ };
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
new file mode 100644
index 000000000..abcb9b961
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate;
+
+import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
+import com.alibaba.cloud.stream.binder.rocketmq.actuator.RocketMQBinderHealthIndicator;
+import com.alibaba.cloud.stream.binder.rocketmq.convert.RocketMQMessageConverter;
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQConfigBeanPostProcessor;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.provisioning.RocketMQTopicProvisioner;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.converter.CompositeMessageConverter;
+
+/**
+ * issue:https://github.com/alibaba/spring-cloud-alibaba/issues/1681
+ * @author Timur Valiev
+ * @author Jim
+ */
+@Configuration(proxyBeanMethods = false)
+@EnableConfigurationProperties({ RocketMQExtendedBindingProperties.class,
+ RocketMQBinderConfigurationProperties.class })
+public class RocketMQBinderAutoConfiguration {
+
+ @Autowired
+ private RocketMQExtendedBindingProperties extendedBindingProperties;
+ @Autowired
+ private RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
+
+ @Bean
+ public RocketMQConfigBeanPostProcessor rocketMQConfigBeanPostProcessor() {
+ return new RocketMQConfigBeanPostProcessor();
+ }
+
+ @Bean(RocketMQMessageConverter.DEFAULT_NAME)
+ @ConditionalOnMissingBean(name = { RocketMQMessageConverter.DEFAULT_NAME })
+ public CompositeMessageConverter rocketMQMessageConverter() {
+ return new RocketMQMessageConverter().getMessageConverter();
+ }
+
+ @Bean
+ @ConditionalOnEnabledHealthIndicator("rocketmq")
+ @ConditionalOnClass(name = "org.springframework.boot.actuate.health.HealthIndicator")
+ public RocketMQBinderHealthIndicator rocketMQBinderHealthIndicator() {
+ return new RocketMQBinderHealthIndicator();
+ }
+
+ @Bean
+ public RocketMQTopicProvisioner rocketMQTopicProvisioner() {
+ return new RocketMQTopicProvisioner();
+ }
+
+ @Bean
+ public RocketMQMessageChannelBinder rocketMQMessageChannelBinder(
+ RocketMQTopicProvisioner provisioningProvider) {
+ return new RocketMQMessageChannelBinder(rocketBinderConfigurationProperties,
+ extendedBindingProperties, provisioningProvider);
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
new file mode 100644
index 000000000..e83a6a172
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.contants;
+
+import org.apache.rocketmq.common.message.MessageConst;
+
+import static org.apache.rocketmq.spring.support.RocketMQHeaders.PREFIX;
+
+/**
+ * @author zkzlx
+ */
+public class RocketMQConst extends MessageConst {
+
+ /**
+ * Header key for RocketMQ Transactional Args.
+ */
+ public static final String ROCKET_TRANSACTIONAL_ARG = "TRANSACTIONAL_ARG";
+
+ /**
+ * Default NameServer value.
+ */
+ public static final String DEFAULT_NAME_SERVER = "127.0.0.1:9876";
+
+ /**
+ * Default group for SCS RocketMQ Binder.
+ */
+ public static final String DEFAULT_GROUP = PREFIX + "binder_default_group_name";
+
+ /**
+ * RocketMQ re-consume times.
+ */
+ public static final String ROCKETMQ_RECONSUME_TIMES = PREFIX + "RECONSUME_TIMES";
+
+ public static final String USER_TRANSACTIONAL_ARGS = "TRANSACTIONAL_ARGS";
+
+ /**
+ * It is mainly provided for conversion between rocketMq-message and Spring-message,
+ * and parameters are passed through HEADERS.
+ */
+ public static class Headers {
+ public static final String KEYS = MessageConst.PROPERTY_KEYS;
+ public static final String TAGS = MessageConst.PROPERTY_TAGS;
+ public static final String TOPIC = "MQ_TOPIC";
+ /**
+ * The ID of the message.
+ */
+ public static final String MESSAGE_ID = "MQ_MESSAGE_ID";
+ /**
+ * The timestamp that the message producer invokes the message sending API.
+ */
+ public static final String BORN_TIMESTAMP = "MQ_BORN_TIMESTAMP";
+ /**
+ * The IP and port number of the message producer
+ */
+ public static final String BORN_HOST = "MQ_BORN_HOST";
+
+ /**
+ * Message flag, MQ is not processed and is available for use by applications.
+ */
+ public static final String FLAG = "MQ_FLAG";
+ /**
+ * Message consumption queue ID
+ */
+ public static final String QUEUE_ID = "MQ_QUEUE_ID";
+ /**
+ * Message system Flag, such as whether or not to compress, whether or not to
+ * transactional messages.
+ */
+ public static final String SYS_FLAG = "MQ_SYS_FLAG";
+ /**
+ * The transaction ID of the transaction message.
+ */
+ public static final String TRANSACTION_ID = "MQ_TRANSACTION_ID";
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java
new file mode 100644
index 000000000..58f17c6ef
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.convert;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.springframework.messaging.converter.ByteArrayMessageConverter;
+import org.springframework.messaging.converter.CompositeMessageConverter;
+import org.springframework.messaging.converter.MappingJackson2MessageConverter;
+import org.springframework.messaging.converter.MessageConverter;
+import org.springframework.messaging.converter.StringMessageConverter;
+import org.springframework.util.ClassUtils;
+
+/**
+ * The default message converter of rocketMq,its bean name is {@link #DEFAULT_NAME}
+ * @author zkzlx
+ */
+public class RocketMQMessageConverter {
+
+ public static final String DEFAULT_NAME = "rocketMQMessageConverter";
+
+ private static final boolean JACKSON_PRESENT;
+ private static final boolean FASTJSON_PRESENT;
+
+ static {
+ ClassLoader classLoader = RocketMQMessageConverter.class.getClassLoader();
+ JACKSON_PRESENT = ClassUtils
+ .isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader)
+ && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
+ classLoader);
+ FASTJSON_PRESENT = ClassUtils.isPresent("com.alibaba.fastjson.JSON", classLoader)
+ && ClassUtils.isPresent(
+ "com.alibaba.fastjson.support.config.FastJsonConfig",
+ classLoader);
+ }
+
+ private CompositeMessageConverter messageConverter;
+
+ public RocketMQMessageConverter() {
+ List messageConverters = new ArrayList<>();
+ ByteArrayMessageConverter byteArrayMessageConverter = new ByteArrayMessageConverter();
+ byteArrayMessageConverter.setContentTypeResolver(null);
+ messageConverters.add(byteArrayMessageConverter);
+ messageConverters.add(new StringMessageConverter());
+ if (JACKSON_PRESENT) {
+ messageConverters.add(new MappingJackson2MessageConverter());
+ }
+ if (FASTJSON_PRESENT) {
+ try {
+ messageConverters.add((MessageConverter) ClassUtils.forName(
+ "com.alibaba.fastjson.support.spring.messaging.MappingFastJsonMessageConverter",
+ ClassUtils.getDefaultClassLoader()).newInstance());
+ }
+ catch (ClassNotFoundException | IllegalAccessException
+ | InstantiationException ignored) {
+ // ignore this exception
+ }
+ }
+ messageConverter = new CompositeMessageConverter(messageConverters);
+ }
+
+ public CompositeMessageConverter getMessageConverter() {
+ return messageConverter;
+ }
+
+ public void setMessageConverter(CompositeMessageConverter messageConverter) {
+ this.messageConverter = messageConverter;
+ }
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java
new file mode 100644
index 000000000..9afc94821
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.custom;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import com.alibaba.cloud.stream.binder.rocketmq.extend.ErrorAcknowledgeHandler;
+import org.apache.rocketmq.client.consumer.AllocateMessageQueueStrategy;
+import org.apache.rocketmq.client.consumer.listener.MessageListener;
+import org.apache.rocketmq.client.hook.CheckForbiddenHook;
+import org.apache.rocketmq.client.hook.SendMessageHook;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.client.producer.TransactionListener;
+
+import org.springframework.messaging.converter.CompositeMessageConverter;
+import org.springframework.util.StringUtils;
+
+/**
+ * Gets the beans configured in the configuration file
+ *
+ * @author junboXiang
+ */
+public final class RocketMQBeanContainerCache {
+
+ private static final Class>[] CLASSES = new Class[] {
+ CompositeMessageConverter.class, AllocateMessageQueueStrategy.class,
+ MessageQueueSelector.class, MessageListener.class, TransactionListener.class,
+ SendCallback.class, CheckForbiddenHook.class, SendMessageHook.class,
+ ErrorAcknowledgeHandler.class };
+
+ private static final Map BEANS_CACHE = new ConcurrentHashMap<>();
+
+ static void putBean(String beanName, Object beanObj) {
+ BEANS_CACHE.put(beanName, beanObj);
+ }
+
+ static Class>[] getClassAry() {
+ return CLASSES;
+ }
+
+ public static T getBean(String beanName, Class clazz) {
+ return getBean(beanName, clazz, null);
+ }
+
+ public static T getBean(String beanName, Class clazz, T defaultObj) {
+ if (StringUtils.isEmpty(beanName)) {
+ return defaultObj;
+ }
+ Object obj = BEANS_CACHE.get(beanName);
+ if (null == obj) {
+ return defaultObj;
+ }
+ if (clazz.isAssignableFrom(obj.getClass())) {
+ return (T) obj;
+ }
+ return defaultObj;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java
new file mode 100644
index 000000000..30bd64328
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.custom;
+
+import java.util.stream.Stream;
+
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+
+/**
+ * find RocketMQ bean by annotations
+ *
+ * @author junboXiang
+ *
+ */
+public class RocketMQConfigBeanPostProcessor implements BeanPostProcessor {
+
+ @Override
+ public Object postProcessAfterInitialization(Object bean, String beanName)
+ throws BeansException {
+ Stream.of(RocketMQBeanContainerCache.getClassAry()).forEach(clazz -> {
+ if (clazz.isAssignableFrom(bean.getClass())) {
+ RocketMQBeanContainerCache.putBean(beanName, bean);
+ }
+ });
+ return bean;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java
new file mode 100644
index 000000000..fcf6de804
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.extend;
+
+import org.springframework.integration.acks.AcknowledgmentCallback.Status;
+import org.springframework.messaging.Message;
+
+/**
+ * @author zkzlx
+ */
+public interface ErrorAcknowledgeHandler {
+
+ /**
+ * Ack state handling, including receive, reject, and retry, when a consumption
+ * exception occurs.
+ * @param message
+ * @return see {@link Status}
+ */
+ Status handler(Message> message);
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
new file mode 100644
index 000000000..876249581
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.inbound;
+
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQBeanContainerCache;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.utils.RocketMQUtils;
+import org.apache.rocketmq.acl.common.AclClientRPCHook;
+import org.apache.rocketmq.acl.common.SessionCredentials;
+import org.apache.rocketmq.client.consumer.AllocateMessageQueueStrategy;
+import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Extended function related to producer . eg:initial
+ *
+ * @author zkzlx
+ */
+public final class RocketMQConsumerFactory {
+
+ private final static Logger log = LoggerFactory
+ .getLogger(RocketMQConsumerFactory.class);
+
+ public static DefaultMQPushConsumer initPushConsumer(
+ ExtendedConsumerProperties extendedConsumerProperties) {
+ RocketMQConsumerProperties consumerProperties = extendedConsumerProperties
+ .getExtension();
+ Assert.notNull(consumerProperties.getGroup(),
+ "Property 'group' is required - consumerGroup");
+ Assert.notNull(consumerProperties.getNameServer(),
+ "Property 'nameServer' is required");
+ AllocateMessageQueueStrategy allocateMessageQueueStrategy = RocketMQBeanContainerCache
+ .getBean(consumerProperties.getAllocateMessageQueueStrategy(),
+ AllocateMessageQueueStrategy.class,
+ new AllocateMessageQueueAveragely());
+ RPCHook rpcHook = null;
+ if (!StringUtils.isEmpty(consumerProperties.getAccessKey())
+ && !StringUtils.isEmpty(consumerProperties.getSecretKey())) {
+ rpcHook = new AclClientRPCHook(
+ new SessionCredentials(consumerProperties.getAccessKey(),
+ consumerProperties.getSecretKey()));
+ }
+ DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(
+ consumerProperties.getGroup(), rpcHook, allocateMessageQueueStrategy,
+ consumerProperties.getEnableMsgTrace(),
+ consumerProperties.getCustomizedTraceTopic());
+ consumer.setVipChannelEnabled(
+ null == rpcHook && consumerProperties.getVipChannelEnabled());
+ consumer.setInstanceName(
+ RocketMQUtils.getInstanceName(rpcHook, consumerProperties.getGroup()));
+ consumer.setNamespace(consumerProperties.getNamespace());
+ consumer.setNamesrvAddr(consumerProperties.getNameServer());
+ consumer.setMessageModel(getMessageModel(consumerProperties.getMessageModel()));
+ consumer.setUseTLS(consumerProperties.getUseTLS());
+ consumer.setPullTimeDelayMillsWhenException(
+ consumerProperties.getPullTimeDelayMillsWhenException());
+ consumer.setPullBatchSize(consumerProperties.getPullBatchSize());
+ consumer.setConsumeFromWhere(consumerProperties.getConsumeFromWhere());
+ consumer.setHeartbeatBrokerInterval(
+ consumerProperties.getHeartbeatBrokerInterval());
+ consumer.setPersistConsumerOffsetInterval(
+ consumerProperties.getPersistConsumerOffsetInterval());
+ consumer.setPullInterval(consumerProperties.getPush().getPullInterval());
+ consumer.setConsumeThreadMin(extendedConsumerProperties.getConcurrency());
+ consumer.setConsumeThreadMax(extendedConsumerProperties.getConcurrency());
+ return consumer;
+ }
+
+ /**
+ * todo Compatible with versions less than 4.6 ?
+ * @return
+ */
+ public static DefaultLitePullConsumer initPullConsumer(
+ ExtendedConsumerProperties extendedConsumerProperties) {
+ RocketMQConsumerProperties consumerProperties = extendedConsumerProperties
+ .getExtension();
+ Assert.notNull(consumerProperties.getGroup(),
+ "Property 'group' is required - consumerGroup");
+ Assert.notNull(consumerProperties.getNameServer(),
+ "Property 'nameServer' is required");
+ AllocateMessageQueueStrategy allocateMessageQueueStrategy = RocketMQBeanContainerCache
+ .getBean(consumerProperties.getAllocateMessageQueueStrategy(),
+ AllocateMessageQueueStrategy.class,
+ new AllocateMessageQueueAveragely());
+
+ RPCHook rpcHook = null;
+ if (!StringUtils.isEmpty(consumerProperties.getAccessKey())
+ && !StringUtils.isEmpty(consumerProperties.getSecretKey())) {
+ rpcHook = new AclClientRPCHook(
+ new SessionCredentials(consumerProperties.getAccessKey(),
+ consumerProperties.getSecretKey()));
+ }
+
+ DefaultLitePullConsumer consumer = new DefaultLitePullConsumer(
+ consumerProperties.getNamespace(), consumerProperties.getGroup(),
+ rpcHook);
+ consumer.setVipChannelEnabled(
+ null == rpcHook && consumerProperties.getVipChannelEnabled());
+ consumer.setInstanceName(
+ RocketMQUtils.getInstanceName(rpcHook, consumerProperties.getGroup()));
+ consumer.setAllocateMessageQueueStrategy(allocateMessageQueueStrategy);
+ consumer.setNamesrvAddr(consumerProperties.getNameServer());
+ consumer.setMessageModel(getMessageModel(consumerProperties.getMessageModel()));
+ consumer.setUseTLS(consumerProperties.getUseTLS());
+ consumer.setPullTimeDelayMillsWhenException(
+ consumerProperties.getPullTimeDelayMillsWhenException());
+ consumer.setConsumerTimeoutMillisWhenSuspend(
+ consumerProperties.getPull().getConsumerTimeoutMillisWhenSuspend());
+ consumer.setPullBatchSize(consumerProperties.getPullBatchSize());
+ consumer.setConsumeFromWhere(consumerProperties.getConsumeFromWhere());
+ consumer.setHeartbeatBrokerInterval(
+ consumerProperties.getHeartbeatBrokerInterval());
+ consumer.setPersistConsumerOffsetInterval(
+ consumerProperties.getPersistConsumerOffsetInterval());
+ consumer.setPollTimeoutMillis(
+ consumerProperties.getPull().getPollTimeoutMillis());
+ consumer.setPullThreadNums(extendedConsumerProperties.getConcurrency());
+ // The internal queues are cached by a maximum of 1000
+ consumer.setPullThresholdForAll(extendedConsumerProperties.getExtension()
+ .getPull().getPullThresholdForAll());
+ return consumer;
+ }
+
+ private static MessageModel getMessageModel(String messageModel) {
+ for (MessageModel model : MessageModel.values()) {
+ if (model.getModeCN().equalsIgnoreCase(messageModel)) {
+ return model;
+ }
+ }
+ return MessageModel.CLUSTERING;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java
new file mode 100644
index 000000000..d0aec5523
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.inbound;
+
+import java.util.List;
+import java.util.function.Supplier;
+
+import com.alibaba.cloud.stream.binder.rocketmq.metrics.Instrumentation;
+import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQMessageConverterSupport;
+import com.alibaba.cloud.stream.binder.rocketmq.utils.RocketMQUtils;
+import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
+import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
+import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
+import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
+import org.springframework.integration.context.OrderlyShutdownCapable;
+import org.springframework.integration.endpoint.MessageProducerSupport;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessagingException;
+import org.springframework.retry.RecoveryCallback;
+import org.springframework.retry.RetryCallback;
+import org.springframework.retry.RetryContext;
+import org.springframework.retry.RetryListener;
+import org.springframework.retry.support.RetryTemplate;
+import org.springframework.util.Assert;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * TODO Describe what it does
+ * @author Jim
+ */
+public class RocketMQInboundChannelAdapter extends MessageProducerSupport
+ implements OrderlyShutdownCapable {
+
+ private static final Logger log = LoggerFactory
+ .getLogger(RocketMQInboundChannelAdapter.class);
+
+ private RetryTemplate retryTemplate;
+ private RecoveryCallback recoveryCallback;
+ private DefaultMQPushConsumer pushConsumer;
+
+ private final String topic;
+ private final ExtendedConsumerProperties extendedConsumerProperties;
+
+ public RocketMQInboundChannelAdapter(String topic,
+ ExtendedConsumerProperties extendedConsumerProperties) {
+ this.topic = topic;
+ this.extendedConsumerProperties = extendedConsumerProperties;
+ }
+
+ @Override
+ protected void onInit() {
+ if (extendedConsumerProperties.getExtension() == null
+ || !extendedConsumerProperties.getExtension().getEnabled()) {
+ return;
+ }
+ Instrumentation instrumentation = new Instrumentation(topic, this);
+ try {
+ super.onInit();
+ if (this.retryTemplate != null) {
+ Assert.state(getErrorChannel() == null,
+ "Cannot have an 'errorChannel' property when a 'RetryTemplate' is "
+ + "provided; use an 'ErrorMessageSendingRecoverer' in the 'recoveryCallback' property to "
+ + "send an error message when retries are exhausted");
+ this.retryTemplate.registerListener(new RetryListener() {
+ @Override
+ public boolean open(RetryContext context,
+ RetryCallback callback) {
+ return true;
+ }
+
+ @Override
+ public void close(RetryContext context,
+ RetryCallback callback, Throwable throwable) {
+ }
+
+ @Override
+ public void onError(RetryContext context,
+ RetryCallback callback, Throwable throwable) {
+ }
+ });
+ }
+ pushConsumer = RocketMQConsumerFactory
+ .initPushConsumer(extendedConsumerProperties);
+ // prepare register consumer message listener,the next step is to be
+ // compatible with a custom MessageListener.
+ if (extendedConsumerProperties.getExtension().getPush().getOrderly()) {
+ pushConsumer.registerMessageListener((MessageListenerOrderly) (msgs,
+ context) -> RocketMQInboundChannelAdapter.this
+ .consumeMessage(msgs, () -> {
+ context.setSuspendCurrentQueueTimeMillis(
+ extendedConsumerProperties.getExtension()
+ .getPush()
+ .getSuspendCurrentQueueTimeMillis());
+ return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
+ }, () -> ConsumeOrderlyStatus.SUCCESS));
+ }
+ else {
+ pushConsumer.registerMessageListener((MessageListenerConcurrently) (msgs,
+ context) -> RocketMQInboundChannelAdapter.this
+ .consumeMessage(msgs, () -> {
+ context.setDelayLevelWhenNextConsume(
+ extendedConsumerProperties.getExtension()
+ .getPush()
+ .getDelayLevelWhenNextConsume());
+ return ConsumeConcurrentlyStatus.RECONSUME_LATER;
+ }, () -> ConsumeConcurrentlyStatus.CONSUME_SUCCESS));
+ }
+ instrumentation.markStartedSuccessfully();
+ }
+ catch (Exception e) {
+ instrumentation.markStartFailed(e);
+ log.error("DefaultMQPushConsumer init failed, Caused by " + e.getMessage());
+ throw new MessagingException(MessageBuilder.withPayload(
+ "DefaultMQPushConsumer init failed, Caused by " + e.getMessage())
+ .build(), e);
+ }
+ finally {
+ InstrumentationManager.addHealthInstrumentation(instrumentation);
+ }
+ }
+
+ /**
+ * The actual execution of a user-defined input consumption service method.
+ * @param messageExtList rocket mq message list
+ * @param failSupplier {@link ConsumeConcurrentlyStatus} or
+ * {@link ConsumeOrderlyStatus}
+ * @param sucSupplier {@link ConsumeConcurrentlyStatus} or
+ * {@link ConsumeOrderlyStatus}
+ * @param
+ * @return
+ */
+ private R consumeMessage(List messageExtList,
+ Supplier failSupplier, Supplier sucSupplier) {
+ if (CollectionUtils.isEmpty(messageExtList)) {
+ throw new MessagingException(
+ "DefaultMQPushConsumer consuming failed, Caused by messageExtList is empty");
+ }
+ for (MessageExt messageExt : messageExtList) {
+ try {
+ Message> message = RocketMQMessageConverterSupport
+ .convertMessage2Spring(messageExt);
+ if (this.retryTemplate != null) {
+ this.retryTemplate.execute(context -> {
+ this.sendMessage(message);
+ return message;
+ }, this.recoveryCallback);
+ }
+ else {
+ this.sendMessage(message);
+ }
+ }
+ catch (Exception e) {
+ log.warn("consume message failed. messageExt:{}", messageExt, e);
+ return failSupplier.get();
+ }
+ }
+ return sucSupplier.get();
+ }
+
+ @Override
+ protected void doStart() {
+ if (extendedConsumerProperties.getExtension() == null
+ || !extendedConsumerProperties.getExtension().getEnabled()) {
+ return;
+ }
+ try {
+ pushConsumer.subscribe(topic, RocketMQUtils.getMessageSelector(
+ extendedConsumerProperties.getExtension().getSubscription()));
+ pushConsumer.start();
+ }
+ catch (Exception e) {
+ log.error("DefaultMQPushConsumer init failed, Caused by " + e.getMessage());
+ throw new MessagingException(MessageBuilder.withPayload(
+ "DefaultMQPushConsumer init failed, Caused by " + e.getMessage())
+ .build(), e);
+ }
+ }
+
+ @Override
+ protected void doStop() {
+ if (pushConsumer != null) {
+ pushConsumer.shutdown();
+ }
+ }
+
+ public void setRetryTemplate(RetryTemplate retryTemplate) {
+ this.retryTemplate = retryTemplate;
+ }
+
+ public void setRecoveryCallback(RecoveryCallback recoveryCallback) {
+ this.recoveryCallback = recoveryCallback;
+ }
+
+ @Override
+ public int beforeShutdown() {
+ this.stop();
+ return 0;
+ }
+
+ @Override
+ public int afterShutdown() {
+ return 0;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java
new file mode 100644
index 000000000..3296a128e
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.pull;
+
+import com.alibaba.cloud.stream.binder.rocketmq.extend.ErrorAcknowledgeHandler;
+
+import org.springframework.integration.acks.AcknowledgmentCallback.Status;
+import org.springframework.messaging.Message;
+
+/**
+ * By default, if consumption fails, the corresponding MessageQueue will always be
+ * retried, that is, the consumption of other messages in the MessageQueue will be
+ * blocked.
+ *
+ * @author zkzlx
+ */
+public class DefaultErrorAcknowledgeHandler implements ErrorAcknowledgeHandler {
+ /**
+ * Ack state handling, including receive, reject, and retry, when a consumption
+ * exception occurs.
+ *
+ * @param message
+ * @return see {@link Status}
+ */
+ @Override
+ public Status handler(Message> message) {
+ return Status.REQUEUE;
+ }
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java
new file mode 100644
index 000000000..f617dd097
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.pull;
+
+import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.consumer.AssignedMessageQueue;
+import org.apache.rocketmq.client.impl.consumer.ProcessQueue;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.common.protocol.heartbeat.MessageModel;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.integration.acks.AcknowledgmentCallback;
+import org.springframework.util.Assert;
+
+/**
+ * A pollable {@link org.springframework.integration.core.MessageSource} for RocketMQ.
+ * @author zkzlx
+ */
+public class RocketMQAckCallback implements AcknowledgmentCallback {
+ private final static Logger log = LoggerFactory.getLogger(RocketMQAckCallback.class);
+
+ private boolean acknowledged;
+ private boolean autoAckEnabled = true;
+ private MessageExt messageExt;
+ private AssignedMessageQueue assignedMessageQueue;
+ private DefaultLitePullConsumer consumer;
+ private final MessageQueue messageQueue;
+
+ public RocketMQAckCallback(DefaultLitePullConsumer consumer,
+ AssignedMessageQueue assignedMessageQueue, MessageQueue messageQueue,
+ MessageExt messageExt) {
+ this.messageExt = messageExt;
+ this.consumer = consumer;
+ this.assignedMessageQueue = assignedMessageQueue;
+ this.messageQueue = messageQueue;
+ }
+
+ @Override
+ public boolean isAcknowledged() {
+ return this.acknowledged;
+ }
+
+ @Override
+ public void noAutoAck() {
+ this.autoAckEnabled = false;
+ }
+
+ @Override
+ public boolean isAutoAck() {
+ return this.autoAckEnabled;
+ }
+
+ @Override
+ public void acknowledge(Status status) {
+ Assert.notNull(status, "'status' cannot be null");
+ if (this.acknowledged) {
+ throw new IllegalStateException("Already acknowledged");
+ }
+ synchronized (messageQueue) {
+ try {
+ long offset = messageExt.getQueueOffset();
+ switch (status) {
+ case REJECT:
+ case ACCEPT:
+ long consumerOffset = assignedMessageQueue
+ .getConsumerOffset(messageQueue);
+ if (consumerOffset != -1) {
+ ProcessQueue processQueue = assignedMessageQueue
+ .getProcessQueue(messageQueue);
+ if (processQueue != null && !processQueue.isDropped()) {
+ consumer.getOffsetStore().updateOffset(messageQueue,
+ consumerOffset, false);
+ }
+ }
+ if (consumer.getMessageModel() == MessageModel.BROADCASTING) {
+ consumer.getOffsetStore().persist(messageQueue);
+ }
+ break;
+ case REQUEUE:
+ consumer.seek(messageQueue, offset);
+ break;
+ default:
+ break;
+ }
+ }
+ catch (MQClientException e) {
+ throw new IllegalStateException(e);
+ }
+ finally {
+ this.acknowledged = true;
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
new file mode 100644
index 000000000..2ca91384b
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.pull;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.RocketMQConsumerFactory;
+import com.alibaba.cloud.stream.binder.rocketmq.metrics.Instrumentation;
+import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQMessageConverterSupport;
+import com.alibaba.cloud.stream.binder.rocketmq.utils.RocketMQUtils;
+import org.apache.rocketmq.client.consumer.DefaultLitePullConsumer;
+import org.apache.rocketmq.client.consumer.MessageSelector;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.impl.consumer.AssignedMessageQueue;
+import org.apache.rocketmq.client.impl.consumer.DefaultLitePullConsumerImpl;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
+import org.springframework.context.Lifecycle;
+import org.springframework.integration.IntegrationMessageHeaderAccessor;
+import org.springframework.integration.endpoint.AbstractMessageSource;
+import org.springframework.integration.support.MessageBuilder;
+import org.springframework.messaging.Message;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.ReflectionUtils;
+
+/**
+ * @author Jim
+ */
+public class RocketMQMessageSource extends AbstractMessageSource
+ implements DisposableBean, Lifecycle {
+
+ private final static Logger log = LoggerFactory
+ .getLogger(RocketMQMessageSource.class);
+
+ private DefaultLitePullConsumer consumer;
+ private AssignedMessageQueue assignedMessageQueue;
+ private volatile boolean running;
+
+ private final String topic;
+ private final MessageSelector messageSelector;
+ private final ExtendedConsumerProperties extendedConsumerProperties;
+
+ public RocketMQMessageSource(String name,
+ ExtendedConsumerProperties extendedConsumerProperties) {
+ this.topic = name;
+ this.messageSelector = RocketMQUtils.getMessageSelector(
+ extendedConsumerProperties.getExtension().getSubscription());
+ this.extendedConsumerProperties = extendedConsumerProperties;
+
+ }
+
+ @Override
+ public synchronized void start() {
+ Instrumentation instrumentation = new Instrumentation(topic, this);
+ try {
+ if (this.isRunning()) {
+ throw new IllegalStateException(
+ "pull consumer already running. " + this.toString());
+ }
+ this.consumer = RocketMQConsumerFactory
+ .initPullConsumer(extendedConsumerProperties);
+ // This parameter must be 1, otherwise doReceive cannot be handled singly.
+ this.consumer.setPullBatchSize(1);
+ this.consumer.subscribe(topic, messageSelector);
+ this.consumer.setAutoCommit(false);
+ this.assignedMessageQueue = acquireAssignedMessageQueue(this.consumer);
+ this.consumer.start();
+ instrumentation.markStartedSuccessfully();
+ }
+ catch (MQClientException e) {
+ instrumentation.markStartFailed(e);
+ log.error("DefaultMQPullConsumer startup error: " + e.getMessage(), e);
+ }
+ finally {
+ InstrumentationManager.addHealthInstrumentation(instrumentation);
+ }
+ this.running = true;
+ }
+
+ private AssignedMessageQueue acquireAssignedMessageQueue(
+ DefaultLitePullConsumer consumer) {
+ Field field = ReflectionUtils.findField(DefaultLitePullConsumer.class,
+ "defaultLitePullConsumerImpl");
+ assert field != null;
+ field.setAccessible(true);
+ DefaultLitePullConsumerImpl defaultLitePullConsumerImpl = (DefaultLitePullConsumerImpl) ReflectionUtils
+ .getField(field, consumer);
+
+ field = ReflectionUtils.findField(DefaultLitePullConsumerImpl.class,
+ "assignedMessageQueue");
+ assert field != null;
+ field.setAccessible(true);
+ return (AssignedMessageQueue) ReflectionUtils.getField(field,
+ defaultLitePullConsumerImpl);
+ }
+
+ @Override
+ public synchronized void stop() {
+ if (this.isRunning() && null != consumer) {
+ consumer.unsubscribe(topic);
+ consumer.shutdown();
+ this.running = false;
+ }
+ }
+
+ @Override
+ public synchronized boolean isRunning() {
+ return running;
+ }
+
+ @Override
+ protected synchronized Object doReceive() {
+ List messageExtList = consumer.poll();
+ if (CollectionUtils.isEmpty(messageExtList) || messageExtList.size() > 1) {
+ return null;
+ }
+ MessageExt messageExt = messageExtList.get(0);
+ MessageQueue messageQueue = null;
+ for (MessageQueue queue : assignedMessageQueue.getAssignedMessageQueues()) {
+ if (queue.getQueueId() == messageExt.getQueueId()) {
+ messageQueue = queue;
+ break;
+ }
+ }
+ Message message = RocketMQMessageConverterSupport
+ .convertMessage2Spring(messageExtList.get(0));
+ return MessageBuilder.fromMessage(message)
+ .setHeader(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK,
+ new RocketMQAckCallback(this.consumer, assignedMessageQueue,
+ messageQueue, messageExt))
+ .build();
+ }
+
+ @Override
+ public String getComponentType() {
+ return "rocketmq:message-source";
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
new file mode 100644
index 000000000..7017ba46e
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.outbound;
+
+import java.lang.reflect.Field;
+
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQBeanContainerCache;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.utils.RocketMQUtils;
+import org.apache.rocketmq.acl.common.AclClientRPCHook;
+import org.apache.rocketmq.acl.common.SessionCredentials;
+import org.apache.rocketmq.client.hook.CheckForbiddenHook;
+import org.apache.rocketmq.client.hook.SendMessageHook;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.TransactionMQProducer;
+import org.apache.rocketmq.client.trace.AsyncTraceDispatcher;
+import org.apache.rocketmq.client.trace.TraceDispatcher;
+import org.apache.rocketmq.client.trace.hook.SendMessageTraceHookImpl;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.remoting.RPCHook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+/**
+ * Extended function related to producer . eg:initial
+ *
+ * @author zkzlx
+ */
+public final class RocketMQProduceFactory {
+
+ private final static Logger log = LoggerFactory
+ .getLogger(RocketMQProduceFactory.class);
+
+ /**
+ * init for the producer,including convert producer params.
+ * @return
+ */
+ public static DefaultMQProducer initRocketMQProducer(String topic,
+ RocketMQProducerProperties producerProperties) {
+ Assert.notNull(producerProperties.getGroup(),
+ "Property 'group' is required - producerGroup");
+ Assert.notNull(producerProperties.getNameServer(),
+ "Property 'nameServer' is required");
+
+ RPCHook rpcHook = null;
+ if (!StringUtils.isEmpty(producerProperties.getAccessKey())
+ && !StringUtils.isEmpty(producerProperties.getSecretKey())) {
+ rpcHook = new AclClientRPCHook(
+ new SessionCredentials(producerProperties.getAccessKey(),
+ producerProperties.getSecretKey()));
+ }
+ DefaultMQProducer producer;
+ if (RocketMQProducerProperties.ProducerType.Trans
+ .equalsName(producerProperties.getProducerType())) {
+ producer = new TransactionMQProducer(producerProperties.getNamespace(),
+ producerProperties.getGroup(), rpcHook);
+ if (producerProperties.getEnableMsgTrace()) {
+ try {
+ AsyncTraceDispatcher dispatcher = new AsyncTraceDispatcher(
+ producerProperties.getGroup(), TraceDispatcher.Type.PRODUCE,
+ producerProperties.getCustomizedTraceTopic(), rpcHook);
+ dispatcher.setHostProducer(producer.getDefaultMQProducerImpl());
+ Field field = DefaultMQProducer.class
+ .getDeclaredField("traceDispatcher");
+ field.setAccessible(true);
+ field.set(producer, dispatcher);
+ producer.getDefaultMQProducerImpl().registerSendMessageHook(
+ new SendMessageTraceHookImpl(dispatcher));
+ }
+ catch (Throwable e) {
+ log.error(
+ "system mq-trace hook init failed ,maybe can't send msg trace data");
+ }
+ }
+ }
+ else {
+ producer = new DefaultMQProducer(producerProperties.getNamespace(),
+ producerProperties.getGroup(), rpcHook,
+ producerProperties.getEnableMsgTrace(),
+ producerProperties.getCustomizedTraceTopic());
+ }
+
+ producer.setVipChannelEnabled(
+ null == rpcHook && producerProperties.getVipChannelEnabled());
+ producer.setInstanceName(
+ RocketMQUtils.getInstanceName(rpcHook, topic + "|" + UtilAll.getPid()));
+ producer.setNamesrvAddr(producerProperties.getNameServer());
+ producer.setSendMsgTimeout(producerProperties.getSendMsgTimeout());
+ producer.setRetryTimesWhenSendFailed(
+ producerProperties.getRetryTimesWhenSendFailed());
+ producer.setRetryTimesWhenSendAsyncFailed(
+ producerProperties.getRetryTimesWhenSendAsyncFailed());
+ producer.setCompressMsgBodyOverHowmuch(
+ producerProperties.getCompressMsgBodyThreshold());
+ producer.setRetryAnotherBrokerWhenNotStoreOK(
+ producerProperties.getRetryAnotherBroker());
+ producer.setMaxMessageSize(producerProperties.getMaxMessageSize());
+ producer.setUseTLS(producerProperties.getUseTLS());
+ CheckForbiddenHook checkForbiddenHook = RocketMQBeanContainerCache.getBean(
+ producerProperties.getCheckForbiddenHook(), CheckForbiddenHook.class);
+ if (null != checkForbiddenHook) {
+ producer.getDefaultMQProducerImpl()
+ .registerCheckForbiddenHook(checkForbiddenHook);
+ }
+ SendMessageHook sendMessageHook = RocketMQBeanContainerCache
+ .getBean(producerProperties.getSendMessageHook(), SendMessageHook.class);
+ if (null != sendMessageHook) {
+ producer.getDefaultMQProducerImpl().registerSendMessageHook(sendMessageHook);
+ }
+
+ return producer;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
new file mode 100644
index 000000000..66b58f797
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.integration.outbound;
+
+import java.util.List;
+
+import com.alibaba.cloud.stream.binder.rocketmq.contants.RocketMQConst;
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQBeanContainerCache;
+import com.alibaba.cloud.stream.binder.rocketmq.metrics.Instrumentation;
+import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQProducerProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.provisioning.selector.PartitionMessageQueueSelector;
+import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQMessageConverterSupport;
+import org.apache.rocketmq.client.exception.MQBrokerException;
+import org.apache.rocketmq.client.exception.MQClientException;
+import org.apache.rocketmq.client.producer.DefaultMQProducer;
+import org.apache.rocketmq.client.producer.MessageQueueSelector;
+import org.apache.rocketmq.client.producer.SendCallback;
+import org.apache.rocketmq.client.producer.SendResult;
+import org.apache.rocketmq.client.producer.SendStatus;
+import org.apache.rocketmq.client.producer.TransactionListener;
+import org.apache.rocketmq.client.producer.TransactionMQProducer;
+import org.apache.rocketmq.common.message.MessageQueue;
+import org.apache.rocketmq.remoting.exception.RemotingException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.stream.binder.ExtendedProducerProperties;
+import org.springframework.cloud.stream.binding.MessageConverterConfigurer;
+import org.springframework.cloud.stream.binding.MessageConverterConfigurer.PartitioningInterceptor;
+import org.springframework.cloud.stream.provisioning.ProducerDestination;
+import org.springframework.context.Lifecycle;
+import org.springframework.integration.handler.AbstractMessageHandler;
+import org.springframework.integration.support.ErrorMessageStrategy;
+import org.springframework.integration.support.ErrorMessageUtils;
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageChannel;
+import org.springframework.messaging.MessagingException;
+
+/**
+ * @author Jim
+ */
+public class RocketMQProducerMessageHandler extends AbstractMessageHandler
+ implements Lifecycle {
+
+ private final static Logger log = LoggerFactory
+ .getLogger(RocketMQProducerMessageHandler.class);
+
+ private volatile boolean running = false;
+ private volatile boolean isTrans = false;
+
+ private ErrorMessageStrategy errorMessageStrategy;
+ private MessageChannel sendFailureChannel;
+ private MessageConverterConfigurer.PartitioningInterceptor partitioningInterceptor;
+ private DefaultMQProducer defaultMQProducer;
+ private MessageQueueSelector messageQueueSelector;
+
+ private final ProducerDestination destination;
+ private final ExtendedProducerProperties extendedProducerProperties;
+ private final RocketMQProducerProperties mqProducerProperties;
+
+ public RocketMQProducerMessageHandler(ProducerDestination destination,
+ ExtendedProducerProperties extendedProducerProperties,
+ RocketMQProducerProperties mqProducerProperties) {
+ this.destination = destination;
+ this.extendedProducerProperties = extendedProducerProperties;
+ this.mqProducerProperties = mqProducerProperties;
+ }
+
+ @Override
+ protected void onInit() {
+ if (null == mqProducerProperties || !mqProducerProperties.getEnabled()) {
+ return;
+ }
+ super.onInit();
+ this.defaultMQProducer = RocketMQProduceFactory
+ .initRocketMQProducer(destination.getName(), mqProducerProperties);
+ this.isTrans = defaultMQProducer instanceof TransactionMQProducer;
+ // Use the default if the partition is on and no customization is available.
+ this.messageQueueSelector = RocketMQBeanContainerCache.getBean(
+ mqProducerProperties.getMessageQueueSelector(),
+ MessageQueueSelector.class,
+ extendedProducerProperties.isPartitioned()
+ ? new PartitionMessageQueueSelector()
+ : null);
+ }
+
+ @Override
+ public void start() {
+ Instrumentation instrumentation = new Instrumentation(destination.getName(),
+ this);
+ try {
+ defaultMQProducer.start();
+ // TransactionMQProducer does not currently support custom
+ // MessageQueueSelector.
+ if (!isTrans && extendedProducerProperties.isPartitioned()) {
+ List messageQueues = defaultMQProducer
+ .fetchPublishMessageQueues(destination.getName());
+ if (extendedProducerProperties.getPartitionCount() != messageQueues
+ .size()) {
+ logger.info(String.format(
+ "The partition count of topic '%s' will change from '%s' to '%s'",
+ destination.getName(),
+ extendedProducerProperties.getPartitionCount(),
+ messageQueues.size()));
+ extendedProducerProperties.setPartitionCount(messageQueues.size());
+ // may be npe!
+ partitioningInterceptor.setPartitionCount(
+ extendedProducerProperties.getPartitionCount());
+ }
+ }
+ running = true;
+ instrumentation.markStartedSuccessfully();
+ }
+ catch (MQClientException | NullPointerException e) {
+ instrumentation.markStartFailed(e);
+ log.error("The defaultMQProducer startup failure !!!", e);
+ }
+ finally {
+ InstrumentationManager.addHealthInstrumentation(instrumentation);
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (running && null != defaultMQProducer) {
+ defaultMQProducer.shutdown();
+ }
+ running = false;
+ }
+
+ @Override
+ public boolean isRunning() {
+ return running;
+ }
+
+ @Override
+ protected void handleMessageInternal(Message> message) {
+ try {
+ org.apache.rocketmq.common.message.Message mqMessage = RocketMQMessageConverterSupport
+ .convertMessage2MQ(destination.getName(), message);
+ SendResult sendResult;
+ if (defaultMQProducer instanceof TransactionMQProducer) {
+ TransactionListener transactionListener = RocketMQBeanContainerCache
+ .getBean(mqProducerProperties.getTransactionListener(),
+ TransactionListener.class);
+ if (transactionListener == null) {
+ throw new MessagingException(
+ "TransactionMQProducer must have a TransactionMQProducer !!! ");
+ }
+ ((TransactionMQProducer) defaultMQProducer)
+ .setTransactionListener(transactionListener);
+ log.info("send transaction message :" + mqMessage);
+ sendResult = defaultMQProducer.sendMessageInTransaction(mqMessage,
+ message.getHeaders().get(RocketMQConst.USER_TRANSACTIONAL_ARGS));
+ }
+ else {
+ log.info("send message :" + mqMessage);
+ sendResult = this.send(mqMessage, this.messageQueueSelector,
+ message.getHeaders(), message);
+ }
+ if (sendResult == null
+ || !SendStatus.SEND_OK.equals(sendResult.getSendStatus())) {
+ log.error("message send fail.SendStatus is not OK ");
+ this.doFail(message, new MessagingException(
+ "message send fail.SendStatus is not OK."));
+ }
+ }
+ catch (Exception e) {
+ log.error("RocketMQ Message hasn't been sent. Caused by " + e.getMessage(),
+ e);
+ this.doFail(message, e);
+ }
+ }
+
+ private SendResult send(org.apache.rocketmq.common.message.Message mqMessage,
+ MessageQueueSelector selector, Object args, Message> message)
+ throws RemotingException, MQClientException, InterruptedException,
+ MQBrokerException {
+ SendResult sendResult = new SendResult();
+ sendResult.setSendStatus(SendStatus.SEND_OK);
+ if (RocketMQProducerProperties.SendType.OneWay
+ .equalsName(mqProducerProperties.getSendType())) {
+ if (null != selector) {
+ defaultMQProducer.sendOneway(mqMessage, selector, args);
+ }
+ else {
+ defaultMQProducer.sendOneway(mqMessage);
+ }
+ return sendResult;
+ }
+ if (RocketMQProducerProperties.SendType.Sync
+ .equalsName(mqProducerProperties.getSendType())) {
+ if (null != selector) {
+ return defaultMQProducer.send(mqMessage, selector, args);
+ }
+ return defaultMQProducer.send(mqMessage);
+ }
+ if (RocketMQProducerProperties.SendType.Async
+ .equalsName(mqProducerProperties.getSendType())) {
+ if (null != selector) {
+ defaultMQProducer.send(mqMessage, selector, args,
+ this.getSendCallback(message));
+ }
+ else {
+ defaultMQProducer.send(mqMessage, this.getSendCallback(message));
+ }
+ return sendResult;
+ }
+ throw new MessagingException(
+ "message hasn't been sent,cause by : the SendType must be in this values[OneWay, Async, Sync]");
+ }
+
+ /**
+ * https://github.com/alibaba/spring-cloud-alibaba/issues/1408
+ * @param message
+ * @return
+ */
+ private SendCallback getSendCallback(Message> message) {
+ SendCallback sendCallback = RocketMQBeanContainerCache
+ .getBean(mqProducerProperties.getSendCallBack(), SendCallback.class);
+ if (null == sendCallback) {
+ sendCallback = new SendCallback() {
+ @Override
+ public void onSuccess(SendResult sendResult) {
+ }
+
+ @Override
+ public void onException(Throwable e) {
+ RocketMQProducerMessageHandler.this.doFail(message, e);
+ }
+ };
+ }
+ return sendCallback;
+ }
+
+ private void doFail(Message> message, Throwable e) {
+ if (getSendFailureChannel() != null) {
+ getSendFailureChannel().send(getErrorMessageStrategy().buildErrorMessage(e,
+ ErrorMessageUtils.getAttributeAccessor(message, message)));
+ }
+ else {
+ throw new MessagingException(message, e);
+ }
+ }
+
+ public MessageChannel getSendFailureChannel() {
+ return sendFailureChannel;
+ }
+
+ public void setSendFailureChannel(MessageChannel sendFailureChannel) {
+ this.sendFailureChannel = sendFailureChannel;
+ }
+
+ public ErrorMessageStrategy getErrorMessageStrategy() {
+ return errorMessageStrategy;
+ }
+
+ public void setErrorMessageStrategy(ErrorMessageStrategy errorMessageStrategy) {
+ this.errorMessageStrategy = errorMessageStrategy;
+ }
+
+ public PartitioningInterceptor getPartitioningInterceptor() {
+ return partitioningInterceptor;
+ }
+
+ public RocketMQProducerMessageHandler setPartitioningInterceptor(
+ PartitioningInterceptor partitioningInterceptor) {
+ this.partitioningInterceptor = partitioningInterceptor;
+ return this;
+ }
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
new file mode 100644
index 000000000..00e7d30dd
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.properties;
+
+import java.io.Serializable;
+
+import org.apache.rocketmq.client.AccessChannel;
+import org.apache.rocketmq.client.impl.factory.MQClientInstance;
+import org.apache.rocketmq.remoting.netty.TlsSystemConfig;
+
+/**
+ * @author zkzlx
+ */
+public class RocketMQCommonProperties implements Serializable {
+ private static final long serialVersionUID = -6724870154343284715L;
+
+ private boolean enabled = true;
+
+ private String nameServer;
+
+ /**
+ * The property of "access-key".
+ */
+ private String accessKey;
+
+ /**
+ * The property of "secret-key".
+ */
+ private String secretKey;
+ /**
+ * Consumers of the same role is required to have exactly same subscriptions and
+ * consumerGroup to correctly achieve load balance. It's required and needs to be
+ * globally unique.
+ *
+ * Producer group conceptually aggregates all producer instances of exactly same role,
+ * which is particularly important when transactional messages are involved.
+ *
+ *
+ * For non-transactional messages, it does not matter as long as it's unique per
+ * process.
+ *
+ *
+ * See here for further
+ * discussion.
+ */
+ private String group;
+
+ private String namespace;
+ private String accessChannel = AccessChannel.LOCAL.name();
+ /**
+ * Pulling topic information interval from the named server.
+ * see{@link MQClientInstance#startScheduledTask()},eg:ScheduledTask
+ * updateTopicRouteInfoFromNameServer.
+ */
+ private int pollNameServerInterval = 1000 * 30;
+ /**
+ * Heartbeat interval in microseconds with message broker.
+ * see{@link MQClientInstance#startScheduledTask()},eg:ScheduledTask
+ * sendHeartbeatToAllBroker .
+ */
+ private int heartbeatBrokerInterval = 1000 * 30;
+ /**
+ * Offset persistent interval for consumer.
+ * see{@link MQClientInstance#startScheduledTask()},eg:ScheduledTask
+ * sendHeartbeatToAllBroker .
+ */
+ private int persistConsumerOffsetInterval = 1000 * 5;
+
+ private boolean vipChannelEnabled = false;
+
+ private boolean useTLS = TlsSystemConfig.tlsEnable;
+
+ private boolean enableMsgTrace = true;
+ private String customizedTraceTopic;
+
+ public boolean getEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ }
+
+ public String getNameServer() {
+ return nameServer;
+ }
+
+ public void setNameServer(String nameServer) {
+ this.nameServer = nameServer;
+ }
+
+ public String getAccessKey() {
+ return accessKey;
+ }
+
+ public void setAccessKey(String accessKey) {
+ this.accessKey = accessKey;
+ }
+
+ public String getSecretKey() {
+ return secretKey;
+ }
+
+ public void setSecretKey(String secretKey) {
+ this.secretKey = secretKey;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ public String getAccessChannel() {
+ return accessChannel;
+ }
+
+ public void setAccessChannel(String accessChannel) {
+ this.accessChannel = accessChannel;
+ }
+
+ public int getPollNameServerInterval() {
+ return pollNameServerInterval;
+ }
+
+ public void setPollNameServerInterval(int pollNameServerInterval) {
+ this.pollNameServerInterval = pollNameServerInterval;
+ }
+
+ public int getHeartbeatBrokerInterval() {
+ return heartbeatBrokerInterval;
+ }
+
+ public void setHeartbeatBrokerInterval(int heartbeatBrokerInterval) {
+ this.heartbeatBrokerInterval = heartbeatBrokerInterval;
+ }
+
+ public int getPersistConsumerOffsetInterval() {
+ return persistConsumerOffsetInterval;
+ }
+
+ public void setPersistConsumerOffsetInterval(int persistConsumerOffsetInterval) {
+ this.persistConsumerOffsetInterval = persistConsumerOffsetInterval;
+ }
+
+ public boolean getVipChannelEnabled() {
+ return vipChannelEnabled;
+ }
+
+ public void setVipChannelEnabled(boolean vipChannelEnabled) {
+ this.vipChannelEnabled = vipChannelEnabled;
+ }
+
+ public boolean getUseTLS() {
+ return useTLS;
+ }
+
+ public void setUseTLS(boolean useTLS) {
+ this.useTLS = useTLS;
+ }
+
+ public boolean getEnableMsgTrace() {
+ return enableMsgTrace;
+ }
+
+ public void setEnableMsgTrace(boolean enableMsgTrace) {
+ this.enableMsgTrace = enableMsgTrace;
+ }
+
+ public String getCustomizedTraceTopic() {
+ return customizedTraceTopic;
+ }
+
+ public void setCustomizedTraceTopic(String customizedTraceTopic) {
+ this.customizedTraceTopic = customizedTraceTopic;
+ }
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java
new file mode 100644
index 000000000..99a1a36fb
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.properties;
+
+import org.springframework.cloud.stream.binder.BinderSpecificPropertiesProvider;
+
+/**
+ * Container object for RocketMQ specific extended producer and consumer binding
+ * properties.
+ *
+ * @author Jim
+ */
+public class RocketMQSpecificPropertiesProvider
+ implements BinderSpecificPropertiesProvider {
+
+ /**
+ * Consumer specific binding properties. @see {@link RocketMQConsumerProperties}.
+ */
+ private RocketMQConsumerProperties consumer = new RocketMQConsumerProperties();
+
+ /**
+ * Producer specific binding properties. @see {@link RocketMQProducerProperties}.
+ */
+ private RocketMQProducerProperties producer = new RocketMQProducerProperties();
+
+ /**
+ * @return {@link RocketMQConsumerProperties} Consumer specific binding
+ * properties. @see {@link RocketMQConsumerProperties}.
+ */
+ @Override
+ public RocketMQConsumerProperties getConsumer() {
+ return this.consumer;
+ }
+
+ public void setConsumer(RocketMQConsumerProperties consumer) {
+ this.consumer = consumer;
+ }
+
+ /**
+ * @return {@link RocketMQProducerProperties} Producer specific binding
+ * properties. @see {@link RocketMQProducerProperties}.
+ */
+ @Override
+ public RocketMQProducerProperties getProducer() {
+ return this.producer;
+ }
+
+ public void setProducer(RocketMQProducerProperties producer) {
+ this.producer = producer;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java
new file mode 100644
index 000000000..d4b62e5fa
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.support;
+
+import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.Objects;
+
+import com.alibaba.cloud.stream.binder.rocketmq.contants.RocketMQConst;
+import com.alibaba.cloud.stream.binder.rocketmq.contants.RocketMQConst.Headers;
+import com.alibaba.cloud.stream.binder.rocketmq.convert.RocketMQMessageConverter;
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQBeanContainerCache;
+import org.apache.rocketmq.common.message.MessageConst;
+import org.apache.rocketmq.common.message.MessageExt;
+
+import org.springframework.messaging.Message;
+import org.springframework.messaging.MessageHeaders;
+import org.springframework.messaging.converter.CompositeMessageConverter;
+import org.springframework.messaging.support.MessageBuilder;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.MimeTypeUtils;
+import org.springframework.util.StringUtils;
+
+/**
+ *
+ * @author zkzlx
+ */
+public class RocketMQMessageConverterSupport {
+
+ private static final CompositeMessageConverter MESSAGE_CONVERTER = RocketMQBeanContainerCache
+ .getBean(RocketMQMessageConverter.DEFAULT_NAME,
+ CompositeMessageConverter.class,
+ new RocketMQMessageConverter().getMessageConverter());
+
+ public static Message convertMessage2Spring(MessageExt message) {
+ MessageBuilder messageBuilder = MessageBuilder.withPayload(message.getBody())
+ .setHeader(toRocketHeaderKey(Headers.KEYS), message.getKeys())
+ .setHeader(toRocketHeaderKey(Headers.TAGS), message.getTags())
+ .setHeader(toRocketHeaderKey(Headers.TOPIC), message.getTopic())
+ .setHeader(toRocketHeaderKey(Headers.MESSAGE_ID), message.getMsgId())
+ .setHeader(toRocketHeaderKey(Headers.BORN_TIMESTAMP),
+ message.getBornTimestamp())
+ .setHeader(toRocketHeaderKey(Headers.BORN_HOST),
+ message.getBornHostString())
+ .setHeader(toRocketHeaderKey(Headers.FLAG), message.getFlag())
+ .setHeader(toRocketHeaderKey(Headers.QUEUE_ID), message.getQueueId())
+ .setHeader(toRocketHeaderKey(Headers.SYS_FLAG), message.getSysFlag())
+ .setHeader(toRocketHeaderKey(Headers.TRANSACTION_ID),
+ message.getTransactionId());
+ addUserProperties(message.getProperties(), messageBuilder);
+ return messageBuilder.build();
+ }
+
+ public static String toRocketHeaderKey(String rawKey) {
+ return "ROCKET_" + rawKey;
+ }
+
+ private static void addUserProperties(Map properties,
+ MessageBuilder messageBuilder) {
+ if (!CollectionUtils.isEmpty(properties)) {
+ properties.forEach((key, val) -> {
+ if (!MessageConst.STRING_HASH_SET.contains(key)
+ && !MessageHeaders.ID.equals(key)
+ && !MessageHeaders.TIMESTAMP.equals(key)) {
+ messageBuilder.setHeader(key, val);
+ }
+ });
+ }
+ }
+
+ public static org.apache.rocketmq.common.message.Message convertMessage2MQ(
+ String destination, Message> source) {
+ Message> message = MESSAGE_CONVERTER.toMessage(source.getPayload(),
+ source.getHeaders());
+ assert message != null;
+ MessageBuilder> builder = MessageBuilder.fromMessage(message);
+ builder.setHeaderIfAbsent(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.TEXT_PLAIN);
+ message = builder.build();
+ return doConvert(destination, message);
+ }
+
+ private static org.apache.rocketmq.common.message.Message doConvert(String topic,
+ Message> message) {
+ Charset charset = Charset.defaultCharset();
+ Object payloadObj = message.getPayload();
+ byte[] payloads;
+ try {
+ if (payloadObj instanceof String) {
+ payloads = ((String) payloadObj).getBytes(charset);
+ }
+ else if (payloadObj instanceof byte[]) {
+ payloads = (byte[]) message.getPayload();
+ }
+ else {
+ String jsonObj = (String) MESSAGE_CONVERTER.fromMessage(message,
+ payloadObj.getClass());
+ if (null == jsonObj) {
+ throw new RuntimeException(String.format(
+ "empty after conversion [messageConverter:%s,payloadClass:%s,payloadObj:%s]",
+ MESSAGE_CONVERTER.getClass(), payloadObj.getClass(),
+ payloadObj));
+ }
+ payloads = jsonObj.getBytes(charset);
+ }
+ }
+ catch (Exception e) {
+ throw new RuntimeException("convert to RocketMQ message failed.", e);
+ }
+ return getAndWrapMessage(topic, message.getHeaders(), payloads);
+ }
+
+ private static org.apache.rocketmq.common.message.Message getAndWrapMessage(
+ String topic, MessageHeaders headers, byte[] payloads) {
+ if (topic == null || topic.length() < 1) {
+ return null;
+ }
+ if (payloads == null || payloads.length < 1) {
+ return null;
+ }
+ org.apache.rocketmq.common.message.Message rocketMsg = new org.apache.rocketmq.common.message.Message(
+ topic, payloads);
+ if (Objects.nonNull(headers) && !headers.isEmpty()) {
+ Object tag = headers.getOrDefault(Headers.TAGS,
+ headers.get(toRocketHeaderKey(Headers.TAGS)));
+ if (!StringUtils.isEmpty(tag)) {
+ rocketMsg.setTags(String.valueOf(tag));
+ }
+
+ Object keys = headers.getOrDefault(Headers.KEYS,
+ headers.get(toRocketHeaderKey(Headers.KEYS)));
+ if (!StringUtils.isEmpty(keys)) {
+ rocketMsg.setKeys(keys.toString());
+ }
+ Object flagObj = headers.getOrDefault(Headers.FLAG,
+ headers.get(toRocketHeaderKey(Headers.FLAG)));
+ int flag = 0;
+ int delayLevel = 0;
+ try {
+ flagObj = flagObj == null ? 0 : flagObj;
+ Object delayLevelObj = headers.getOrDefault(
+ RocketMQConst.PROPERTY_DELAY_TIME_LEVEL,
+ headers.get(toRocketHeaderKey(
+ RocketMQConst.PROPERTY_DELAY_TIME_LEVEL)));
+ delayLevelObj = delayLevelObj == null ? 0 : delayLevelObj;
+ delayLevel = Integer.parseInt(String.valueOf(delayLevelObj));
+ flag = Integer.parseInt(String.valueOf(flagObj));
+ }
+ catch (Exception ignored) {
+ }
+ if (delayLevel > 0) {
+ rocketMsg.setDelayTimeLevel(delayLevel);
+ }
+ rocketMsg.setFlag(flag);
+ Object waitStoreMsgOkObj = headers
+ .getOrDefault(RocketMQConst.PROPERTY_WAIT_STORE_MSG_OK, "true");
+ rocketMsg.setWaitStoreMsgOK(
+ Boolean.parseBoolean(String.valueOf(waitStoreMsgOkObj)));
+ headers.entrySet().stream()
+ .filter(entry -> !Objects.equals(entry.getKey(), Headers.FLAG))
+ .forEach(entry -> {
+ if (!MessageConst.STRING_HASH_SET.contains(entry.getKey())) {
+ rocketMsg.putUserProperty(entry.getKey(),
+ String.valueOf(entry.getValue()));
+ }
+ });
+
+ }
+ return rocketMsg;
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
new file mode 100644
index 000000000..3f7898422
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.stream.binder.rocketmq.utils;
+
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
+import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQCommonProperties;
+import org.apache.rocketmq.acl.common.AclClientRPCHook;
+import org.apache.rocketmq.acl.common.SessionCredentials;
+import org.apache.rocketmq.client.consumer.MessageSelector;
+import org.apache.rocketmq.common.UtilAll;
+import org.apache.rocketmq.remoting.RPCHook;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * TODO Describe what it does
+ *
+ * @author Jim
+ */
+public class RocketMQUtils {
+
+ public static T mergeRocketMQProperties(
+ RocketMQBinderConfigurationProperties binderConfigurationProperties,
+ T mqProperties) {
+ if (null == binderConfigurationProperties || mqProperties == null) {
+ return mqProperties;
+ }
+ if (StringUtils.isEmpty(mqProperties.getNameServer())) {
+ mqProperties.setNameServer(binderConfigurationProperties.getNameServer());
+ }
+ if (StringUtils.isEmpty(mqProperties.getSecretKey())) {
+ mqProperties.setSecretKey(binderConfigurationProperties.getSecretKey());
+ }
+ if (StringUtils.isEmpty(mqProperties.getAccessKey())) {
+ mqProperties.setAccessKey(binderConfigurationProperties.getAccessKey());
+ }
+ if (StringUtils.isEmpty(mqProperties.getAccessChannel())) {
+ mqProperties
+ .setAccessChannel(binderConfigurationProperties.getAccessChannel());
+ }
+ if (StringUtils.isEmpty(mqProperties.getNamespace())) {
+ mqProperties.setNamespace(binderConfigurationProperties.getNamespace());
+ }
+ if (StringUtils.isEmpty(mqProperties.getGroup())) {
+ mqProperties.setGroup(binderConfigurationProperties.getGroup());
+ }
+ if (StringUtils.isEmpty(mqProperties.getCustomizedTraceTopic())) {
+ mqProperties.setCustomizedTraceTopic(
+ binderConfigurationProperties.getCustomizedTraceTopic());
+ }
+ mqProperties.setNameServer(getNameServerStr(mqProperties.getNameServer()));
+ return mqProperties;
+ }
+
+ public static String getInstanceName(RPCHook rpcHook, String identify) {
+ String separator = "|";
+ StringBuilder instanceName = new StringBuilder();
+ if (null != rpcHook) {
+ SessionCredentials sessionCredentials = ((AclClientRPCHook) rpcHook)
+ .getSessionCredentials();
+ instanceName.append(sessionCredentials.getAccessKey()).append(separator)
+ .append(sessionCredentials.getSecretKey()).append(separator);
+ }
+ instanceName.append(identify).append(separator).append(UtilAll.getPid());
+ return instanceName.toString();
+ }
+
+ public static String getNameServerStr(String nameServer) {
+ if (StringUtils.isEmpty(nameServer)) {
+ return null;
+ }
+ return nameServer.replaceAll(",", ";");
+ }
+
+ private static final String SQL = "sql:";
+
+ public static MessageSelector getMessageSelector(String expression) {
+ if (StringUtils.hasText(expression) && expression.startsWith(SQL)) {
+ return MessageSelector.bySql(expression.replaceFirst(SQL, ""));
+ }
+ return MessageSelector.byTag(expression);
+ }
+
+}
From 5a763e0ec987041ae85702bfe36494bbc45f1ecf Mon Sep 17 00:00:00 2001
From: zkzlx
Date: Mon, 1 Feb 2021 11:29:37 +0800
Subject: [PATCH 08/99] Code refactoring and some new feature support - delete
some invalid files.
---
.../rocketmq/RocketMQBinderConstants.java | 51 ---------
.../RocketMQBinderAutoConfiguration.java | 81 --------------
...inderHealthIndicatorAutoConfiguration.java | 40 -------
...etMQComponent4BinderAutoConfiguration.java | 102 ------------------
.../main/resources/META-INF/spring.binders | 2 +-
.../main/resources/META-INF/spring.factories | 2 +-
6 files changed, 2 insertions(+), 276 deletions(-)
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderConstants.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderAutoConfiguration.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderHealthIndicatorAutoConfiguration.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderConstants.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderConstants.java
deleted file mode 100644
index 47e4b9e7f..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderConstants.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq;
-
-import static org.apache.rocketmq.spring.support.RocketMQHeaders.PREFIX;
-
-/**
- * @author Jim
- * @author Xiejiashuai
- */
-public final class RocketMQBinderConstants {
-
- /**
- * Header key for RocketMQ Transactional Args.
- */
- public static final String ROCKET_TRANSACTIONAL_ARG = "TRANSACTIONAL_ARG";
-
- /**
- * Default NameServer value.
- */
- public static final String DEFAULT_NAME_SERVER = "127.0.0.1:9876";
-
- /**
- * Default group for SCS RocketMQ Binder.
- */
- public static final String DEFAULT_GROUP = PREFIX + "binder_default_group_name";
-
- /**
- * RocketMQ re-consume times.
- */
- public static final String ROCKETMQ_RECONSUME_TIMES = PREFIX + "RECONSUME_TIMES";
-
- private RocketMQBinderConstants() {
- throw new AssertionError("Must not instantiate constant utility class");
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderAutoConfiguration.java
deleted file mode 100644
index 3031c2656..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderAutoConfiguration.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq.config;
-
-import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
-import com.alibaba.cloud.stream.binder.rocketmq.metrics.InstrumentationManager;
-import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
-import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
-import com.alibaba.cloud.stream.binder.rocketmq.provisioning.RocketMQTopicProvisioner;
-import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration;
-import org.apache.rocketmq.spring.autoconfigure.RocketMQProperties;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Import;
-
-/**
- * @author Timur Valiev
- * @author Jim
- */
-@Configuration(proxyBeanMethods = false)
-@Import({ RocketMQAutoConfiguration.class,
- RocketMQBinderHealthIndicatorAutoConfiguration.class })
-@EnableConfigurationProperties({ RocketMQBinderConfigurationProperties.class,
- RocketMQExtendedBindingProperties.class })
-public class RocketMQBinderAutoConfiguration {
-
- private final RocketMQExtendedBindingProperties extendedBindingProperties;
-
- private final RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
-
- @Autowired(required = false)
- private RocketMQProperties rocketMQProperties = new RocketMQProperties();
-
- @Autowired
- public RocketMQBinderAutoConfiguration(
- RocketMQExtendedBindingProperties extendedBindingProperties,
- RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties) {
- this.extendedBindingProperties = extendedBindingProperties;
- this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
- }
-
- @Bean
- public RocketMQTopicProvisioner provisioningProvider() {
- return new RocketMQTopicProvisioner();
- }
-
- @Bean
- public RocketMQMessageChannelBinder rocketMessageChannelBinder(
- RocketMQTopicProvisioner provisioningProvider,
- InstrumentationManager instrumentationManager) {
- RocketMQMessageChannelBinder binder = new RocketMQMessageChannelBinder(
- provisioningProvider, extendedBindingProperties,
- rocketBinderConfigurationProperties, rocketMQProperties,
- instrumentationManager);
- binder.setExtendedBindingProperties(extendedBindingProperties);
- return binder;
- }
-
- @Bean
- public InstrumentationManager instrumentationManager() {
- return new InstrumentationManager();
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderHealthIndicatorAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderHealthIndicatorAutoConfiguration.java
deleted file mode 100644
index 1c3b5dc0d..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQBinderHealthIndicatorAutoConfiguration.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq.config;
-
-import com.alibaba.cloud.stream.binder.rocketmq.actuator.RocketMQBinderHealthIndicator;
-
-import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
-import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-/**
- * @author Jim
- */
-@Configuration(proxyBeanMethods = false)
-@ConditionalOnClass(Endpoint.class)
-public class RocketMQBinderHealthIndicatorAutoConfiguration {
-
- @Bean
- @ConditionalOnEnabledHealthIndicator("rocketmq")
- public RocketMQBinderHealthIndicator rocketBinderHealthIndicator() {
- return new RocketMQBinderHealthIndicator();
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
deleted file mode 100644
index 6968ead86..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq.config;
-
-import com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderConstants;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import org.apache.rocketmq.acl.common.AclClientRPCHook;
-import org.apache.rocketmq.acl.common.SessionCredentials;
-import org.apache.rocketmq.client.producer.DefaultMQProducer;
-import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration;
-import org.apache.rocketmq.spring.config.RocketMQConfigUtils;
-import org.apache.rocketmq.spring.config.RocketMQTransactionAnnotationProcessor;
-import org.apache.rocketmq.spring.config.TransactionHandlerRegistry;
-import org.apache.rocketmq.spring.core.RocketMQTemplate;
-
-import org.springframework.boot.autoconfigure.AutoConfigureAfter;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.util.StringUtils;
-
-/**
- * @author Jim
- */
-@Configuration(proxyBeanMethods = false)
-@AutoConfigureAfter(RocketMQAutoConfiguration.class)
-@ConditionalOnMissingBean(DefaultMQProducer.class)
-public class RocketMQComponent4BinderAutoConfiguration {
-
- private final Environment environment;
-
- public RocketMQComponent4BinderAutoConfiguration(Environment environment) {
- this.environment = environment;
- }
-
- @Bean
- @ConditionalOnMissingBean(DefaultMQProducer.class)
- public DefaultMQProducer defaultMQProducer() {
- DefaultMQProducer producer;
- String configNameServer = environment.resolveRequiredPlaceholders(
- "${spring.cloud.stream.rocketmq.binder.name-server:${rocketmq.producer.name-server:}}");
- String ak = environment.resolveRequiredPlaceholders(
- "${spring.cloud.stream.rocketmq.binder.access-key:${rocketmq.producer.access-key:}}");
- String sk = environment.resolveRequiredPlaceholders(
- "${spring.cloud.stream.rocketmq.binder.secret-key:${rocketmq.producer.secret-key:}}");
- if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
- producer = new DefaultMQProducer(RocketMQBinderConstants.DEFAULT_GROUP,
- new AclClientRPCHook(new SessionCredentials(ak, sk)));
- producer.setVipChannelEnabled(false);
- }
- else {
- producer = new DefaultMQProducer(RocketMQBinderConstants.DEFAULT_GROUP);
- }
- if (StringUtils.isEmpty(configNameServer)) {
- configNameServer = RocketMQBinderConstants.DEFAULT_NAME_SERVER;
- }
- producer.setNamesrvAddr(configNameServer);
- return producer;
- }
-
- @Bean(destroyMethod = "destroy")
- @ConditionalOnMissingBean
- public RocketMQTemplate rocketMQTemplate(DefaultMQProducer mqProducer,
- ObjectMapper objectMapper) {
- RocketMQTemplate rocketMQTemplate = new RocketMQTemplate();
- rocketMQTemplate.setProducer(mqProducer);
- rocketMQTemplate.setObjectMapper(objectMapper);
- return rocketMQTemplate;
- }
-
- @Bean
- @ConditionalOnBean(RocketMQTemplate.class)
- @ConditionalOnMissingBean(TransactionHandlerRegistry.class)
- public TransactionHandlerRegistry transactionHandlerRegistry(
- RocketMQTemplate template) {
- return new TransactionHandlerRegistry(template);
- }
-
- @Bean(name = RocketMQConfigUtils.ROCKETMQ_TRANSACTION_ANNOTATION_PROCESSOR_BEAN_NAME)
- @ConditionalOnBean(TransactionHandlerRegistry.class)
- public static RocketMQTransactionAnnotationProcessor transactionAnnotationProcessor(
- TransactionHandlerRegistry transactionHandlerRegistry) {
- return new RocketMQTransactionAnnotationProcessor(transactionHandlerRegistry);
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.binders b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.binders
index 2e5b99538..b232e1f10 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.binders
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.binders
@@ -1 +1 @@
-rocketmq:com.alibaba.cloud.stream.binder.rocketmq.config.RocketMQBinderAutoConfiguration
\ No newline at end of file
+rocketmq:com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.RocketMQBinderAutoConfiguration
\ No newline at end of file
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
index 82d344e00..e18651dc4 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.alibaba.cloud.stream.binder.rocketmq.config.RocketMQComponent4BinderAutoConfiguration
+com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.ExtendedBindingHandlerMappingsProviderConfiguration
From c1c559717154a92d87739450ea85e3186fea4029 Mon Sep 17 00:00:00 2001
From: zkzlx
Date: Mon, 1 Feb 2021 13:46:28 +0800
Subject: [PATCH 09/99] Code refactoring and some new feature support - delete
some invalid files.
---
.../RocketMQListenerBindingContainer.java | 470 ------------------
.../RocketMQMessageQueueChooser.java | 62 ---
2 files changed, 532 deletions(-)
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQMessageQueueChooser.java
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
deleted file mode 100644
index 7bd875f33..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
+++ /dev/null
@@ -1,470 +0,0 @@
-/// *
-// * Copyright 2013-2018 the original author or authors.
-// *
-// * Licensed under the Apache License, Version 2.0 (the "License");
-// * you may not use this file except in compliance with the License.
-// * You may obtain a copy of the License at
-// *
-// * https://www.apache.org/licenses/LICENSE-2.0
-// *
-// * Unless required by applicable law or agreed to in writing, software
-// * distributed under the License is distributed on an "AS IS" BASIS,
-// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// * See the License for the specific language governing permissions and
-// * limitations under the License.
-// */
-//
-// package com.alibaba.cloud.stream.binder.rocketmq.consuming;
-//
-// import java.util.List;
-// import java.util.Objects;
-//
-// import com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderUtils;
-// import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
-// import
-/// com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
-// import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerProperties;
-// import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQHeaderMapper;
-// import org.apache.rocketmq.acl.common.AclClientRPCHook;
-// import org.apache.rocketmq.acl.common.SessionCredentials;
-// import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
-// import org.apache.rocketmq.client.consumer.MessageSelector;
-// import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
-// import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
-// import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyContext;
-// import org.apache.rocketmq.client.consumer.listener.ConsumeOrderlyStatus;
-// import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
-// import org.apache.rocketmq.client.consumer.listener.MessageListenerOrderly;
-// import org.apache.rocketmq.client.consumer.rebalance.AllocateMessageQueueAveragely;
-// import org.apache.rocketmq.client.exception.MQClientException;
-// import org.apache.rocketmq.common.UtilAll;
-// import org.apache.rocketmq.common.message.MessageExt;
-// import org.apache.rocketmq.remoting.RPCHook;
-// import org.apache.rocketmq.spring.annotation.ConsumeMode;
-// import org.apache.rocketmq.spring.annotation.MessageModel;
-// import org.apache.rocketmq.spring.annotation.SelectorType;
-// import org.apache.rocketmq.spring.core.RocketMQListener;
-// import org.apache.rocketmq.spring.core.RocketMQPushConsumerLifecycleListener;
-// import org.apache.rocketmq.spring.support.RocketMQListenerContainer;
-// import org.apache.rocketmq.spring.support.RocketMQUtil;
-// import org.slf4j.Logger;
-// import org.slf4j.LoggerFactory;
-//
-// import org.springframework.beans.factory.InitializingBean;
-// import org.springframework.cloud.stream.binder.ExtendedConsumerProperties;
-// import org.springframework.context.SmartLifecycle;
-// import org.springframework.integration.support.MessageBuilder;
-// import org.springframework.messaging.Message;
-// import org.springframework.util.Assert;
-// import org.springframework.util.StringUtils;
-//
-// import static
-/// com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderConstants.ROCKETMQ_RECONSUME_TIMES;
-//
-/// **
-// * A class that Listen on rocketmq message.
-// *
-// * this class will delegate {@link RocketMQListener} to handle message
-// *
-// * @author Jim
-// * @author Xiejiashuai
-// * @see RocketMQListener
-// */
-// public class RocketMQListenerBindingContainer
-// implements InitializingBean, RocketMQListenerContainer, SmartLifecycle {
-//
-// private final static Logger log = LoggerFactory
-// .getLogger(RocketMQListenerBindingContainer.class);
-//
-// private long suspendCurrentQueueTimeMillis = 1000;
-//
-// /**
-// * Message consume retry strategy
-// * -1,no retry,put into DLQ directly
-// * 0,broker control retry frequency
-// * >0,client control retry frequency.
-// */
-// private int delayLevelWhenNextConsume = 0;
-//
-// private List nameServer;
-//
-// private String consumerGroup;
-//
-// private String topic;
-//
-// private int consumeThreadMax = 64;
-//
-// private String charset = "UTF-8";
-//
-// private RocketMQListener rocketMQListener;
-//
-// private RocketMQHeaderMapper headerMapper;
-//
-// private DefaultMQPushConsumer consumer;
-//
-// private boolean running;
-//
-// private final ExtendedConsumerProperties
-/// rocketMQConsumerProperties;
-//
-// private final RocketMQMessageChannelBinder rocketMQMessageChannelBinder;
-//
-// private final RocketMQBinderConfigurationProperties
-/// rocketBinderConfigurationProperties;
-//
-// // The following properties came from RocketMQConsumerProperties.
-// private ConsumeMode consumeMode;
-//
-// private SelectorType selectorType;
-//
-// private String selectorExpression;
-//
-// private MessageModel messageModel;
-//
-// public RocketMQListenerBindingContainer(
-// ExtendedConsumerProperties rocketMQConsumerProperties,
-// RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties,
-// RocketMQMessageChannelBinder rocketMQMessageChannelBinder) {
-// this.rocketMQConsumerProperties = rocketMQConsumerProperties;
-// this.rocketBinderConfigurationProperties = rocketBinderConfigurationProperties;
-// this.rocketMQMessageChannelBinder = rocketMQMessageChannelBinder;
-// this.consumeMode = rocketMQConsumerProperties.getExtension().getOrderly()
-// ? ConsumeMode.ORDERLY : ConsumeMode.CONCURRENTLY;
-// if (StringUtils.isEmpty(rocketMQConsumerProperties.getExtension().getSql())) {
-// this.selectorType = SelectorType.TAG;
-// this.selectorExpression = rocketMQConsumerProperties.getExtension().getTags();
-// }
-// else {
-// this.selectorType = SelectorType.SQL92;
-// this.selectorExpression = rocketMQConsumerProperties.getExtension().getSql();
-// }
-// this.messageModel = rocketMQConsumerProperties.getExtension().getBroadcasting()
-// ? MessageModel.BROADCASTING : MessageModel.CLUSTERING;
-// }
-//
-// @Override
-// public void setupMessageListener(RocketMQListener> rocketMQListener) {
-// this.rocketMQListener = rocketMQListener;
-// }
-//
-// @Override
-// public void destroy() throws Exception {
-// this.setRunning(false);
-// if (Objects.nonNull(consumer)) {
-// consumer.shutdown();
-// }
-// log.info("container destroyed, {}", this.toString());
-// }
-//
-// @Override
-// public void afterPropertiesSet() throws Exception {
-// initRocketMQPushConsumer();
-// }
-//
-// @Override
-// public boolean isAutoStartup() {
-// return true;
-// }
-//
-// @Override
-// public void stop(Runnable callback) {
-// stop();
-// callback.run();
-// }
-//
-// @Override
-// public void start() {
-// if (this.isRunning()) {
-// throw new IllegalStateException(
-// "container already running. " + this.toString());
-// }
-//
-// try {
-// consumer.start();
-// }
-// catch (MQClientException e) {
-// throw new IllegalStateException("Failed to start RocketMQ push consumer", e);
-// }
-// this.setRunning(true);
-//
-// log.info("running container: {}", this.toString());
-// }
-//
-// @Override
-// public void stop() {
-// if (this.isRunning()) {
-// if (Objects.nonNull(consumer)) {
-// consumer.shutdown();
-// }
-// setRunning(false);
-// }
-// }
-//
-// @Override
-// public boolean isRunning() {
-// return running;
-// }
-//
-// private void setRunning(boolean running) {
-// this.running = running;
-// }
-//
-// @Override
-// public int getPhase() {
-// return Integer.MAX_VALUE;
-// }
-//
-// private void initRocketMQPushConsumer() throws MQClientException {
-// Assert.notNull(rocketMQListener, "Property 'rocketMQListener' is required");
-// Assert.notNull(consumerGroup, "Property 'consumerGroup' is required");
-// Assert.notNull(nameServer, "Property 'nameServer' is required");
-// Assert.notNull(topic, "Property 'topic' is required");
-//
-// String ak = rocketBinderConfigurationProperties.getAccessKey();
-// String sk = rocketBinderConfigurationProperties.getSecretKey();
-// if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
-// RPCHook rpcHook = new AclClientRPCHook(new SessionCredentials(ak, sk));
-// consumer = new DefaultMQPushConsumer(consumerGroup, rpcHook,
-// new AllocateMessageQueueAveragely(),
-// rocketBinderConfigurationProperties.isEnableMsgTrace(),
-// rocketBinderConfigurationProperties.getCustomizedTraceTopic());
-// consumer.setInstanceName(RocketMQUtil.getInstanceName(rpcHook,
-// topic + "|" + UtilAll.getPid()));
-// consumer.setVipChannelEnabled(false);
-// }
-// else {
-// consumer = new DefaultMQPushConsumer(consumerGroup,
-// rocketBinderConfigurationProperties.isEnableMsgTrace(),
-// rocketBinderConfigurationProperties.getCustomizedTraceTopic());
-// }
-//
-// consumer.setNamesrvAddr(RocketMQBinderUtils.getNameServerStr(nameServer));
-// consumer.setConsumeThreadMax(rocketMQConsumerProperties.getConcurrency());
-// consumer.setConsumeThreadMin(rocketMQConsumerProperties.getConcurrency());
-//
-// switch (messageModel) {
-// case BROADCASTING:
-// consumer.setMessageModel(
-// org.apache.rocketmq.common.protocol.heartbeat.MessageModel.BROADCASTING);
-// break;
-// case CLUSTERING:
-// consumer.setMessageModel(
-// org.apache.rocketmq.common.protocol.heartbeat.MessageModel.CLUSTERING);
-// break;
-// default:
-// throw new IllegalArgumentException("Property 'messageModel' was wrong.");
-// }
-//
-// switch (selectorType) {
-// case TAG:
-// consumer.subscribe(topic, selectorExpression);
-// break;
-// case SQL92:
-// consumer.subscribe(topic, MessageSelector.bySql(selectorExpression));
-// break;
-// default:
-// throw new IllegalArgumentException("Property 'selectorType' was wrong.");
-// }
-//
-// switch (consumeMode) {
-// case ORDERLY:
-// consumer.setMessageListener(new DefaultMessageListenerOrderly());
-// break;
-// case CONCURRENTLY:
-// consumer.setMessageListener(new DefaultMessageListenerConcurrently());
-// break;
-// default:
-// throw new IllegalArgumentException("Property 'consumeMode' was wrong.");
-// }
-//
-// if (rocketMQListener instanceof RocketMQPushConsumerLifecycleListener) {
-// ((RocketMQPushConsumerLifecycleListener) rocketMQListener)
-// .prepareStart(consumer);
-// }
-//
-// }
-//
-// @Override
-// public String toString() {
-// return "RocketMQListenerBindingContainer{" + "consumerGroup='" + consumerGroup
-// + '\'' + ", nameServer='" + nameServer + '\'' + ", topic='" + topic + '\''
-// + ", consumeMode=" + consumeMode + ", selectorType=" + selectorType
-// + ", selectorExpression='" + selectorExpression + '\'' + ", messageModel="
-// + messageModel + '}';
-// }
-//
-// public long getSuspendCurrentQueueTimeMillis() {
-// return suspendCurrentQueueTimeMillis;
-// }
-//
-// public void setSuspendCurrentQueueTimeMillis(long suspendCurrentQueueTimeMillis) {
-// this.suspendCurrentQueueTimeMillis = suspendCurrentQueueTimeMillis;
-// }
-//
-// public int getDelayLevelWhenNextConsume() {
-// return delayLevelWhenNextConsume;
-// }
-//
-// public void setDelayLevelWhenNextConsume(int delayLevelWhenNextConsume) {
-// this.delayLevelWhenNextConsume = delayLevelWhenNextConsume;
-// }
-//
-// public List getNameServer() {
-// return nameServer;
-// }
-//
-// public void setNameServer(List nameServer) {
-// this.nameServer = nameServer;
-// }
-//
-// public String getConsumerGroup() {
-// return consumerGroup;
-// }
-//
-// public void setConsumerGroup(String consumerGroup) {
-// this.consumerGroup = consumerGroup;
-// }
-//
-// public String getTopic() {
-// return topic;
-// }
-//
-// public void setTopic(String topic) {
-// this.topic = topic;
-// }
-//
-// public int getConsumeThreadMax() {
-// return consumeThreadMax;
-// }
-//
-// public void setConsumeThreadMax(int consumeThreadMax) {
-// this.consumeThreadMax = consumeThreadMax;
-// }
-//
-// public String getCharset() {
-// return charset;
-// }
-//
-// public void setCharset(String charset) {
-// this.charset = charset;
-// }
-//
-// public RocketMQListener getRocketMQListener() {
-// return rocketMQListener;
-// }
-//
-// public void setRocketMQListener(RocketMQListener rocketMQListener) {
-// this.rocketMQListener = rocketMQListener;
-// }
-//
-// public DefaultMQPushConsumer getConsumer() {
-// return consumer;
-// }
-//
-// public void setConsumer(DefaultMQPushConsumer consumer) {
-// this.consumer = consumer;
-// }
-//
-// public ExtendedConsumerProperties
-/// getRocketMQConsumerProperties() {
-// return rocketMQConsumerProperties;
-// }
-//
-// public ConsumeMode getConsumeMode() {
-// return consumeMode;
-// }
-//
-// public SelectorType getSelectorType() {
-// return selectorType;
-// }
-//
-// public String getSelectorExpression() {
-// return selectorExpression;
-// }
-//
-// public MessageModel getMessageModel() {
-// return messageModel;
-// }
-//
-// public RocketMQHeaderMapper getHeaderMapper() {
-// return headerMapper;
-// }
-//
-// public void setHeaderMapper(RocketMQHeaderMapper headerMapper) {
-// this.headerMapper = headerMapper;
-// }
-//
-// /**
-// * Convert rocketmq {@link MessageExt} to Spring {@link Message}.
-// * @param messageExt the rocketmq message
-// * @return the converted Spring {@link Message}
-// */
-// @SuppressWarnings("unchecked")
-// private Message convertToSpringMessage(MessageExt messageExt) {
-//
-// // add reconsume-times header to messageExt
-// int reconsumeTimes = messageExt.getReconsumeTimes();
-// messageExt.putUserProperty(ROCKETMQ_RECONSUME_TIMES,
-// String.valueOf(reconsumeTimes));
-// Message message = RocketMQUtil.convertToSpringMessage(messageExt);
-// return MessageBuilder.fromMessage(message)
-// .copyHeaders(headerMapper.toHeaders(messageExt.getProperties())).build();
-// }
-//
-// public class DefaultMessageListenerConcurrently
-// implements MessageListenerConcurrently {
-//
-// @SuppressWarnings({ "unchecked", "Duplicates" })
-// @Override
-// public ConsumeConcurrentlyStatus consumeMessage(List msgs,
-// ConsumeConcurrentlyContext context) {
-// for (MessageExt messageExt : msgs) {
-// log.debug("received msg: {}", messageExt);
-// try {
-// long now = System.currentTimeMillis();
-// rocketMQListener.onMessage(convertToSpringMessage(messageExt));
-// long costTime = System.currentTimeMillis() - now;
-// log.debug("consume {} message key:[{}] cost: {} ms",
-// messageExt.getMsgId(), messageExt.getKeys(), costTime);
-// }
-// catch (Exception e) {
-// log.warn("consume message failed. messageExt:{}", messageExt, e);
-// context.setDelayLevelWhenNextConsume(delayLevelWhenNextConsume);
-// return ConsumeConcurrentlyStatus.RECONSUME_LATER;
-// }
-// }
-//
-// return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
-// }
-//
-// }
-//
-// public class DefaultMessageListenerOrderly implements MessageListenerOrderly {
-//
-// @SuppressWarnings({ "unchecked", "Duplicates" })
-// @Override
-// public ConsumeOrderlyStatus consumeMessage(List msgs,
-// ConsumeOrderlyContext context) {
-// for (MessageExt messageExt : msgs) {
-// log.debug("received msg: {}", messageExt);
-// try {
-// long now = System.currentTimeMillis();
-// rocketMQListener.onMessage(convertToSpringMessage(messageExt));
-// long costTime = System.currentTimeMillis() - now;
-// log.info("consume {} message key:[{}] cost: {} ms",
-// messageExt.getMsgId(), messageExt.getKeys(), costTime);
-// }
-// catch (Exception e) {
-// log.warn("consume message failed. messageExt:{}", messageExt, e);
-// context.setSuspendCurrentQueueTimeMillis(
-// suspendCurrentQueueTimeMillis);
-// return ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT;
-// }
-// }
-//
-// return ConsumeOrderlyStatus.SUCCESS;
-// }
-//
-// }
-//
-// }
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQMessageQueueChooser.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQMessageQueueChooser.java
deleted file mode 100644
index 948555924..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQMessageQueueChooser.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.stream.binder.rocketmq.consuming;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.rocketmq.common.message.MessageQueue;
-
-/**
- * @author Jim
- */
-public class RocketMQMessageQueueChooser {
-
- private volatile int queueIndex = 0;
-
- private volatile List messageQueues;
-
- public MessageQueue choose() {
- return messageQueues.get(queueIndex);
- }
-
- public int requeue() {
- if (queueIndex - 1 < 0) {
- this.queueIndex = messageQueues.size() - 1;
- }
- else {
- this.queueIndex = this.queueIndex - 1;
- }
- return this.queueIndex;
- }
-
- public void increment() {
- this.queueIndex = (this.queueIndex + 1) % messageQueues.size();
- }
-
- public void reset(Set queueSet) {
- this.messageQueues = null;
- this.messageQueues = new ArrayList<>(queueSet);
- this.queueIndex = 0;
- }
-
- public List getMessageQueues() {
- return messageQueues;
- }
-
-}
From 7684fe71ca9e1257e658c2635644311fc5edb51f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=A4=A7=E7=9B=B8?=
Date: Fri, 26 Feb 2021 10:33:13 +0800
Subject: [PATCH 10/99] Upgrade Sentinel to 1.8.1
---
spring-cloud-alibaba-dependencies/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml
index 1fdaf8695..6914341bf 100644
--- a/spring-cloud-alibaba-dependencies/pom.xml
+++ b/spring-cloud-alibaba-dependencies/pom.xml
@@ -19,7 +19,7 @@
2.2.5.RC2
- 1.8.0
+ 1.8.11.3.01.4.10.8.0
From 15df0bff6b1f4489508e68c56ce59e09178f6cf0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=A4=A7=E7=9B=B8?=
Date: Fri, 26 Feb 2021 10:59:39 +0800
Subject: [PATCH 11/99] Upgrade Sentinel to 1.8.1
---
.../sentinel/endpoint/SentinelHealthIndicator.java | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java
index 996a483b7..8be1174a2 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java
@@ -16,17 +16,15 @@
package com.alibaba.cloud.sentinel.endpoint;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
import com.alibaba.cloud.sentinel.SentinelProperties;
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider;
import com.alibaba.csp.sentinel.transport.HeartbeatSender;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
-import com.alibaba.csp.sentinel.util.function.Tuple2;
-
+import com.alibaba.csp.sentinel.transport.endpoint.Endpoint;
+import java.util.List;
+import java.util.Map;
+import java.util.HashMap;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
@@ -84,8 +82,7 @@ public class SentinelHealthIndicator extends AbstractHealthIndicator {
// Check health of Dashboard
boolean dashboardUp = true;
- List> consoleServerList = TransportConfig
- .getConsoleServerList();
+ List consoleServerList = TransportConfig.getConsoleServerList();
if (CollectionUtils.isEmpty(consoleServerList)) {
// If Dashboard isn't configured, it's OK and mark the status of Dashboard
// with UNKNOWN.
From 4817ca53b86949dca8cbd1ca7cabcfd8057373f9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=A4=A7=E7=9B=B8?=
Date: Fri, 26 Feb 2021 11:32:15 +0800
Subject: [PATCH 12/99] Upgrade Sentinel to 1.8.1
---
.../cloud/sentinel/endpoint/SentinelHealthIndicator.java | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java
index 8be1174a2..b502fc543 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/main/java/com/alibaba/cloud/sentinel/endpoint/SentinelHealthIndicator.java
@@ -16,15 +16,17 @@
package com.alibaba.cloud.sentinel.endpoint;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import com.alibaba.cloud.sentinel.SentinelProperties;
import com.alibaba.csp.sentinel.datasource.AbstractDataSource;
import com.alibaba.csp.sentinel.heartbeat.HeartbeatSenderProvider;
import com.alibaba.csp.sentinel.transport.HeartbeatSender;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint;
-import java.util.List;
-import java.util.Map;
-import java.util.HashMap;
+
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
import org.springframework.boot.actuate.health.Health;
From 9d164f9a0a72ebba55f0d6c02d4a4ceca317a2dd Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=A4=A7=E7=9B=B8?=
Date: Fri, 26 Feb 2021 13:40:31 +0800
Subject: [PATCH 13/99] Upgrade Sentinel to 1.8.1
---
.../SentinelAutoConfigurationTests.java | 31 ++++++++++---------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java
index 56c5bf6bd..99b9fd3b5 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java
@@ -16,8 +16,11 @@
package com.alibaba.cloud.sentinel;
-import java.util.Arrays;
-import java.util.Map;
+import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration;
@@ -31,11 +34,13 @@ import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
-import com.alibaba.csp.sentinel.util.function.Tuple2;
+import com.alibaba.csp.sentinel.transport.endpoint.Endpoint;
+import com.alibaba.csp.sentinel.transport.endpoint.Protocol;
+import java.util.Arrays;
+import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
@@ -52,12 +57,6 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
-import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
-
/**
* @author Jim
* @author jiashuai.xie
@@ -134,8 +133,10 @@ public class SentinelAutoConfigurationTests {
Map map = sentinelEndpoint.invoke();
assertThat(map.get("logUsePid")).isEqualTo(Boolean.TRUE);
- assertThat(map.get("consoleServer").toString()).isEqualTo(
- Arrays.asList(Tuple2.of("localhost", 8080), Tuple2.of("localhost", 8081))
+ assertThat(map.get("consoleServer").toString())
+ .isEqualTo(Arrays
+ .asList(new Endpoint(Protocol.HTTP, "localhost", 8080),
+ new Endpoint(Protocol.HTTP, "localhost", 8081))
.toString());
assertThat(map.get("clientPort")).isEqualTo("9999");
assertThat(map.get("heartbeatIntervalMs")).isEqualTo(20000L);
@@ -185,8 +186,10 @@ public class SentinelAutoConfigurationTests {
@Test
public void testSentinelSystemProperties() {
assertThat(LogBase.isLogNameUsePid()).isEqualTo(true);
- assertThat(TransportConfig.getConsoleServerList().toString()).isEqualTo(
- Arrays.asList(Tuple2.of("localhost", 8080), Tuple2.of("localhost", 8081))
+ assertThat(TransportConfig.getConsoleServerList().toString())
+ .isEqualTo(Arrays
+ .asList(new Endpoint(Protocol.HTTP, "localhost", 8080),
+ new Endpoint(Protocol.HTTP, "localhost", 8081))
.toString());
assertThat(TransportConfig.getPort()).isEqualTo("9999");
assertThat(TransportConfig.getHeartbeatIntervalMs().longValue())
From 2701624da227149e39b9890702a91c3390a15514 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=BB=84=E5=A4=A7=E7=9B=B8?=
Date: Fri, 26 Feb 2021 13:54:51 +0800
Subject: [PATCH 14/99] Upgrade Sentinel to 1.8.1
---
.../sentinel/SentinelAutoConfigurationTests.java | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java
index 99b9fd3b5..2b4c51e0f 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-sentinel/src/test/java/com/alibaba/cloud/sentinel/SentinelAutoConfigurationTests.java
@@ -16,11 +16,8 @@
package com.alibaba.cloud.sentinel;
-import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.Mockito.mock;
-import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+import java.util.Arrays;
+import java.util.Map;
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import com.alibaba.cloud.sentinel.custom.SentinelAutoConfiguration;
@@ -36,11 +33,10 @@ import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.transport.config.TransportConfig;
import com.alibaba.csp.sentinel.transport.endpoint.Endpoint;
import com.alibaba.csp.sentinel.transport.endpoint.Protocol;
-import java.util.Arrays;
-import java.util.Map;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
@@ -57,6 +53,12 @@ import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;
+import static com.alibaba.cloud.sentinel.SentinelConstants.BLOCK_PAGE_URL_CONF_KEY;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.mock;
+import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
+
/**
* @author Jim
* @author jiashuai.xie
From fd1deaa475c907f9048dd30caf721235a09d8140 Mon Sep 17 00:00:00 2001
From: dhb
Date: Thu, 11 Mar 2021 12:21:02 +0800
Subject: [PATCH 15/99] fix dubbo service group and service merger cannot
obtain urls
---
.../DubboServiceMetadataRepository.java | 32 +++++++++++++++++--
1 file changed, 30 insertions(+), 2 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
index a5be34df8..494c78c68 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
@@ -19,6 +19,7 @@ package com.alibaba.cloud.dubbo.metadata.repository;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -41,6 +42,7 @@ import com.alibaba.cloud.dubbo.util.JSONUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.constants.CommonConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -407,8 +409,34 @@ public class DubboServiceMetadataRepository
public List getExportedURLs(String serviceInterface, String group,
String version) {
- String serviceKey = URL.buildKey(serviceInterface, group, version);
- return allExportedURLs.getOrDefault(serviceKey, Collections.emptyList());
+ if (group != null) {
+ List urls = new LinkedList<>();
+ if (CommonConstants.ANY_VALUE.equals(group)) {
+ String serviceKey = URL.buildKey(serviceInterface, group, version);
+ String expectKey = serviceKey.substring(2);
+ for (String key : allExportedURLs.keySet()) {
+ if (key.endsWith(expectKey)) {
+ urls.addAll(allExportedURLs.get(key));
+ }
+ }
+ }
+ else {
+ String[] groups = group.split(CommonConstants.COMMA_SEPARATOR);
+ for (String expectKey : groups) {
+ String serviceKey = URL.buildKey(serviceInterface, expectKey,
+ version);
+ List urlList = allExportedURLs.get(serviceKey);
+ if (urlList != null) {
+ urls.addAll(urlList);
+ }
+ }
+ }
+ return urls;
+ }
+ else {
+ String serviceKey = URL.buildKey(serviceInterface, null, version);
+ return allExportedURLs.getOrDefault(serviceKey, Collections.emptyList());
+ }
}
/**
From b7f1dc9b04749b23e4cef0d2d0fd85ceac912816 Mon Sep 17 00:00:00 2001
From: luyanbo
Date: Mon, 15 Mar 2021 17:12:07 +0800
Subject: [PATCH 16/99] =?UTF-8?q?=E6=B7=BB=E5=8A=A0RamRoleName=E6=94=AF?=
=?UTF-8?q?=E6=8C=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../cloud/nacos/NacosConfigProperties.java | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java
index 4827aebf1..6722f8bba 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/NacosConfigProperties.java
@@ -53,6 +53,7 @@ import static com.alibaba.nacos.api.PropertyKeyConst.ENDPOINT_PORT;
import static com.alibaba.nacos.api.PropertyKeyConst.MAX_RETRY;
import static com.alibaba.nacos.api.PropertyKeyConst.NAMESPACE;
import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
+import static com.alibaba.nacos.api.PropertyKeyConst.RAM_ROLE_NAME;
import static com.alibaba.nacos.api.PropertyKeyConst.SECRET_KEY;
import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
@@ -202,6 +203,11 @@ public class NacosConfigProperties {
*/
private String secretKey;
+ /**
+ * access key for namespace.
+ */
+ private String ramRoleName;
+
/**
* context path for nacos config server.
*/
@@ -356,6 +362,14 @@ public class NacosConfigProperties {
this.secretKey = secretKey;
}
+ public String getRamRoleName() {
+ return ramRoleName;
+ }
+
+ public void setRamRoleName(String ramRoleName) {
+ this.ramRoleName = ramRoleName;
+ }
+
public String getEncode() {
return encode;
}
@@ -548,6 +562,7 @@ public class NacosConfigProperties {
properties.put(NAMESPACE, Objects.toString(this.namespace, ""));
properties.put(ACCESS_KEY, Objects.toString(this.accessKey, ""));
properties.put(SECRET_KEY, Objects.toString(this.secretKey, ""));
+ properties.put(RAM_ROLE_NAME, Objects.toString(this.ramRoleName, ""));
properties.put(CLUSTER_NAME, Objects.toString(this.clusterName, ""));
properties.put(MAX_RETRY, Objects.toString(this.maxRetry, ""));
properties.put(CONFIG_LONG_POLL_TIMEOUT,
@@ -560,8 +575,7 @@ public class NacosConfigProperties {
int index = endpoint.indexOf(":");
properties.put(ENDPOINT, endpoint.substring(0, index));
properties.put(ENDPOINT_PORT, endpoint.substring(index + 1));
- }
- else {
+ } else {
properties.put(ENDPOINT, endpoint);
}
@@ -597,6 +611,7 @@ public class NacosConfigProperties {
+ ", enableRemoteSyncConfig=" + enableRemoteSyncConfig + ", endpoint='"
+ endpoint + '\'' + ", namespace='" + namespace + '\'' + ", accessKey='"
+ accessKey + '\'' + ", secretKey='" + secretKey + '\''
+ + ", ramRoleName='" + ramRoleName + '\''
+ ", contextPath='" + contextPath + '\'' + ", clusterName='" + clusterName
+ '\'' + ", name='" + name + '\'' + '\'' + ", shares=" + sharedConfigs
+ ", extensions=" + extensionConfigs + ", refreshEnabled="
From 6d7c47a3660de3aa40fd519f52c84947638a4733 Mon Sep 17 00:00:00 2001
From: zkzlx
Date: Mon, 22 Mar 2021 11:05:31 +0800
Subject: [PATCH 17/99] Code refactoring and some new feature support - delete
some invalid files.
---
.../src/main/resources/application.properties | 8 ++--
.../alibaba/cloud/examples/SenderService.java | 4 +-
.../examples/TransactionListenerImpl.java | 38 +++++++++----------
.../src/main/resources/application.properties | 1 +
.../rocketmq/contants/RocketMQConst.java | 13 +------
.../inbound/pull/RocketMQMessageSource.java | 25 +++++++++---
.../RocketMQProducerMessageHandler.java | 2 +-
.../binder/rocketmq/utils/RocketMQUtils.java | 3 +-
.../RocketMQAutoConfigurationTests.java | 22 +++++------
9 files changed, 61 insertions(+), 55 deletions(-)
diff --git a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-consume-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-consume-example/src/main/resources/application.properties
index 2779db522..e2e77bd0b 100644
--- a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-consume-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-consume-example/src/main/resources/application.properties
@@ -3,20 +3,20 @@ spring.cloud.stream.rocketmq.binder.name-server=127.0.0.1:9876
spring.cloud.stream.bindings.input1.destination=test-topic
spring.cloud.stream.bindings.input1.content-type=text/plain
spring.cloud.stream.bindings.input1.group=test-group1
-spring.cloud.stream.rocketmq.bindings.input1.consumer.orderly=true
+spring.cloud.stream.rocketmq.bindings.input1.consumer.push.orderly=true
spring.cloud.stream.bindings.input2.destination=test-topic
spring.cloud.stream.bindings.input2.content-type=text/plain
spring.cloud.stream.bindings.input2.group=test-group2
-spring.cloud.stream.rocketmq.bindings.input2.consumer.orderly=false
-spring.cloud.stream.rocketmq.bindings.input2.consumer.tags=tagStr
+spring.cloud.stream.rocketmq.bindings.input2.consumer.push.orderly=false
+spring.cloud.stream.rocketmq.bindings.input2.consumer.subscription=tagStr
spring.cloud.stream.bindings.input2.consumer.concurrency=20
spring.cloud.stream.bindings.input2.consumer.maxAttempts=1
spring.cloud.stream.bindings.input3.destination=test-topic
spring.cloud.stream.bindings.input3.content-type=application/json
spring.cloud.stream.bindings.input3.group=test-group3
-spring.cloud.stream.rocketmq.bindings.input3.consumer.tags=tagObj
+spring.cloud.stream.rocketmq.bindings.input3.consumer.subscription=tagObj
spring.cloud.stream.bindings.input3.consumer.concurrency=20
spring.cloud.stream.bindings.input4.destination=TransactionTopic
diff --git a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/SenderService.java b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/SenderService.java
index cd9e50939..f7db15b57 100644
--- a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/SenderService.java
+++ b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/SenderService.java
@@ -20,8 +20,8 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.alibaba.cloud.examples.RocketMQProduceApplication.MySource;
+import com.alibaba.cloud.stream.binder.rocketmq.contants.RocketMQConst;
import org.apache.rocketmq.common.message.MessageConst;
-import org.apache.rocketmq.spring.support.RocketMQHeaders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
@@ -62,7 +62,7 @@ public class SenderService {
MessageBuilder builder = MessageBuilder.withPayload(msg)
.setHeader(MessageHeaders.CONTENT_TYPE, MimeTypeUtils.APPLICATION_JSON);
builder.setHeader("test", String.valueOf(num));
- builder.setHeader(RocketMQHeaders.TAGS, "binder");
+ builder.setHeader(RocketMQConst.USER_TRANSACTIONAL_ARGS, "binder");
Message message = builder.build();
source.output2().send(message);
}
diff --git a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java
index e58beb221..1cc1b3290 100644
--- a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java
+++ b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java
@@ -16,43 +16,43 @@
package com.alibaba.cloud.examples;
-import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
-import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
-import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
-import org.springframework.messaging.Message;
+import org.apache.rocketmq.client.producer.LocalTransactionState;
+import org.apache.rocketmq.client.producer.TransactionListener;
+import org.apache.rocketmq.common.message.Message;
+import org.apache.rocketmq.common.message.MessageExt;
+import org.springframework.stereotype.Component;
/**
* @author Jim
*/
-@RocketMQTransactionListener(txProducerGroup = "myTxProducerGroup", corePoolSize = 5,
- maximumPoolSize = 10)
-public class TransactionListenerImpl implements RocketMQLocalTransactionListener {
+@Component("myTransactionListener")
+public class TransactionListenerImpl implements TransactionListener {
@Override
- public RocketMQLocalTransactionState executeLocalTransaction(Message msg,
- Object arg) {
- Object num = msg.getHeaders().get("test");
+ public LocalTransactionState executeLocalTransaction(Message msg,
+ Object arg) {
+ Object num = msg.getProperty("test");
if ("1".equals(num)) {
System.out.println(
- "executer: " + new String((byte[]) msg.getPayload()) + " unknown");
- return RocketMQLocalTransactionState.UNKNOWN;
+ "executer: " + new String(msg.getBody()) + " unknown");
+ return LocalTransactionState.UNKNOW;
}
else if ("2".equals(num)) {
System.out.println(
- "executer: " + new String((byte[]) msg.getPayload()) + " rollback");
- return RocketMQLocalTransactionState.ROLLBACK;
+ "executer: " + new String(msg.getBody()) + " rollback");
+ return LocalTransactionState.ROLLBACK_MESSAGE;
}
System.out.println(
- "executer: " + new String((byte[]) msg.getPayload()) + " commit");
- return RocketMQLocalTransactionState.COMMIT;
+ "executer: " + new String(msg.getBody()) + " commit");
+ return LocalTransactionState.COMMIT_MESSAGE;
}
@Override
- public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
- System.out.println("check: " + new String((byte[]) msg.getPayload()));
- return RocketMQLocalTransactionState.COMMIT;
+ public LocalTransactionState checkLocalTransaction(MessageExt msg) {
+ System.out.println("check: " + new String(msg.getBody()));
+ return LocalTransactionState.COMMIT_MESSAGE;
}
}
diff --git a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties
index 772bf456e..08ab26ca0 100644
--- a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties
@@ -11,6 +11,7 @@ spring.cloud.stream.bindings.output2.destination=TransactionTopic
spring.cloud.stream.bindings.output2.content-type=application/json
spring.cloud.stream.rocketmq.bindings.output2.producer.transactional=true
spring.cloud.stream.rocketmq.bindings.output2.producer.group=myTxProducerGroup
+spring.cloud.stream.rocketmq.bindings.output2.producer.transactionListener=myTransactionListener
spring.cloud.stream.bindings.output3.destination=pull-topic
spring.cloud.stream.bindings.output3.content-type=text/plain
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
index e83a6a172..694c8519c 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
@@ -18,18 +18,11 @@ package com.alibaba.cloud.stream.binder.rocketmq.contants;
import org.apache.rocketmq.common.message.MessageConst;
-import static org.apache.rocketmq.spring.support.RocketMQHeaders.PREFIX;
-
/**
* @author zkzlx
*/
public class RocketMQConst extends MessageConst {
- /**
- * Header key for RocketMQ Transactional Args.
- */
- public static final String ROCKET_TRANSACTIONAL_ARG = "TRANSACTIONAL_ARG";
-
/**
* Default NameServer value.
*/
@@ -38,12 +31,8 @@ public class RocketMQConst extends MessageConst {
/**
* Default group for SCS RocketMQ Binder.
*/
- public static final String DEFAULT_GROUP = PREFIX + "binder_default_group_name";
+ public static final String DEFAULT_GROUP = "binder_default_group_name";
- /**
- * RocketMQ re-consume times.
- */
- public static final String ROCKETMQ_RECONSUME_TIMES = PREFIX + "RECONSUME_TIMES";
public static final String USER_TRANSACTIONAL_ARGS = "TRANSACTIONAL_ARGS";
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
index 2ca91384b..a378fc615 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
@@ -17,6 +17,7 @@
package com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.pull;
import java.lang.reflect.Field;
+import java.util.Iterator;
import java.util.List;
import com.alibaba.cloud.stream.binder.rocketmq.integration.inbound.RocketMQConsumerFactory;
@@ -62,6 +63,8 @@ public class RocketMQMessageSource extends AbstractMessageSource
private final MessageSelector messageSelector;
private final ExtendedConsumerProperties extendedConsumerProperties;
+ private volatile Iterator messageExtIterator=null;
+
public RocketMQMessageSource(String name,
ExtendedConsumerProperties extendedConsumerProperties) {
this.topic = name;
@@ -82,7 +85,7 @@ public class RocketMQMessageSource extends AbstractMessageSource
this.consumer = RocketMQConsumerFactory
.initPullConsumer(extendedConsumerProperties);
// This parameter must be 1, otherwise doReceive cannot be handled singly.
- this.consumer.setPullBatchSize(1);
+// this.consumer.setPullBatchSize(1);
this.consumer.subscribe(topic, messageSelector);
this.consumer.setAutoCommit(false);
this.assignedMessageQueue = acquireAssignedMessageQueue(this.consumer);
@@ -132,11 +135,20 @@ public class RocketMQMessageSource extends AbstractMessageSource
@Override
protected synchronized Object doReceive() {
- List messageExtList = consumer.poll();
- if (CollectionUtils.isEmpty(messageExtList) || messageExtList.size() > 1) {
+ if(messageExtIterator == null){
+ List messageExtList = consumer.poll();
+ if (CollectionUtils.isEmpty(messageExtList) || messageExtList.size() > 1) {
+ return null;
+ }
+ messageExtIterator = messageExtList.iterator();
+ }
+ MessageExt messageExt=messageExtIterator.next();
+ if(!messageExtIterator.hasNext()){
+ messageExtIterator = null;
+ }
+ if(null == messageExt){
return null;
}
- MessageExt messageExt = messageExtList.get(0);
MessageQueue messageQueue = null;
for (MessageQueue queue : assignedMessageQueue.getAssignedMessageQueues()) {
if (queue.getQueueId() == messageExt.getQueueId()) {
@@ -144,8 +156,11 @@ public class RocketMQMessageSource extends AbstractMessageSource
break;
}
}
+ if(messageQueue == null){
+ throw new IllegalArgumentException("The message queue is not in assigned list");
+ }
Message message = RocketMQMessageConverterSupport
- .convertMessage2Spring(messageExtList.get(0));
+ .convertMessage2Spring(messageExt);
return MessageBuilder.fromMessage(message)
.setHeader(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK,
new RocketMQAckCallback(this.consumer, assignedMessageQueue,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
index 66b58f797..3d58b8af0 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
@@ -160,7 +160,7 @@ public class RocketMQProducerMessageHandler extends AbstractMessageHandler
TransactionListener.class);
if (transactionListener == null) {
throw new MessagingException(
- "TransactionMQProducer must have a TransactionMQProducer !!! ");
+ "TransactionMQProducer must have a TransactionListener !!! ");
}
((TransactionMQProducer) defaultMQProducer)
.setTransactionListener(transactionListener);
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
index 3f7898422..85165955d 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
@@ -16,6 +16,7 @@
package com.alibaba.cloud.stream.binder.rocketmq.utils;
+import com.alibaba.cloud.stream.binder.rocketmq.contants.RocketMQConst;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQCommonProperties;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
@@ -81,7 +82,7 @@ public class RocketMQUtils {
public static String getNameServerStr(String nameServer) {
if (StringUtils.isEmpty(nameServer)) {
- return null;
+ return RocketMQConst.DEFAULT_NAME_SERVER;
}
return nameServer.replaceAll(",", ";");
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
index 8207f9893..02d0de9f9 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
@@ -18,7 +18,7 @@ package com.alibaba.cloud.stream.binder.rocketmq;
import java.util.Arrays;
-import com.alibaba.cloud.stream.binder.rocketmq.config.RocketMQBinderAutoConfiguration;
+import com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.RocketMQBinderAutoConfiguration;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
import org.junit.Test;
@@ -37,20 +37,20 @@ public class RocketMQAutoConfigurationTests {
.withConfiguration(
AutoConfigurations.of(RocketMQBinderAutoConfiguration.class))
.withPropertyValues(
- "spring.cloud.stream.rocketmq.binder.name-server[0]=127.0.0.1:9876",
- "spring.cloud.stream.rocketmq.binder.name-server[1]=127.0.0.1:9877",
+ "spring.cloud.stream.rocketmq.binder.name-server=127.0.0.1:9876,127.0.0.1:9877",
"spring.cloud.stream.bindings.output.destination=TopicOrderTest",
"spring.cloud.stream.bindings.output.content-type=application/json",
+
"spring.cloud.stream.bindings.input1.destination=TopicOrderTest",
"spring.cloud.stream.bindings.input1.content-type=application/json",
"spring.cloud.stream.bindings.input1.group=test-group1",
- "spring.cloud.stream.rocketmq.bindings.input1.consumer.orderly=true",
+ "spring.cloud.stream.rocketmq.bindings.input1.consumer.push.orderly=true",
"spring.cloud.stream.bindings.input1.consumer.maxAttempts=1",
"spring.cloud.stream.bindings.input2.destination=TopicOrderTest",
"spring.cloud.stream.bindings.input2.content-type=application/json",
"spring.cloud.stream.bindings.input2.group=test-group2",
- "spring.cloud.stream.rocketmq.bindings.input2.consumer.orderly=false",
- "spring.cloud.stream.rocketmq.bindings.input2.consumer.tags=tag1");
+ "spring.cloud.stream.rocketmq.bindings.input2.consumer.push.orderly=false",
+ "spring.cloud.stream.rocketmq.bindings.input2.consumer.subscription=tag1");
@Test
public void testProperties() {
@@ -58,16 +58,16 @@ public class RocketMQAutoConfigurationTests {
RocketMQBinderConfigurationProperties binderConfigurationProperties = context
.getBean(RocketMQBinderConfigurationProperties.class);
assertThat(binderConfigurationProperties.getNameServer())
- .isEqualTo(Arrays.asList("127.0.0.1:9876", "127.0.0.1:9877"));
+ .isEqualTo("127.0.0.1:9876,127.0.0.1:9877");
RocketMQExtendedBindingProperties bindingProperties = context
.getBean(RocketMQExtendedBindingProperties.class);
assertThat(
- bindingProperties.getExtendedConsumerProperties("input2").getTags())
+ bindingProperties.getExtendedConsumerProperties("input2").getSubscription())
.isEqualTo("tag1");
- assertThat(bindingProperties.getExtendedConsumerProperties("input2")
- .getOrderly()).isFalse();
+ assertThat(bindingProperties.getExtendedConsumerProperties("input2").getPush().getOrderly()
+ ).isFalse();
assertThat(bindingProperties.getExtendedConsumerProperties("input1")
- .getOrderly()).isTrue();
+ .getPush().getOrderly()).isTrue();
});
}
From 9379d18ace1a4ca3fb2400920c7e95b17eb4fda9 Mon Sep 17 00:00:00 2001
From: zkzlx
Date: Mon, 22 Mar 2021 14:37:22 +0800
Subject: [PATCH 18/99] Code style
---
.../examples/TransactionListenerImpl.java | 14 +++---
.../RocketMQMessageChannelBinder.java | 7 +--
.../RocketMQBinderAutoConfiguration.java | 4 +-
.../rocketmq/contants/RocketMQConst.java | 33 +++++++++++---
.../convert/RocketMQMessageConverter.java | 14 ++++--
.../custom/RocketMQBeanContainerCache.java | 9 ++--
.../RocketMQConfigBeanPostProcessor.java | 6 +--
.../extend/ErrorAcknowledgeHandler.java | 6 +--
.../inbound/RocketMQConsumerFactory.java | 6 ++-
.../RocketMQInboundChannelAdapter.java | 12 ++---
.../pull/DefaultErrorAcknowledgeHandler.java | 9 ++--
.../inbound/pull/RocketMQAckCallback.java | 13 ++++--
.../inbound/pull/RocketMQMessageSource.java | 21 +++++----
.../outbound/RocketMQProduceFactory.java | 9 +++-
.../RocketMQProducerMessageHandler.java | 24 ++++++----
.../rocketmq/metrics/Instrumentation.java | 14 ++++++
.../metrics/InstrumentationManager.java | 3 ++
...RocketMQBinderConfigurationProperties.java | 5 ++-
.../properties/RocketMQCommonProperties.java | 29 ++++++------
.../RocketMQConsumerProperties.java | 45 ++++++++++---------
.../RocketMQExtendedBindingProperties.java | 4 +-
.../RocketMQProducerProperties.java | 32 ++++++++++---
.../RocketMQSpecificPropertiesProvider.java | 4 +-
.../RocketMQMessageConverterSupport.java | 10 +++--
.../binder/rocketmq/utils/RocketMQUtils.java | 11 ++---
.../RocketMQAutoConfigurationTests.java | 15 +++----
26 files changed, 231 insertions(+), 128 deletions(-)
diff --git a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java
index 1cc1b3290..446570ec9 100644
--- a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java
+++ b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/java/com/alibaba/cloud/examples/TransactionListenerImpl.java
@@ -16,11 +16,11 @@
package com.alibaba.cloud.examples;
-
import org.apache.rocketmq.client.producer.LocalTransactionState;
import org.apache.rocketmq.client.producer.TransactionListener;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;
+
import org.springframework.stereotype.Component;
/**
@@ -30,22 +30,18 @@ import org.springframework.stereotype.Component;
public class TransactionListenerImpl implements TransactionListener {
@Override
- public LocalTransactionState executeLocalTransaction(Message msg,
- Object arg) {
+ public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
Object num = msg.getProperty("test");
if ("1".equals(num)) {
- System.out.println(
- "executer: " + new String(msg.getBody()) + " unknown");
+ System.out.println("executer: " + new String(msg.getBody()) + " unknown");
return LocalTransactionState.UNKNOW;
}
else if ("2".equals(num)) {
- System.out.println(
- "executer: " + new String(msg.getBody()) + " rollback");
+ System.out.println("executer: " + new String(msg.getBody()) + " rollback");
return LocalTransactionState.ROLLBACK_MESSAGE;
}
- System.out.println(
- "executer: " + new String(msg.getBody()) + " commit");
+ System.out.println("executer: " + new String(msg.getBody()) + " commit");
return LocalTransactionState.COMMIT_MESSAGE;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
index 5683bff68..403f51476 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -60,6 +60,7 @@ public class RocketMQMessageChannelBinder extends
ExtendedPropertiesBinder {
private final RocketMQExtendedBindingProperties extendedBindingProperties;
+
private final RocketMQBinderConfigurationProperties binderConfigurationProperties;
public RocketMQMessageChannelBinder(
@@ -175,7 +176,6 @@ public class RocketMQMessageChannelBinder extends
/**
* Binders can return an {@link ErrorMessageStrategy} for building error messages;
* binder implementations typically might add extra headers to the error message.
- *
* @return the implementation - may be null.
*/
@Override
@@ -203,4 +203,5 @@ public class RocketMQMessageChannelBinder extends
public Class extends BinderSpecificPropertiesProvider> getExtendedPropertiesEntryClass() {
return this.extendedBindingProperties.getExtendedPropertiesEntryClass();
}
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
index abcb9b961..ec47e951a 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
@@ -34,7 +34,8 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.converter.CompositeMessageConverter;
/**
- * issue:https://github.com/alibaba/spring-cloud-alibaba/issues/1681
+ * issue:https://github.com/alibaba/spring-cloud-alibaba/issues/1681 .
+ *
* @author Timur Valiev
* @author Jim
*/
@@ -45,6 +46,7 @@ public class RocketMQBinderAutoConfiguration {
@Autowired
private RocketMQExtendedBindingProperties extendedBindingProperties;
+
@Autowired
private RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
index 694c8519c..4f893642e 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/contants/RocketMQConst.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,9 +31,11 @@ public class RocketMQConst extends MessageConst {
/**
* Default group for SCS RocketMQ Binder.
*/
- public static final String DEFAULT_GROUP = "binder_default_group_name";
-
+ public static final String DEFAULT_GROUP = "binder_default_group_name";
+ /**
+ * user args for SCS RocketMQ Binder.
+ */
public static final String USER_TRANSACTIONAL_ARGS = "TRANSACTIONAL_ARGS";
/**
@@ -41,19 +43,34 @@ public class RocketMQConst extends MessageConst {
* and parameters are passed through HEADERS.
*/
public static class Headers {
+
+ /**
+ * keys for SCS RocketMQ Headers.
+ */
public static final String KEYS = MessageConst.PROPERTY_KEYS;
+
+ /**
+ * tags for SCS RocketMQ Headers.
+ */
public static final String TAGS = MessageConst.PROPERTY_TAGS;
+
+ /**
+ * topic for SCS RocketMQ Headers.
+ */
public static final String TOPIC = "MQ_TOPIC";
+
/**
* The ID of the message.
*/
public static final String MESSAGE_ID = "MQ_MESSAGE_ID";
+
/**
* The timestamp that the message producer invokes the message sending API.
*/
public static final String BORN_TIMESTAMP = "MQ_BORN_TIMESTAMP";
+
/**
- * The IP and port number of the message producer
+ * The IP and port number of the message producer.
*/
public static final String BORN_HOST = "MQ_BORN_HOST";
@@ -61,19 +78,23 @@ public class RocketMQConst extends MessageConst {
* Message flag, MQ is not processed and is available for use by applications.
*/
public static final String FLAG = "MQ_FLAG";
+
/**
- * Message consumption queue ID
+ * Message consumption queue ID.
*/
public static final String QUEUE_ID = "MQ_QUEUE_ID";
+
/**
* Message system Flag, such as whether or not to compress, whether or not to
* transactional messages.
*/
public static final String SYS_FLAG = "MQ_SYS_FLAG";
+
/**
* The transaction ID of the transaction message.
*/
public static final String TRANSACTION_ID = "MQ_TRANSACTION_ID";
+
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java
index 58f17c6ef..98bd03263 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/convert/RocketMQMessageConverter.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,14 +27,19 @@ import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.util.ClassUtils;
/**
- * The default message converter of rocketMq,its bean name is {@link #DEFAULT_NAME}
+ * The default message converter of rocketMq,its bean name is {@link #DEFAULT_NAME} .
+ *
* @author zkzlx
*/
public class RocketMQMessageConverter {
+ /**
+ * rocketMQMessageConverter.
+ */
public static final String DEFAULT_NAME = "rocketMQMessageConverter";
private static final boolean JACKSON_PRESENT;
+
private static final boolean FASTJSON_PRESENT;
static {
@@ -81,4 +86,5 @@ public class RocketMQMessageConverter {
public void setMessageConverter(CompositeMessageConverter messageConverter) {
this.messageConverter = messageConverter;
}
-}
\ No newline at end of file
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java
index 9afc94821..21c62aede 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQBeanContainerCache.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -32,12 +32,15 @@ import org.springframework.messaging.converter.CompositeMessageConverter;
import org.springframework.util.StringUtils;
/**
- * Gets the beans configured in the configuration file
+ * Gets the beans configured in the configuration file.
*
* @author junboXiang
*/
public final class RocketMQBeanContainerCache {
+ private RocketMQBeanContainerCache() {
+ }
+
private static final Class>[] CLASSES = new Class[] {
CompositeMessageConverter.class, AllocateMessageQueueStrategy.class,
MessageQueueSelector.class, MessageListener.class, TransactionListener.class,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java
index 30bd64328..a83fdbe08 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/custom/RocketMQConfigBeanPostProcessor.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,7 +22,7 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
- * find RocketMQ bean by annotations
+ * find RocketMQ bean by annotations.
*
* @author junboXiang
*
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java
index fcf6de804..dfe65fd94 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/extend/ErrorAcknowledgeHandler.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,7 +27,7 @@ public interface ErrorAcknowledgeHandler {
/**
* Ack state handling, including receive, reject, and retry, when a consumption
* exception occurs.
- * @param message
+ * @param message message
* @return see {@link Status}
*/
Status handler(Message> message);
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
index 876249581..7f7e1bf26 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
@@ -41,6 +41,9 @@ import org.springframework.util.StringUtils;
*/
public final class RocketMQConsumerFactory {
+ private RocketMQConsumerFactory() {
+ }
+
private final static Logger log = LoggerFactory
.getLogger(RocketMQConsumerFactory.class);
@@ -91,7 +94,8 @@ public final class RocketMQConsumerFactory {
/**
* todo Compatible with versions less than 4.6 ?
- * @return
+ * @param extendedConsumerProperties extendedConsumerProperties
+ * @return DefaultLitePullConsumer
*/
public static DefaultLitePullConsumer initPullConsumer(
ExtendedConsumerProperties extendedConsumerProperties) {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java
index d0aec5523..61c0eedd3 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQInboundChannelAdapter.java
@@ -48,7 +48,6 @@ import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
- * TODO Describe what it does
* @author Jim
*/
public class RocketMQInboundChannelAdapter extends MessageProducerSupport
@@ -58,10 +57,13 @@ public class RocketMQInboundChannelAdapter extends MessageProducerSupport
.getLogger(RocketMQInboundChannelAdapter.class);
private RetryTemplate retryTemplate;
+
private RecoveryCallback recoveryCallback;
+
private DefaultMQPushConsumer pushConsumer;
private final String topic;
+
private final ExtendedConsumerProperties extendedConsumerProperties;
public RocketMQInboundChannelAdapter(String topic,
@@ -146,11 +148,11 @@ public class RocketMQInboundChannelAdapter extends MessageProducerSupport
* The actual execution of a user-defined input consumption service method.
* @param messageExtList rocket mq message list
* @param failSupplier {@link ConsumeConcurrentlyStatus} or
- * {@link ConsumeOrderlyStatus}
+ * {@link ConsumeOrderlyStatus}
* @param sucSupplier {@link ConsumeConcurrentlyStatus} or
- * {@link ConsumeOrderlyStatus}
- * @param
- * @return
+ * {@link ConsumeOrderlyStatus}
+ * @param object
+ * @return R
*/
private R consumeMessage(List messageExtList,
Supplier failSupplier, Supplier sucSupplier) {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java
index 3296a128e..458324741 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/DefaultErrorAcknowledgeHandler.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -29,15 +29,16 @@ import org.springframework.messaging.Message;
* @author zkzlx
*/
public class DefaultErrorAcknowledgeHandler implements ErrorAcknowledgeHandler {
+
/**
* Ack state handling, including receive, reject, and retry, when a consumption
* exception occurs.
- *
- * @param message
+ * @param message message
* @return see {@link Status}
*/
@Override
public Status handler(Message> message) {
return Status.REQUEUE;
}
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java
index f617dd097..56e50ca4a 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQAckCallback.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -31,16 +31,23 @@ import org.springframework.util.Assert;
/**
* A pollable {@link org.springframework.integration.core.MessageSource} for RocketMQ.
+ *
* @author zkzlx
*/
public class RocketMQAckCallback implements AcknowledgmentCallback {
+
private final static Logger log = LoggerFactory.getLogger(RocketMQAckCallback.class);
private boolean acknowledged;
+
private boolean autoAckEnabled = true;
+
private MessageExt messageExt;
+
private AssignedMessageQueue assignedMessageQueue;
+
private DefaultLitePullConsumer consumer;
+
private final MessageQueue messageQueue;
public RocketMQAckCallback(DefaultLitePullConsumer consumer,
@@ -109,4 +116,4 @@ public class RocketMQAckCallback implements AcknowledgmentCallback {
}
}
-}
\ No newline at end of file
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
index a378fc615..a7d7e73da 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/pull/RocketMQMessageSource.java
@@ -56,14 +56,18 @@ public class RocketMQMessageSource extends AbstractMessageSource
.getLogger(RocketMQMessageSource.class);
private DefaultLitePullConsumer consumer;
+
private AssignedMessageQueue assignedMessageQueue;
+
private volatile boolean running;
private final String topic;
+
private final MessageSelector messageSelector;
+
private final ExtendedConsumerProperties extendedConsumerProperties;
- private volatile Iterator messageExtIterator=null;
+ private volatile Iterator messageExtIterator = null;
public RocketMQMessageSource(String name,
ExtendedConsumerProperties extendedConsumerProperties) {
@@ -85,7 +89,7 @@ public class RocketMQMessageSource extends AbstractMessageSource
this.consumer = RocketMQConsumerFactory
.initPullConsumer(extendedConsumerProperties);
// This parameter must be 1, otherwise doReceive cannot be handled singly.
-// this.consumer.setPullBatchSize(1);
+ // this.consumer.setPullBatchSize(1);
this.consumer.subscribe(topic, messageSelector);
this.consumer.setAutoCommit(false);
this.assignedMessageQueue = acquireAssignedMessageQueue(this.consumer);
@@ -135,18 +139,18 @@ public class RocketMQMessageSource extends AbstractMessageSource
@Override
protected synchronized Object doReceive() {
- if(messageExtIterator == null){
+ if (messageExtIterator == null) {
List messageExtList = consumer.poll();
if (CollectionUtils.isEmpty(messageExtList) || messageExtList.size() > 1) {
return null;
}
messageExtIterator = messageExtList.iterator();
}
- MessageExt messageExt=messageExtIterator.next();
- if(!messageExtIterator.hasNext()){
+ MessageExt messageExt = messageExtIterator.next();
+ if (!messageExtIterator.hasNext()) {
messageExtIterator = null;
}
- if(null == messageExt){
+ if (null == messageExt) {
return null;
}
MessageQueue messageQueue = null;
@@ -156,8 +160,9 @@ public class RocketMQMessageSource extends AbstractMessageSource
break;
}
}
- if(messageQueue == null){
- throw new IllegalArgumentException("The message queue is not in assigned list");
+ if (messageQueue == null) {
+ throw new IllegalArgumentException(
+ "The message queue is not in assigned list");
}
Message message = RocketMQMessageConverterSupport
.convertMessage2Spring(messageExt);
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
index 7017ba46e..463868438 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
@@ -39,18 +39,23 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
- * Extended function related to producer . eg:initial
+ * Extended function related to producer . eg:initial .
*
* @author zkzlx
*/
public final class RocketMQProduceFactory {
+ private RocketMQProduceFactory() {
+ }
+
private final static Logger log = LoggerFactory
.getLogger(RocketMQProduceFactory.class);
/**
* init for the producer,including convert producer params.
- * @return
+ * @param topic topic
+ * @param producerProperties producerProperties
+ * @return DefaultMQProducer
*/
public static DefaultMQProducer initRocketMQProducer(String topic,
RocketMQProducerProperties producerProperties) {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
index 3d58b8af0..56c208759 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -61,16 +61,23 @@ public class RocketMQProducerMessageHandler extends AbstractMessageHandler
.getLogger(RocketMQProducerMessageHandler.class);
private volatile boolean running = false;
+
private volatile boolean isTrans = false;
private ErrorMessageStrategy errorMessageStrategy;
+
private MessageChannel sendFailureChannel;
+
private MessageConverterConfigurer.PartitioningInterceptor partitioningInterceptor;
+
private DefaultMQProducer defaultMQProducer;
+
private MessageQueueSelector messageQueueSelector;
private final ProducerDestination destination;
+
private final ExtendedProducerProperties extendedProducerProperties;
+
private final RocketMQProducerProperties mqProducerProperties;
public RocketMQProducerMessageHandler(ProducerDestination destination,
@@ -93,10 +100,8 @@ public class RocketMQProducerMessageHandler extends AbstractMessageHandler
// Use the default if the partition is on and no customization is available.
this.messageQueueSelector = RocketMQBeanContainerCache.getBean(
mqProducerProperties.getMessageQueueSelector(),
- MessageQueueSelector.class,
- extendedProducerProperties.isPartitioned()
- ? new PartitionMessageQueueSelector()
- : null);
+ MessageQueueSelector.class, extendedProducerProperties.isPartitioned()
+ ? new PartitionMessageQueueSelector() : null);
}
@Override
@@ -226,9 +231,9 @@ public class RocketMQProducerMessageHandler extends AbstractMessageHandler
}
/**
- * https://github.com/alibaba/spring-cloud-alibaba/issues/1408
- * @param message
- * @return
+ * https://github.com/alibaba/spring-cloud-alibaba/issues/1408 .
+ * @param message message
+ * @return SendCallback
*/
private SendCallback getSendCallback(Message> message) {
SendCallback sendCallback = RocketMQBeanContainerCache
@@ -283,4 +288,5 @@ public class RocketMQProducerMessageHandler extends AbstractMessageHandler
this.partitioningInterceptor = partitioningInterceptor;
return this;
}
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/Instrumentation.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/Instrumentation.java
index 397e62854..e26482855 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/Instrumentation.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/Instrumentation.java
@@ -28,6 +28,7 @@ import org.springframework.context.Lifecycle;
public class Instrumentation {
private final String name;
+
private Lifecycle actuator;
protected final AtomicBoolean started = new AtomicBoolean(false);
@@ -88,4 +89,17 @@ public class Instrumentation {
public int hashCode() {
return Objects.hash(getName(), getActuator());
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ Instrumentation that = (Instrumentation) o;
+ return name.equals(that.name) && actuator.equals(that.actuator);
+ }
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/InstrumentationManager.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/InstrumentationManager.java
index de6e1e794..ad7958e44 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/InstrumentationManager.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/metrics/InstrumentationManager.java
@@ -26,6 +26,9 @@ import java.util.Map;
*/
public final class InstrumentationManager {
+ private InstrumentationManager() {
+ }
+
private static final Map HEALTH_INSTRUMENTATIONS = new HashMap<>();
public static Collection getHealthInstrumentations() {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
index fd5e77919..3da04ea18 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,6 +20,7 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* binding rocketMq properties.
+ *
* @author Jim
*/
@ConfigurationProperties(prefix = "spring.cloud.stream.rocketmq.binder")
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
index 00e7d30dd..9e9114641 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -26,6 +26,7 @@ import org.apache.rocketmq.remoting.netty.TlsSystemConfig;
* @author zkzlx
*/
public class RocketMQCommonProperties implements Serializable {
+
private static final long serialVersionUID = -6724870154343284715L;
private boolean enabled = true;
@@ -41,38 +42,36 @@ public class RocketMQCommonProperties implements Serializable {
* The property of "secret-key".
*/
private String secretKey;
+
/**
* Consumers of the same role is required to have exactly same subscriptions and
* consumerGroup to correctly achieve load balance. It's required and needs to be
- * globally unique.
- *
- * Producer group conceptually aggregates all producer instances of exactly same role,
- * which is particularly important when transactional messages are involved.
- *
- *
- * For non-transactional messages, it does not matter as long as it's unique per
- * process.
- *
- *
- * See here for further
- * discussion.
+ * globally unique. Producer group conceptually aggregates all producer instances of
+ * exactly same role, which is particularly important when transactional messages are
+ * involved. For non-transactional messages, it does not matter as long as it's unique
+ * per process. See here
+ * for further discussion.
*/
private String group;
private String namespace;
+
private String accessChannel = AccessChannel.LOCAL.name();
+
/**
* Pulling topic information interval from the named server.
* see{@link MQClientInstance#startScheduledTask()},eg:ScheduledTask
* updateTopicRouteInfoFromNameServer.
*/
private int pollNameServerInterval = 1000 * 30;
+
/**
* Heartbeat interval in microseconds with message broker.
* see{@link MQClientInstance#startScheduledTask()},eg:ScheduledTask
* sendHeartbeatToAllBroker .
*/
private int heartbeatBrokerInterval = 1000 * 30;
+
/**
* Offset persistent interval for consumer.
* see{@link MQClientInstance#startScheduledTask()},eg:ScheduledTask
@@ -85,6 +84,7 @@ public class RocketMQCommonProperties implements Serializable {
private boolean useTLS = TlsSystemConfig.tlsEnable;
private boolean enableMsgTrace = true;
+
private String customizedTraceTopic;
public boolean getEnabled() {
@@ -198,4 +198,5 @@ public class RocketMQCommonProperties implements Serializable {
public void setCustomizedTraceTopic(String customizedTraceTopic) {
this.customizedTraceTopic = customizedTraceTopic;
}
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQConsumerProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQConsumerProperties.java
index 1a889f6d7..ebe2c1c43 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQConsumerProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQConsumerProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -37,8 +37,6 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
/**
* Message model defines the way how messages are delivered to each consumer clients.
- *
- *
* This field defaults to clustering.
*/
private String messageModel = MessageModel.CLUSTERING.getModeCN();
@@ -60,13 +58,12 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
private String subscription;
/**
- * Delay some time when exception occur
+ * Delay some time when exception occur .
*/
private long pullTimeDelayMillsWhenException = 1000;
/**
* Consuming point on consumer booting.
- *
*
* There are three consuming points:
*
@@ -90,6 +87,7 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
*
*/
private ConsumeFromWhere consumeFromWhere = ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET;
+
/**
* Backtracking consumption time with second precision. Time format is
* 20131223171201
@@ -102,13 +100,14 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
/**
* Flow control threshold on queue level, each message queue will cache at most 1000
* messages by default, Consider the {@link #pullBatchSize}, the instantaneous value
- * may exceed the limit
+ * may exceed the limit .
*/
private int pullThresholdForQueue = 1000;
+
/**
* Limit the cached message size on queue level, each message queue will cache at most
* 100 MiB messages by default, Consider the {@link #pullBatchSize}, the instantaneous
- * value may exceed the limit
+ * value may exceed the limit .
*
*
* The size of a message only measured by message body, so it's not accurate
@@ -126,6 +125,7 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
private int consumeMaxSpan = 2000;
private Push push = new Push();
+
private Pull pull = new Pull();
public String getMessageModel() {
@@ -238,6 +238,7 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
}
public static class Push implements Serializable {
+
private static final long serialVersionUID = -7398468554978817630L;
/**
@@ -245,6 +246,7 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
* false, using {@link MessageListenerConcurrently}.
*/
private boolean orderly = false;
+
/**
* Suspending pulling time for cases requiring slow pulling like flow-control
* scenario. see{@link ConsumeMessageOrderlyService#processConsumeResult}.
@@ -254,10 +256,9 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
/**
* https://github.com/alibaba/spring-cloud-alibaba/issues/1866 Max re-consume
- * times. -1 means 16 times.
- *
- * If messages are re-consumed more than {@link #maxReconsumeTimes} before
- * success, it's be directed to a deletion queue waiting.
+ * times. -1 means 16 times. If messages are re-consumed more than
+ * {@link #maxReconsumeTimes} before success, it's be directed to a deletion queue
+ * waiting.
*/
private int maxReconsumeTimes;
@@ -285,21 +286,21 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
* MiB(Unlimited)
*
* The value of {@code pullThresholdSizeForQueue} will be overwrote and calculated
- * based on {@code pullThresholdSizeForTopic} if it is't unlimited
+ * based on {@code pullThresholdSizeForTopic} if it is't unlimited .
*
* For example, if the value of pullThresholdSizeForTopic is 1000 MiB and 10
* message queues are assigned to this consumer, then pullThresholdSizeForQueue
- * will be set to 100 MiB
+ * will be set to 100 MiB .
*/
private int pullThresholdSizeForTopic = -1;
/**
- * Message pull Interval
+ * Message pull Interval.
*/
private long pullInterval = 0;
/**
- * Batch consumption size
+ * Batch consumption size.
*/
private int consumeMessageBatchMaxSize = 1;
@@ -366,15 +367,18 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
public void setConsumeMessageBatchMaxSize(int consumeMessageBatchMaxSize) {
this.consumeMessageBatchMaxSize = consumeMessageBatchMaxSize;
}
+
}
public static class Pull implements Serializable {
+
/**
- * The poll timeout in milliseconds
+ * The poll timeout in milliseconds.
*/
private long pollTimeoutMillis = 1000 * 5;
+
/**
- * Pull thread number
+ * Pull thread number.
*/
private int pullThreadNums = 20;
@@ -385,13 +389,13 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
/**
* Long polling mode, the Consumer connection timeout(must greater than
- * brokerSuspendMaxTimeMillis), it is not recommended to modify
+ * brokerSuspendMaxTimeMillis), it is not recommended to modify.
*/
private long consumerTimeoutMillisWhenSuspend = 1000 * 30;
/**
* Ack state handling, including receive, reject, and retry, when a consumption
- * exception occurs. see {@link }
+ * exception occurs.
*/
private String errAcknowledge;
@@ -446,6 +450,7 @@ public class RocketMQConsumerProperties extends RocketMQCommonProperties {
public void setPullThresholdForAll(long pullThresholdForAll) {
this.pullThresholdForAll = pullThresholdForAll;
}
+
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java
index 5fc34ed08..6c4af119d 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQExtendedBindingProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java
index 8f73cf93f..4035f1483 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQProducerProperties.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -37,7 +37,6 @@ public class RocketMQProducerProperties extends RocketMQCommonProperties {
/**
* Maximum number of retry to perform internally before claiming sending failure in
* synchronous mode.
- *
*
* This may potentially cause message duplication which is up to application
* developers to resolve.
@@ -47,7 +46,6 @@ public class RocketMQProducerProperties extends RocketMQCommonProperties {
/**
* Maximum number of retry to perform internally before claiming sending failure in
* asynchronous mode.
- *
*
* This may potentially cause message duplication which is up to application
* developers to resolve.
@@ -203,19 +201,41 @@ public class RocketMQProducerProperties extends RocketMQCommonProperties {
}
public enum ProducerType {
- Normal, Trans;
+
+ /**
+ * Is not a transaction.
+ */
+ Normal,
+ /**
+ * a transaction.
+ */
+ Trans;
public boolean equalsName(String name) {
return this.name().equalsIgnoreCase(name);
}
+
}
public enum SendType {
- OneWay, Async, Sync,;
+
+ /**
+ * one way.
+ */
+ OneWay,
+ /**
+ * Asynchronization Model.
+ */
+ Async,
+ /**
+ * synchronization.
+ */
+ Sync,;
public boolean equalsName(String name) {
return this.name().equalsIgnoreCase(name);
}
+
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java
index 99a1a36fb..990a211ce 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQSpecificPropertiesProvider.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java
index d4b62e5fa..0509805ea 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/support/RocketMQMessageConverterSupport.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -36,10 +36,12 @@ import org.springframework.util.MimeTypeUtils;
import org.springframework.util.StringUtils;
/**
- *
* @author zkzlx
*/
-public class RocketMQMessageConverterSupport {
+public final class RocketMQMessageConverterSupport {
+
+ private RocketMQMessageConverterSupport() {
+ }
private static final CompositeMessageConverter MESSAGE_CONVERTER = RocketMQBeanContainerCache
.getBean(RocketMQMessageConverter.DEFAULT_NAME,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
index 85165955d..1aed546a0 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
@@ -1,11 +1,11 @@
/*
- * Copyright (C) 2018 the original author or authors.
+ * Copyright 2013-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -28,11 +28,12 @@ import org.apache.rocketmq.remoting.RPCHook;
import org.springframework.util.StringUtils;
/**
- * TODO Describe what it does
- *
* @author Jim
*/
-public class RocketMQUtils {
+public final class RocketMQUtils {
+
+ private RocketMQUtils() {
+ }
public static T mergeRocketMQProperties(
RocketMQBinderConfigurationProperties binderConfigurationProperties,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
index 02d0de9f9..f850afb4e 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
@@ -16,8 +16,6 @@
package com.alibaba.cloud.stream.binder.rocketmq;
-import java.util.Arrays;
-
import com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.RocketMQBinderAutoConfiguration;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
@@ -61,13 +59,12 @@ public class RocketMQAutoConfigurationTests {
.isEqualTo("127.0.0.1:9876,127.0.0.1:9877");
RocketMQExtendedBindingProperties bindingProperties = context
.getBean(RocketMQExtendedBindingProperties.class);
- assertThat(
- bindingProperties.getExtendedConsumerProperties("input2").getSubscription())
- .isEqualTo("tag1");
- assertThat(bindingProperties.getExtendedConsumerProperties("input2").getPush().getOrderly()
- ).isFalse();
- assertThat(bindingProperties.getExtendedConsumerProperties("input1")
- .getPush().getOrderly()).isTrue();
+ assertThat(bindingProperties.getExtendedConsumerProperties("input2")
+ .getSubscription()).isEqualTo("tag1");
+ assertThat(bindingProperties.getExtendedConsumerProperties("input2").getPush()
+ .getOrderly()).isFalse();
+ assertThat(bindingProperties.getExtendedConsumerProperties("input1").getPush()
+ .getOrderly()).isTrue();
});
}
From eaab60ebdb9b9d2bb866adb5b1d0efa1829385b7 Mon Sep 17 00:00:00 2001
From: tangyuewei <472680811@qq.com>
Date: Tue, 30 Mar 2021 17:26:07 +0800
Subject: [PATCH 19/99] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E4=BA=86=E4=B8=80?=
=?UTF-8?q?=E4=BA=9B=E7=A9=BA=E6=A0=BC=EF=BC=8C=E6=9B=B4=E7=AC=A6=E5=90=88?=
=?UTF-8?q?=E8=A7=84=E8=8C=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/resources/bootstrap.properties | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/src/main/resources/bootstrap.properties b/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/src/main/resources/bootstrap.properties
index 4d880443f..c9c1c9f64 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/src/main/resources/bootstrap.properties
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-config-example/src/main/resources/bootstrap.properties
@@ -18,18 +18,18 @@ spring.cloud.nacos.password=nacos
#spring.cloud.nacos.config.shared-data-ids=common.properties,base-common.properties
## recommended.
-spring.cloud.nacos.config.shared-configs[0].data-id= test2.yaml
+spring.cloud.nacos.config.shared-configs[0].data-id=test2.yaml
spring.cloud.nacos.config.shared-configs[0].refresh=true
## the default value is 'DEFAULT_GROUP' , if not specified.
-spring.cloud.nacos.config.shared-configs[0].group= GROUP_APP1
+spring.cloud.nacos.config.shared-configs[0].group=GROUP_APP1
## not recommended.
#spring.cloud.nacos.config.ext-config[0]=ext.properties
## recommended.
-spring.cloud.nacos.config.extension-configs[0].data-id= extension1.properties
+spring.cloud.nacos.config.extension-configs[0].data-id=extension1.properties
spring.cloud.nacos.config.extension-configs[0].refresh=true
-spring.cloud.nacos.config.extension-configs[1].data-id= test1.yml
-spring.cloud.nacos.config.extension-configs[1].refresh= true
+spring.cloud.nacos.config.extension-configs[1].data-id=test1.yml
+spring.cloud.nacos.config.extension-configs[1].refresh=true
From a869ef7ed651d983020106676682d515470ad888 Mon Sep 17 00:00:00 2001
From: eden-yuan <916928826@qq.com>
Date: Wed, 31 Mar 2021 16:44:06 +0800
Subject: [PATCH 20/99] fix adoc
---
spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc | 2 +-
spring-cloud-alibaba-docs/src/main/asciidoc/schedulerx.adoc | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc
index 540d42c41..305813e8f 100644
--- a/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc
+++ b/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc
@@ -57,7 +57,7 @@ Send messages:
sh bin/tools.sh org.apache.rocketmq.example.quickstart.Producer
```
-Output when the message is successfuly sent: `SendResult [sendStatus=SEND_OK, msgId= ...`
+Output when the message is successfully sent: `SendResult [sendStatus=SEND_OK, msgId= ...`
Receive messages:
diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc/schedulerx.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc/schedulerx.adoc
index 38c79c50e..ea68fd8a9 100644
--- a/spring-cloud-alibaba-docs/src/main/asciidoc/schedulerx.adoc
+++ b/spring-cloud-alibaba-docs/src/main/asciidoc/schedulerx.adoc
@@ -82,7 +82,7 @@ Job Description: Empty
Custom Parameters: Empty
----
-The job above is a “Simple Single-Server Job”, and speficied a Cron expression of "0 * * * * ?" . This means that the job will be executed once and once only in every minute.
+The job above is a “Simple Single-Server Job”, and specified a Cron expression of "0 * * * * ?" . This means that the job will be executed once and once only in every minute.
For more job types, refer to https://help.aliyun.com/document_detail/43136.html[SchedulerX Documentation].
From d653a1447667bfb7a8c6343511647ab5a11ed8b3 Mon Sep 17 00:00:00 2001
From: tangyuewei <472680811@qq.com>
Date: Wed, 31 Mar 2021 16:54:15 +0800
Subject: [PATCH 21/99] =?UTF-8?q?=E5=8D=87=E7=BA=A7=E6=A1=88=E4=BE=8B?=
=?UTF-8?q?=E6=B3=A8=E8=A7=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../sentinel-example/sentinel-dubbo-example/readme-zh.md | 4 ++--
.../java/com/alibaba/cloud/examples/FooServiceConsumer.java | 4 ++--
.../main/java/com/alibaba/cloud/examples/FooServiceImpl.java | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/readme-zh.md b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/readme-zh.md
index ca7459db7..b721036bd 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/readme-zh.md
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/readme-zh.md
@@ -73,7 +73,7 @@ Provider端在application.properties文件中定义dubbo相关的配置,比如
定义具体的服务:
- @Service(
+ @DubboService(
version = "${foo.service.version}",
application = "${dubbo.application.id}",
protocol = "${dubbo.protocol.id}",
@@ -111,7 +111,7 @@ Consumer端在服务调用之前,先定义限流规则。
根据Provider端中发布的定义,使用Dubbo的@Reference注解注入服务对应的Bean:
- @Reference(version = "${foo.service.version}", application = "${dubbo.application.id}",
+ @DubboReference(version = "${foo.service.version}", application = "${dubbo.application.id}",
path = "dubbo://localhost:12345", timeout = 30000)
private FooService fooService;
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/src/main/java/com/alibaba/cloud/examples/FooServiceConsumer.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/src/main/java/com/alibaba/cloud/examples/FooServiceConsumer.java
index c92f0bf10..877e4b81b 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/src/main/java/com/alibaba/cloud/examples/FooServiceConsumer.java
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-consumer-example/src/main/java/com/alibaba/cloud/examples/FooServiceConsumer.java
@@ -16,14 +16,14 @@
package com.alibaba.cloud.examples;
-import org.apache.dubbo.config.annotation.Reference;
+import org.apache.dubbo.config.annotation.DubboReference;
/**
* @author fangjian
*/
public class FooServiceConsumer {
- @Reference(version = "${foo.service.version}",
+ @DubboReference(version = "${foo.service.version}",
application = "${dubbo.application.id}",
url = "dubbo://localhost:12345?version=1.0.0", timeout = 30000)
private FooService fooService;
diff --git a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/src/main/java/com/alibaba/cloud/examples/FooServiceImpl.java b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/src/main/java/com/alibaba/cloud/examples/FooServiceImpl.java
index 0d280ee8b..11ebe1516 100644
--- a/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/src/main/java/com/alibaba/cloud/examples/FooServiceImpl.java
+++ b/spring-cloud-alibaba-examples/sentinel-example/sentinel-dubbo-example/sentinel-dubbo-provider-example/src/main/java/com/alibaba/cloud/examples/FooServiceImpl.java
@@ -16,12 +16,12 @@
package com.alibaba.cloud.examples;
-import org.apache.dubbo.config.annotation.Service;
+import org.apache.dubbo.config.annotation.DubboService;
/**
* @author fangjian
*/
-@Service(version = "${foo.service.version}", application = "${dubbo.application.id}",
+@DubboService(version = "${foo.service.version}", application = "${dubbo.application.id}",
protocol = "${dubbo.protocol.id}", registry = "${dubbo.registry.id}")
public class FooServiceImpl implements FooService {
From 8894793ce14c9e81493592b29819adf31834451f Mon Sep 17 00:00:00 2001
From: theonefx
Date: Mon, 12 Apr 2021 14:56:33 +0800
Subject: [PATCH 22/99] update readme
---
README-zh.md | 15 ++++++++-------
README.md | 16 +++++++++-------
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/README-zh.md b/README-zh.md
index a52b26ffb..373608c4b 100644
--- a/README-zh.md
+++ b/README-zh.md
@@ -48,15 +48,16 @@ Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案。
更多组件请参考 [Roadmap](https://github.com/alibaba/spring-cloud-alibaba/blob/master/Roadmap-zh.md)。
## 如何构建
-
-* master 分支对应的是 Spring Cloud Greenwich,最低支持 JDK 1.8。
+* 2020.0 分支对应的是 Spring Cloud 2020,最低支持 JDK 1.8。
+* master 分支对应的是 Spring Cloud Hoxton,最低支持 JDK 1.8。
+* greenwich 分支对应的是 Spring Cloud Greenwich,最低支持 JDK 1.8。
* finchley 分支对应的是 Spring Cloud Finchley,最低支持 JDK 1.8。
* 1.x 分支对应的是 Spring Cloud Edgware,最低支持 JDK 1.7。
Spring Cloud 使用 Maven 来构建,最快的使用方式是将本项目 clone 到本地,然后执行以下命令:
-
+```bash
./mvnw install
-
+```
执行完毕后,项目将被安装到本地 Maven 仓库。
## 如何使用
@@ -64,7 +65,7 @@ Spring Cloud 使用 Maven 来构建,最快的使用方式是将本项目 clone
### 如何引入依赖
如果需要使用已发布的版本,在 `dependencyManagement` 中添加如下配置。
-
+```xml
@@ -76,7 +77,7 @@ Spring Cloud 使用 Maven 来构建,最快的使用方式是将本项目 clone
-
+```
然后在 `dependencies` 中添加自己所需使用的依赖即可使用。
## 演示 Demo
@@ -111,7 +112,7 @@ Example 列表:
* 2.0.x 版本适用于 Spring Boot 2.0.x
* 2.1.x 版本适用于 Spring Boot 2.1.x
* 2.2.x 版本适用于 Spring Boot 2.2.x
-
+* 2021.x 版本适用于 Spring Boot 2.4.x
## 社区交流
diff --git a/README.md b/README.md
index df9a1d1aa..559683cfe 100644
--- a/README.md
+++ b/README.md
@@ -51,22 +51,23 @@ For more features, please refer to [Roadmap](https://github.com/alibaba/spring-c
For more features please refer to [Roadmap](https://github.com/alibaba/spring-cloud-alibaba/blob/master/Roadmap.md).
## How to build
-
-* **master branch**: Corresponds to Spring Cloud Greenwich & Spring Boot 2.x. JDK 1.8 or later versions are supported.
-* **finchley branch**: Corresponds to Spring Cloud Finchley & Spring Boot 2.x. JDK 1.8 or later versions are supported.
+* **2020.0 branch**: Corresponds to Spring Cloud 2020 & Spring Boot 2.4.x. JDK 1.8 or later versions are supported.
+* **master branch**: Corresponds to Spring Cloud Hoxton & Spring Boot 2.2.x. JDK 1.8 or later versions are supported.
+* **greenwich branch**: Corresponds to Spring Cloud Greenwich & Spring Boot 2.1.x. JDK 1.8 or later versions are supported.
+* **finchley branch**: Corresponds to Spring Cloud Finchley & Spring Boot 2.0.x. JDK 1.8 or later versions are supported.
* **1.x branch**: Corresponds to Spring Cloud Edgware & Spring Boot 1.x, JDK 1.7 or later versions are supported.
Spring Cloud uses Maven for most build-related activities, and you should be able to get off the ground quite quickly by cloning the project you are interested in and typing:
-
+```bash
./mvnw install
-
+```
## How to Use
### Add maven dependency
These artifacts are available from Maven Central and Spring Release repository via BOM:
-
+```xml
@@ -78,7 +79,7 @@ These artifacts are available from Maven Central and Spring Release repository v
-
+```
add the module in `dependencies`.
@@ -118,6 +119,7 @@ As the interfaces and annotations of Spring Boot 1 and Spring Boot 2 have been c
* 2.0.x for Spring Boot 2.0.x
* 2.1.x for Spring Boot 2.1.x
* 2.2.x for Spring Boot 2.2.x
+* 2020.x for Spring Boot 2.4.x
## Code of Conduct
This project is a sub-project of Spring Cloud, it adheres to the Contributor Covenant [code of conduct](https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
From e3c791179b6b9e5a08493d6677b70431a7ac8c37 Mon Sep 17 00:00:00 2001
From: panzhi33
Date: Tue, 13 Apr 2021 17:51:24 +0800
Subject: [PATCH 23/99] =?UTF-8?q?=E5=8D=87=E7=BA=A7rocketmq-spring-boot-st?=
=?UTF-8?q?arter=E7=89=88=E6=9C=AC=EF=BC=8C=E5=95=86=E4=B8=9A=E7=89=88?=
=?UTF-8?q?=E6=B6=88=E6=81=AF=E8=BD=A8=E8=BF=B9=E6=97=A0=E9=9C=80=E6=89=8B?=
=?UTF-8?q?=E5=8A=A8=E9=85=8D=E7=BD=AE=E8=BD=A8=E8=BF=B9topic?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../src/main/asciidoc-zh/rocketmq.adoc | 6 ++++++
.../src/main/asciidoc/rocketmq.adoc | 6 +++++-
.../stream/binder/rocketmq/RocketMQBinderUtils.java | 7 +++++++
.../rocketmq/RocketMQMessageChannelBinder.java | 4 ++++
.../RocketMQComponent4BinderAutoConfiguration.java | 6 ++++++
.../consuming/RocketMQListenerBindingContainer.java | 5 +++++
.../RocketMQBinderConfigurationProperties.java | 13 +++++++++++++
.../rocketmq/RocketMQAutoConfigurationTests.java | 4 +++-
9 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index 0208a34b4..3fb48600e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,7 +90,7 @@
4.0.1
- 2.0.2
+ 2.0.43.7.0
diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/rocketmq.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/rocketmq.adoc
index 340da4d8b..7823c649f 100644
--- a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/rocketmq.adoc
+++ b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/rocketmq.adoc
@@ -249,6 +249,11 @@ spring.cloud.stream.rocketmq.binder.customized-trace-topic::
消息轨迹开启后存储的 topic 名称。
+
Default: `RMQ_SYS_TRACE_TOPIC`.
++
+spring.cloud.stream.rocketmq.binder.access-channel::
+商业版rocketmq消息轨迹topic自适应,值为CLOUD
++
+Default: null.
==== RocketMQ Consumer Properties
@@ -346,6 +351,7 @@ NOTE: 0.1.2 & 0.2.2 & 0.9.0 才支持该功能
spring.cloud.stream.rocketmq.binder.access-key=YourAccessKey
spring.cloud.stream.rocketmq.binder.secret-key=YourSecretKey
spring.cloud.stream.rocketmq.binder.name-server=NameServerInMQ
+spring.cloud.stream.rocketmq.binder.access-channel=CLOUD
```
NOTE: topic 和 group 请以 实例id% 为前缀进行配置。比如 topic 为 "test",需要配置成 "实例id%test"
diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc
index 540d42c41..08cad42cf 100644
--- a/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc
+++ b/spring-cloud-alibaba-docs/src/main/asciidoc/rocketmq.adoc
@@ -246,7 +246,11 @@ spring.cloud.stream.rocketmq.binder.customized-trace-topic::
The trace topic for message trace.
+
Default: `RMQ_SYS_TRACE_TOPIC`.
-
++
+spring.cloud.stream.rocketmq.binder.access-channel::
+The commercial version of rocketmq message trajectory topic is adaptive,the value is CLOUD
++
+Default: null.
==== RocketMQ Consumer Properties
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
index c7daff0ef..83a1c3604 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQBinderUtils.java
@@ -76,6 +76,13 @@ public final class RocketMQBinderUtils {
result.setEnableMsgTrace(
rocketBinderConfigurationProperties.isEnableMsgTrace());
}
+ if (StringUtils.isEmpty(rocketMQProperties.getAccessChannel())) {
+ result.setAccessChannel(rocketBinderConfigurationProperties.getAccessChannel());
+ }
+ else {
+ result.setAccessChannel(
+ rocketMQProperties.getAccessChannel());
+ }
return result;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
index e5a2e24b1..7d0d997cc 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQMessageChannelBinder.java
@@ -38,6 +38,7 @@ import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQHeaderMapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
+import org.apache.rocketmq.client.AccessChannel;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.common.UtilAll;
import org.apache.rocketmq.remoting.RPCHook;
@@ -158,6 +159,9 @@ public class RocketMQMessageChannelBinder extends
producerProperties.getExtension().isRetryNextServer());
producer.setMaxMessageSize(
producerProperties.getExtension().getMaxMessageSize());
+ if (!StringUtils.isEmpty(mergedProperties.getAccessChannel())) {
+ producer.setAccessChannel(AccessChannel.valueOf(mergedProperties.getAccessChannel()));
+ }
rocketMQTemplate.setProducer(producer);
if (producerProperties.isPartitioned()) {
rocketMQTemplate
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
index 6968ead86..5b1fb513a 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/config/RocketMQComponent4BinderAutoConfiguration.java
@@ -20,6 +20,7 @@ import com.alibaba.cloud.stream.binder.rocketmq.RocketMQBinderConstants;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
+import org.apache.rocketmq.client.AccessChannel;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration;
import org.apache.rocketmq.spring.config.RocketMQConfigUtils;
@@ -59,6 +60,8 @@ public class RocketMQComponent4BinderAutoConfiguration {
"${spring.cloud.stream.rocketmq.binder.access-key:${rocketmq.producer.access-key:}}");
String sk = environment.resolveRequiredPlaceholders(
"${spring.cloud.stream.rocketmq.binder.secret-key:${rocketmq.producer.secret-key:}}");
+ String accessChannel = environment.resolveRequiredPlaceholders(
+ "${spring.cloud.stream.rocketmq.binder.access-channel:${rocketmq.access-channel:}}");
if (!StringUtils.isEmpty(ak) && !StringUtils.isEmpty(sk)) {
producer = new DefaultMQProducer(RocketMQBinderConstants.DEFAULT_GROUP,
new AclClientRPCHook(new SessionCredentials(ak, sk)));
@@ -71,6 +74,9 @@ public class RocketMQComponent4BinderAutoConfiguration {
configNameServer = RocketMQBinderConstants.DEFAULT_NAME_SERVER;
}
producer.setNamesrvAddr(configNameServer);
+ if (!StringUtils.isEmpty(configNameServer)) {
+ producer.setAccessChannel(AccessChannel.valueOf(accessChannel));
+ }
return producer;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
index fb167c697..ecf5f2a01 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/consuming/RocketMQListenerBindingContainer.java
@@ -26,6 +26,7 @@ import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQConsumerPrope
import com.alibaba.cloud.stream.binder.rocketmq.support.RocketMQHeaderMapper;
import org.apache.rocketmq.acl.common.AclClientRPCHook;
import org.apache.rocketmq.acl.common.SessionCredentials;
+import org.apache.rocketmq.client.AccessChannel;
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer;
import org.apache.rocketmq.client.consumer.MessageSelector;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
@@ -238,6 +239,10 @@ public class RocketMQListenerBindingContainer
consumer.setConsumeThreadMax(rocketMQConsumerProperties.getConcurrency());
consumer.setConsumeThreadMin(rocketMQConsumerProperties.getConcurrency());
+ if (!StringUtils.isEmpty(rocketBinderConfigurationProperties.getAccessChannel())) {
+ consumer.setAccessChannel(AccessChannel.valueOf(rocketBinderConfigurationProperties.getAccessChannel()));
+ }
+
switch (messageModel) {
case BROADCASTING:
consumer.setMessageModel(
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
index 3a9dcb403..686b46a7e 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
@@ -47,6 +47,11 @@ public class RocketMQBinderConfigurationProperties {
*/
private String secretKey;
+ /**
+ * Enum type for accessChannel, values: LOCAL, CLOUD
+ */
+ private String accessChannel;
+
/**
* Switch flag instance for message trace.
*/
@@ -82,6 +87,14 @@ public class RocketMQBinderConfigurationProperties {
this.secretKey = secretKey;
}
+ public String getAccessChannel() {
+ return accessChannel;
+ }
+
+ public void setAccessChannel(String accessChannel) {
+ this.accessChannel = accessChannel;
+ }
+
public boolean isEnableMsgTrace() {
return enableMsgTrace;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
index 8207f9893..6feee3b97 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/test/java/com/alibaba/cloud/stream/binder/rocketmq/RocketMQAutoConfigurationTests.java
@@ -50,7 +50,8 @@ public class RocketMQAutoConfigurationTests {
"spring.cloud.stream.bindings.input2.content-type=application/json",
"spring.cloud.stream.bindings.input2.group=test-group2",
"spring.cloud.stream.rocketmq.bindings.input2.consumer.orderly=false",
- "spring.cloud.stream.rocketmq.bindings.input2.consumer.tags=tag1");
+ "spring.cloud.stream.rocketmq.bindings.input2.consumer.tags=tag1",
+ "spring.cloud.stream.rocketmq.binder.access-channel=CLOUD");
@Test
public void testProperties() {
@@ -68,6 +69,7 @@ public class RocketMQAutoConfigurationTests {
.getOrderly()).isFalse();
assertThat(bindingProperties.getExtendedConsumerProperties("input1")
.getOrderly()).isTrue();
+ assertThat(binderConfigurationProperties.getAccessChannel()).isEqualTo("CLOUD");
});
}
From f8ee5dc71c9d173f6062915156bd631ebbf40909 Mon Sep 17 00:00:00 2001
From: panzhi33
Date: Tue, 13 Apr 2021 18:36:19 +0800
Subject: [PATCH 24/99] fix style code
---
.../properties/RocketMQBinderConfigurationProperties.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
index 686b46a7e..ae735840c 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQBinderConfigurationProperties.java
@@ -48,7 +48,7 @@ public class RocketMQBinderConfigurationProperties {
private String secretKey;
/**
- * Enum type for accessChannel, values: LOCAL, CLOUD
+ * Enum type for accessChannel, values: LOCAL, CLOUD.
*/
private String accessChannel;
From 3ad550f211e652677b9776766944b5249f0fa6ab Mon Sep 17 00:00:00 2001
From: chris
Date: Wed, 14 Apr 2021 09:59:49 +0800
Subject: [PATCH 25/99] bugfix invokers metadata tag error
---
.../cloud/dubbo/registry/DubboCloudRegistry.java | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index 2101a217b..04d9c99e5 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -308,6 +308,16 @@ public class DubboCloudRegistry extends FailbackRegistry {
String protocol = templateURL.getProtocol();
Integer port = repository.getDubboProtocolPort(serviceInstance,
protocol);
+
+ // reserve tag
+ String tag = null;
+ List urls = jsonUtils.toURLs(serviceInstance.getMetadata()
+ .get("dubbo.metadata-service.urls"));
+ if (urls != null && urls.size() > 0) {
+ Map parameters = urls.get(0).getParameters();
+ tag = parameters.get("dubbo.tag");
+ }
+
if (Objects.equals(templateURL.getHost(), host)
&& Objects.equals(templateURL.getPort(), port)) { // use
// templateURL
@@ -331,7 +341,8 @@ public class DubboCloudRegistry extends FailbackRegistry {
// the template
// URL
.setHost(host) // reset the host
- .setPort(port); // reset the port
+ .setPort(port) // reset the port
+ .addParameter("dubbo.tag", tag); // reset the tag
return clonedURLBuilder.build();
}
From 3ee8d4bf562fef6ce32c2f033534baa5ebd9dbe2 Mon Sep 17 00:00:00 2001
From: Spike
Date: Thu, 15 Apr 2021 13:29:15 +0800
Subject: [PATCH 26/99] =?UTF-8?q?=E4=BA=8B=E5=8A=A1=E6=B6=88=E6=81=AF?=
=?UTF-8?q?=E6=8C=87=E5=AE=9A=E6=96=B9=E5=BC=8F=E5=8F=98=E6=9B=B4=E4=B8=BA?=
=?UTF-8?q?producerType=3DTrans?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/resources/application.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties
index 08ab26ca0..428991930 100644
--- a/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/rocketmq-example/rocketmq-produce-example/src/main/resources/application.properties
@@ -9,7 +9,7 @@ spring.cloud.stream.rocketmq.bindings.output1.producer.sync=true
spring.cloud.stream.bindings.output2.destination=TransactionTopic
spring.cloud.stream.bindings.output2.content-type=application/json
-spring.cloud.stream.rocketmq.bindings.output2.producer.transactional=true
+spring.cloud.stream.rocketmq.bindings.output2.producer.producerType=Trans
spring.cloud.stream.rocketmq.bindings.output2.producer.group=myTxProducerGroup
spring.cloud.stream.rocketmq.bindings.output2.producer.transactionListener=myTransactionListener
From 1f9f10ce901b8dc538a67a6dee143470e9d24d1c Mon Sep 17 00:00:00 2001
From: Spike
Date: Thu, 15 Apr 2021 13:32:13 +0800
Subject: [PATCH 27/99] =?UTF-8?q?issue#2040=20=E7=A7=BB=E9=99=A4RocketMQCo?=
=?UTF-8?q?nfigBeanPostProcessor=E5=9C=A8RocketMQBinderAutoConfiguration?=
=?UTF-8?q?=E7=B1=BB=E4=B8=AD=E7=9A=84=E6=B3=A8=E5=85=A5=EF=BC=8C=E6=94=B9?=
=?UTF-8?q?=E4=B8=BA=E9=80=9A=E8=BF=87spirng.factories=E6=B3=A8=E5=85=A5?=
=?UTF-8?q?=EF=BC=8C=E5=8E=9F=E6=9D=A5=E6=98=AF=E9=80=9A=E8=BF=87spirng.bi?=
=?UTF-8?q?nders=E7=BB=8F=E8=BF=87spring-cloud-stream=E4=BB=A3=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../autoconfigurate/RocketMQBinderAutoConfiguration.java | 5 -----
.../src/main/resources/META-INF/spring.factories | 3 ++-
2 files changed, 2 insertions(+), 6 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
index ec47e951a..2ddcaf8a1 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
@@ -50,11 +50,6 @@ public class RocketMQBinderAutoConfiguration {
@Autowired
private RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
- @Bean
- public RocketMQConfigBeanPostProcessor rocketMQConfigBeanPostProcessor() {
- return new RocketMQConfigBeanPostProcessor();
- }
-
@Bean(RocketMQMessageConverter.DEFAULT_NAME)
@ConditionalOnMissingBean(name = { RocketMQMessageConverter.DEFAULT_NAME })
public CompositeMessageConverter rocketMQMessageConverter() {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
index e18651dc4..3fa0357ad 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
@@ -1,2 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.ExtendedBindingHandlerMappingsProviderConfiguration
+com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.ExtendedBindingHandlerMappingsProviderConfiguration,\
+com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQConfigBeanPostProcessor
\ No newline at end of file
From ba80fcac2f3b5a4c71bd8f9aeb696ab9b0804a05 Mon Sep 17 00:00:00 2001
From: Spike
Date: Thu, 15 Apr 2021 15:40:39 +0800
Subject: [PATCH 28/99] #checkstyle removed unused import
---
.../autoconfigurate/RocketMQBinderAutoConfiguration.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
index 2ddcaf8a1..85ca379e5 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
@@ -19,7 +19,6 @@ package com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate;
import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
import com.alibaba.cloud.stream.binder.rocketmq.actuator.RocketMQBinderHealthIndicator;
import com.alibaba.cloud.stream.binder.rocketmq.convert.RocketMQMessageConverter;
-import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQConfigBeanPostProcessor;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
import com.alibaba.cloud.stream.binder.rocketmq.provisioning.RocketMQTopicProvisioner;
From 10e9a99d08b1c317cc296e7f35721393b7ca2a6f Mon Sep 17 00:00:00 2001
From: Spike
Date: Fri, 30 Apr 2021 10:07:51 +0800
Subject: [PATCH 29/99] =?UTF-8?q?issue#2040=20=E8=BD=AC=E7=A7=BBRocketMQCo?=
=?UTF-8?q?nfigBeanPostProcessor=E5=92=8CCompositeMessageConverter?=
=?UTF-8?q?=E4=BB=8ERocketMQBinderAutoConfiguration=E8=87=B3ExtendedBindin?=
=?UTF-8?q?gHandlerMappingsProviderConfiguration?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
从RocketMQBinderAutoConfiguration中注入会被stream代理生成一个新的上下文层,上层使用者和它会被隔离导致无法使用
原来是通过spirng.binders经过spring-cloud-stream代理
---
...dingHandlerMappingsProviderConfiguration.java | 16 ++++++++++++++++
.../RocketMQBinderAutoConfiguration.java | 9 ---------
.../src/main/resources/META-INF/spring.factories | 3 +--
3 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
index eb6e6ce52..626ab7b16 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
@@ -19,10 +19,14 @@ package com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate;
import java.util.HashMap;
import java.util.Map;
+import com.alibaba.cloud.stream.binder.rocketmq.convert.RocketMQMessageConverter;
+import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQConfigBeanPostProcessor;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.cloud.stream.config.BindingHandlerAdvise.MappingsProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.messaging.converter.CompositeMessageConverter;
@Configuration
public class ExtendedBindingHandlerMappingsProviderConfiguration {
@@ -42,4 +46,16 @@ public class ExtendedBindingHandlerMappingsProviderConfiguration {
};
}
+ @Bean
+ public RocketMQConfigBeanPostProcessor rocketMQConfigBeanPostProcessor() {
+ return new RocketMQConfigBeanPostProcessor();
+ }
+
+
+ @Bean(RocketMQMessageConverter.DEFAULT_NAME)
+ @ConditionalOnMissingBean(name = { RocketMQMessageConverter.DEFAULT_NAME })
+ public CompositeMessageConverter rocketMQMessageConverter() {
+ return new RocketMQMessageConverter().getMessageConverter();
+ }
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
index 85ca379e5..b9b85db24 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/RocketMQBinderAutoConfiguration.java
@@ -18,7 +18,6 @@ package com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate;
import com.alibaba.cloud.stream.binder.rocketmq.RocketMQMessageChannelBinder;
import com.alibaba.cloud.stream.binder.rocketmq.actuator.RocketMQBinderHealthIndicator;
-import com.alibaba.cloud.stream.binder.rocketmq.convert.RocketMQMessageConverter;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQBinderConfigurationProperties;
import com.alibaba.cloud.stream.binder.rocketmq.properties.RocketMQExtendedBindingProperties;
import com.alibaba.cloud.stream.binder.rocketmq.provisioning.RocketMQTopicProvisioner;
@@ -26,11 +25,9 @@ import com.alibaba.cloud.stream.binder.rocketmq.provisioning.RocketMQTopicProvis
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
-import org.springframework.messaging.converter.CompositeMessageConverter;
/**
* issue:https://github.com/alibaba/spring-cloud-alibaba/issues/1681 .
@@ -49,12 +46,6 @@ public class RocketMQBinderAutoConfiguration {
@Autowired
private RocketMQBinderConfigurationProperties rocketBinderConfigurationProperties;
- @Bean(RocketMQMessageConverter.DEFAULT_NAME)
- @ConditionalOnMissingBean(name = { RocketMQMessageConverter.DEFAULT_NAME })
- public CompositeMessageConverter rocketMQMessageConverter() {
- return new RocketMQMessageConverter().getMessageConverter();
- }
-
@Bean
@ConditionalOnEnabledHealthIndicator("rocketmq")
@ConditionalOnClass(name = "org.springframework.boot.actuate.health.HealthIndicator")
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
index 3fa0357ad..b67a42530 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/resources/META-INF/spring.factories
@@ -1,3 +1,2 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
-com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.ExtendedBindingHandlerMappingsProviderConfiguration,\
-com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQConfigBeanPostProcessor
\ No newline at end of file
+com.alibaba.cloud.stream.binder.rocketmq.autoconfigurate.ExtendedBindingHandlerMappingsProviderConfiguration
\ No newline at end of file
From c138dd17ac54af9a1d9b9630a2afce2fd0f1c9c2 Mon Sep 17 00:00:00 2001
From: Spike
Date: Fri, 30 Apr 2021 10:29:05 +0800
Subject: [PATCH 30/99] fix check style
---
.../ExtendedBindingHandlerMappingsProviderConfiguration.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
index 626ab7b16..ce48fccb0 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/autoconfigurate/ExtendedBindingHandlerMappingsProviderConfiguration.java
@@ -21,6 +21,7 @@ import java.util.Map;
import com.alibaba.cloud.stream.binder.rocketmq.convert.RocketMQMessageConverter;
import com.alibaba.cloud.stream.binder.rocketmq.custom.RocketMQConfigBeanPostProcessor;
+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.source.ConfigurationPropertyName;
import org.springframework.cloud.stream.config.BindingHandlerAdvise.MappingsProvider;
From 3d5eaefe1c3151e79cdc93673b85f77fd817b3ab Mon Sep 17 00:00:00 2001
From: theonefx
Date: Wed, 12 May 2021 09:36:33 +0800
Subject: [PATCH 31/99] resolve @order not effect when handle
ServiceInstanceChangedEvent
---
.../dubbo/registry/DubboCloudRegistry.java | 71 ++++++++++---------
.../ServiceInstanceChangeListener.java | 35 +++++++++
2 files changed, 71 insertions(+), 35 deletions(-)
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ServiceInstanceChangeListener.java
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index 04d9c99e5..81464733d 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -45,12 +45,10 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
import org.springframework.util.CollectionUtils;
import static java.lang.String.format;
import static java.util.Collections.emptyList;
-import static java.util.stream.StreamSupport.stream;
import static org.apache.dubbo.common.URLBuilder.from;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
@@ -188,18 +186,24 @@ public class DubboCloudRegistry extends FailbackRegistry {
// Async subscription
registerServiceInstancesChangedListener(url,
- new ApplicationListener() {
+ new ServiceInstanceChangeListener() {
- private final URL url2subscribe = url;
+ @Override
+ public int getOrder() {
+ return Ordered.LOWEST_PRECEDENCE;
+ }
@Override
- @Order
public void onApplicationEvent(ServiceInstancesChangedEvent event) {
+
Set serviceNames = getServices(url);
String serviceName = event.getServiceName();
if (serviceNames.contains(serviceName)) {
+ logger.debug(
+ "handle serviceInstanceChange of general service, serviceName = {}, subscribeUrl={}",
+ event.getServiceName(), url.getServiceKey());
subscribeURLs(url, serviceNames, listener);
}
}
@@ -419,11 +423,6 @@ public class DubboCloudRegistry extends FailbackRegistry {
listener.notify(subscribedURLs);
}
- private List getServiceInstances(Iterable serviceNames) {
- return stream(serviceNames.spliterator(), false).map(this::getServiceInstances)
- .flatMap(Collection::stream).collect(Collectors.toList());
- }
-
private List getServiceInstances(String serviceName) {
return hasText(serviceName) ? doGetServiceInstances(serviceName) : emptyList();
}
@@ -471,27 +470,38 @@ public class DubboCloudRegistry extends FailbackRegistry {
private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
NotifyListener listener) {
- // Sync subscription
- subscribeDubboMetadataServiceURLs(subscribedURL, listener,
- getServiceName(subscribedURL));
-
// Sync subscription
if (containsProviderCategory(subscribedURL)) {
+
+ subscribeDubboMetadataServiceURLs(subscribedURL, listener,
+ getServiceName(subscribedURL));
+
registerServiceInstancesChangedListener(subscribedURL,
- new ApplicationListener() {
+ new ServiceInstanceChangeListener() {
- private final URL url2subscribe = subscribedURL;
+ @Override
+ public int getOrder() {
+ return Ordered.LOWEST_PRECEDENCE - 1;
+ }
@Override
- @Order(Ordered.LOWEST_PRECEDENCE - 1)
public void onApplicationEvent(
ServiceInstancesChangedEvent event) {
String sourceServiceName = event.getServiceName();
+ List serviceInstances = event
+ .getServiceInstances();
String serviceName = getServiceName(subscribedURL);
if (Objects.equals(sourceServiceName, serviceName)) {
+ logger.debug(
+ "handle serviceInstanceChange of metadata service, serviceName = {}, subscribeUrl={}",
+ event.getServiceName(),
+ subscribedURL.getServiceKey());
+
+ // only update serviceInstances of the specified
+ // serviceName
subscribeDubboMetadataServiceURLs(subscribedURL, listener,
- sourceServiceName);
+ sourceServiceName, serviceInstances);
}
}
@@ -509,34 +519,25 @@ public class DubboCloudRegistry extends FailbackRegistry {
}
private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
- NotifyListener listener, String serviceName) {
+ NotifyListener listener, String serviceName,
+ List serviceInstances) {
String serviceInterface = subscribedURL.getServiceInterface();
String version = subscribedURL.getParameter(VERSION_KEY);
String protocol = subscribedURL.getParameter(PROTOCOL_KEY);
- List serviceInstances = getServiceInstances(serviceName);
-
List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances,
serviceInterface, version, protocol);
notifyAllSubscribedURLs(subscribedURL, urls, listener);
}
- // private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
- // NotifyListener listener, Set serviceNames) {
- //
- // String serviceInterface = subscribedURL.getServiceInterface();
- // String version = subscribedURL.getParameter(VERSION_KEY);
- // String protocol = subscribedURL.getParameter(PROTOCOL_KEY);
- //
- // List serviceInstances = getServiceInstances(serviceNames);
- //
- // List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances,
- // serviceInterface, version, protocol);
- //
- // notifyAllSubscribedURLs(subscribedURL, urls, listener);
- // }
+ private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
+ NotifyListener listener, String serviceName) {
+ List serviceInstances = getServiceInstances(serviceName);
+ subscribeDubboMetadataServiceURLs(subscribedURL, listener, serviceName,
+ serviceInstances);
+ }
private boolean containsProviderCategory(URL subscribedURL) {
String category = subscribedURL.getParameter(CATEGORY_KEY);
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ServiceInstanceChangeListener.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ServiceInstanceChangeListener.java
new file mode 100644
index 000000000..123214831
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ServiceInstanceChangeListener.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.registry;
+
+import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
+
+import org.springframework.context.ApplicationListener;
+import org.springframework.core.Ordered;
+
+/**
+ * The interface of ServiceInstanceChange event Listener.
+ *
+ * @author theonefx
+ * @see ServiceInstancesChangedEvent
+ * @see Ordered
+ * @see ApplicationListener
+ */
+public interface ServiceInstanceChangeListener
+ extends ApplicationListener, Ordered {
+
+}
From f8161141224157aea0bcc08b36332aa2c2e58a80 Mon Sep 17 00:00:00 2001
From: theonefx
Date: Wed, 12 May 2021 20:27:50 +0800
Subject: [PATCH 32/99] re subscribe when failed
---
.../cloud/dubbo/env/DubboCloudProperties.java | 20 +++++
.../dubbo/registry/DubboCloudRegistry.java | 65 +++++++++++++--
.../registry/ReSubscribeMetadataJob.java | 82 +++++++++++++++++++
.../registry/SpringCloudRegistryFactory.java | 4 +-
4 files changed, 162 insertions(+), 9 deletions(-)
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java
index 577d19e59..5135c5a8c 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/env/DubboCloudProperties.java
@@ -51,6 +51,10 @@ public class DubboCloudProperties {
private String registryType = DUBBO_CLOUD_REGISTRY_PROPERTY_VALUE;
+ private int maxReSubscribeMetadataTimes = 1000;
+
+ private int reSubscribeMetadataIntervial = 5;
+
public String getSubscribedServices() {
return subscribedServices;
}
@@ -91,4 +95,20 @@ public class DubboCloudProperties {
this.registryType = registryType;
}
+ public int getMaxReSubscribeMetadataTimes() {
+ return maxReSubscribeMetadataTimes;
+ }
+
+ public void setMaxReSubscribeMetadataTimes(int maxReSubscribeMetadataTimes) {
+ this.maxReSubscribeMetadataTimes = maxReSubscribeMetadataTimes;
+ }
+
+ public int getReSubscribeMetadataIntervial() {
+ return reSubscribeMetadataIntervial;
+ }
+
+ public void setReSubscribeMetadataIntervial(int reSubscribeMetadataIntervial) {
+ this.reSubscribeMetadataIntervial = reSubscribeMetadataIntervial;
+ }
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index 81464733d..b7768c307 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -23,6 +23,9 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@@ -108,11 +111,23 @@ public class DubboCloudRegistry extends FailbackRegistry {
private final String currentApplicationName;
+ private final Map urlNotifyListenerMap = new ConcurrentHashMap<>();
+
+ private final Map reConnectJobMap = new ConcurrentHashMap<>();
+
+ private final ScheduledThreadPoolExecutor reConnectPool = new ScheduledThreadPoolExecutor(
+ 2);
+
+ private final int maxReSubscribeMetadataTimes;
+
+ private final int reSubscribeMetadataIntervial;
+
public DubboCloudRegistry(URL url, DiscoveryClient discoveryClient,
DubboServiceMetadataRepository repository,
DubboMetadataServiceProxy dubboMetadataConfigServiceProxy,
JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory,
- ConfigurableApplicationContext applicationContext) {
+ ConfigurableApplicationContext applicationContext,
+ int maxReSubscribeMetadataTimes, int reSubscribeMetadataIntervial) {
super(url);
this.servicesLookupInterval = url
@@ -125,6 +140,11 @@ public class DubboCloudRegistry extends FailbackRegistry {
this.applicationContext = applicationContext;
this.dubboMetadataUtils = getBean(DubboMetadataUtils.class);
this.currentApplicationName = dubboMetadataUtils.getCurrentApplicationName();
+ this.maxReSubscribeMetadataTimes = maxReSubscribeMetadataTimes;
+ this.reSubscribeMetadataIntervial = reSubscribeMetadataIntervial;
+
+ reConnectPool.setKeepAliveTime(10, TimeUnit.MINUTES);
+ reConnectPool.allowCoreThreadTimeOut(true);
}
private T getBean(Class beanClass) {
@@ -175,6 +195,7 @@ public class DubboCloudRegistry extends FailbackRegistry {
}
else { // for general Dubbo Services
subscribeURLs(url, listener);
+ urlNotifyListenerMap.put(url, listener);
}
}
@@ -204,7 +225,16 @@ public class DubboCloudRegistry extends FailbackRegistry {
logger.debug(
"handle serviceInstanceChange of general service, serviceName = {}, subscribeUrl={}",
event.getServiceName(), url.getServiceKey());
- subscribeURLs(url, serviceNames, listener);
+ try {
+ subscribeURLs(url, serviceNames, listener);
+ reConnectJobMap.remove(serviceName);
+ }
+ catch (Exception e) {
+ logger.warn(String.format(
+ "subscribeURLs failed, serviceName = %s, try reSubscribe again",
+ serviceName), e);
+ addReSubscribeMetadataJob(serviceName, 0);
+ }
}
}
@@ -216,8 +246,19 @@ public class DubboCloudRegistry extends FailbackRegistry {
});
}
- private void subscribeURLs(URL url, Set serviceNames,
- NotifyListener listener) {
+ void addReSubscribeMetadataJob(String serviceName, int count) {
+ if (count > maxReSubscribeMetadataTimes) {
+ logger.error(
+ "reSubscribe failed too many times, serviceName = {}, count = {}",
+ serviceName, count);
+ return;
+ }
+ ReSubscribeMetadataJob job = new ReSubscribeMetadataJob(serviceName, this, count);
+ reConnectJobMap.put(serviceName, job);
+ reConnectPool.schedule(job, reSubscribeMetadataIntervial, TimeUnit.SECONDS);
+ }
+
+ void subscribeURLs(URL url, Set serviceNames, NotifyListener listener) {
List subscribedURLs = new LinkedList<>();
@@ -393,7 +434,7 @@ public class DubboCloudRegistry extends FailbackRegistry {
return metadata.containsKey(METADATA_SERVICE_URLS_PROPERTY_NAME);
}
- private Set getServices(URL url) {
+ Set getServices(URL url) {
Set subscribedServices = repository.getSubscribedServices();
// TODO Add the filter feature
return subscribedServices;
@@ -470,12 +511,12 @@ public class DubboCloudRegistry extends FailbackRegistry {
private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
NotifyListener listener) {
+ subscribeDubboMetadataServiceURLs(subscribedURL, listener,
+ getServiceName(subscribedURL));
+
// Sync subscription
if (containsProviderCategory(subscribedURL)) {
- subscribeDubboMetadataServiceURLs(subscribedURL, listener,
- getServiceName(subscribedURL));
-
registerServiceInstancesChangedListener(subscribedURL,
new ServiceInstanceChangeListener() {
@@ -558,6 +599,14 @@ public class DubboCloudRegistry extends FailbackRegistry {
return ADMIN_PROTOCOL.equals(url.getProtocol());
}
+ public Map getUrlNotifyListenerMap() {
+ return urlNotifyListenerMap;
+ }
+
+ public Map getReConnectJobMap() {
+ return reConnectJobMap;
+ }
+
protected boolean isDubboMetadataServiceURL(URL url) {
return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
new file mode 100644
index 000000000..68e0f42cb
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.registry;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.NotifyListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * For re subscribe URL from provider.
+ *
+ * @author theonefx
+ */
+public class ReSubscribeMetadataJob implements Runnable {
+
+ protected final Logger logger = LoggerFactory.getLogger(ReSubscribeMetadataJob.class);
+
+ private final String serviceName;
+
+ private final DubboCloudRegistry dubboCloudRegistry;
+
+ private final int errorCounts;
+
+ public ReSubscribeMetadataJob(String serviceName,
+ DubboCloudRegistry dubboCloudRegistry, int errorCounts) {
+ this.errorCounts = errorCounts;
+ this.serviceName = serviceName;
+ this.dubboCloudRegistry = dubboCloudRegistry;
+ }
+
+ public ReSubscribeMetadataJob(String serviceName,
+ DubboCloudRegistry dubboCloudRegistry) {
+ this(serviceName, dubboCloudRegistry, 0);
+ }
+
+ @Override
+ public void run() {
+ if (dubboCloudRegistry.getReConnectJobMap().get(serviceName) != this) {
+ return;
+ }
+ try {
+ for (Map.Entry entry : dubboCloudRegistry
+ .getUrlNotifyListenerMap().entrySet()) {
+ doRun(entry.getKey(), entry.getValue());
+ }
+ dubboCloudRegistry.getReConnectJobMap().remove(serviceName);
+ }
+ catch (Exception e) {
+ logger.warn(String.format(
+ "reSubscribe failed, serviceName = %s, try refresh again",
+ serviceName), e);
+ dubboCloudRegistry.addReSubscribeMetadataJob(serviceName, errorCounts + 1);
+ }
+ }
+
+ private void doRun(URL url, NotifyListener listener) {
+ Set serviceNames = dubboCloudRegistry.getServices(url);
+
+ if (serviceNames.contains(serviceName)) {
+ dubboCloudRegistry.subscribeURLs(url, serviceNames, listener);
+ }
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java
index f8b7896dc..d13c5179c 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java
@@ -100,7 +100,9 @@ public class SpringCloudRegistryFactory extends AbstractRegistryFactory {
default:
registry = new DubboCloudRegistry(url, discoveryClient,
dubboServiceMetadataRepository, dubboMetadataConfigServiceProxy,
- jsonUtils, dubboGenericServiceFactory, applicationContext);
+ jsonUtils, dubboGenericServiceFactory, applicationContext,
+ dubboCloudProperties.getMaxReSubscribeMetadataTimes(),
+ dubboCloudProperties.getReSubscribeMetadataIntervial());
break;
}
From cf71b7aa26764c98009fbf5cd2ef34963e111e02 Mon Sep 17 00:00:00 2001
From: theonefx
Date: Wed, 12 May 2021 22:23:24 +0800
Subject: [PATCH 33/99] add more log
---
.../com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java | 4 ++++
.../alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java | 2 ++
2 files changed, 6 insertions(+)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index b7768c307..cce75ba39 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -297,6 +297,10 @@ public class DubboCloudRegistry extends FailbackRegistry {
serviceName));
}
}
+ else {
+ logger.debug("subscribe from serviceName = {}, size = {}", serviceName,
+ serviceInstances.size());
+ }
List exportedURLs = getExportedURLs(subscribedURL, serviceName,
serviceInstances);
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
index 68e0f42cb..74d917f07 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
@@ -57,6 +57,8 @@ public class ReSubscribeMetadataJob implements Runnable {
return;
}
try {
+ logger.info("reSubscribe, serviceName = {}, count = {}", serviceName,
+ errorCounts);
for (Map.Entry entry : dubboCloudRegistry
.getUrlNotifyListenerMap().entrySet()) {
doRun(entry.getKey(), entry.getValue());
From 39d6a3e1ae884af901e856f7682233143fb5fe5f Mon Sep 17 00:00:00 2001
From: qukun
Date: Wed, 19 May 2021 15:45:54 +0800
Subject: [PATCH 34/99] fix word "namespae" -> "namespace"
---
PULL_REQUEST_TEMPLATE.md | 8 ++++----
.../src/main/asciidoc-zh/nacos-config.adoc | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 7261357c5..2286f0578 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -1,15 +1,15 @@
### Describe what this PR does / why we need it
-
+fix words that we can read more friendly
### Does this pull request fix one issue?
-
+no
### Describe how you did it
-
+when I read wiki-document, I find it
### Describe how to verify it
-
+By google translate
### Special notes for reviews
diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc
index 4f7de3127..0332d68c5 100644
--- a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc
+++ b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc
@@ -260,7 +260,7 @@ Nacos 内部有 https://nacos.io/zh-cn/docs/concepts.html[Namespace 的概念]:
[quote]
用于进行租户粒度的配置隔离。不同的命名空间下,可以存在相同的 Group 或 Data ID 的配置。Namespace 的常用场景之一是不同环境的配置的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等。
-在没有明确指定 `${spring.cloud.nacos.config.namespace}` 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespae。如果需要使用自定义的命名空间,可以通过以下配置来实现:
+在没有明确指定 `${spring.cloud.nacos.config.namespace}` 配置的情况下, 默认使用的是 Nacos 上 Public 这个namespace。如果需要使用自定义的命名空间,可以通过以下配置来实现:
[source,properties]
----
spring.cloud.nacos.config.namespace=b3404bc0-d7dc-4855-b519-570ed34b62d7
From 0612c9c7266d41ff6de670581486215691a94ef4 Mon Sep 17 00:00:00 2001
From: captainkun <44936259+captainkun@users.noreply.github.com>
Date: Wed, 19 May 2021 16:38:18 +0800
Subject: [PATCH 35/99] Update PULL_REQUEST_TEMPLATE.md
rollback
---
PULL_REQUEST_TEMPLATE.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md
index 2286f0578..7261357c5 100644
--- a/PULL_REQUEST_TEMPLATE.md
+++ b/PULL_REQUEST_TEMPLATE.md
@@ -1,15 +1,15 @@
### Describe what this PR does / why we need it
-fix words that we can read more friendly
+
### Does this pull request fix one issue?
-no
+
### Describe how you did it
-when I read wiki-document, I find it
+
### Describe how to verify it
-By google translate
+
### Special notes for reviews
From c3d393b09e4c74b91a191494115c85f2a1ab5d70 Mon Sep 17 00:00:00 2001
From: eden-yuan <916928826@qq.com>
Date: Mon, 24 May 2021 15:22:25 +0800
Subject: [PATCH 36/99] =?UTF-8?q?1.=20try=E6=89=A7=E8=A1=8C=E5=90=8E?=
=?UTF-8?q?=E6=97=A0catch=20=E4=BE=9D=E7=84=B6=E6=98=AFreturn=20null=202.?=
=?UTF-8?q?=20=E5=8F=98=E9=87=8F=E5=90=8E=E7=BB=AD=E6=B2=A1=E7=94=A8?=
=?UTF-8?q?=E5=88=B0=E5=8F=AF=E5=AE=9A=E4=B9=89=E5=88=B0=20try=20=E5=86=85?=
=?UTF-8?q?=203.=20=E6=B7=BB=E5=8A=A0UP/DOWN=20=E5=B8=B8=E9=87=8F=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../config/DataSourcePropertiesConfiguration.java | 1 -
.../datasource/converter/SentinelConverter.java | 3 +--
.../nacos/endpoint/NacosConfigHealthIndicator.java | 14 ++++++++++++--
.../health/NacosDiscoveryHealthIndicator.java | 14 ++++++++++++--
4 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java
index a0a5526f3..330a0a04b 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/config/DataSourcePropertiesConfiguration.java
@@ -132,7 +132,6 @@ public class DataSourcePropertiesConfiguration {
if (!ObjectUtils.isEmpty(field.get(this))) {
return field.getName();
}
- return null;
}
catch (IllegalAccessException e) {
// won't happen
diff --git a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/converter/SentinelConverter.java b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/converter/SentinelConverter.java
index 306dd1a0b..1cc8c725d 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/converter/SentinelConverter.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-alibaba-sentinel-datasource/src/main/java/com/alibaba/cloud/sentinel/datasource/converter/SentinelConverter.java
@@ -86,9 +86,8 @@ public abstract class SentinelConverter
});
for (Object obj : sourceArray) {
- String item = null;
try {
- item = objectMapper.writeValueAsString(obj);
+ String item = objectMapper.writeValueAsString(obj);
Optional.ofNullable(convertRule(item))
.ifPresent(convertRule -> ruleCollection.add(convertRule));
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosConfigHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosConfigHealthIndicator.java
index affd0139f..37e3c2463 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosConfigHealthIndicator.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config/src/main/java/com/alibaba/cloud/nacos/endpoint/NacosConfigHealthIndicator.java
@@ -32,6 +32,16 @@ public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
private final ConfigService configService;
+ /**
+ * status up .
+ */
+ private final String STATUS_UP = "UP";
+
+ /**
+ * status down .
+ */
+ private final String STATUS_DOWN = "DOWN";
+
public NacosConfigHealthIndicator(ConfigService configService) {
this.configService = configService;
}
@@ -43,10 +53,10 @@ public class NacosConfigHealthIndicator extends AbstractHealthIndicator {
// Set the status to Builder
builder.status(status);
switch (status) {
- case "UP":
+ case STATUS_UP:
builder.up();
break;
- case "DOWN":
+ case STATUS_DOWN:
builder.down();
break;
default:
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java
index 5a925ec30..32e523bb1 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/discovery/actuate/health/NacosDiscoveryHealthIndicator.java
@@ -31,6 +31,16 @@ import org.springframework.boot.actuate.health.HealthIndicator;
*/
public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator {
+ /**
+ * status up.
+ */
+ private static final String STATUS_UP = "UP";
+
+ /**
+ * status down.
+ */
+ private static final String STATUS_DOWN = "DOWN";
+
private final NamingService namingService;
public NacosDiscoveryHealthIndicator(NamingService namingService) {
@@ -44,10 +54,10 @@ public class NacosDiscoveryHealthIndicator extends AbstractHealthIndicator {
// Set the status to Builder
builder.status(status);
switch (status) {
- case "UP":
+ case STATUS_UP:
builder.up();
break;
- case "DOWN":
+ case STATUS_DOWN:
builder.down();
break;
default:
From 66bdd10ac93824296cf3cfe555af96734cd2918c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=A8=E9=B9=8F?=
Date: Mon, 24 May 2021 22:32:20 +0800
Subject: [PATCH 37/99] =?UTF-8?q?add=20Wiki=20=E6=96=87=E6=A1=A3=E2=80=9C?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=E7=9A=84=E4=BC=98=E5=85=88=E7=BA=A7=E2=80=9D?=
=?UTF-8?q?=E5=AD=98=E5=9C=A8=E5=AE=B9=E6=98=93=E6=B7=B7=E6=B7=86=E7=9A=84?=
=?UTF-8?q?=E8=A1=A8=E8=BF=B0=20#1874?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../src/main/asciidoc-zh/nacos-config.adoc | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc
index 4f7de3127..0c1237629 100644
--- a/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc
+++ b/spring-cloud-alibaba-docs/src/main/asciidoc-zh/nacos-config.adoc
@@ -348,7 +348,13 @@ Nacos Config 目前提供了三种配置能力从 Nacos 拉取相关的配置
* B: 通过 `spring.cloud.nacos.config.ext-config[n].data-id` 的方式支持多个扩展 Data Id 的配置
* C: 通过内部相关规则(应用名、应用名+ Profile )自动生成相关的 Data Id 配置
-当三种方式共同使用时,他们的一个优先级关系是:A < B < C
+当三种方式共同使用时,他们的一个优先级关系是:
+
+->A为优先级最高的
+
+->B的优先级低于A,
+
+->C的优先级是最低的
=== Nacos Config 对外暴露的 Endpoint
From a0ad31f11c94eb3ac85657a91bd01ca265517b7e Mon Sep 17 00:00:00 2001
From: theonefx
Date: Thu, 27 May 2021 11:52:48 +0800
Subject: [PATCH 38/99] update nacos-client to 1.2.4
---
spring-cloud-alibaba-dependencies/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-dependencies/pom.xml b/spring-cloud-alibaba-dependencies/pom.xml
index e1e58b0b1..1adf679d2 100644
--- a/spring-cloud-alibaba-dependencies/pom.xml
+++ b/spring-cloud-alibaba-dependencies/pom.xml
@@ -21,7 +21,7 @@
2.2.6-SNAPSHOT1.8.11.3.0
- 1.4.1
+ 1.4.20.8.01.0.10
From 479540c8357ef8e95b9005ed4bc8aaff3f2ca4d7 Mon Sep 17 00:00:00 2001
From: theonefx
Date: Tue, 1 Jun 2021 11:15:14 +0800
Subject: [PATCH 39/99] optimize dubbo registry
---
.../metadata/DefaultMetadataParamsFilter.java | 55 ++
.../dubbo/metadata/MetadataParamsFilter.java | 35 +
.../dubbo/metadata/RevisionResolver.java | 74 ++
.../cloud/dubbo/metadata/ServiceInfo.java | 351 +++++++++
.../DubboServiceMetadataRepository.java | 71 +-
.../AbstractServiceSubscribeHandler.java | 90 +++
.../dubbo/registry/DubboCloudRegistry.java | 673 ++++++++----------
.../GenearalServiceSubscribeHandler.java | 270 +++++++
.../MetadataServiceSubscribeHandler.java | 75 ++
.../dubbo/registry/ReSubscribeManager.java | 125 ++++
.../registry/ReSubscribeMetadataJob.java | 84 ---
.../registry/SpringCloudRegistryFactory.java | 6 +-
....cloud.dubbo.metadata.MetadataParamsFilter | 1 +
13 files changed, 1419 insertions(+), 491 deletions(-)
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractServiceSubscribeHandler.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/MetadataServiceSubscribeHandler.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeManager.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java
new file mode 100644
index 000000000..53d090f1c
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.metadata;
+
+import org.apache.dubbo.common.extension.Activate;
+
+import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
+import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
+import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
+import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
+import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
+import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
+import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.WARMUP_KEY;
+import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY;
+
+/**
+ * Copy from org.apache.dubbo.metadata.DefaultMetadataParamsFilter.
+ *
+ * @author theonefx
+ */
+@Activate
+public class DefaultMetadataParamsFilter implements MetadataParamsFilter {
+
+ @Override
+ public String[] serviceParamsIncluded() {
+ return new String[] { CODEC_KEY, EXCHANGER_KEY, SERIALIZATION_KEY, CLUSTER_KEY,
+ CONNECTIONS_KEY, DEPRECATED_KEY, GROUP_KEY, LOADBALANCE_KEY, MOCK_KEY,
+ PATH_KEY, TIMEOUT_KEY, TOKEN_KEY, VERSION_KEY, WARMUP_KEY, WEIGHT_KEY,
+ DUBBO_VERSION_KEY, RELEASE_KEY };
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java
new file mode 100644
index 000000000..f7b4dc7d1
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.metadata;
+
+import org.apache.dubbo.common.extension.SPI;
+
+/**
+ * Copy from org.apache.dubbo.metadata.MetadataParamsFilter.
+ *
+ * @author theonefx
+ */
+@SPI
+public interface MetadataParamsFilter {
+
+ /**
+ * params that need to be sent to metadata center.
+ * @return arrays of keys
+ */
+ String[] serviceParamsIncluded();
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java
new file mode 100644
index 000000000..53f9f1bf4
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.metadata;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+/**
+ * Copy from org.apache.dubbo.metadata.RevisionResolver.
+ *
+ * @author theonefx
+ */
+public final class RevisionResolver {
+
+ private static final Logger logger = LoggerFactory.getLogger(RevisionResolver.class);
+
+ private static final String EMPTY_REVISION = "0";
+
+ private static final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ private static MessageDigest mdInst;
+
+ static {
+ try {
+ mdInst = MessageDigest.getInstance("MD5");
+ }
+ catch (NoSuchAlgorithmException e) {
+ logger.error("Failed to calculate metadata revision", e);
+ }
+ }
+
+ private RevisionResolver() {
+
+ }
+
+ public static String getEmptyRevision() {
+ return EMPTY_REVISION;
+ }
+
+ public static String calRevision(String metadata) {
+ mdInst.update(metadata.getBytes(UTF_8));
+ byte[] md5 = mdInst.digest();
+
+ int j = md5.length;
+ char[] str = new char[j * 2];
+ int k = 0;
+ for (byte byte0 : md5) {
+ str[k++] = hexDigits[byte0 >>> 4 & 0xf];
+ str[k++] = hexDigits[byte0 & 0xf];
+ }
+ return new String(str);
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
new file mode 100644
index 000000000..a734a8e7e
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
@@ -0,0 +1,351 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.metadata;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.compiler.support.ClassUtils;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.ArrayUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+
+import static org.apache.dubbo.common.constants.CommonConstants.DOT_SEPARATOR;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+
+/**
+ * Copy from org.apache.dubbo.metadata.MetadataInfo.ServiceInfo.
+ *
+ * @author theonefx
+ */
+public class ServiceInfo implements Serializable {
+
+ private static final long serialVersionUID = -258557978718735302L;
+
+ private static ExtensionLoader loader = ExtensionLoader
+ .getExtensionLoader(MetadataParamsFilter.class);
+
+ private String name;
+
+ private String group;
+
+ private String version;
+
+ private String protocol;
+
+ private String path; // most of the time, path is the same with the interface name.
+
+ private Map params;
+
+ // params configured on consumer side,
+ private transient Map consumerParams;
+
+ // cached method params
+ private transient Map> methodParams;
+
+ private transient Map> consumerMethodParams;
+
+ // cached numbers
+ private transient Map numbers;
+
+ private transient Map> methodNumbers;
+
+ // service + group + version
+ private transient String serviceKey;
+
+ // service + group + version + protocol
+ private transient String matchKey;
+
+ private transient URL url;
+
+ public ServiceInfo() {
+ }
+
+ public ServiceInfo(URL url) {
+ this(url.getServiceInterface(), url.getParameter(GROUP_KEY),
+ url.getParameter(VERSION_KEY), url.getProtocol(), url.getPath(), null);
+
+ this.url = url;
+ Map params = new HashMap<>();
+ List filters = loader.getActivateExtension(url,
+ "params-filter");
+ for (MetadataParamsFilter filter : filters) {
+ String[] paramsIncluded = filter.serviceParamsIncluded();
+ if (ArrayUtils.isNotEmpty(paramsIncluded)) {
+ for (String p : paramsIncluded) {
+ String value = url.getParameter(p);
+ if (StringUtils.isNotEmpty(value) && params.get(p) == null) {
+ params.put(p, value);
+ }
+ String[] methods = url.getParameter(METHODS_KEY, (String[]) null);
+ if (methods != null) {
+ for (String method : methods) {
+ String mValue = getMethodParameterStrict(url, method, p);
+ if (StringUtils.isNotEmpty(mValue)) {
+ params.put(method + DOT_SEPARATOR + p, mValue);
+ }
+ }
+ }
+ }
+ }
+ }
+ this.params = params;
+ }
+
+ public String getMethodParameterStrict(URL url, String method, String key) {
+ Map keyMap = url.getMethodParameters().get(method);
+ String value = null;
+ if (keyMap != null) {
+ value = keyMap.get(key);
+ }
+ return value;
+ }
+
+ public ServiceInfo(String name, String group, String version, String protocol,
+ String path, Map params) {
+ this.name = name;
+ this.group = group;
+ this.version = version;
+ this.protocol = protocol;
+ this.path = path;
+ this.params = params == null ? new HashMap<>() : params;
+
+ this.serviceKey = URL.buildKey(name, group, version);
+ this.matchKey = buildMatchKey();
+ }
+
+ public String getMatchKey() {
+ if (matchKey != null) {
+ return matchKey;
+ }
+ buildMatchKey();
+ return matchKey;
+ }
+
+ private String buildMatchKey() {
+ matchKey = getServiceKey();
+ if (StringUtils.isNotEmpty(protocol)) {
+ matchKey = getServiceKey() + GROUP_CHAR_SEPARATOR + protocol;
+ }
+ return matchKey;
+ }
+
+ public String getServiceKey() {
+ if (serviceKey != null) {
+ return serviceKey;
+ }
+ this.serviceKey = URL.buildKey(name, group, version);
+ return serviceKey;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public void setGroup(String group) {
+ this.group = group;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public Map getParams() {
+ if (params == null) {
+ return Collections.emptyMap();
+ }
+ return params;
+ }
+
+ public void setParams(Map params) {
+ this.params = params;
+ }
+
+ public Map getAllParams() {
+ if (consumerParams != null) {
+ Map allParams = new HashMap<>(
+ (int) ((params.size() + consumerParams.size()) / 0.75f + 1));
+ allParams.putAll(params);
+ allParams.putAll(consumerParams);
+ return allParams;
+ }
+ return params;
+ }
+
+ public String getParameter(String key) {
+ if (consumerParams != null) {
+ String value = consumerParams.get(key);
+ if (value != null) {
+ return value;
+ }
+ }
+ return params.get(key);
+ }
+
+ public String getMethodParameter(String method, String key, String defaultValue) {
+ if (methodParams == null) {
+ methodParams = URL.toMethodParameters(params);
+ consumerMethodParams = URL.toMethodParameters(consumerParams);
+ }
+
+ String value = getMethodParameter(method, key, consumerMethodParams);
+ if (value != null) {
+ return value;
+ }
+ value = getMethodParameter(method, key, methodParams);
+ return value == null ? defaultValue : value;
+ }
+
+ private String getMethodParameter(String method, String key,
+ Map> map) {
+ Map keyMap = map.get(method);
+ String value = null;
+ if (keyMap != null) {
+ value = keyMap.get(key);
+ }
+ if (StringUtils.isEmpty(value)) {
+ value = getParameter(key);
+ }
+ return value;
+ }
+
+ public boolean hasMethodParameter(String method, String key) {
+ String value = this.getMethodParameter(method, key, (String) null);
+ return StringUtils.isNotEmpty(value);
+ }
+
+ public boolean hasMethodParameter(String method) {
+ if (methodParams == null) {
+ methodParams = URL.toMethodParameters(params);
+ consumerMethodParams = URL.toMethodParameters(consumerParams);
+ }
+
+ return consumerMethodParams.containsKey(method)
+ || methodParams.containsKey(method);
+ }
+
+ public String toDescString() {
+ return this.getMatchKey() + getMethodSignaturesString() + getParams();
+ }
+
+ private String getMethodSignaturesString() {
+ SortedSet methodStrings = new TreeSet();
+
+ Method[] methods = ClassUtils.forName(name).getMethods();
+ for (Method method : methods) {
+ methodStrings.add(method.toString());
+ }
+ return methodStrings.toString();
+ }
+
+ public void addParameter(String key, String value) {
+ if (consumerParams != null) {
+ this.consumerParams.put(key, value);
+ }
+ }
+
+ public void addParameterIfAbsent(String key, String value) {
+ if (consumerParams != null) {
+ this.consumerParams.putIfAbsent(key, value);
+ }
+ }
+
+ public void addConsumerParams(Map params) {
+ // copy once for one service subscription
+ if (consumerParams == null) {
+ consumerParams = new HashMap<>(params);
+ }
+ }
+
+ public Map getNumbers() {
+ // concurrent initialization is tolerant
+ if (numbers == null) {
+ numbers = new ConcurrentHashMap<>();
+ }
+ return numbers;
+ }
+
+ public Map> getMethodNumbers() {
+ if (methodNumbers == null) { // concurrent initialization is tolerant
+ methodNumbers = new ConcurrentHashMap<>();
+ }
+ return methodNumbers;
+ }
+
+ public URL getUrl() {
+ return url;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof ServiceInfo)) {
+ return false;
+ }
+
+ ServiceInfo serviceInfo = (ServiceInfo) obj;
+ return this.getMatchKey().equals(serviceInfo.getMatchKey())
+ && this.getParams().equals(serviceInfo.getParams());
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(getMatchKey(), getParams());
+ }
+
+ @Override
+ public String toString() {
+ return "service{" + "name='" + name + "'," + "group='" + group + "',"
+ + "version='" + version + "'," + "protocol='" + protocol + "',"
+ + "params=" + params + "," + "consumerParams=" + consumerParams + "}";
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
index 85c507384..7e85e624c 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
@@ -16,6 +16,7 @@
package com.alibaba.cloud.dubbo.metadata.repository;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -32,6 +33,8 @@ import com.alibaba.cloud.dubbo.env.DubboCloudProperties;
import com.alibaba.cloud.dubbo.http.matcher.RequestMetadataMatcher;
import com.alibaba.cloud.dubbo.metadata.DubboRestServiceMetadata;
import com.alibaba.cloud.dubbo.metadata.RequestMetadata;
+import com.alibaba.cloud.dubbo.metadata.RevisionResolver;
+import com.alibaba.cloud.dubbo.metadata.ServiceInfo;
import com.alibaba.cloud.dubbo.metadata.ServiceRestMetadata;
import com.alibaba.cloud.dubbo.registry.event.SubscribedServicesChangedEvent;
import com.alibaba.cloud.dubbo.service.DubboMetadataService;
@@ -43,6 +46,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.utils.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -96,6 +100,12 @@ public class DubboServiceMetadataRepository
@Deprecated
public static final String DUBBO_METADATA_SERVICE_URLS_PROPERTY_NAME = METADATA_SERVICE_URLS_PROPERTY_NAME;
+ /**
+ * The key of dubbo metadata revision. copyed from
+ * ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME.
+ */
+ public static String EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.metadata.revision";
+
/**
* The {@link String#format(String, Object...) pattern} of dubbo protocols port.
*/
@@ -117,14 +127,11 @@ public class DubboServiceMetadataRepository
*/
private final MultiValueMap allExportedURLs = new LinkedMultiValueMap<>();
- // =================================== Registration
- // =================================== //
+ // ======================== Registration ======================== //
- // ====================================================================================
- // //
+ // ============================================================== //
- // =================================== Subscription
- // =================================== //
+ // ======================== Subscription ======================== //
/**
* A Map to store REST metadata temporary, its' key is the special service name for a
* Dubbo service, the value is a JSON content of JAX-RS or Spring MVC REST metadata
@@ -134,11 +141,9 @@ public class DubboServiceMetadataRepository
private ApplicationEventPublisher applicationEventPublisher;
- // ====================================================================================
- // //
+ // =============================================================== //
- // =================================== REST Metadata
- // ================================== //
+ // ======================== REST Metadata ======================== //
private volatile Set subscribedServices = emptySet();
/**
@@ -147,11 +152,9 @@ public class DubboServiceMetadataRepository
*/
private Map> dubboRestServiceMetadataRepository = newHashMap();
- // ====================================================================================
- // //
+ // =============================================================== //
- // =================================== Dependencies
- // =================================== //
+ // ======================== Dependencies ========================= //
@Autowired
private DubboCloudProperties dubboCloudProperties;
@@ -180,8 +183,7 @@ public class DubboServiceMetadataRepository
@Autowired
private DubboMetadataServiceExporter dubboMetadataServiceExporter;
- // ====================================================================================
- // //
+ // =============================================================== //
private static Map getMap(Map> repository,
String key) {
@@ -189,12 +191,7 @@ public class DubboServiceMetadataRepository
}
private static V getOrDefault(Map source, K key, V defaultValue) {
- V value = source.get(key);
- if (value == null) {
- value = defaultValue;
- source.put(key, value);
- }
- return value;
+ return source.computeIfAbsent(key, k -> defaultValue);
}
private static Map newHashMap() {
@@ -248,13 +245,13 @@ public class DubboServiceMetadataRepository
@Override
public void afterSingletonsInstantiated() {
- initializeMetadata();
+ // initializeMetadata();
}
/**
* Initialize the metadata.
*/
- private void initializeMetadata() {
+ public void initializeMetadata() {
doGetSubscribedServices().forEach(this::initializeMetadata);
if (logger.isInfoEnabled()) {
logger.info("The metadata of Dubbo services has been initialized");
@@ -301,12 +298,36 @@ public class DubboServiceMetadataRepository
addDubboMetadataServiceURLsMetadata(metadata, dubboMetadataServiceURLs);
addDubboProtocolsPortMetadata(metadata);
+ addRevision(metadata);
return Collections.unmodifiableMap(metadata);
}
+ private void addRevision(Map metadata) {
+ metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, calAndGetRevision());
+ }
+
+ public String calAndGetRevision() {
+ if (CollectionUtils.isEmptyMap(allExportedURLs)) {
+ return RevisionResolver.getEmptyRevision();
+ }
+ else {
+ List descs = new ArrayList<>(allExportedURLs.size());
+ for (Map.Entry> entry : allExportedURLs.entrySet()) {
+ entry.getValue().stream().map(ServiceInfo::new)
+ .map(ServiceInfo::toDescString).forEach(descs::add);
+ }
+
+ descs.sort(String::compareTo);
+
+ return RevisionResolver.calRevision(descs.toString());
+ }
+ }
+
private void removeDubboMetadataServiceURLs(List dubboMetadataServiceURLs) {
- dubboMetadataServiceURLs.forEach(this::unexportURL);
+ dubboMetadataServiceURLs.stream().map(URL::getServiceKey).distinct()
+ .forEach(allExportedURLs::remove);
+ // dubboMetadataServiceURLs.forEach(this::unexportURL);
}
private void addDubboMetadataServiceURLsMetadata(Map metadata,
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractServiceSubscribeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractServiceSubscribeHandler.java
new file mode 100644
index 000000000..aa642c3c6
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/AbstractServiceSubscribeHandler.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.registry;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.NotifyListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.dubbo.common.URLBuilder.from;
+import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
+import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
+import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
+
+/**
+ * @author theonefx
+ */
+public abstract class AbstractServiceSubscribeHandler {
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ protected final URL url;
+
+ protected final NotifyListener listener;
+
+ protected final DubboCloudRegistry registry;
+
+ public AbstractServiceSubscribeHandler(URL url, NotifyListener listener,
+ DubboCloudRegistry registry) {
+ this.url = url;
+ this.listener = listener;
+ this.registry = registry;
+ }
+
+ protected void notifyAllSubscribedURLs(URL url, List subscribedURLs,
+ NotifyListener listener) {
+
+ if (isEmpty(subscribedURLs)) {
+ // Add the EMPTY_PROTOCOL URL
+ listener.notify(Collections.singletonList(emptyURL(url)));
+ // if (isDubboMetadataServiceURL(url)) {
+ // if meta service change, and serviceInstances is zero, will clean up
+ // information about this client
+ // String serviceName = url.getParameter(GROUP_KEY);
+ // repository.removeMetadataAndInitializedService(serviceName, url);
+ // }
+ }
+ else {
+ // Notify all
+ listener.notify(subscribedURLs);
+ }
+ }
+
+ private URL emptyURL(URL url) {
+ // issue : When the last service provider is closed, the client still periodically
+ // connects to the last provider.n
+ // fix https://github.com/alibaba/spring-cloud-alibaba/issues/1259
+ return from(url).setProtocol(EMPTY_PROTOCOL).removeParameter(CATEGORY_KEY)
+ .build();
+ }
+
+ private final AtomicBoolean inited = new AtomicBoolean(false);
+
+ public void init() {
+ if (inited.compareAndSet(false, true)) {
+ doInit();
+ }
+ }
+
+ protected abstract void doInit();
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index cce75ba39..1fe831834 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -16,54 +16,47 @@
package com.alibaba.cloud.dubbo.registry;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Supplier;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
+import com.alibaba.cloud.commons.lang.StringUtils;
+import com.alibaba.cloud.dubbo.metadata.RevisionResolver;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
-import com.alibaba.cloud.dubbo.service.DubboGenericServiceFactory;
import com.alibaba.cloud.dubbo.service.DubboMetadataService;
import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy;
import com.alibaba.cloud.dubbo.util.DubboMetadataUtils;
import com.alibaba.cloud.dubbo.util.JSONUtils;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.support.FailbackRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.core.Ordered;
-import org.springframework.util.CollectionUtils;
+import org.springframework.context.event.ContextRefreshedEvent;
-import static java.lang.String.format;
+import static com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
import static java.util.Collections.emptyList;
-import static org.apache.dubbo.common.URLBuilder.from;
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.CATEGORY_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL;
-import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
import static org.apache.dubbo.registry.Constants.ADMIN_PROTOCOL;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME;
import static org.springframework.util.StringUtils.hasText;
@@ -72,22 +65,14 @@ import static org.springframework.util.StringUtils.hasText;
* Dubbo Cloud {@link FailbackRegistry} is based on Spring Cloud {@link DiscoveryClient}.
*
* @author Mercy
+ * @author theonefx
*/
-public class DubboCloudRegistry extends FailbackRegistry {
-
- /**
- * The parameter name of {@link #servicesLookupInterval}.
- */
- public static final String SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.services.lookup.interval";
+public class DubboCloudRegistry extends FailbackRegistry
+ implements ApplicationListener {
protected static final String DUBBO_METADATA_SERVICE_CLASS_NAME = DubboMetadataService.class
.getName();
- /**
- * Caches the IDs of {@link ApplicationListener}.
- */
- private static final Set REGISTER_LISTENERS = new HashSet<>();
-
protected final Logger logger = LoggerFactory.getLogger(getClass());
private final DiscoveryClient discoveryClient;
@@ -98,56 +83,84 @@ public class DubboCloudRegistry extends FailbackRegistry {
private final JSONUtils jsonUtils;
- private final DubboGenericServiceFactory dubboGenericServiceFactory;
-
private final DubboMetadataUtils dubboMetadataUtils;
- /**
- * The interval in second of lookup service names(only for Dubbo-OPS).
- */
- private final long servicesLookupInterval;
-
private final ConfigurableApplicationContext applicationContext;
- private final String currentApplicationName;
-
- private final Map urlNotifyListenerMap = new ConcurrentHashMap<>();
+ private final ReSubscribeManager reSubscribeManager;
- private final Map reConnectJobMap = new ConcurrentHashMap<>();
+ private final AtomicBoolean inited = new AtomicBoolean(false);
- private final ScheduledThreadPoolExecutor reConnectPool = new ScheduledThreadPoolExecutor(
- 2);
+ /**
+ * {subscribedURL : ServiceSubscribeHandler}.
+ */
+ private final Map urlSubscribeHandlerMap = new ConcurrentHashMap<>();
- private final int maxReSubscribeMetadataTimes;
+ /**
+ * {appName: MetadataServiceSubscribeHandler}.
+ */
+ private final Map metadataSubscribeHandlerMap = new ConcurrentHashMap<>();
- private final int reSubscribeMetadataIntervial;
+ /**
+ * {appName : {revision: [instances]}}.
+ */
+ private final Map>> serviceRevisionInstanceMap = new ConcurrentHashMap<>();
public DubboCloudRegistry(URL url, DiscoveryClient discoveryClient,
DubboServiceMetadataRepository repository,
DubboMetadataServiceProxy dubboMetadataConfigServiceProxy,
- JSONUtils jsonUtils, DubboGenericServiceFactory dubboGenericServiceFactory,
- ConfigurableApplicationContext applicationContext,
- int maxReSubscribeMetadataTimes, int reSubscribeMetadataIntervial) {
+ JSONUtils jsonUtils, ConfigurableApplicationContext applicationContext) {
super(url);
- this.servicesLookupInterval = url
- .getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L);
this.discoveryClient = discoveryClient;
this.repository = repository;
this.dubboMetadataConfigServiceProxy = dubboMetadataConfigServiceProxy;
this.jsonUtils = jsonUtils;
- this.dubboGenericServiceFactory = dubboGenericServiceFactory;
this.applicationContext = applicationContext;
this.dubboMetadataUtils = getBean(DubboMetadataUtils.class);
- this.currentApplicationName = dubboMetadataUtils.getCurrentApplicationName();
- this.maxReSubscribeMetadataTimes = maxReSubscribeMetadataTimes;
- this.reSubscribeMetadataIntervial = reSubscribeMetadataIntervial;
+ this.reSubscribeManager = new ReSubscribeManager(this);
- reConnectPool.setKeepAliveTime(10, TimeUnit.MINUTES);
- reConnectPool.allowCoreThreadTimeOut(true);
+ applicationContext.addApplicationListener(
+ (ApplicationListener) event -> preInit());
}
- private T getBean(Class beanClass) {
+ private void preInit() {
+ if (inited.compareAndSet(false, true)) {
+ Set subscribeApps = getServices(null);
+
+ for (String appName : subscribeApps) {
+ List instances = discoveryClient.getInstances(appName);
+
+ Map> map = serviceRevisionInstanceMap
+ .computeIfAbsent(appName, k -> new HashMap<>());
+
+ for (ServiceInstance instance : instances) {
+ String revision = getRevision(instance);
+ List list = map.computeIfAbsent(revision,
+ k -> new ArrayList<>());
+ list.add(instance);
+ }
+
+ if (map.size() == 0) {
+ logger.debug("APP {} preInited, instance siez is zero!!", appName);
+ }
+ else {
+ map.forEach((revision, list) -> logger.debug(
+ "APP {} revision {} preInited, instance size = {}", appName,
+ revision, list.size()));
+ }
+ }
+
+ metadataSubscribeHandlerMap.forEach((url, handler) -> handler.init());
+ urlSubscribeHandlerMap.forEach((url, handler) -> handler.init());
+ repository.initializeMetadata();
+ applicationContext.addApplicationListener(this);
+
+ logger.info("DubboCloudRegistry preInit Done.");
+ }
+ }
+
+ protected T getBean(Class beanClass) {
return this.applicationContext.getBean(beanClass);
}
@@ -183,249 +196,248 @@ public class DubboCloudRegistry extends FailbackRegistry {
@Override
public final void doSubscribe(URL url, NotifyListener listener) {
-
- if (isAdminURL(url)) {
- // TODO in future
- if (logger.isWarnEnabled()) {
- logger.warn("This feature about admin will be supported in the future.");
+ synchronized (this) {
+ if (isAdminURL(url)) {
+ // TODO in future
+ if (logger.isWarnEnabled()) {
+ logger.warn(
+ "This feature about admin will be supported in the future.");
+ }
+ }
+ else if (isDubboMetadataServiceURL(url) && containsProviderCategory(url)) {
+ // for DubboMetadataService
+ String appName = getServiceName(url);
+ MetadataServiceSubscribeHandler handler = new MetadataServiceSubscribeHandler(
+ appName, url, listener, this, dubboMetadataUtils);
+ if (inited.get()) {
+ handler.init();
+ }
+ metadataSubscribeHandlerMap.put(appName, handler);
+ }
+ else if (isConsumerServiceURL(url)) {
+ // for general Dubbo Services
+ GenearalServiceSubscribeHandler handler = new GenearalServiceSubscribeHandler(
+ url, listener, this, repository, jsonUtils,
+ dubboMetadataConfigServiceProxy);
+ if (inited.get()) {
+ handler.init();
+ }
+ urlSubscribeHandlerMap.put(url, handler);
}
- }
- else if (isDubboMetadataServiceURL(url)) { // for DubboMetadataService
- subscribeDubboMetadataServiceURLs(url, listener);
- }
- else { // for general Dubbo Services
- subscribeURLs(url, listener);
- urlNotifyListenerMap.put(url, listener);
}
}
- private void subscribeURLs(URL url, NotifyListener listener) {
-
- // Sync subscription
- subscribeURLs(url, getServices(url), listener);
-
- // Async subscription
- registerServiceInstancesChangedListener(url,
+ /**
+ * Process ServiceInstanceChangedEvent, refresh dubbo reference and metadata info.
+ */
+ @Override
+ public void onApplicationEvent(ServiceInstancesChangedEvent event) {
- new ServiceInstanceChangeListener() {
+ String appName = event.getServiceName();
- @Override
- public int getOrder() {
- return Ordered.LOWEST_PRECEDENCE;
- }
+ List instances = filter(event.getServiceInstances() != null
+ ? event.getServiceInstances() : Collections.emptyList());
- @Override
- public void onApplicationEvent(ServiceInstancesChangedEvent event) {
-
- Set serviceNames = getServices(url);
-
- String serviceName = event.getServiceName();
-
- if (serviceNames.contains(serviceName)) {
- logger.debug(
- "handle serviceInstanceChange of general service, serviceName = {}, subscribeUrl={}",
- event.getServiceName(), url.getServiceKey());
- try {
- subscribeURLs(url, serviceNames, listener);
- reConnectJobMap.remove(serviceName);
- }
- catch (Exception e) {
- logger.warn(String.format(
- "subscribeURLs failed, serviceName = %s, try reSubscribe again",
- serviceName), e);
- addReSubscribeMetadataJob(serviceName, 0);
- }
- }
- }
-
- @Override
- public String toString() {
- return "ServiceInstancesChangedEventListener:"
- + url.getServiceKey();
- }
- });
- }
+ Set subscribedServiceNames = getServices(null);
- void addReSubscribeMetadataJob(String serviceName, int count) {
- if (count > maxReSubscribeMetadataTimes) {
- logger.error(
- "reSubscribe failed too many times, serviceName = {}, count = {}",
- serviceName, count);
+ if (!subscribedServiceNames.contains(appName)) {
return;
}
- ReSubscribeMetadataJob job = new ReSubscribeMetadataJob(serviceName, this, count);
- reConnectJobMap.put(serviceName, job);
- reConnectPool.schedule(job, reSubscribeMetadataIntervial, TimeUnit.SECONDS);
- }
- void subscribeURLs(URL url, Set serviceNames, NotifyListener listener) {
+ if (instances.size() == 0) {
+ logger.warn("APP {} instance changed, size changed zero!!!", appName);
+ }
+ else {
+ logger.info("APP {} instance changed, size changed to {}", appName,
+ instances.size());
+ }
+ // group by revision
+ Map> newGroup = instances.stream()
+ .collect(Collectors.groupingBy(this::getRevision));
+
+ synchronized (this) {
- List subscribedURLs = new LinkedList<>();
+ Map> oldGroup = serviceRevisionInstanceMap
+ .computeIfAbsent(appName, k -> new HashMap<>());
- serviceNames.forEach(serviceName -> {
+ if (serviceInstanceNotChanged(oldGroup, newGroup)) {
+ logger.debug("APP {} instance changed, but nothing different", appName);
+ return;
+ }
- subscribeURLs(url, subscribedURLs, serviceName,
- () -> getServiceInstances(serviceName));
+ try {
- });
+ // ensure that the service metadata is correct
+ refreshServiceMetadataInfo(appName, instances);
- // Notify all
- notifyAllSubscribedURLs(url, subscribedURLs, listener);
- }
+ // then , refresh general service associated with current application
+ refreshGeneralServiceInfo(appName, oldGroup, newGroup);
- private void registerServiceInstancesChangedListener(URL url,
- ApplicationListener listener) {
- String listenerId = generateId(url);
- if (REGISTER_LISTENERS.add(listenerId)) {
- applicationContext.addApplicationListener(listener);
+ // mark process successful
+ reSubscribeManager.onRefreshSuccess(event);
+ }
+ catch (Exception e) {
+ logger.error(String.format(
+ "APP %s instance changed, handler faild, try resubscribe",
+ appName), e);
+ reSubscribeManager.onRefreshFail(event);
+ }
}
}
- private void subscribeURLs(URL subscribedURL, List subscribedURLs,
- String serviceName,
- Supplier> serviceInstancesSupplier) {
- List serviceInstances = serviceInstancesSupplier.get();
- subscribeURLs(subscribedURL, subscribedURLs, serviceName, serviceInstances);
- }
+ private void refreshGeneralServiceInfo(String appName,
+ Map> oldGroup,
+ Map> newGroup) {
+
+ Set urls2refresh = new HashSet<>();
- private void subscribeURLs(URL subscribedURL, List subscribedURLs,
- String serviceName, List serviceInstances) {
+ // compare with local
+ for (String revision : oldGroup.keySet()) {
- if (CollectionUtils.isEmpty(serviceInstances)) {
- if (logger.isWarnEnabled()) {
- logger.warn(format("There is no instance in service[name : %s]",
- serviceName));
+ if (!newGroup.containsKey(revision)) {
+ // all instances of this list with revision has losted
+ urlSubscribeHandlerMap.forEach((url, handler) -> {
+ if (handler.relatedWith(appName, revision)) {
+ handler.removeAppNameWithRevision(appName, revision);
+ urls2refresh.add(url);
+ }
+ });
+ logger.debug("Subscription app {} revision {} has all losted", appName,
+ revision);
}
}
- else {
- logger.debug("subscribe from serviceName = {}, size = {}", serviceName,
- serviceInstances.size());
- }
- List exportedURLs = getExportedURLs(subscribedURL, serviceName,
- serviceInstances);
+ for (Map.Entry> entry : newGroup.entrySet()) {
+ String revision = entry.getKey();
+ List instanceList = entry.getValue();
- /**
- * Add the exported URLs from {@link MetadataService}
- */
- subscribedURLs.addAll(exportedURLs);
- }
-
- private List getExportedURLs(URL subscribedURL, String serviceName,
- List serviceInstances) {
+ if (!oldGroup.containsKey(revision)) {
+ // this instance list of revision not exists
+ // should acquire urls
+ urlSubscribeHandlerMap.forEach(
+ (url, handler) -> handler.init(appName, revision, instanceList));
+ }
- List validServiceInstances = filter(serviceInstances);
+ urlSubscribeHandlerMap.forEach((url, handler) -> {
+ if (handler.relatedWith(appName, revision)) {
+ urls2refresh.add(url);
+ }
+ });
- // If there is no valid ServiceInstance, return empty result
- if (isEmpty(validServiceInstances)) {
- if (logger.isWarnEnabled()) {
- logger.warn(
- "There is no instance from service[name : {}], and then Dubbo Service[key : {}] will not be "
- + "available , please make sure the further impact",
- serviceName, subscribedURL.getServiceKey());
+ if (logger.isDebugEnabled()) {
+ logger.debug("Subscription app {} revision {} changed, instance list {}",
+ appName, revision,
+ instanceList.stream().map(
+ instance -> instance.getHost() + ":" + instance.getPort())
+ .collect(Collectors.toList()));
}
- return emptyList();
}
- List subscribedURLs = cloneExportedURLs(subscribedURL, serviceInstances);
-
- // clear local service instances, help GC
- validServiceInstances.clear();
+ serviceRevisionInstanceMap.put(appName, newGroup);
- return subscribedURLs;
+ if (urls2refresh.size() == 0) {
+ logger.debug("Subscription app {}, no urls will be refreshed", appName);
+ }
+ else {
+ logger.debug("Subscription app {}, the following url will be refresh:{}",
+ appName, urls2refresh.stream().map(URL::getServiceKey)
+ .collect(Collectors.toList()));
+
+ for (URL url : urls2refresh) {
+ GenearalServiceSubscribeHandler handler = urlSubscribeHandlerMap.get(url);
+ if (handler == null) {
+ logger.warn("Subscription app {}, can't find handler for service {}",
+ appName, url.getServiceKey());
+ continue;
+ }
+ handler.refresh();
+ }
+ }
}
- /**
- * Clone the subscribed URLs based on the template URLs.
- * @param subscribedURL the URL to be subscribed
- * @param serviceInstances the list of {@link ServiceInstance service instances}
- * @return non-null
- */
- private List cloneExportedURLs(URL subscribedURL,
+ private void refreshServiceMetadataInfo(String serviceName,
List serviceInstances) {
+ MetadataServiceSubscribeHandler handler = metadataSubscribeHandlerMap
+ .get(serviceName);
- List clonedExportedURLs = new LinkedList<>();
-
- serviceInstances.forEach(serviceInstance -> {
-
- String host = serviceInstance.getHost();
-
- getTemplateExportedURLs(subscribedURL, serviceInstances).stream()
- .map(templateURL -> templateURL.removeParameter(TIMESTAMP_KEY))
- .map(templateURL -> templateURL.removeParameter(PID_KEY))
- .map(templateURL -> {
- String protocol = templateURL.getProtocol();
- Integer port = repository.getDubboProtocolPort(serviceInstance,
- protocol);
-
- // reserve tag
- String tag = null;
- List urls = jsonUtils.toURLs(serviceInstance.getMetadata()
- .get("dubbo.metadata-service.urls"));
- if (urls != null && urls.size() > 0) {
- Map parameters = urls.get(0).getParameters();
- tag = parameters.get("dubbo.tag");
- }
-
- if (Objects.equals(templateURL.getHost(), host)
- && Objects.equals(templateURL.getPort(), port)) { // use
- // templateURL
- // if
- // equals
- return templateURL;
- }
-
- if (port == null) {
- if (logger.isWarnEnabled()) {
- logger.warn(
- "The protocol[{}] port of Dubbo service instance[host : {}] "
- + "can't be resolved",
- protocol, host);
- }
- return null;
- }
- else {
- URLBuilder clonedURLBuilder = from(templateURL) // remove the
- // parameters from
- // the template
- // URL
- .setHost(host) // reset the host
- .setPort(port) // reset the port
- .addParameter("dubbo.tag", tag); // reset the tag
-
- return clonedURLBuilder.build();
- }
-
- }).filter(Objects::nonNull).forEach(clonedExportedURLs::add);
- });
- return clonedExportedURLs;
+ if (handler == null) {
+ logger.warn("Subscription app {}, can't find metadata handler", serviceName);
+ return;
+ }
+ handler.refresh(serviceInstances);
}
- private List getTemplateExportedURLs(URL subscribedURL,
- List serviceInstances) {
+ private boolean serviceInstanceNotChanged(Map> oldGroup,
+ Map> newGroup) {
+ if (newGroup.size() != oldGroup.size()) {
+ return false;
+ }
- DubboMetadataService dubboMetadataService = getProxy(serviceInstances);
+ for (Map.Entry> entry : newGroup.entrySet()) {
+ String appName = entry.getKey();
+ List newInstances = entry.getValue();
- List templateExportedURLs = emptyList();
+ if (!oldGroup.containsKey(appName)) {
+ return false;
+ }
- if (dubboMetadataService != null) {
- templateExportedURLs = getExportedURLs(dubboMetadataService, subscribedURL);
- }
- else {
- if (logger.isWarnEnabled()) {
- logger.warn(
- "The metadata of Dubbo service[key : {}] still can't be found, it could effect the further "
- + "Dubbo service invocation",
- subscribedURL.getServiceKey());
+ List oldInstances = oldGroup.get(appName);
+ if (newInstances.size() != oldInstances.size()) {
+ return false;
}
+ boolean matched = newInstances.stream().allMatch(newInstance -> {
+
+ for (ServiceInstance oldInstance : oldInstances) {
+ if (instanceSame(newInstance, oldInstance)) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+ if (!matched) {
+ return false;
+ }
}
- return templateExportedURLs;
+ return true;
}
- private DubboMetadataService getProxy(List serviceInstances) {
- return dubboMetadataConfigServiceProxy.getProxy(serviceInstances);
+ private boolean instanceSame(ServiceInstance newInstance,
+ ServiceInstance oldInstance) {
+ if (!StringUtils.equals(newInstance.getInstanceId(),
+ oldInstance.getInstanceId())) {
+ return false;
+ }
+ if (!StringUtils.equals(newInstance.getHost(), oldInstance.getHost())) {
+ return false;
+ }
+ if (!StringUtils.equals(newInstance.getServiceId(), oldInstance.getServiceId())) {
+ return false;
+ }
+ if (!StringUtils.equals(newInstance.getScheme(), oldInstance.getScheme())) {
+ return false;
+ }
+ if (oldInstance.getPort() != newInstance.getPort()) {
+ return false;
+ }
+
+ if (!oldInstance.getMetadata().equals(newInstance.getMetadata())) {
+ return false;
+ }
+
+ return true;
+ }
+
+ String getRevision(ServiceInstance instance) {
+ Map metadata = instance.getMetadata();
+ String revision = metadata.get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME);
+
+ if (revision == null) {
+ revision = RevisionResolver.getEmptyRevision();
+ }
+ return revision;
}
private List filter(Collection serviceInstances) {
@@ -440,35 +452,14 @@ public class DubboCloudRegistry extends FailbackRegistry {
Set getServices(URL url) {
Set subscribedServices = repository.getSubscribedServices();
+ if (subscribedServices.contains("*")) {
+ subscribedServices = new HashSet<>(discoveryClient.getServices());
+ }
// TODO Add the filter feature
return subscribedServices;
}
- private void notifyAllSubscribedURLs(URL url, List subscribedURLs,
- NotifyListener listener) {
-
- if (isEmpty(subscribedURLs)) {
- // Add the EMPTY_PROTOCOL URL
- subscribedURLs.add(emptyURL(url));
-
- // if (isDubboMetadataServiceURL(url)) {
- // if meta service change, and serviceInstances is zero, will clean up
- // information about this client
- // String serviceName = url.getParameter(GROUP_KEY);
- // repository.removeMetadataAndInitializedService(serviceName, url);
- // }
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug("The subscribed URL[{}] will notify all URLs : {}", url,
- subscribedURLs);
- }
-
- // Notify all
- listener.notify(subscribedURLs);
- }
-
- private List getServiceInstances(String serviceName) {
+ List getServiceInstances(String serviceName) {
return hasText(serviceName) ? doGetServiceInstances(serviceName) : emptyList();
}
@@ -485,108 +476,14 @@ public class DubboCloudRegistry extends FailbackRegistry {
return serviceInstances;
}
- private String generateId(URL url) {
- return url.toString();
- }
-
- private URL emptyURL(URL url) {
- // issue : When the last service provider is closed, the client still periodically
- // connects to the last provider.n
- // fix https://github.com/alibaba/spring-cloud-alibaba/issues/1259
- return from(url).setProtocol(EMPTY_PROTOCOL).removeParameter(CATEGORY_KEY)
- .build();
- }
-
- private List getExportedURLs(DubboMetadataService dubboMetadataService,
- URL subscribedURL) {
- String serviceInterface = subscribedURL.getServiceInterface();
- String group = subscribedURL.getParameter(GROUP_KEY);
- String version = subscribedURL.getParameter(VERSION_KEY);
- // The subscribed protocol may be null
- String subscribedProtocol = subscribedURL.getParameter(PROTOCOL_KEY);
- String exportedURLsJSON = dubboMetadataService.getExportedURLs(serviceInterface,
- group, version);
- return jsonUtils.toURLs(exportedURLsJSON).stream()
- .filter(exportedURL -> subscribedProtocol == null
- || subscribedProtocol.equalsIgnoreCase(exportedURL.getProtocol()))
- .collect(Collectors.toList());
- }
-
- private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
- NotifyListener listener) {
-
- subscribeDubboMetadataServiceURLs(subscribedURL, listener,
- getServiceName(subscribedURL));
-
- // Sync subscription
- if (containsProviderCategory(subscribedURL)) {
-
- registerServiceInstancesChangedListener(subscribedURL,
- new ServiceInstanceChangeListener() {
-
- @Override
- public int getOrder() {
- return Ordered.LOWEST_PRECEDENCE - 1;
- }
-
- @Override
- public void onApplicationEvent(
- ServiceInstancesChangedEvent event) {
- String sourceServiceName = event.getServiceName();
- List serviceInstances = event
- .getServiceInstances();
- String serviceName = getServiceName(subscribedURL);
-
- if (Objects.equals(sourceServiceName, serviceName)) {
- logger.debug(
- "handle serviceInstanceChange of metadata service, serviceName = {}, subscribeUrl={}",
- event.getServiceName(),
- subscribedURL.getServiceKey());
-
- // only update serviceInstances of the specified
- // serviceName
- subscribeDubboMetadataServiceURLs(subscribedURL, listener,
- sourceServiceName, serviceInstances);
- }
- }
-
- @Override
- public String toString() {
- return "ServiceInstancesChangedEventListener:"
- + subscribedURL.getServiceKey();
- }
- });
- }
- }
-
+ // the group of DubboMetadataService is current application name
private String getServiceName(URL subscribedURL) {
return subscribedURL.getParameter(GROUP_KEY);
}
- private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
- NotifyListener listener, String serviceName,
- List serviceInstances) {
-
- String serviceInterface = subscribedURL.getServiceInterface();
- String version = subscribedURL.getParameter(VERSION_KEY);
- String protocol = subscribedURL.getParameter(PROTOCOL_KEY);
-
- List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances,
- serviceInterface, version, protocol);
-
- notifyAllSubscribedURLs(subscribedURL, urls, listener);
- }
-
- private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
- NotifyListener listener, String serviceName) {
- List serviceInstances = getServiceInstances(serviceName);
- subscribeDubboMetadataServiceURLs(subscribedURL, listener, serviceName,
- serviceInstances);
- }
-
private boolean containsProviderCategory(URL subscribedURL) {
String category = subscribedURL.getParameter(CATEGORY_KEY);
- return category == null ? false : category.contains(PROVIDER);
+ return category != null && category.contains(PROVIDER);
}
@Override
@@ -603,16 +500,36 @@ public class DubboCloudRegistry extends FailbackRegistry {
return ADMIN_PROTOCOL.equals(url.getProtocol());
}
- public Map getUrlNotifyListenerMap() {
- return urlNotifyListenerMap;
+ protected boolean isDubboMetadataServiceURL(URL url) {
+ return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
}
- public Map getReConnectJobMap() {
- return reConnectJobMap;
+ protected boolean isConsumerServiceURL(URL url) {
+ return CONSUMER.equals(url.getProtocol());
}
- protected boolean isDubboMetadataServiceURL(URL url) {
- return DUBBO_METADATA_SERVICE_CLASS_NAME.equals(url.getServiceInterface());
+ public List getServiceInstances(Map> providers) {
+ List instances = new ArrayList<>();
+
+ providers.forEach((appName, revisions) -> {
+ Map> revisionMap = serviceRevisionInstanceMap
+ .get(appName);
+ if (revisionMap == null) {
+ return;
+ }
+ for (String revision : revisions) {
+ List list = revisionMap.get(revision);
+ if (list != null) {
+ instances.addAll(list);
+ }
+ }
+ });
+
+ return instances;
+ }
+
+ public Map>> getServiceRevisionInstanceMap() {
+ return serviceRevisionInstanceMap;
}
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java
new file mode 100644
index 000000000..a2f3ca4f7
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.registry;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
+import com.alibaba.cloud.dubbo.service.DubboMetadataService;
+import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy;
+import com.alibaba.cloud.dubbo.util.JSONUtils;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.URLBuilder;
+import org.apache.dubbo.registry.NotifyListener;
+
+import org.springframework.cloud.client.ServiceInstance;
+
+import static java.util.Collections.emptyList;
+import static org.apache.dubbo.common.URLBuilder.from;
+import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+
+/**
+ * @author theonefx
+ */
+public class GenearalServiceSubscribeHandler extends AbstractServiceSubscribeHandler {
+
+ private final Map> providers = new HashMap<>();
+
+ private final Map urlTemplateMap = new HashMap<>();
+
+ private final JSONUtils jsonUtils;
+
+ private final DubboServiceMetadataRepository repository;
+
+ private final DubboMetadataServiceProxy dubboMetadataConfigServiceProxy;
+
+ public GenearalServiceSubscribeHandler(URL url, NotifyListener listener,
+ DubboCloudRegistry registry, DubboServiceMetadataRepository repository,
+ JSONUtils jsonUtils,
+ DubboMetadataServiceProxy dubboMetadataConfigServiceProxy) {
+ super(url, listener, registry);
+ this.repository = repository;
+ this.jsonUtils = jsonUtils;
+ this.dubboMetadataConfigServiceProxy = dubboMetadataConfigServiceProxy;
+ }
+
+ public boolean relatedWith(String appName, String revision) {
+ Set list = providers.get(appName);
+ if (list != null && list.size() > 0) {
+ if (list.contains(revision)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void removeAppNameWithRevision(String appName, String revision) {
+ Set list = providers.get(appName);
+ if (list != null) {
+ list.remove(revision);
+ if (list.size() == 0) {
+ providers.remove(appName);
+ }
+ }
+ }
+
+ public void addAppNameWithRevision(String appName, String revision) {
+ Set set = providers.computeIfAbsent(appName, k -> new HashSet<>());
+ set.add(revision);
+ }
+
+ public synchronized void doInit() {
+ logger.debug("Subscription interface {}, GenearalServiceSubscribeHandler init",
+ url.getServiceKey());
+ Map>> map = registry
+ .getServiceRevisionInstanceMap();
+ for (Map.Entry>> entry : map
+ .entrySet()) {
+ String appName = entry.getKey();
+ Map> revisionMap = entry.getValue();
+
+ for (Map.Entry> revisionEntity : revisionMap
+ .entrySet()) {
+ String revision = revisionEntity.getKey();
+ List instances = revisionEntity.getValue();
+ init(appName, revision, instances);
+ }
+ }
+ refresh();
+ }
+
+ public void init(String appName, String revision,
+ List instanceList) {
+ List urls = getTemplateExportedURLs(url, instanceList);
+ if (urls != null && urls.size() > 0) {
+ addAppNameWithRevision(appName, revision);
+ setUrlTemplate(appName, revision, urls);
+ }
+ }
+
+ public synchronized void refresh() {
+ List urls = getProviderURLs();
+ notifyAllSubscribedURLs(url, urls, listener);
+ }
+
+ private List getProviderURLs() {
+ List instances = registry.getServiceInstances(providers);
+
+ logger.debug("Subscription interfece {}, providers {}, total {}",
+ url.getServiceKey(), providers, instances.size());
+
+ if (instances.size() == 0) {
+ return Collections.emptyList();
+ }
+
+ return cloneExportedURLs(instances);
+ }
+
+ void setUrlTemplate(String appName, String revision, List urls) {
+ if (urls == null || urls.size() == 0) {
+ return;
+ }
+ String key = getAppRevisionKey(appName, revision);
+ if (urlTemplateMap.containsKey(key)) {
+ return;
+ }
+ urlTemplateMap.put(key, urls.get(0));
+ }
+
+ private String getAppRevisionKey(String appName, String revision) {
+ return appName + "@" + revision;
+ }
+
+ /**
+ * Clone the subscribed URLs based on the template URLs.
+ * @param serviceInstances the list of
+ * {@link org.springframework.cloud.client.ServiceInstance service instances}
+ * @return
+ */
+ List cloneExportedURLs(List serviceInstances) {
+
+ List urlsCloneTo = new ArrayList<>();
+ serviceInstances.forEach(serviceInstance -> {
+
+ String host = serviceInstance.getHost();
+ String appName = serviceInstance.getServiceId();
+ String revision = registry.getRevision(serviceInstance);
+
+ URL template = urlTemplateMap.get(getAppRevisionKey(appName, revision));
+
+ Stream.of(template)
+ .map(templateURL -> templateURL.removeParameter(TIMESTAMP_KEY))
+ .map(templateURL -> templateURL.removeParameter(PID_KEY))
+ .map(templateURL -> {
+ String protocol = templateURL.getProtocol();
+ Integer port = repository.getDubboProtocolPort(serviceInstance,
+ protocol);
+
+ // reserve tag
+ String tag = null;
+ List urls = jsonUtils.toURLs(serviceInstance.getMetadata()
+ .get("dubbo.metadata-service.urls"));
+ if (urls != null && urls.size() > 0) {
+ Map parameters = urls.get(0).getParameters();
+ tag = parameters.get("dubbo.tag");
+ }
+
+ if (Objects.equals(templateURL.getHost(), host)
+ && Objects.equals(templateURL.getPort(), port)) { // use
+ // templateURL
+ // if
+ // equals
+ return templateURL;
+ }
+
+ if (port == null) {
+ if (logger.isWarnEnabled()) {
+ logger.warn(
+ "The protocol[{}] port of Dubbo service instance[host : {}] "
+ + "can't be resolved",
+ protocol, host);
+ }
+ return null;
+ }
+ else {
+ URLBuilder clonedURLBuilder = from(templateURL) // remove the
+ // parameters from
+ // the template
+ // URL
+ .setHost(host) // reset the host
+ .setPort(port) // reset the port
+ .addParameter("dubbo.tag", tag); // reset the tag
+
+ return clonedURLBuilder.build();
+ }
+
+ }).filter(Objects::nonNull).forEach(urlsCloneTo::add);
+ });
+ return urlsCloneTo;
+ }
+
+ private List getTemplateExportedURLs(URL subscribedURL,
+ List serviceInstances) {
+
+ DubboMetadataService dubboMetadataService = getProxy(serviceInstances);
+
+ List templateExportedURLs = emptyList();
+
+ if (dubboMetadataService != null) {
+ templateExportedURLs = getExportedURLs(dubboMetadataService, subscribedURL);
+ }
+ else {
+ if (logger.isWarnEnabled()) {
+ logger.warn(
+ "The metadata of Dubbo service[key : {}] still can't be found, it could effect the further "
+ + "Dubbo service invocation",
+ subscribedURL.getServiceKey());
+ }
+
+ }
+
+ return templateExportedURLs;
+ }
+
+ private DubboMetadataService getProxy(List serviceInstances) {
+ return dubboMetadataConfigServiceProxy.getProxy(serviceInstances);
+ }
+
+ private List getExportedURLs(DubboMetadataService dubboMetadataService,
+ URL subscribedURL) {
+ String serviceInterface = subscribedURL.getServiceInterface();
+ String group = subscribedURL.getParameter(GROUP_KEY);
+ String version = subscribedURL.getParameter(VERSION_KEY);
+ // The subscribed protocol may be null
+ String subscribedProtocol = subscribedURL.getParameter(PROTOCOL_KEY);
+ String exportedURLsJSON = dubboMetadataService.getExportedURLs(serviceInterface,
+ group, version);
+ return jsonUtils.toURLs(exportedURLsJSON).stream()
+ .filter(exportedURL -> subscribedProtocol == null
+ || subscribedProtocol.equalsIgnoreCase(exportedURL.getProtocol()))
+ .collect(Collectors.toList());
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/MetadataServiceSubscribeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/MetadataServiceSubscribeHandler.java
new file mode 100644
index 000000000..9a9f99325
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/MetadataServiceSubscribeHandler.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.registry;
+
+import java.util.List;
+
+import com.alibaba.cloud.dubbo.util.DubboMetadataUtils;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.NotifyListener;
+
+import org.springframework.cloud.client.ServiceInstance;
+
+import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
+
+/**
+ * @author theonefx
+ */
+public class MetadataServiceSubscribeHandler extends AbstractServiceSubscribeHandler {
+
+ private final String appName;
+
+ private final DubboMetadataUtils dubboMetadataUtils;
+
+ public MetadataServiceSubscribeHandler(String appName, URL url,
+ NotifyListener listener, DubboCloudRegistry registry,
+ DubboMetadataUtils dubboMetadataUtils) {
+ super(url, listener, registry);
+ this.appName = appName;
+ this.dubboMetadataUtils = dubboMetadataUtils;
+ }
+
+ public void doInit() {
+ logger.debug("Subscription app {} MetadataService handler init", appName);
+ List serviceInstances = registry.getServiceInstances(appName);
+ subscribeDubboMetadataServiceURLs(url, listener, serviceInstances);
+ }
+
+ public void refresh(List serviceInstances) {
+ logger.debug("Subscription app {}, instance changed, new size = {}", appName,
+ serviceInstances.size());
+ subscribeDubboMetadataServiceURLs(url, listener, serviceInstances);
+ }
+
+ private void subscribeDubboMetadataServiceURLs(URL subscribedURL,
+ NotifyListener listener, List serviceInstances) {
+
+ logger.debug("Subscription app {}, service instance changed to size {}", appName,
+ serviceInstances.size());
+
+ String serviceInterface = subscribedURL.getServiceInterface();
+ String version = subscribedURL.getParameter(VERSION_KEY);
+ String protocol = subscribedURL.getParameter(PROTOCOL_KEY);
+
+ List urls = dubboMetadataUtils.getDubboMetadataServiceURLs(serviceInstances,
+ serviceInterface, version, protocol);
+
+ notifyAllSubscribedURLs(subscribedURL, urls, listener);
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeManager.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeManager.java
new file mode 100644
index 000000000..5de52dbf6
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeManager.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2013-2018 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.alibaba.cloud.dubbo.registry;
+
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import com.alibaba.cloud.dubbo.env.DubboCloudProperties;
+import com.alibaba.cloud.dubbo.registry.event.ServiceInstancesChangedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.client.ServiceInstance;
+
+/**
+ * @author theonefx
+ */
+public class ReSubscribeManager {
+
+ private final Logger logger = LoggerFactory.getLogger(ReSubscribeManager.class);
+
+ private final Map reConnectJobMap = new ConcurrentHashMap<>();
+
+ private final ScheduledThreadPoolExecutor reConnectPool = new ScheduledThreadPoolExecutor(
+ 5);
+
+ private final DubboCloudRegistry registry;
+
+ private final DubboCloudProperties properties;
+
+ public ReSubscribeManager(DubboCloudRegistry registry) {
+ this.registry = registry;
+ this.properties = registry.getBean(DubboCloudProperties.class);
+
+ reConnectPool.setKeepAliveTime(10, TimeUnit.MINUTES);
+ reConnectPool.allowCoreThreadTimeOut(true);
+ }
+
+ public void onRefreshSuccess(ServiceInstancesChangedEvent event) {
+ reConnectJobMap.remove(event.getServiceName());
+ }
+
+ public void onRefreshFail(ServiceInstancesChangedEvent event) {
+ String serviceName = event.getServiceName();
+
+ int count = 1;
+
+ if (event instanceof FakeServiceInstancesChangedEvent) {
+ count = ((FakeServiceInstancesChangedEvent) event).getCount() + 1;
+ }
+
+ if (count >= properties.getMaxReSubscribeMetadataTimes()) {
+ logger.error(
+ "reSubscribe failed too many times, serviceName = {}, count = {}",
+ serviceName, count);
+ return;
+ }
+
+ ReSubscribeMetadataJob job = new ReSubscribeMetadataJob(serviceName, count);
+ reConnectPool.schedule(job, properties.getReSubscribeMetadataIntervial(),
+ TimeUnit.SECONDS);
+ }
+
+ private final class ReSubscribeMetadataJob implements Runnable {
+
+ private final String serviceName;
+
+ private final int errorCounts;
+
+ private ReSubscribeMetadataJob(String serviceName, int errorCounts) {
+ this.errorCounts = errorCounts;
+ this.serviceName = serviceName;
+ }
+
+ @Override
+ public void run() {
+ if (!reConnectJobMap.containsKey(serviceName)
+ || reConnectJobMap.get(serviceName) != this) {
+ return;
+ }
+ List list = registry.getServiceInstances(serviceName);
+ FakeServiceInstancesChangedEvent event = new FakeServiceInstancesChangedEvent(
+ serviceName, list, errorCounts);
+ registry.onApplicationEvent(event);
+ }
+
+ }
+
+ private static final class FakeServiceInstancesChangedEvent
+ extends ServiceInstancesChangedEvent {
+
+ private static final long serialVersionUID = -2832478604601472915L;
+
+ private final int count;
+
+ private FakeServiceInstancesChangedEvent(String serviceName,
+ List serviceInstances, int count) {
+ super(serviceName, serviceInstances);
+ this.count = count;
+ }
+
+ public int getCount() {
+ return count;
+ }
+
+ }
+
+}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
deleted file mode 100644
index 74d917f07..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/ReSubscribeMetadataJob.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.dubbo.registry;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.NotifyListener;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * For re subscribe URL from provider.
- *
- * @author theonefx
- */
-public class ReSubscribeMetadataJob implements Runnable {
-
- protected final Logger logger = LoggerFactory.getLogger(ReSubscribeMetadataJob.class);
-
- private final String serviceName;
-
- private final DubboCloudRegistry dubboCloudRegistry;
-
- private final int errorCounts;
-
- public ReSubscribeMetadataJob(String serviceName,
- DubboCloudRegistry dubboCloudRegistry, int errorCounts) {
- this.errorCounts = errorCounts;
- this.serviceName = serviceName;
- this.dubboCloudRegistry = dubboCloudRegistry;
- }
-
- public ReSubscribeMetadataJob(String serviceName,
- DubboCloudRegistry dubboCloudRegistry) {
- this(serviceName, dubboCloudRegistry, 0);
- }
-
- @Override
- public void run() {
- if (dubboCloudRegistry.getReConnectJobMap().get(serviceName) != this) {
- return;
- }
- try {
- logger.info("reSubscribe, serviceName = {}, count = {}", serviceName,
- errorCounts);
- for (Map.Entry entry : dubboCloudRegistry
- .getUrlNotifyListenerMap().entrySet()) {
- doRun(entry.getKey(), entry.getValue());
- }
- dubboCloudRegistry.getReConnectJobMap().remove(serviceName);
- }
- catch (Exception e) {
- logger.warn(String.format(
- "reSubscribe failed, serviceName = %s, try refresh again",
- serviceName), e);
- dubboCloudRegistry.addReSubscribeMetadataJob(serviceName, errorCounts + 1);
- }
- }
-
- private void doRun(URL url, NotifyListener listener) {
- Set serviceNames = dubboCloudRegistry.getServices(url);
-
- if (serviceNames.contains(serviceName)) {
- dubboCloudRegistry.subscribeURLs(url, serviceNames, listener);
- }
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java
index d13c5179c..2b3b676a3 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/SpringCloudRegistryFactory.java
@@ -89,7 +89,7 @@ public class SpringCloudRegistryFactory extends AbstractRegistryFactory {
DubboCloudProperties dubboCloudProperties = applicationContext
.getBean(DubboCloudProperties.class);
- Registry registry = null;
+ Registry registry;
switch (dubboCloudProperties.getRegistryType()) {
case SPRING_CLOUD_REGISTRY_PROPERTY_VALUE:
@@ -100,9 +100,7 @@ public class SpringCloudRegistryFactory extends AbstractRegistryFactory {
default:
registry = new DubboCloudRegistry(url, discoveryClient,
dubboServiceMetadataRepository, dubboMetadataConfigServiceProxy,
- jsonUtils, dubboGenericServiceFactory, applicationContext,
- dubboCloudProperties.getMaxReSubscribeMetadataTimes(),
- dubboCloudProperties.getReSubscribeMetadataIntervial());
+ jsonUtils, applicationContext);
break;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter
new file mode 100644
index 000000000..ce4f0db1e
--- /dev/null
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter
@@ -0,0 +1 @@
+default=com.alibaba.cloud.dubbo.metadata.DefaultMetadataParamsFilter
\ No newline at end of file
From df2bced6f2a01ca6254f26ad221f6edc081353f8 Mon Sep 17 00:00:00 2001
From: theonefx
Date: Tue, 1 Jun 2021 11:18:47 +0800
Subject: [PATCH 40/99] optimize dubbo registry
---
.../repository/DubboServiceMetadataRepository.java | 1 +
.../alibaba/cloud/dubbo/registry/DubboCloudRegistry.java | 8 +++++---
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
index 7e85e624c..8b687cd19 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
@@ -245,6 +245,7 @@ public class DubboServiceMetadataRepository
@Override
public void afterSingletonsInstantiated() {
+ // inited by DubboCloudRegistry.preInit() @theonefx
// initializeMetadata();
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index 1fe831834..a18823947 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -42,7 +42,6 @@ import org.apache.dubbo.registry.support.FailbackRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationListener;
@@ -154,6 +153,8 @@ public class DubboCloudRegistry extends FailbackRegistry
metadataSubscribeHandlerMap.forEach((url, handler) -> handler.init());
urlSubscribeHandlerMap.forEach((url, handler) -> handler.init());
repository.initializeMetadata();
+
+ // meke sure everything prepared, then can listening ServiceInstanceChangeEvent
applicationContext.addApplicationListener(this);
logger.info("DubboCloudRegistry preInit Done.");
@@ -235,8 +236,9 @@ public class DubboCloudRegistry extends FailbackRegistry
String appName = event.getServiceName();
- List instances = filter(event.getServiceInstances() != null
- ? event.getServiceInstances() : Collections.emptyList());
+ List instances = filter(
+ event.getServiceInstances() != null ? event.getServiceInstances()
+ : Collections.emptyList());
Set subscribedServiceNames = getServices(null);
From 87d0939411e284d59a64a999ab359a20b3596702 Mon Sep 17 00:00:00 2001
From: joeqiaoyao
Date: Tue, 1 Jun 2021 21:06:52 +0800
Subject: [PATCH 41/99] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0unitName=EF=BC=8C=E6=94=AF=E6=8C=81=E5=90=8C=E4=B8=80?=
=?UTF-8?q?=E5=BA=94=E7=94=A8=E8=BF=9E=E6=8E=A5=E5=A4=9A=E4=B8=AA=E9=9B=86?=
=?UTF-8?q?=E7=BE=A4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../integration/inbound/RocketMQConsumerFactory.java | 2 ++
.../integration/outbound/RocketMQProduceFactory.java | 1 +
.../properties/RocketMQCommonProperties.java | 12 ++++++++++++
.../stream/binder/rocketmq/utils/RocketMQUtils.java | 3 +++
4 files changed, 18 insertions(+)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
index 7f7e1bf26..2aeb1a19f 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/inbound/RocketMQConsumerFactory.java
@@ -89,6 +89,7 @@ public final class RocketMQConsumerFactory {
consumer.setPullInterval(consumerProperties.getPush().getPullInterval());
consumer.setConsumeThreadMin(extendedConsumerProperties.getConcurrency());
consumer.setConsumeThreadMax(extendedConsumerProperties.getConcurrency());
+ consumer.setUnitName(consumerProperties.getUnitName());
return consumer;
}
@@ -145,6 +146,7 @@ public final class RocketMQConsumerFactory {
// The internal queues are cached by a maximum of 1000
consumer.setPullThresholdForAll(extendedConsumerProperties.getExtension()
.getPull().getPullThresholdForAll());
+ consumer.setUnitName(consumerProperties.getUnitName());
return consumer;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
index 463868438..509aae652 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProduceFactory.java
@@ -118,6 +118,7 @@ public final class RocketMQProduceFactory {
producerProperties.getRetryAnotherBroker());
producer.setMaxMessageSize(producerProperties.getMaxMessageSize());
producer.setUseTLS(producerProperties.getUseTLS());
+ producer.setUnitName(producerProperties.getUnitName());
CheckForbiddenHook checkForbiddenHook = RocketMQBeanContainerCache.getBean(
producerProperties.getCheckForbiddenHook(), CheckForbiddenHook.class);
if (null != checkForbiddenHook) {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
index 9e9114641..4973dd759 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/properties/RocketMQCommonProperties.java
@@ -56,6 +56,11 @@ public class RocketMQCommonProperties implements Serializable {
private String namespace;
+ /**
+ * The property of "unitName".
+ */
+ private String unitName;
+
private String accessChannel = AccessChannel.LOCAL.name();
/**
@@ -199,4 +204,11 @@ public class RocketMQCommonProperties implements Serializable {
this.customizedTraceTopic = customizedTraceTopic;
}
+ public String getUnitName() {
+ return unitName;
+ }
+
+ public void setUnitName(String unitName) {
+ this.unitName = unitName;
+ }
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
index 1aed546a0..6bc969d24 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/utils/RocketMQUtils.java
@@ -64,6 +64,9 @@ public final class RocketMQUtils {
mqProperties.setCustomizedTraceTopic(
binderConfigurationProperties.getCustomizedTraceTopic());
}
+ if (StringUtils.isEmpty(mqProperties.getUnitName())) {
+ mqProperties.setUnitName(binderConfigurationProperties.getUnitName());
+ }
mqProperties.setNameServer(getNameServerStr(mqProperties.getNameServer()));
return mqProperties;
}
From a2b2c2f8c1fd81a9af9675ab864d27067b168f31 Mon Sep 17 00:00:00 2001
From: yuhuangbin
Date: Thu, 3 Jun 2021 12:36:21 +0800
Subject: [PATCH 42/99] Nacos Discovery supports registration for quick failed
configurations
---
.../src/main/resources/application.properties | 1 +
.../cloud/nacos/NacosDiscoveryProperties.java | 19 +++++++++++++++++--
.../nacos/registry/NacosServiceRegistry.java | 14 +++++++++-----
3 files changed, 27 insertions(+), 7 deletions(-)
diff --git a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties
index cd4cc01d0..c1071da86 100644
--- a/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties
+++ b/spring-cloud-alibaba-examples/nacos-example/nacos-discovery-example/nacos-discovery-consumer-example/src/main/resources/application.properties
@@ -2,6 +2,7 @@ spring.application.name=service-consumer
server.port=18083
management.endpoints.web.exposure.include=*
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
+spring.cloud.nacos.discovery.fail-fast=true
spring.cloud.nacos.username=nacos
spring.cloud.nacos.password=nacos
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java
index 632448dbd..0b0d27a90 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/NacosDiscoveryProperties.java
@@ -207,6 +207,12 @@ public class NacosDiscoveryProperties {
*/
private boolean ephemeral = true;
+ /**
+ * Throw exceptions during service registration if true, otherwise, log error
+ * (defaults to true).
+ */
+ private boolean failFast = true;
+
@Autowired
private InetUtils inetUtils;
@@ -486,6 +492,14 @@ public class NacosDiscoveryProperties {
this.ephemeral = ephemeral;
}
+ public boolean isFailFast() {
+ return failFast;
+ }
+
+ public void setFailFast(boolean failFast) {
+ this.failFast = failFast;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
@@ -510,6 +524,7 @@ public class NacosDiscoveryProperties {
&& Objects.equals(secretKey, that.secretKey)
&& Objects.equals(heartBeatInterval, that.heartBeatInterval)
&& Objects.equals(heartBeatTimeout, that.heartBeatTimeout)
+ && Objects.equals(failFast, that.failFast)
&& Objects.equals(ipDeleteTimeout, that.ipDeleteTimeout);
}
@@ -519,7 +534,7 @@ public class NacosDiscoveryProperties {
watchDelay, logName, service, weight, clusterName, group,
namingLoadCacheAtStart, registerEnabled, ip, networkInterface, port,
secure, accessKey, secretKey, heartBeatInterval, heartBeatTimeout,
- ipDeleteTimeout, instanceEnabled, ephemeral);
+ ipDeleteTimeout, instanceEnabled, ephemeral, failFast);
}
@Override
@@ -535,7 +550,7 @@ public class NacosDiscoveryProperties {
+ ", port=" + port + ", secure=" + secure + ", accessKey='" + accessKey
+ '\'' + ", secretKey='" + secretKey + '\'' + ", heartBeatInterval="
+ heartBeatInterval + ", heartBeatTimeout=" + heartBeatTimeout
- + ", ipDeleteTimeout=" + ipDeleteTimeout + '}';
+ + ", ipDeleteTimeout=" + ipDeleteTimeout + ", failFast=" + failFast + '}';
}
public void overrideFromEnv(Environment env) {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
index 9a79a568f..aabac3a9c 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
@@ -76,11 +76,15 @@ public class NacosServiceRegistry implements ServiceRegistry {
instance.getIp(), instance.getPort());
}
catch (Exception e) {
- log.error("nacos registry, {} register failed...{},", serviceId,
- registration.toString(), e);
- // rethrow a RuntimeException if the registration is failed.
- // issue : https://github.com/alibaba/spring-cloud-alibaba/issues/1132
- rethrowRuntimeException(e);
+ if (nacosDiscoveryProperties.isFailFast()) {
+ log.error("nacos registry, {} register failed...{},", serviceId,
+ registration.toString(), e);
+ rethrowRuntimeException(e);
+ }
+ else {
+ log.warn("Failfast is false. {} register failed...{},", serviceId,
+ registration.toString(), e);
+ }
}
}
From 4786725e8e84d5463e3bb28a92c77b9d8581c28e Mon Sep 17 00:00:00 2001
From: HuGuirong
Date: Thu, 10 Jun 2021 20:27:22 +0800
Subject: [PATCH 43/99] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=BD=93=E5=AE=9E?=
=?UTF-8?q?=E4=BE=8B=E4=B8=8D=E5=9C=A8=E9=BB=98=E8=AE=A4=E5=88=86=E7=BB=84?=
=?UTF-8?q?=E4=B8=8B=E6=97=B6=E8=8E=B7=E5=8F=96=E4=B8=8D=E5=88=B0=E5=AE=9E?=
=?UTF-8?q?=E4=BE=8B=E7=8A=B6=E6=80=81=E7=9A=84BUG?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
index aabac3a9c..16010b373 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
@@ -159,8 +159,9 @@ public class NacosServiceRegistry implements ServiceRegistry {
public Object getStatus(Registration registration) {
String serviceName = registration.getServiceId();
+ String group = nacosDiscoveryProperties.getGroup();
try {
- List instances = namingService().getAllInstances(serviceName);
+ List instances = namingService().getAllInstances(serviceName, group);
for (Instance instance : instances) {
if (instance.getIp().equalsIgnoreCase(nacosDiscoveryProperties.getIp())
&& instance.getPort() == nacosDiscoveryProperties.getPort()) {
From e4f2f4150c8e79d811a13d4bbbe3858fb3c3c09f Mon Sep 17 00:00:00 2001
From: theonefx
Date: Tue, 22 Jun 2021 17:14:34 +0800
Subject: [PATCH 44/99] init DubboCloudRegistry when subscribe or unsubscribe
---
.../spring-cloud-dubbo-client-sample/pom.xml | 1 -
.../src/main/resources/bootstrap.yaml | 10 +++--
.../src/main/resources/bootstrap.yaml | 2 +
.../dubbo/registry/DubboCloudRegistry.java | 42 +++++++++++--------
4 files changed, 34 insertions(+), 21 deletions(-)
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/pom.xml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/pom.xml
index c37db212c..1a675b438 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/pom.xml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/pom.xml
@@ -10,7 +10,6 @@
4.0.0
- com.alibaba.cloudspring-cloud-dubbo-client-sampleSpring Cloud Dubbo Client Sample
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/src/main/resources/bootstrap.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/src/main/resources/bootstrap.yaml
index 6801b6c4b..19d22ad11 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/src/main/resources/bootstrap.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-client-sample/src/main/resources/bootstrap.yaml
@@ -12,7 +12,11 @@ spring:
allow-bean-definition-overriding: true
cloud:
nacos:
- username: nacos
- password: nacos
discovery:
- server-addr: 127.0.0.1:8848
\ No newline at end of file
+ username: nacos
+ password: nacos
+ server-addr: 127.0.0.1:8848
+ namespace: public
+
+server:
+ port: 8080
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-server-sample/src/main/resources/bootstrap.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-server-sample/src/main/resources/bootstrap.yaml
index 650b9861c..db7e38c0d 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-server-sample/src/main/resources/bootstrap.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-server-sample/src/main/resources/bootstrap.yaml
@@ -1,4 +1,6 @@
dubbo:
+ cloud:
+ subscribed-services: ${spring.application.name}
scan:
base-packages: com.alibaba.cloud.dubbo.bootstrap
protocol:
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index a18823947..f02ebe1a2 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -46,7 +46,6 @@ import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.context.event.ContextRefreshedEvent;
import static com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
import static java.util.Collections.emptyList;
@@ -118,9 +117,6 @@ public class DubboCloudRegistry extends FailbackRegistry
this.applicationContext = applicationContext;
this.dubboMetadataUtils = getBean(DubboMetadataUtils.class);
this.reSubscribeManager = new ReSubscribeManager(this);
-
- applicationContext.addApplicationListener(
- (ApplicationListener) event -> preInit());
}
private void preInit() {
@@ -154,7 +150,8 @@ public class DubboCloudRegistry extends FailbackRegistry
urlSubscribeHandlerMap.forEach((url, handler) -> handler.init());
repository.initializeMetadata();
- // meke sure everything prepared, then can listening ServiceInstanceChangeEvent
+ // meke sure everything prepared, then can listening
+ // ServiceInstanceChangeEvent
applicationContext.addApplicationListener(this);
logger.info("DubboCloudRegistry preInit Done.");
@@ -165,39 +162,50 @@ public class DubboCloudRegistry extends FailbackRegistry
return this.applicationContext.getBean(beanClass);
}
- protected boolean shouldRegister(URL url) {
+ protected boolean shouldNotRegister(URL url) {
String side = url.getParameter(SIDE_KEY);
boolean should = PROVIDER_SIDE.equals(side); // Only register the Provider.
- if (!should) {
- if (logger.isDebugEnabled()) {
- logger.debug("The URL[{}] should not be registered.", url.toString());
+ if (logger.isDebugEnabled()) {
+ if (!should) {
+ logger.debug("The URL should NOT!! be registered & unregistered [{}] .",
+ url);
+ }
+ else {
+ logger.debug("The URL should be registered & unregistered [{}] .", url);
}
}
- return should;
+ return !should;
}
@Override
public final void doRegister(URL url) {
- if (!shouldRegister(url)) {
- return;
+ synchronized (this) {
+ preInit();
+ if (shouldNotRegister(url)) {
+ return;
+ }
+ repository.exportURL(url);
}
- repository.exportURL(url);
}
@Override
public final void doUnregister(URL url) {
- if (!shouldRegister(url)) {
- return;
+ synchronized (this) {
+ preInit();
+ if (shouldNotRegister(url)) {
+ return;
+ }
+ repository.unexportURL(url);
}
- repository.unexportURL(url);
}
@Override
public final void doSubscribe(URL url, NotifyListener listener) {
synchronized (this) {
+ preInit();
if (isAdminURL(url)) {
// TODO in future
if (logger.isWarnEnabled()) {
@@ -452,7 +460,7 @@ public class DubboCloudRegistry extends FailbackRegistry
return metadata.containsKey(METADATA_SERVICE_URLS_PROPERTY_NAME);
}
- Set getServices(URL url) {
+ private Set getServices(URL url) {
Set subscribedServices = repository.getSubscribedServices();
if (subscribedServices.contains("*")) {
subscribedServices = new HashSet<>(discoveryClient.getServices());
From fb9521b2e6649c913995ca96012dd5a4b8a78465 Mon Sep 17 00:00:00 2001
From: theonefx
Date: Wed, 23 Jun 2021 16:26:54 +0800
Subject: [PATCH 45/99] remove unused code; make sure param not lost, so that
different param calculate different revision.
---
.../nacos/registry/NacosServiceRegistry.java | 3 +-
.../metadata/DefaultMetadataParamsFilter.java | 55 ------
.../dubbo/metadata/MetadataParamsFilter.java | 35 ----
.../cloud/dubbo/metadata/ServiceInfo.java | 172 ++++--------------
.../dubbo/registry/DubboCloudRegistry.java | 5 +-
....cloud.dubbo.metadata.MetadataParamsFilter | 1 -
6 files changed, 39 insertions(+), 232 deletions(-)
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java
delete mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
index 16010b373..9b91ce48e 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-discovery/src/main/java/com/alibaba/cloud/nacos/registry/NacosServiceRegistry.java
@@ -161,7 +161,8 @@ public class NacosServiceRegistry implements ServiceRegistry {
String serviceName = registration.getServiceId();
String group = nacosDiscoveryProperties.getGroup();
try {
- List instances = namingService().getAllInstances(serviceName, group);
+ List instances = namingService().getAllInstances(serviceName,
+ group);
for (Instance instance : instances) {
if (instance.getIp().equalsIgnoreCase(nacosDiscoveryProperties.getIp())
&& instance.getPort() == nacosDiscoveryProperties.getPort()) {
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java
deleted file mode 100644
index 53d090f1c..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/DefaultMetadataParamsFilter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.dubbo.metadata;
-
-import org.apache.dubbo.common.extension.Activate;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
-import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
-import static org.apache.dubbo.remoting.Constants.CONNECTIONS_KEY;
-import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
-import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
-import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
-import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
-import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.WARMUP_KEY;
-import static org.apache.dubbo.rpc.cluster.Constants.WEIGHT_KEY;
-
-/**
- * Copy from org.apache.dubbo.metadata.DefaultMetadataParamsFilter.
- *
- * @author theonefx
- */
-@Activate
-public class DefaultMetadataParamsFilter implements MetadataParamsFilter {
-
- @Override
- public String[] serviceParamsIncluded() {
- return new String[] { CODEC_KEY, EXCHANGER_KEY, SERIALIZATION_KEY, CLUSTER_KEY,
- CONNECTIONS_KEY, DEPRECATED_KEY, GROUP_KEY, LOADBALANCE_KEY, MOCK_KEY,
- PATH_KEY, TIMEOUT_KEY, TOKEN_KEY, VERSION_KEY, WARMUP_KEY, WEIGHT_KEY,
- DUBBO_VERSION_KEY, RELEASE_KEY };
- }
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java
deleted file mode 100644
index f7b4dc7d1..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/MetadataParamsFilter.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright 2013-2018 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * https://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.alibaba.cloud.dubbo.metadata;
-
-import org.apache.dubbo.common.extension.SPI;
-
-/**
- * Copy from org.apache.dubbo.metadata.MetadataParamsFilter.
- *
- * @author theonefx
- */
-@SPI
-public interface MetadataParamsFilter {
-
- /**
- * params that need to be sent to metadata center.
- * @return arrays of keys
- */
- String[] serviceParamsIncluded();
-
-}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
index a734a8e7e..7e1095f98 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
@@ -20,23 +20,32 @@ import java.io.Serializable;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
+import java.util.Set;
import java.util.SortedSet;
+import java.util.TreeMap;
import java.util.TreeSet;
-import java.util.concurrent.ConcurrentHashMap;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.compiler.support.ClassUtils;
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.StringUtils;
-import static org.apache.dubbo.common.constants.CommonConstants.DOT_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.QUEUES_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.RETRIES_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
/**
@@ -48,9 +57,6 @@ public class ServiceInfo implements Serializable {
private static final long serialVersionUID = -258557978718735302L;
- private static ExtensionLoader loader = ExtensionLoader
- .getExtensionLoader(MetadataParamsFilter.class);
-
private String name;
private String group;
@@ -66,16 +72,6 @@ public class ServiceInfo implements Serializable {
// params configured on consumer side,
private transient Map consumerParams;
- // cached method params
- private transient Map> methodParams;
-
- private transient Map> consumerMethodParams;
-
- // cached numbers
- private transient Map numbers;
-
- private transient Map> methodNumbers;
-
// service + group + version
private transient String serviceKey;
@@ -84,7 +80,20 @@ public class ServiceInfo implements Serializable {
private transient URL url;
- public ServiceInfo() {
+ private static final Set IGNORE_KEYS = new HashSet<>();
+ static {
+ IGNORE_KEYS.add(TIMESTAMP_KEY);
+ IGNORE_KEYS.add(PID_KEY);
+ IGNORE_KEYS.add(INTERFACE_KEY);
+ IGNORE_KEYS.add(METHODS_KEY);
+ IGNORE_KEYS.add(THREADS_KEY);
+ IGNORE_KEYS.add(QUEUES_KEY);
+ IGNORE_KEYS.add(TIMEOUT_KEY);
+ IGNORE_KEYS.add(USERNAME_KEY);
+ IGNORE_KEYS.add(PASSWORD_KEY);
+ IGNORE_KEYS.add(HOST_KEY);
+ IGNORE_KEYS.add(PORT_KEY);
+ IGNORE_KEYS.add(RETRIES_KEY);
}
public ServiceInfo(URL url) {
@@ -92,40 +101,16 @@ public class ServiceInfo implements Serializable {
url.getParameter(VERSION_KEY), url.getProtocol(), url.getPath(), null);
this.url = url;
- Map params = new HashMap<>();
- List filters = loader.getActivateExtension(url,
- "params-filter");
- for (MetadataParamsFilter filter : filters) {
- String[] paramsIncluded = filter.serviceParamsIncluded();
- if (ArrayUtils.isNotEmpty(paramsIncluded)) {
- for (String p : paramsIncluded) {
- String value = url.getParameter(p);
- if (StringUtils.isNotEmpty(value) && params.get(p) == null) {
- params.put(p, value);
- }
- String[] methods = url.getParameter(METHODS_KEY, (String[]) null);
- if (methods != null) {
- for (String method : methods) {
- String mValue = getMethodParameterStrict(url, method, p);
- if (StringUtils.isNotEmpty(mValue)) {
- params.put(method + DOT_SEPARATOR + p, mValue);
- }
- }
- }
- }
+ Map params = new TreeMap<>();
+ url.getParameters().forEach((k, v) -> {
+ if (IGNORE_KEYS.contains(k)) {
+ return;
}
- }
+ params.put(k, v);
+ });
this.params = params;
}
- public String getMethodParameterStrict(URL url, String method, String key) {
- Map keyMap = url.getMethodParameters().get(method);
- String value = null;
- if (keyMap != null) {
- value = keyMap.get(key);
- }
- return value;
- }
public ServiceInfo(String name, String group, String version, String protocol,
String path, Map params) {
@@ -207,17 +192,6 @@ public class ServiceInfo implements Serializable {
this.params = params;
}
- public Map getAllParams() {
- if (consumerParams != null) {
- Map allParams = new HashMap<>(
- (int) ((params.size() + consumerParams.size()) / 0.75f + 1));
- allParams.putAll(params);
- allParams.putAll(consumerParams);
- return allParams;
- }
- return params;
- }
-
public String getParameter(String key) {
if (consumerParams != null) {
String value = consumerParams.get(key);
@@ -228,54 +202,12 @@ public class ServiceInfo implements Serializable {
return params.get(key);
}
- public String getMethodParameter(String method, String key, String defaultValue) {
- if (methodParams == null) {
- methodParams = URL.toMethodParameters(params);
- consumerMethodParams = URL.toMethodParameters(consumerParams);
- }
-
- String value = getMethodParameter(method, key, consumerMethodParams);
- if (value != null) {
- return value;
- }
- value = getMethodParameter(method, key, methodParams);
- return value == null ? defaultValue : value;
- }
-
- private String getMethodParameter(String method, String key,
- Map> map) {
- Map keyMap = map.get(method);
- String value = null;
- if (keyMap != null) {
- value = keyMap.get(key);
- }
- if (StringUtils.isEmpty(value)) {
- value = getParameter(key);
- }
- return value;
- }
-
- public boolean hasMethodParameter(String method, String key) {
- String value = this.getMethodParameter(method, key, (String) null);
- return StringUtils.isNotEmpty(value);
- }
-
- public boolean hasMethodParameter(String method) {
- if (methodParams == null) {
- methodParams = URL.toMethodParameters(params);
- consumerMethodParams = URL.toMethodParameters(consumerParams);
- }
-
- return consumerMethodParams.containsKey(method)
- || methodParams.containsKey(method);
- }
-
public String toDescString() {
return this.getMatchKey() + getMethodSignaturesString() + getParams();
}
private String getMethodSignaturesString() {
- SortedSet methodStrings = new TreeSet();
+ SortedSet methodStrings = new TreeSet<>();
Method[] methods = ClassUtils.forName(name).getMethods();
for (Method method : methods) {
@@ -284,40 +216,6 @@ public class ServiceInfo implements Serializable {
return methodStrings.toString();
}
- public void addParameter(String key, String value) {
- if (consumerParams != null) {
- this.consumerParams.put(key, value);
- }
- }
-
- public void addParameterIfAbsent(String key, String value) {
- if (consumerParams != null) {
- this.consumerParams.putIfAbsent(key, value);
- }
- }
-
- public void addConsumerParams(Map params) {
- // copy once for one service subscription
- if (consumerParams == null) {
- consumerParams = new HashMap<>(params);
- }
- }
-
- public Map getNumbers() {
- // concurrent initialization is tolerant
- if (numbers == null) {
- numbers = new ConcurrentHashMap<>();
- }
- return numbers;
- }
-
- public Map> getMethodNumbers() {
- if (methodNumbers == null) { // concurrent initialization is tolerant
- methodNumbers = new ConcurrentHashMap<>();
- }
- return methodNumbers;
- }
-
public URL getUrl() {
return url;
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index f02ebe1a2..f207d7994 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -244,9 +244,8 @@ public class DubboCloudRegistry extends FailbackRegistry
String appName = event.getServiceName();
- List instances = filter(
- event.getServiceInstances() != null ? event.getServiceInstances()
- : Collections.emptyList());
+ List instances = filter(event.getServiceInstances() != null
+ ? event.getServiceInstances() : Collections.emptyList());
Set subscribedServiceNames = getServices(null);
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter
deleted file mode 100644
index ce4f0db1e..000000000
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/com.alibaba.cloud.dubbo.metadata.MetadataParamsFilter
+++ /dev/null
@@ -1 +0,0 @@
-default=com.alibaba.cloud.dubbo.metadata.DefaultMetadataParamsFilter
\ No newline at end of file
From c448027f34cdab68a740877e410b1406eca199ed Mon Sep 17 00:00:00 2001
From: theonefx
Date: Wed, 23 Jun 2021 17:19:10 +0800
Subject: [PATCH 46/99] add spring-cloud-starter-bootstrap to compatible with
spring boot bootstrap
---
.../cloud/dubbo/metadata/ServiceInfo.java | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
index 7e1095f98..add184c4f 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/ServiceInfo.java
@@ -34,18 +34,10 @@ import org.apache.dubbo.common.utils.StringUtils;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.QUEUES_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.RETRIES_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
/**
@@ -86,14 +78,6 @@ public class ServiceInfo implements Serializable {
IGNORE_KEYS.add(PID_KEY);
IGNORE_KEYS.add(INTERFACE_KEY);
IGNORE_KEYS.add(METHODS_KEY);
- IGNORE_KEYS.add(THREADS_KEY);
- IGNORE_KEYS.add(QUEUES_KEY);
- IGNORE_KEYS.add(TIMEOUT_KEY);
- IGNORE_KEYS.add(USERNAME_KEY);
- IGNORE_KEYS.add(PASSWORD_KEY);
- IGNORE_KEYS.add(HOST_KEY);
- IGNORE_KEYS.add(PORT_KEY);
- IGNORE_KEYS.add(RETRIES_KEY);
}
public ServiceInfo(URL url) {
@@ -111,7 +95,6 @@ public class ServiceInfo implements Serializable {
this.params = params;
}
-
public ServiceInfo(String name, String group, String version, String protocol,
String path, Map params) {
this.name = name;
From 3009b162a0b78a0de6ba19336d9cad1f8c57c461 Mon Sep 17 00:00:00 2001
From: theonefx
Date: Thu, 24 Jun 2021 20:55:41 +0800
Subject: [PATCH 47/99] add a router to make sure that use revision when invoke
DubboMetadataService
---
.../dubbo/metadata/RevisionResolver.java | 21 +++++-
.../DubboServiceMetadataRepository.java | 7 +-
.../dubbo/registry/DubboCloudRegistry.java | 15 +---
.../GenearalServiceSubscribeHandler.java | 24 +++++--
.../MetadataServiceSubscribeHandler.java | 10 +++
.../service/DubboMetadataServiceProxy.java | 1 +
.../MetadataServiceRevisionRouterFactory.java | 69 +++++++++++++++++++
.../cloud/dubbo/util/DubboMetadataUtils.java | 8 ++-
...org.apache.dubbo.rpc.cluster.RouterFactory | 1 +
9 files changed, 128 insertions(+), 28 deletions(-)
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/service/MetadataServiceRevisionRouterFactory.java
create mode 100644 spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/resources/META-INF/dubbo/org.apache.dubbo.rpc.cluster.RouterFactory
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java
index 53f9f1bf4..8ffc18457 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/RevisionResolver.java
@@ -18,10 +18,14 @@ package com.alibaba.cloud.dubbo.metadata;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
+import java.util.Map;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
+import org.springframework.cloud.client.ServiceInstance;
+
+import static com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
import static java.nio.charset.StandardCharsets.UTF_8;
/**
@@ -31,10 +35,15 @@ import static java.nio.charset.StandardCharsets.UTF_8;
*/
public final class RevisionResolver {
- private static final Logger logger = LoggerFactory.getLogger(RevisionResolver.class);
+ /**
+ * The param key in url.
+ */
+ public static final String SCA_REVSION_KEY = "sca_revision";
private static final String EMPTY_REVISION = "0";
+ private static final Logger logger = LoggerFactory.getLogger(RevisionResolver.class);
+
private static final char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
'9', 'A', 'B', 'C', 'D', 'E', 'F' };
@@ -71,4 +80,14 @@ public final class RevisionResolver {
return new String(str);
}
+ public static String getRevision(ServiceInstance instance) {
+ Map metadata = instance.getMetadata();
+ String revision = metadata.get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME);
+
+ if (revision == null) {
+ revision = RevisionResolver.getEmptyRevision();
+ }
+ return revision;
+ }
+
}
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
index 8b687cd19..2579b12ab 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/metadata/repository/DubboServiceMetadataRepository.java
@@ -106,11 +106,6 @@ public class DubboServiceMetadataRepository
*/
public static String EXPORTED_SERVICES_REVISION_PROPERTY_NAME = "dubbo.metadata.revision";
- /**
- * The {@link String#format(String, Object...) pattern} of dubbo protocols port.
- */
- public static final String DUBBO_PROTOCOLS_PORT_PROPERTY_NAME_PATTERN = "dubbo.protocols.%s.port";
-
private final Logger logger = LoggerFactory.getLogger(getClass());
private final ObjectMapper objectMapper = new ObjectMapper();
@@ -150,7 +145,7 @@ public class DubboServiceMetadataRepository
* Key is application name Value is Map<RequestMetadata,
* DubboRestServiceMetadata>.
*/
- private Map> dubboRestServiceMetadataRepository = newHashMap();
+ private final Map> dubboRestServiceMetadataRepository = newHashMap();
// =============================================================== //
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
index f207d7994..643acdf1a 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/DubboCloudRegistry.java
@@ -47,7 +47,6 @@ import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
-import static com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
import static java.util.Collections.emptyList;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -130,7 +129,7 @@ public class DubboCloudRegistry extends FailbackRegistry
.computeIfAbsent(appName, k -> new HashMap<>());
for (ServiceInstance instance : instances) {
- String revision = getRevision(instance);
+ String revision = RevisionResolver.getRevision(instance);
List list = map.computeIfAbsent(revision,
k -> new ArrayList<>());
list.add(instance);
@@ -262,7 +261,7 @@ public class DubboCloudRegistry extends FailbackRegistry
}
// group by revision
Map> newGroup = instances.stream()
- .collect(Collectors.groupingBy(this::getRevision));
+ .collect(Collectors.groupingBy(RevisionResolver::getRevision));
synchronized (this) {
@@ -439,16 +438,6 @@ public class DubboCloudRegistry extends FailbackRegistry
return true;
}
- String getRevision(ServiceInstance instance) {
- Map metadata = instance.getMetadata();
- String revision = metadata.get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME);
-
- if (revision == null) {
- revision = RevisionResolver.getEmptyRevision();
- }
- return revision;
- }
-
private List filter(Collection serviceInstances) {
return serviceInstances.stream().filter(this::isDubboServiceInstance)
.collect(Collectors.toList());
diff --git a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java
index a2f3ca4f7..b92e8c4e5 100644
--- a/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java
+++ b/spring-cloud-alibaba-starters/spring-cloud-starter-dubbo/src/main/java/com/alibaba/cloud/dubbo/registry/GenearalServiceSubscribeHandler.java
@@ -27,6 +27,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
+import com.alibaba.cloud.dubbo.metadata.RevisionResolver;
import com.alibaba.cloud.dubbo.metadata.repository.DubboServiceMetadataRepository;
import com.alibaba.cloud.dubbo.service.DubboMetadataService;
import com.alibaba.cloud.dubbo.service.DubboMetadataServiceProxy;
@@ -34,9 +35,11 @@ import com.alibaba.cloud.dubbo.util.JSONUtils;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.registry.NotifyListener;
+import org.apache.dubbo.rpc.RpcContext;
import org.springframework.cloud.client.ServiceInstance;
+import static com.alibaba.cloud.dubbo.metadata.RevisionResolver.SCA_REVSION_KEY;
import static java.util.Collections.emptyList;
import static org.apache.dubbo.common.URLBuilder.from;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
@@ -50,6 +53,9 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
*/
public class GenearalServiceSubscribeHandler extends AbstractServiceSubscribeHandler {
+ /**
+ * the provider which can provide service of the url. {appName, [revisions]}
+ */
private final Map> providers = new HashMap<>();
private final Map urlTemplateMap = new HashMap<>();
@@ -117,7 +123,7 @@ public class GenearalServiceSubscribeHandler extends AbstractServiceSubscribeHan
public void init(String appName, String revision,
List instanceList) {
- List