From 71ab4297221d19e63b6b97bb2cf2b2eedeac6f96 Mon Sep 17 00:00:00 2001 From: songxiaosheng Date: Mon, 29 May 2023 19:46:11 +0800 Subject: [PATCH 01/30] =?UTF-8?q?=F0=9F=90=9B=20add=20bootstarter=20and=20?= =?UTF-8?q?fix=20endpoints=20bug=20(#12408)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * degist-concurrency-bugfix * stytle opt * fix i++ * revert demo * fix sonar * remove apache licence * add licence * add testcase&& fix notice * add notice * add notice * add notice * add notice * fix ci timeout * fix ci timeout * remove testcase because of timeout * remove testcase because of timeout * remove testcase because of timeout * fix ci * fix sonar * :fire: remove metricsPort config * :fire: remove metricsPath config * observer starter add actuator starter * :bug: add bootstarter and fix endpoints bug --------- Co-authored-by: wxbty Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../spring/boot/actuate/mertics/DubboMetricsBinder.java | 2 ++ .../dubbo-spring-boot-observability-starter/pom.xml | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/mertics/DubboMetricsBinder.java b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/mertics/DubboMetricsBinder.java index e670303fbd..dbb8ce349c 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/mertics/DubboMetricsBinder.java +++ b/dubbo-spring-boot/dubbo-spring-boot-actuator/src/main/java/org/apache/dubbo/spring/boot/actuate/mertics/DubboMetricsBinder.java @@ -34,6 +34,8 @@ public class DubboMetricsBinder implements ApplicationListenerdubbo-spring-boot-observability-autoconfigure ${project.version} + + org.apache.dubbo + dubbo-spring-boot-actuator + ${project.version} + - \ No newline at end of file + From ccf7b7b7dbe0d7f7f2891e580b4f655082c46fb7 Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Tue, 30 May 2023 10:37:15 +0800 Subject: [PATCH 02/30] fix invocation.getServiceKey maybe null (#12425) --- .../java/org/apache/dubbo/metrics/data/RtStatComposite.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java index b49a2864c7..a6e7a681d2 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/data/RtStatComposite.java @@ -94,7 +94,7 @@ public class RtStatComposite extends AbstractMetricsExport { public void calcMethodKeyRt(Invocation invocation, String registryOpType, Long responseTime) { for (LongContainer container : rtStats.stream().filter(longContainer -> longContainer.specifyType(registryOpType)).collect(Collectors.toList())) { - Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, invocation.getServiceName() + "_" + invocation.getMethodName(), container.getInitFunc()); + Number current = (Number) ConcurrentHashMapUtils.computeIfAbsent(container, invocation.getTargetServiceUniqueName() + "_" + invocation.getMethodName(), container.getInitFunc()); container.getConsumerFunc().accept(responseTime, current); } } From 891277912add64efde92121c6a5428332bb70657 Mon Sep 17 00:00:00 2001 From: conghuhu <56248584+conghuhu@users.noreply.github.com> Date: Tue, 30 May 2023 12:57:42 +0800 Subject: [PATCH 03/30] fix: remove ConditionalOnDubboTracingEnable matchIfMissing (#12409) * chore: remove ConditionalOnDubboTracingEnable matchIfMissing * fix: fix missing property in test --------- Co-authored-by: songxiaosheng --- .../annotation/ConditionalOnDubboTracingEnable.java | 2 +- .../autoconfigure/exporter/zipkin/ZipkinAutoConfiguration.java | 2 -- .../DubboMicrometerTracingAutoConfigurationTests.java | 3 ++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/annotation/ConditionalOnDubboTracingEnable.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/annotation/ConditionalOnDubboTracingEnable.java index eaa7d28e15..1404b62908 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/annotation/ConditionalOnDubboTracingEnable.java +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/annotation/ConditionalOnDubboTracingEnable.java @@ -38,6 +38,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented -@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PREFIX, name = "enabled", matchIfMissing = true) +@ConditionalOnProperty(prefix = ObservabilityUtils.DUBBO_TRACING_PREFIX, name = "enabled") public @interface ConditionalOnDubboTracingEnable { } diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/exporter/zipkin/ZipkinAutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/exporter/zipkin/ZipkinAutoConfiguration.java index 604e7af5da..8e16503b4f 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/exporter/zipkin/ZipkinAutoConfiguration.java +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/main/java/org/apache/dubbo/spring/boot/observability/autoconfigure/exporter/zipkin/ZipkinAutoConfiguration.java @@ -36,7 +36,6 @@ import zipkin2.codec.BytesEncoder; import zipkin2.codec.SpanBytesEncoder; import zipkin2.reporter.Sender; -import static org.apache.dubbo.spring.boot.observability.autoconfigure.ObservabilityUtils.DUBBO_TRACING_PREFIX; import static org.apache.dubbo.spring.boot.observability.autoconfigure.ObservabilityUtils.DUBBO_TRACING_ZIPKIN_CONFIG_PREFIX; @@ -54,7 +53,6 @@ import static org.apache.dubbo.spring.boot.observability.autoconfigure.Observabi @Import({SenderConfiguration.class, ReporterConfiguration.class, BraveConfiguration.class, OpenTelemetryConfiguration.class}) -@ConditionalOnProperty(prefix = DUBBO_TRACING_PREFIX, name = "enabled", havingValue = "true") @ConditionalOnDubboTracingEnable public class ZipkinAutoConfiguration { diff --git a/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/test/java/org/apache/dubbo/spring/boot/observability/autoconfigure/observability/DubboMicrometerTracingAutoConfigurationTests.java b/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/test/java/org/apache/dubbo/spring/boot/observability/autoconfigure/observability/DubboMicrometerTracingAutoConfigurationTests.java index d0e4c64b67..0e4734a992 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/test/java/org/apache/dubbo/spring/boot/observability/autoconfigure/observability/DubboMicrometerTracingAutoConfigurationTests.java +++ b/dubbo-spring-boot/dubbo-spring-boot-observability-starters/autoconfigure/src/test/java/org/apache/dubbo/spring/boot/observability/autoconfigure/observability/DubboMicrometerTracingAutoConfigurationTests.java @@ -44,7 +44,8 @@ import static org.mockito.Mockito.mock; class DubboMicrometerTracingAutoConfigurationTests { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(DubboMicrometerTracingAutoConfiguration.class)); + .withConfiguration(AutoConfigurations.of(DubboMicrometerTracingAutoConfiguration.class)) + .withPropertyValues("dubbo.tracing.enabled=true"); @Test void shouldSupplyBeans() { From 1835a106c9d8f261bc9ea98e2b877a9c2b4790e1 Mon Sep 17 00:00:00 2001 From: jojocodeX <571943037@qq.com> Date: Wed, 31 May 2023 18:54:07 +0800 Subject: [PATCH 04/30] Ut change note for english (#12432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加Jackson序列化器 支持Jackson序列化器扩展配置 代码格式化调整 * Jackson module 注册错误忽略异常 * Jackson module 注册错误忽略异常 * add LdapJackson2Module Jackson module * add spi to dubbo-all pom config * remove unused code * undo remove code * Run CI * merge conflict * ignore codec error * Change log output * Add log error code * Add sliding window stat * fix checkstyle * rename and version change * MetricsKey rename * MetricsKey rename * change ut * Ut change note for english --------- Co-authored-by: songxiaosheng --- .../metrics/aggregate/TimeWindowAggregatorTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java index fc2d42c614..e0db96730f 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java +++ b/dubbo-metrics/dubbo-metrics-api/src/test/java/org/apache/dubbo/metrics/aggregate/TimeWindowAggregatorTest.java @@ -27,7 +27,8 @@ public class TimeWindowAggregatorTest { public void testTimeWindowAggregator() { TimeWindowAggregator aggregator = new TimeWindowAggregator(5, 5); - // 第一个时间窗口,时间范围:0秒 - 5秒 + //First time window, time range: 0 - 5 seconds + aggregator.add(10); aggregator.add(20); aggregator.add(30); @@ -39,7 +40,7 @@ public class TimeWindowAggregatorTest { Assertions.assertEquals(30, entry1.getMax()); Assertions.assertEquals(10, entry1.getMin()); - // 第二个时间窗口,时间范围:5秒 - 10秒 + //Second time window, time range: 5 - 10 seconds try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { @@ -57,7 +58,9 @@ public class TimeWindowAggregatorTest { Assertions.assertEquals(35, entry2.getMax()); Assertions.assertEquals(15, entry2.getMin()); - // 第三个时间窗口,时间范围:10秒 - 15秒 + + //Third time window, time range: 10 - 15 seconds + try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { From ed3a01716969342038663663fd8d3f6c62b5f71d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:01:40 +0800 Subject: [PATCH 05/30] Bump fastjson2 from 2.0.32 to 2.0.33 (#12423) Bumps [fastjson2](https://github.com/alibaba/fastjson2) from 2.0.32 to 2.0.33. - [Release notes](https://github.com/alibaba/fastjson2/releases) - [Commits](https://github.com/alibaba/fastjson2/compare/2.0.32...2.0.33) --- updated-dependencies: - dependency-name: com.alibaba.fastjson2:fastjson2 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index fd7962824d..d6c14d481f 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -102,7 +102,7 @@ 4.5.14 4.4.16 1.2.83 - 2.0.32 + 2.0.33 3.4.14 4.3.0 2.12.0 From a948d544c212a5d689caf902ae81a06f30fe440d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:01:56 +0800 Subject: [PATCH 06/30] Bump snappy-java from 1.1.9.1 to 1.1.10.0 (#12422) Bumps [snappy-java](https://github.com/xerial/snappy-java) from 1.1.9.1 to 1.1.10.0. - [Release notes](https://github.com/xerial/snappy-java/releases) - [Commits](https://github.com/xerial/snappy-java/compare/v1.1.9.1...v1.1.10.0) --- updated-dependencies: - dependency-name: org.xerial.snappy:snappy-java dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index d6c14d481f..4f4ab679e6 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -179,7 +179,7 @@ 3.2.13 1.6.11 - 1.1.9.1 + 1.1.10.0 1.70 2.0.6 5.4.3 From 0e77a42fa7e8030f61cc4a6fd578ebf7889a7ee1 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 1 Jun 2023 15:04:42 +0800 Subject: [PATCH 07/30] Update grpc version (#12441) --- dubbo-plugin/dubbo-security/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-plugin/dubbo-security/pom.xml b/dubbo-plugin/dubbo-security/pom.xml index 64333a8ff5..a31a27bf89 100644 --- a/dubbo-plugin/dubbo-security/pom.xml +++ b/dubbo-plugin/dubbo-security/pom.xml @@ -27,7 +27,7 @@ false 3.22.2 - 1.41.0 + 1.55.1 dubbo-security From 16a8aea896067ff2e24a3f3fed8f29573db6b92d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:23:29 +0800 Subject: [PATCH 08/30] Bump nacos-client from 2.2.2 to 2.2.3 (#12420) Bumps [nacos-client](https://github.com/alibaba/nacos) from 2.2.2 to 2.2.3. - [Release notes](https://github.com/alibaba/nacos/releases) - [Changelog](https://github.com/alibaba/nacos/blob/develop/CHANGELOG.md) - [Commits](https://github.com/alibaba/nacos/compare/2.2.2...2.2.3) --- updated-dependencies: - dependency-name: com.alibaba.nacos:nacos-client dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 4f4ab679e6..e42f7f686b 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -148,7 +148,7 @@ 1.9.13 8.5.87 0.7.5 - 2.2.2 + 2.2.3 1.55.1 0.8.1 1.2.2 From f750b66a31d2637545f98afa603daeb8865c58b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Jun 2023 15:23:39 +0800 Subject: [PATCH 09/30] Bump protobuf-java_version from 3.23.1 to 3.23.2 (#12419) Bumps `protobuf-java_version` from 3.23.1 to 3.23.2. Updates `protobuf-java` from 3.23.1 to 3.23.2 - [Release notes](https://github.com/protocolbuffers/protobuf/releases) - [Changelog](https://github.com/protocolbuffers/protobuf/blob/main/generate_changelog.py) - [Commits](https://github.com/protocolbuffers/protobuf/compare/v3.23.1...v3.23.2) Updates `protobuf-java-util` from 3.23.1 to 3.23.2 --- updated-dependencies: - dependency-name: com.google.protobuf:protobuf-java dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.google.protobuf:protobuf-java-util dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index e42f7f686b..b9dc95e2b0 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -114,7 +114,7 @@ 3.5.5 0.18.1 4.0.66 - 3.23.1 + 3.23.2 1.3.2 3.1.0 9.4.51.v20230217 From 057dcb451202a5f8440a7405c9323b75bb19693a Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 1 Jun 2023 15:43:07 +0800 Subject: [PATCH 10/30] Fix alibaba Filter / Result Compact (#12440) --- .../src/main/java/com/alibaba/dubbo/rpc/Filter.java | 9 ++++++++- .../src/main/java/com/alibaba/dubbo/rpc/Result.java | 10 ++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java index fa7b3e40a3..fa33393123 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java @@ -18,6 +18,9 @@ package com.alibaba.dubbo.rpc; import org.apache.dubbo.rpc.AsyncRpcResult; +import org.apache.dubbo.rpc.AttachmentsAdapter; + +import java.util.Map; @Deprecated public interface Filter extends org.apache.dubbo.rpc.Filter { @@ -27,7 +30,7 @@ public interface Filter extends org.apache.dubbo.rpc.Filter { @Override default org.apache.dubbo.rpc.Result invoke(org.apache.dubbo.rpc.Invoker invoker, org.apache.dubbo.rpc.Invocation invocation) - throws org.apache.dubbo.rpc.RpcException { + throws org.apache.dubbo.rpc.RpcException { Result invokeResult = invoke(new Invoker.CompatibleInvoker<>(invoker), new Invocation.CompatibleInvocation(invocation)); @@ -38,6 +41,10 @@ public interface Filter extends org.apache.dubbo.rpc.Filter { AsyncRpcResult asyncRpcResult = AsyncRpcResult.newDefaultAsyncResult(invocation); asyncRpcResult.setValue(invokeResult.getValue()); asyncRpcResult.setException(invokeResult.getException()); + Map attachments = invokeResult.getAttachments(); + if (!(attachments instanceof AttachmentsAdapter.ObjectToStringMap)) { + asyncRpcResult.setAttachments(attachments); + } asyncRpcResult.setObjectAttachments(invokeResult.getObjectAttachments()); return asyncRpcResult; diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java index 009ee707c2..040736647a 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java @@ -64,6 +64,16 @@ public interface Result extends org.apache.dubbo.rpc.Result { return null; } + + /** + * @see com.alibaba.dubbo.rpc.Result#getValue() + * @deprecated Replace to getValue() + */ + @Deprecated + default Object getResult() { + return getValue(); + } + class CompatibleResult implements Result { private org.apache.dubbo.rpc.Result delegate; From 3fd0a5a922f42c8914a70d0a89134e9f55782dd9 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 1 Jun 2023 16:04:00 +0800 Subject: [PATCH 11/30] Remove some utils usage from alibaba-spring-context (#12442) --- .../AbstractAnnotationBeanPostProcessor.java | 7 +- .../AnnotationPropertyValuesAdapter.java | 8 +- .../DubboConfigAliasPostProcessor.java | 4 +- .../ReferenceAnnotationBeanPostProcessor.java | 5 +- .../ServiceAnnotationPostProcessor.java | 8 +- .../annotation/ServiceBeanNameBuilder.java | 6 +- ...DefaultPropertyValueBeanPostProcessor.java | 6 +- ...DefaultValueDubboConfigBeanCustomizer.java | 4 +- .../properties/DefaultDubboConfigBinder.java | 5 +- .../reference/ReferenceBeanSupport.java | 3 +- .../spring/reference/ReferenceCreator.java | 14 +- .../config/spring/util/AnnotationUtils.java | 437 ++++++++++++++++++ .../config/spring/util/BeanRegistrar.java | 40 ++ .../spring/util/DubboAnnotationUtils.java | 5 +- .../util/GenericBeanPostProcessorAdapter.java | 125 +++++ .../dubbo/config/spring/util/ObjectUtils.java | 40 ++ .../spring/util/PropertySourcesUtils.java | 148 ++++++ ...DubboRelaxedBinding2AutoConfiguration.java | 5 +- 18 files changed, 830 insertions(+), 40 deletions(-) create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/GenericBeanPostProcessorAdapter.java create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationBeanPostProcessor.java index 801333217e..ade274d59a 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AbstractAnnotationBeanPostProcessor.java @@ -18,6 +18,8 @@ package org.apache.dubbo.config.spring.beans.factory.annotation; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.config.spring.util.AnnotationUtils; + import org.springframework.beans.BeanUtils; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; @@ -53,7 +55,6 @@ import java.util.List; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import static com.alibaba.spring.util.AnnotationUtils.getAnnotationAttributes; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_INITIALIZER; import static org.springframework.core.BridgeMethodResolver.findBridgedMethod; import static org.springframework.core.BridgeMethodResolver.isVisibilityBridgeMethodPair; @@ -135,7 +136,7 @@ public abstract class AbstractAnnotationBeanPostProcessor implements for (Class annotationType : getAnnotationTypes()) { - AnnotationAttributes attributes = getAnnotationAttributes(field, annotationType, getEnvironment(), true, true); + AnnotationAttributes attributes = AnnotationUtils.getAnnotationAttributes(field, annotationType, getEnvironment(), true, true); if (attributes != null) { @@ -180,7 +181,7 @@ public abstract class AbstractAnnotationBeanPostProcessor implements for (Class annotationType : getAnnotationTypes()) { - AnnotationAttributes attributes = getAnnotationAttributes(bridgedMethod, annotationType, getEnvironment(), true, true); + AnnotationAttributes attributes = AnnotationUtils.getAnnotationAttributes(bridgedMethod, annotationType, getEnvironment(), true, true); if (attributes != null && method.equals(ClassUtils.getMostSpecificMethod(method, beanClass))) { if (Modifier.isStatic(method.getModifiers())) { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java index 88280a57e5..c0c2e96eb2 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/AnnotationPropertyValuesAdapter.java @@ -16,6 +16,8 @@ */ package org.apache.dubbo.config.spring.beans.factory.annotation; +import org.apache.dubbo.config.spring.util.AnnotationUtils; + import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValue; import org.springframework.beans.PropertyValues; @@ -24,8 +26,6 @@ import org.springframework.core.env.PropertyResolver; import java.lang.annotation.Annotation; import java.util.Map; -import static com.alibaba.spring.util.AnnotationUtils.getAttributes; - /** * {@link Annotation} {@link PropertyValues} Adapter * @@ -45,12 +45,12 @@ public class AnnotationPropertyValuesAdapter implements PropertyValues { */ public AnnotationPropertyValuesAdapter(Map attributes, PropertyResolver propertyResolver, String... ignoreAttributeNames) { - this.delegate = new MutablePropertyValues(getAttributes(attributes, propertyResolver, ignoreAttributeNames)); + this.delegate = new MutablePropertyValues(AnnotationUtils.getAttributes(attributes, propertyResolver, ignoreAttributeNames)); } public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, boolean ignoreDefaultValue, String... ignoreAttributeNames) { - this.delegate = new MutablePropertyValues(getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames)); + this.delegate = new MutablePropertyValues(AnnotationUtils.getAttributes(annotation, propertyResolver, ignoreDefaultValue, ignoreAttributeNames)); } public AnnotationPropertyValuesAdapter(Annotation annotation, PropertyResolver propertyResolver, String... ignoreAttributeNames) { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java index 28b6a6cf8b..84a1eb03a2 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/DubboConfigAliasPostProcessor.java @@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.beans.factory.annotation; import org.apache.dubbo.config.AbstractConfig; import org.apache.dubbo.config.spring.context.annotation.DubboConfigConfigurationRegistrar; +import org.apache.dubbo.config.spring.util.BeanRegistrar; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -25,7 +26,6 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import static com.alibaba.spring.util.BeanRegistrar.hasAlias; import static org.springframework.util.ObjectUtils.nullSafeEquals; import static org.springframework.util.StringUtils.hasText; @@ -65,7 +65,7 @@ public class DubboConfigAliasPostProcessor implements BeanDefinitionRegistryPost String id = ((AbstractConfig) bean).getId(); if (hasText(id) // id MUST be present in AbstractConfig && !nullSafeEquals(id, beanName) // id MUST NOT be equal to bean name - && !hasAlias(registry, beanName, id)) { // id MUST NOT be present in AliasRegistry + && !BeanRegistrar.hasAlias(registry, beanName, id)) { // id MUST NOT be present in AliasRegistry registry.registerAlias(beanName, id); } } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java index bc6ddabfbb..f679627932 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java @@ -31,8 +31,10 @@ import org.apache.dubbo.config.spring.context.event.DubboConfigInitEvent; import org.apache.dubbo.config.spring.reference.ReferenceAttributes; import org.apache.dubbo.config.spring.reference.ReferenceBeanManager; import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport; +import org.apache.dubbo.config.spring.util.AnnotationUtils; import org.apache.dubbo.config.spring.util.SpringCompatUtils; import org.apache.dubbo.rpc.service.GenericService; + import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValue; import org.springframework.beans.PropertyValues; @@ -65,7 +67,6 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import static com.alibaba.spring.util.AnnotationUtils.getAttribute; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUBBO_BEAN_INITIALIZER; import static org.apache.dubbo.common.utils.AnnotationUtils.filterDefaultValues; import static org.springframework.util.StringUtils.hasText; @@ -383,7 +384,7 @@ public class ReferenceAnnotationBeanPostProcessor extends AbstractAnnotationBean boolean renameable = true; // referenceBeanName - String referenceBeanName = getAttribute(attributes, ReferenceAttributes.ID); + String referenceBeanName = AnnotationUtils.getAttribute(attributes, ReferenceAttributes.ID); if (hasText(referenceBeanName)) { renameable = false; } else { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java index b5b8ac20fb..4ce2c0caef 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java @@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.beans.factory.annotation; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.AnnotationUtils; import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.common.utils.ReflectUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -30,9 +31,9 @@ import org.apache.dubbo.config.spring.ServiceBean; import org.apache.dubbo.config.spring.context.annotation.DubboClassPathBeanDefinitionScanner; import org.apache.dubbo.config.spring.schema.AnnotationBeanDefinitionParser; import org.apache.dubbo.config.spring.util.DubboAnnotationUtils; +import org.apache.dubbo.config.spring.util.ObjectUtils; import org.apache.dubbo.config.spring.util.SpringCompatUtils; -import com.alibaba.spring.util.AnnotationUtils; import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -79,11 +80,10 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import static com.alibaba.spring.util.ObjectUtils.of; import static java.util.Arrays.asList; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUPLICATED_BEAN_DEFINITION; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_NO_ANNOTATIONS_FOUND; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_NO_BEANS_SCANNED; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_DUPLICATED_BEAN_DEFINITION; import static org.apache.dubbo.common.utils.AnnotationUtils.filterDefaultValues; import static org.apache.dubbo.config.spring.beans.factory.annotation.ServiceBeanNameBuilder.create; import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveInterfaceName; @@ -431,7 +431,7 @@ public class ServiceAnnotationPostProcessor implements BeanDefinitionRegistryPos MutablePropertyValues propertyValues = beanDefinition.getPropertyValues(); - String[] ignoreAttributeNames = of("provider", "monitor", "application", "module", "registry", "protocol", + String[] ignoreAttributeNames = ObjectUtils.of("provider", "monitor", "application", "module", "registry", "protocol", "methods", "interfaceName", "parameters", "executor"); propertyValues.addPropertyValues(new AnnotationPropertyValuesAdapter(serviceAnnotationAttributes, environment, ignoreAttributeNames)); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java index 6bdddc9ed8..a3957f6076 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceBeanNameBuilder.java @@ -20,12 +20,12 @@ import org.apache.dubbo.config.annotation.Reference; import org.apache.dubbo.config.annotation.Service; import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.config.spring.ServiceBean; +import org.apache.dubbo.config.spring.util.AnnotationUtils; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.env.Environment; import org.springframework.util.StringUtils; -import static com.alibaba.spring.util.AnnotationUtils.getAttribute; import static org.apache.dubbo.config.spring.util.DubboAnnotationUtils.resolveInterfaceName; import static org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes; @@ -63,8 +63,8 @@ public class ServiceBeanNameBuilder { private ServiceBeanNameBuilder(AnnotationAttributes attributes, Class defaultInterfaceClass, Environment environment) { this(resolveInterfaceName(attributes, defaultInterfaceClass), environment); - this.group(getAttribute(attributes,"group")); - this.version(getAttribute(attributes,"version")); + this.group(AnnotationUtils.getAttribute(attributes,"group")); + this.version(AnnotationUtils.getAttribute(attributes,"version")); } /** diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java index 05851fce04..a3599cae3d 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/config/DubboConfigDefaultPropertyValueBeanPostProcessor.java @@ -18,8 +18,9 @@ package org.apache.dubbo.config.spring.beans.factory.config; import org.apache.dubbo.config.AbstractConfig; import org.apache.dubbo.config.Constants; +import org.apache.dubbo.config.spring.util.GenericBeanPostProcessorAdapter; +import org.apache.dubbo.config.spring.util.ObjectUtils; -import com.alibaba.spring.beans.factory.config.GenericBeanPostProcessorAdapter; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -34,7 +35,6 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.Arrays; -import static com.alibaba.spring.util.ObjectUtils.of; import static org.springframework.aop.support.AopUtils.getTargetClass; import static org.springframework.beans.BeanUtils.getPropertyDescriptor; import static org.springframework.util.ReflectionUtils.invokeMethod; @@ -91,7 +91,7 @@ public class DubboConfigDefaultPropertyValueBeanPostProcessor extends GenericBea Method setterMethod = propertyDescriptor.getWriteMethod(); if (setterMethod != null) { // the getter and setter methods are present - if (Arrays.equals(of(String.class), setterMethod.getParameterTypes())) { // the param type is String + if (Arrays.equals(ObjectUtils.of(String.class), setterMethod.getParameterTypes())) { // the param type is String // set bean name to the value of the property invokeMethod(setterMethod, bean, beanName); } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java index bafcf04aaf..298e9e0015 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/config/NamePropertyDefaultValueDubboConfigBeanCustomizer.java @@ -18,6 +18,7 @@ package org.apache.dubbo.config.spring.context.config; import org.apache.dubbo.config.AbstractConfig; import org.apache.dubbo.config.spring.beans.factory.config.DubboConfigDefaultPropertyValueBeanPostProcessor; +import org.apache.dubbo.config.spring.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -25,7 +26,6 @@ import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.Arrays; -import static com.alibaba.spring.util.ObjectUtils.of; import static org.springframework.beans.BeanUtils.getPropertyDescriptor; /** @@ -71,7 +71,7 @@ public class NamePropertyDefaultValueDubboConfigBeanCustomizer implements DubboC Method setNameMethod = propertyDescriptor.getWriteMethod(); if (setNameMethod != null) { // "setName" and "getName" methods are present - if (Arrays.equals(of(String.class), setNameMethod.getParameterTypes())) { // the param type is String + if (Arrays.equals(ObjectUtils.of(String.class), setNameMethod.getParameterTypes())) { // the param type is String // set bean name to the value of the "name" property ReflectionUtils.invokeMethod(setNameMethod, dubboConfigBean, beanName); } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java index 0a637bf424..117207038f 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/properties/DefaultDubboConfigBinder.java @@ -17,6 +17,7 @@ package org.apache.dubbo.config.spring.context.properties; import org.apache.dubbo.config.AbstractConfig; +import org.apache.dubbo.config.spring.util.PropertySourcesUtils; import org.springframework.beans.MutablePropertyValues; import org.springframework.validation.BindingResult; @@ -27,8 +28,6 @@ import java.util.List; import java.util.Map; import java.util.stream.IntStream; -import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties; - /** * Default {@link DubboConfigBinder} implementation based on Spring {@link DataBinder} */ @@ -41,7 +40,7 @@ public class DefaultDubboConfigBinder extends AbstractDubboConfigBinder { dataBinder.setIgnoreInvalidFields(isIgnoreInvalidFields()); dataBinder.setIgnoreUnknownFields(isIgnoreUnknownFields()); // Get properties under specified prefix from PropertySources - Map properties = getSubProperties(getPropertySources(), prefix); + Map properties = PropertySourcesUtils.getSubProperties(getPropertySources(), prefix); // Convert Map to MutablePropertyValues MutablePropertyValues propertyValues = new MutablePropertyValues(properties); // Bind diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java index e828b6f720..97df3b5b78 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java @@ -16,14 +16,15 @@ */ package org.apache.dubbo.config.spring.reference; -import com.alibaba.spring.util.AnnotationUtils; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.config.annotation.ProvidedBy; import org.apache.dubbo.config.spring.Constants; import org.apache.dubbo.config.spring.ReferenceBean; +import org.apache.dubbo.config.spring.util.AnnotationUtils; import org.apache.dubbo.config.spring.util.DubboAnnotationUtils; import org.apache.dubbo.rpc.service.GenericService; + import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.PropertyValue; import org.springframework.beans.factory.config.BeanDefinition; diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceCreator.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceCreator.java index 203226cc61..0f8e69087d 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceCreator.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceCreator.java @@ -29,11 +29,12 @@ import org.apache.dubbo.config.annotation.Argument; import org.apache.dubbo.config.annotation.DubboReference; import org.apache.dubbo.config.annotation.Method; import org.apache.dubbo.config.spring.beans.factory.annotation.AnnotationPropertyValuesAdapter; +import org.apache.dubbo.config.spring.util.AnnotationUtils; import org.apache.dubbo.config.spring.util.DubboAnnotationUtils; import org.apache.dubbo.config.spring.util.DubboBeanUtils; +import org.apache.dubbo.config.spring.util.ObjectUtils; import org.apache.dubbo.rpc.model.ModuleModel; -import com.alibaba.spring.util.AnnotationUtils; import org.springframework.beans.propertyeditors.StringTrimmerEditor; import org.springframework.context.ApplicationContext; import org.springframework.core.convert.support.DefaultConversionService; @@ -43,9 +44,6 @@ import org.springframework.validation.DataBinder; import java.util.Map; -import static com.alibaba.spring.util.AnnotationUtils.getAttribute; -import static com.alibaba.spring.util.ObjectUtils.of; - /** * {@link ReferenceConfig} Creator for @{@link DubboReference} * @@ -54,7 +52,7 @@ import static com.alibaba.spring.util.ObjectUtils.of; public class ReferenceCreator { // Ignore those fields - static final String[] IGNORE_FIELD_NAMES = of("application", "module", "consumer", "monitor", "registry", "interfaceClass"); + static final String[] IGNORE_FIELD_NAMES = ObjectUtils.of("application", "module", "consumer", "monitor", "registry", "interfaceClass"); private static final String ONRETURN = "onreturn"; @@ -117,7 +115,7 @@ public class ReferenceCreator { } private void configureMonitorConfig(ReferenceConfig configBean) { - String monitorConfigId = getAttribute(attributes, "monitor"); + String monitorConfigId = AnnotationUtils.getAttribute(attributes, "monitor"); if (StringUtils.hasText(monitorConfigId)) { MonitorConfig monitorConfig = getConfig(monitorConfigId, MonitorConfig.class); configBean.setMonitor(monitorConfig); @@ -125,7 +123,7 @@ public class ReferenceCreator { } private void configureModuleConfig(ReferenceConfig configBean) { - String moduleConfigId = getAttribute(attributes, "module"); + String moduleConfigId = AnnotationUtils.getAttribute(attributes, "module"); if (StringUtils.hasText(moduleConfigId)) { ModuleConfig moduleConfig = getConfig(moduleConfigId, ModuleConfig.class); configBean.setModule(moduleConfig); @@ -134,7 +132,7 @@ public class ReferenceCreator { private void configureConsumerConfig(ReferenceConfig referenceBean) { ConsumerConfig consumerConfig = null; - Object consumer = getAttribute(attributes, "consumer"); + Object consumer = AnnotationUtils.getAttribute(attributes, "consumer"); if (consumer != null) { if (consumer instanceof String) { consumerConfig = getConfig((String) consumer, ConsumerConfig.class); diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java new file mode 100644 index 0000000000..dcef582525 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/AnnotationUtils.java @@ -0,0 +1,437 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.env.Environment; +import org.springframework.core.env.PropertyResolver; +import org.springframework.util.ClassUtils; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import static java.lang.String.valueOf; +import static java.util.Arrays.asList; +import static org.springframework.core.annotation.AnnotationAttributes.fromMap; +import static org.springframework.core.annotation.AnnotationUtils.getDefaultValue; +import static org.springframework.util.ClassUtils.resolveClassName; +import static org.springframework.util.CollectionUtils.isEmpty; +import static org.springframework.util.ObjectUtils.nullSafeEquals; +import static org.springframework.util.ReflectionUtils.findMethod; +import static org.springframework.util.ReflectionUtils.invokeMethod; +import static org.springframework.util.StringUtils.trimWhitespace; + +@SuppressWarnings("unchecked") +public abstract class AnnotationUtils { + + /** + * The class name of AnnotatedElementUtils that is introduced since Spring Framework 4 + */ + public static final String ANNOTATED_ELEMENT_UTILS_CLASS_NAME = "org.springframework.core.annotation.AnnotatedElementUtils"; + + private static final Map annotatedElementUtilsPresentCache = new ConcurrentHashMap<>(); + + /** + * Get the {@link Annotation} attributes + * + * @param annotation specified {@link Annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param ignoreDefaultValue whether ignore default value or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return non-null + */ + public static Map getAttributes(Annotation annotation, PropertyResolver propertyResolver, + boolean ignoreDefaultValue, String... ignoreAttributeNames) { + return getAttributes(annotation, propertyResolver, false, false, ignoreDefaultValue, ignoreAttributeNames); + } + + /** + * Get the {@link Annotation} attributes + * + * @param annotationAttributes the attributes of specified {@link Annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return non-null + */ + public static Map getAttributes(Map annotationAttributes, + PropertyResolver propertyResolver, String... ignoreAttributeNames) { + + Set ignoreAttributeNamesSet = new HashSet<>(Arrays.asList(ignoreAttributeNames)); + + Map actualAttributes = new LinkedHashMap(); + + for (Map.Entry annotationAttribute : annotationAttributes.entrySet()) { + + String attributeName = annotationAttribute.getKey(); + Object attributeValue = annotationAttribute.getValue(); + + // ignore attribute name + if (ignoreAttributeNamesSet.contains(attributeName)) { + continue; + } + + if (attributeValue instanceof String) { + attributeValue = resolvePlaceholders(valueOf(attributeValue), propertyResolver); + } else if (attributeValue instanceof String[]) { + String[] values = (String[]) attributeValue; + for (int i = 0; i < values.length; i++) { + values[i] = resolvePlaceholders(values[i], propertyResolver); + } + attributeValue = values; + } + actualAttributes.put(attributeName, attributeValue); + } + return actualAttributes; + } + + /** + * @param annotation specified {@link Annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param classValuesAsString whether to turn Class references into Strings (for + * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to + * preserve them as Class references + * @param nestedAnnotationsAsMap whether to turn nested Annotation instances into + * {@link AnnotationAttributes} maps (for compatibility with + * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as + * Annotation instances + * @param ignoreDefaultValue whether ignore default value or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return + */ + public static Map getAttributes(Annotation annotation, + PropertyResolver propertyResolver, + boolean classValuesAsString, + boolean nestedAnnotationsAsMap, + boolean ignoreDefaultValue, + String... ignoreAttributeNames) { + + Map annotationAttributes = org.springframework.core.annotation.AnnotationUtils.getAnnotationAttributes(annotation, classValuesAsString, nestedAnnotationsAsMap); + + String[] actualIgnoreAttributeNames = ignoreAttributeNames; + + if (ignoreDefaultValue && !isEmpty(annotationAttributes)) { + + List attributeNamesToIgnore = new LinkedList(asList(ignoreAttributeNames)); + + for (Map.Entry annotationAttribute : annotationAttributes.entrySet()) { + String attributeName = annotationAttribute.getKey(); + Object attributeValue = annotationAttribute.getValue(); + if (nullSafeEquals(attributeValue, getDefaultValue(annotation, attributeName))) { + attributeNamesToIgnore.add(attributeName); + } + } + // extends the ignored list + actualIgnoreAttributeNames = attributeNamesToIgnore.toArray(new String[attributeNamesToIgnore.size()]); + } + + return getAttributes(annotationAttributes, propertyResolver, actualIgnoreAttributeNames); + } + + private static String resolvePlaceholders(String attributeValue, PropertyResolver propertyResolver) { + String resolvedValue = attributeValue; + if (propertyResolver != null) { + resolvedValue = propertyResolver.resolvePlaceholders(resolvedValue); + resolvedValue = trimWhitespace(resolvedValue); + } + return resolvedValue; + } + + /** + * Get the attribute value + * + * @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes} + * @param attributeName the name of attribute + * @param the type of attribute value + * @return the attribute value if found + */ + public static T getAttribute(Map attributes, String attributeName) { + return getAttribute(attributes, attributeName, false); + } + + /** + * Get the attribute value the will + * + * @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes} + * @param attributeName the name of attribute + * @param required the required attribute or not + * @param the type of attribute value + * @return the attribute value if found + * @throws IllegalStateException if attribute value can't be found + */ + public static T getAttribute(Map attributes, String attributeName, boolean required) { + T value = getAttribute(attributes, attributeName, null); + if (required && value == null) { + throw new IllegalStateException("The attribute['" + attributeName + "] is required!"); + } + return value; + } + + /** + * Get the attribute value with default value + * + * @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes} + * @param attributeName the name of attribute + * @param defaultValue the default value of attribute + * @param the type of attribute value + * @return the attribute value if found + */ + public static T getAttribute(Map attributes, String attributeName, T defaultValue) { + T value = (T) attributes.get(attributeName); + return value == null ? defaultValue : value; + } + + /** + * Get the required attribute value + * + * @param attributes {@link Map the annotation attributes} or {@link AnnotationAttributes} + * @param attributeName the name of attribute + * @param the type of attribute value + * @return the attribute value if found + * @throws IllegalStateException if attribute value can't be found + */ + public static T getRequiredAttribute(Map attributes, String attributeName) { + return getAttribute(attributes, attributeName, true); + } + + /** + * Get the {@link AnnotationAttributes} + * + * @param annotation specified {@link Annotation} + * @param ignoreDefaultValue whether ignore default value or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return non-null + * @see #getAnnotationAttributes(Annotation, PropertyResolver, boolean, String...) + */ + public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, boolean ignoreDefaultValue, + String... ignoreAttributeNames) { + return getAnnotationAttributes(annotation, null, ignoreDefaultValue, ignoreAttributeNames); + } + + /** + * Get the {@link AnnotationAttributes} + * + * @param annotation specified {@link Annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param classValuesAsString whether to turn Class references into Strings (for + * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to + * preserve them as Class references + * @param nestedAnnotationsAsMap whether to turn nested Annotation instances into + * {@link AnnotationAttributes} maps (for compatibility with + * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as + * Annotation instances + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @param ignoreDefaultValue whether ignore default value or not + * @return non-null + * @see #getAttributes(Annotation, PropertyResolver, boolean, String...) + * @see #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...) + */ + public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, + PropertyResolver propertyResolver, + boolean classValuesAsString, + boolean nestedAnnotationsAsMap, + boolean ignoreDefaultValue, + String... ignoreAttributeNames) { + return fromMap(getAttributes(annotation, propertyResolver, classValuesAsString, nestedAnnotationsAsMap, + ignoreDefaultValue, ignoreAttributeNames)); + } + + /** + * Get the {@link AnnotationAttributes} + * + * @param annotation specified {@link Annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param ignoreDefaultValue whether ignore default value or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return non-null + * @see #getAttributes(Annotation, PropertyResolver, boolean, String...) + * @see #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...) + */ + public static AnnotationAttributes getAnnotationAttributes(Annotation annotation, PropertyResolver propertyResolver, + boolean ignoreDefaultValue, String... ignoreAttributeNames) { + return getAnnotationAttributes(annotation, propertyResolver, false, false, ignoreDefaultValue, ignoreAttributeNames); + } + + /** + * Get the {@link AnnotationAttributes} + * + * @param annotatedElement {@link AnnotatedElement the annotated element} + * @param annotationType the {@link Class tyoe} pf {@link Annotation annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param ignoreDefaultValue whether ignore default value or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return if annotatedElement can't be found in annotatedElement, return null + */ + public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement, + Class annotationType, + PropertyResolver propertyResolver, + boolean classValuesAsString, + boolean nestedAnnotationsAsMap, + boolean ignoreDefaultValue, + String... ignoreAttributeNames) { + Annotation annotation = annotatedElement.getAnnotation(annotationType); + return annotation == null ? null : getAnnotationAttributes(annotation, propertyResolver, + classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames); + } + + /** + * Get the {@link AnnotationAttributes}, if the argument tryMergedAnnotation is true, + * the {@link AnnotationAttributes} will be got from + * {@link #tryGetMergedAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...) merged annotation} first, + * if failed, and then to get from + * {@link #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, boolean, String...) normal one} + * + * @param annotatedElement {@link AnnotatedElement the annotated element} + * @param annotationType the {@link Class tyoe} pf {@link Annotation annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param ignoreDefaultValue whether ignore default value or not + * @param tryMergedAnnotation whether try merged annotation or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return if annotatedElement can't be found in annotatedElement, return null + */ + public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement, + Class annotationType, + PropertyResolver propertyResolver, + boolean ignoreDefaultValue, + boolean tryMergedAnnotation, + String... ignoreAttributeNames) { + return getAnnotationAttributes(annotatedElement, annotationType, propertyResolver, + false, false, ignoreDefaultValue, tryMergedAnnotation, ignoreAttributeNames); + } + + /** + * Get the {@link AnnotationAttributes}, if the argument tryMergedAnnotation is true, + * the {@link AnnotationAttributes} will be got from + * {@link #tryGetMergedAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, String...) merged annotation} first, + * if failed, and then to get from + * {@link #getAnnotationAttributes(AnnotatedElement, Class, PropertyResolver, boolean, boolean, String...) normal one} + * + * @param annotatedElement {@link AnnotatedElement the annotated element} + * @param annotationType the {@link Class tyoe} pf {@link Annotation annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param classValuesAsString whether to turn Class references into Strings (for + * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to + * preserve them as Class references + * @param nestedAnnotationsAsMap whether to turn nested Annotation instances into + * {@link AnnotationAttributes} maps (for compatibility with + * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as + * Annotation instances + * @param ignoreDefaultValue whether ignore default value or not + * @param tryMergedAnnotation whether try merged annotation or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return if annotatedElement can't be found in annotatedElement, return null + */ + public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement annotatedElement, + Class annotationType, + PropertyResolver propertyResolver, + boolean classValuesAsString, + boolean nestedAnnotationsAsMap, + boolean ignoreDefaultValue, + boolean tryMergedAnnotation, + String... ignoreAttributeNames) { + + AnnotationAttributes attributes = null; + + if (tryMergedAnnotation) { + attributes = tryGetMergedAnnotationAttributes(annotatedElement, annotationType, propertyResolver, + classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames); + } + + if (attributes == null) { + attributes = getAnnotationAttributes(annotatedElement, annotationType, propertyResolver, + classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames); + } + + return attributes; + } + + /** + * Try to get the merged {@link Annotation annotation} + * + * @param annotatedElement {@link AnnotatedElement the annotated element} + * @param annotationType the {@link Class tyoe} pf {@link Annotation annotation} + * @param classValuesAsString whether to turn Class references into Strings (for + * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to + * preserve them as Class references + * @param nestedAnnotationsAsMap whether to turn nested Annotation instances into + * {@link AnnotationAttributes} maps (for compatibility with + * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as + * Annotation instances + * @return If current version of Spring Framework is below 4.2, return null + */ + public static Annotation tryGetMergedAnnotation(AnnotatedElement annotatedElement, + Class annotationType, + boolean classValuesAsString, + boolean nestedAnnotationsAsMap) { + + Annotation mergedAnnotation = null; + + ClassLoader classLoader = annotationType.getClassLoader(); + + if (annotatedElementUtilsPresentCache.computeIfAbsent(System.identityHashCode(classLoader), + (_k) -> ClassUtils.isPresent(ANNOTATED_ELEMENT_UTILS_CLASS_NAME, classLoader))) { + Class annotatedElementUtilsClass = resolveClassName(ANNOTATED_ELEMENT_UTILS_CLASS_NAME, classLoader); + // getMergedAnnotation method appears in the Spring Framework 4.2 + Method getMergedAnnotationMethod = findMethod(annotatedElementUtilsClass, "getMergedAnnotation", + AnnotatedElement.class, Class.class, boolean.class, boolean.class); + if (getMergedAnnotationMethod != null) { + mergedAnnotation = (Annotation) invokeMethod(getMergedAnnotationMethod, null, + annotatedElement, annotationType, classValuesAsString, nestedAnnotationsAsMap); + } + } + + return mergedAnnotation; + } + + /** + * Try to get {@link AnnotationAttributes the annotation attributes} after merging and resolving the placeholders + * + * @param annotatedElement {@link AnnotatedElement the annotated element} + * @param annotationType the {@link Class tyoe} pf {@link Annotation annotation} + * @param propertyResolver {@link PropertyResolver} instance, e.g {@link Environment} + * @param classValuesAsString whether to turn Class references into Strings (for + * compatibility with {@link org.springframework.core.type.AnnotationMetadata} or to + * preserve them as Class references + * @param nestedAnnotationsAsMap whether to turn nested Annotation instances into + * {@link AnnotationAttributes} maps (for compatibility with + * {@link org.springframework.core.type.AnnotationMetadata} or to preserve them as + * Annotation instances + * @param ignoreDefaultValue whether ignore default value or not + * @param ignoreAttributeNames the attribute names of annotation should be ignored + * @return If the specified annotation type is not found, return null + */ + public static AnnotationAttributes tryGetMergedAnnotationAttributes(AnnotatedElement annotatedElement, + Class annotationType, + PropertyResolver propertyResolver, + boolean classValuesAsString, + boolean nestedAnnotationsAsMap, + boolean ignoreDefaultValue, + String... ignoreAttributeNames) { + Annotation annotation = tryGetMergedAnnotation(annotatedElement, annotationType, classValuesAsString, nestedAnnotationsAsMap); + return annotation == null ? null : getAnnotationAttributes(annotation, propertyResolver, + classValuesAsString, nestedAnnotationsAsMap, ignoreDefaultValue, ignoreAttributeNames); + } + +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java new file mode 100644 index 0000000000..9fe70222ea --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/BeanRegistrar.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +import org.springframework.core.AliasRegistry; + +import static org.springframework.util.ObjectUtils.containsElement; +import static org.springframework.util.StringUtils.hasText; + +/** + * Bean Registrar + */ +public abstract class BeanRegistrar { + + /** + * Detect the alias is present or not in the given bean name from {@link AliasRegistry} + * + * @param registry {@link AliasRegistry} + * @param beanName the bean name + * @param alias alias to test + * @return if present, return true, or false + */ + public static boolean hasAlias(AliasRegistry registry, String beanName, String alias) { + return hasText(beanName) && hasText(alias) && containsElement(registry.getAliases(beanName), alias); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java index 5575a24c75..170bbab0ba 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/DubboAnnotationUtils.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import static com.alibaba.spring.util.AnnotationUtils.getAttribute; import static org.springframework.util.ClassUtils.getAllInterfacesForClass; import static org.springframework.util.StringUtils.hasText; @@ -78,7 +77,7 @@ public class DubboAnnotationUtils { */ public static String resolveInterfaceName(Map attributes, Class defaultInterfaceClass) { // 1. get from DubboService.interfaceName() - String interfaceClassName = getAttribute(attributes, "interfaceName"); + String interfaceClassName = AnnotationUtils.getAttribute(attributes, "interfaceName"); if (StringUtils.hasText(interfaceClassName)) { if (GenericService.class.getName().equals(interfaceClassName) || com.alibaba.dubbo.rpc.service.GenericService.class.getName().equals(interfaceClassName)) { @@ -88,7 +87,7 @@ public class DubboAnnotationUtils { } // 2. get from DubboService.interfaceClass() - Class interfaceClass = getAttribute(attributes, "interfaceClass"); + Class interfaceClass = AnnotationUtils.getAttribute(attributes, "interfaceClass"); if (interfaceClass == null || void.class.equals(interfaceClass)) { // default or set void.class for purpose. interfaceClass = null; } else if (GenericService.class.isAssignableFrom(interfaceClass)) { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/GenericBeanPostProcessorAdapter.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/GenericBeanPostProcessorAdapter.java new file mode 100644 index 0000000000..c7678f8a96 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/GenericBeanPostProcessorAdapter.java @@ -0,0 +1,125 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.util.ClassUtils; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +/** + * Generic {@link BeanPostProcessor} Adapter + * + * @see BeanPostProcessor + */ +@SuppressWarnings("unchecked") +public abstract class GenericBeanPostProcessorAdapter implements BeanPostProcessor { + + private final Class beanType; + + public GenericBeanPostProcessorAdapter() { + ParameterizedType parameterizedType = (ParameterizedType) getClass().getGenericSuperclass(); + Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); + this.beanType = (Class) actualTypeArguments[0]; + } + + @Override + public final Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (ClassUtils.isAssignableValue(beanType, bean)) { + return doPostProcessBeforeInitialization((T) bean, beanName); + } + return bean; + } + + @Override + public final Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (ClassUtils.isAssignableValue(beanType, bean)) { + return doPostProcessAfterInitialization((T) bean, beanName); + } + return bean; + } + + /** + * Bean Type + * + * @return Bean Type + */ + public final Class getBeanType() { + return beanType; + } + + /** + * Adapter BeanPostProcessor#postProcessBeforeInitialization(Object, String) method , sub-type + * could override this method. + * + * @param bean Bean Object + * @param beanName Bean Name + * @return Bean Object + * @see BeanPostProcessor#postProcessBeforeInitialization(Object, String) + */ + protected T doPostProcessBeforeInitialization(T bean, String beanName) throws BeansException { + + processBeforeInitialization(bean, beanName); + + return bean; + + } + + /** + * Adapter BeanPostProcessor#postProcessAfterInitialization(Object, String) method , sub-type + * could override this method. + * + * @param bean Bean Object + * @param beanName Bean Name + * @return Bean Object + * @see BeanPostProcessor#postProcessAfterInitialization(Object, String) + */ + protected T doPostProcessAfterInitialization(T bean, String beanName) throws BeansException { + + processAfterInitialization(bean, beanName); + + return bean; + + } + + /** + * Process {@link T Bean} with name without return value before initialization, + *

+ * This method will be invoked by BeanPostProcessor#postProcessBeforeInitialization(Object, String) + * + * @param bean Bean Object + * @param beanName Bean Name + * @throws BeansException in case of errors + */ + protected void processBeforeInitialization(T bean, String beanName) throws BeansException { + } + + /** + * Process {@link T Bean} with name without return value after initialization, + *

+ * This method will be invoked by BeanPostProcessor#postProcessAfterInitialization(Object, String) + * + * @param bean Bean Object + * @param beanName Bean Name + * @throws BeansException in case of errors + */ + protected void processAfterInitialization(T bean, String beanName) throws BeansException { + } + +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java new file mode 100644 index 0000000000..ee327dd417 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/ObjectUtils.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +/** + * Object Utilities + */ +@SuppressWarnings("unchecked") +public abstract class ObjectUtils { + + /** + * Empty String array + */ + public static final String[] EMPTY_STRING_ARRAY = {}; + + /** + * Convert from variable arguments to array + * + * @param values variable arguments + * @param The class + * @return array + */ + public static T[] of(T... values) { + return values; + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java new file mode 100644 index 0000000000..e2f8145711 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/PropertySourcesUtils.java @@ -0,0 +1,148 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.MutablePropertySources; +import org.springframework.core.env.PropertyResolver; +import org.springframework.core.env.PropertySource; +import org.springframework.core.env.PropertySources; +import org.springframework.core.env.PropertySourcesPropertyResolver; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Properties; + +import static java.util.Collections.unmodifiableMap; + +/** + * {@link PropertySources} Utilities + * + * @see PropertySources + */ +public abstract class PropertySourcesUtils { + + /** + * Get Sub {@link Properties} + * + * @param propertySources {@link PropertySource} Iterable + * @param prefix the prefix of property name + * @return Map + * @see Properties + */ + public static Map getSubProperties(Iterable> propertySources, String prefix) { + + MutablePropertySources mutablePropertySources = new MutablePropertySources(); + + for (PropertySource source : propertySources) { + mutablePropertySources.addLast(source); + } + + return getSubProperties(mutablePropertySources, prefix); + + } + + /** + * Get Sub {@link Properties} + * + * @param environment {@link ConfigurableEnvironment} + * @param prefix the prefix of property name + * @return Map + * @see Properties + */ + public static Map getSubProperties(ConfigurableEnvironment environment, String prefix) { + return getSubProperties(environment.getPropertySources(), environment, prefix); + } + + /** + * Normalize the prefix + * + * @param prefix the prefix + * @return the prefix + */ + public static String normalizePrefix(String prefix) { + return prefix.endsWith(".") ? prefix : prefix + "."; + } + + /** + * Get prefixed {@link Properties} + * + * @param propertySources {@link PropertySources} + * @param prefix the prefix of property name + * @return Map + * @see Properties + */ + public static Map getSubProperties(PropertySources propertySources, String prefix) { + return getSubProperties(propertySources, new PropertySourcesPropertyResolver(propertySources), prefix); + } + + /** + * Get prefixed {@link Properties} + * + * @param propertySources {@link PropertySources} + * @param propertyResolver {@link PropertyResolver} to resolve the placeholder if present + * @param prefix the prefix of property name + * @return Map + * @see Properties + */ + public static Map getSubProperties(PropertySources propertySources, PropertyResolver propertyResolver, String prefix) { + + Map subProperties = new LinkedHashMap(); + + String normalizedPrefix = normalizePrefix(prefix); + + Iterator> iterator = propertySources.iterator(); + + while (iterator.hasNext()) { + PropertySource source = iterator.next(); + for (String name : getPropertyNames(source)) { + if (!subProperties.containsKey(name) && name.startsWith(normalizedPrefix)) { + String subName = name.substring(normalizedPrefix.length()); + if (!subProperties.containsKey(subName)) { // take first one + Object value = source.getProperty(name); + if (value instanceof String) { + // Resolve placeholder + value = propertyResolver.resolvePlaceholders((String) value); + } + subProperties.put(subName, value); + } + } + } + } + + return unmodifiableMap(subProperties); + } + + /** + * Get the property names as the array from the specified {@link PropertySource} instance. + * + * @param propertySource {@link PropertySource} instance + * @return non-null + */ + public static String[] getPropertyNames(PropertySource propertySource) { + String[] propertyNames = propertySource instanceof EnumerablePropertySource ? + ((EnumerablePropertySource) propertySource).getPropertyNames() : null; + + if (propertyNames == null) { + propertyNames = ObjectUtils.EMPTY_STRING_ARRAY; + } + + return propertyNames; + } +} diff --git a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboRelaxedBinding2AutoConfiguration.java b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboRelaxedBinding2AutoConfiguration.java index 0b858f81c7..8e3454937f 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboRelaxedBinding2AutoConfiguration.java +++ b/dubbo-spring-boot/dubbo-spring-boot-autoconfigure/src/main/java/org/apache/dubbo/spring/boot/autoconfigure/DubboRelaxedBinding2AutoConfiguration.java @@ -16,6 +16,8 @@ */ package org.apache.dubbo.spring.boot.autoconfigure; +import org.apache.dubbo.config.spring.util.PropertySourcesUtils; + import com.alibaba.spring.context.config.ConfigurationBeanBinder; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -35,7 +37,6 @@ import org.springframework.core.env.PropertyResolver; import java.util.Map; import java.util.Set; -import static com.alibaba.spring.util.PropertySourcesUtils.getSubProperties; import static java.util.Collections.emptySet; import static org.apache.dubbo.spring.boot.util.DubboUtils.BASE_PACKAGES_BEAN_NAME; import static org.apache.dubbo.spring.boot.util.DubboUtils.BASE_PACKAGES_PROPERTY_NAME; @@ -60,7 +61,7 @@ public class DubboRelaxedBinding2AutoConfiguration { ConfigurableEnvironment propertyResolver = new AbstractEnvironment() { @Override protected void customizePropertySources(MutablePropertySources propertySources) { - Map dubboScanProperties = getSubProperties(environment.getPropertySources(), DUBBO_SCAN_PREFIX); + Map dubboScanProperties = PropertySourcesUtils.getSubProperties(environment.getPropertySources(), DUBBO_SCAN_PREFIX); propertySources.addLast(new MapPropertySource("dubboScanProperties", dubboScanProperties)); } }; From 55a8940ad1a98d8ad78da67d8b73856768e09a53 Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Thu, 1 Jun 2023 17:19:25 +0800 Subject: [PATCH 12/30] Add default enable for protocol and histogram (#12137) * fix default enable for agg and histogram * fix default enable for agg and histogram * add default protocol * fix ci * fix ci * fix ci * fix ci * fix ci --------- Co-authored-by: x-shadow-man <1494445739@qq.com> Co-authored-by: songxiaosheng --- .../apache/dubbo/config/AbstractInterfaceConfig.java | 10 ++++++---- .../config/deploy/DefaultMetricsServiceExporter.java | 5 +++-- .../metrics/collector/HistogramMetricsCollector.java | 10 ++++++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java index 414b2a4b25..450d49f605 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java @@ -277,9 +277,10 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig { protected void appendMetricsCompatible(Map map) { MetricsConfig metricsConfig = getConfigManager().getMetrics().orElse(null); if (metricsConfig != null) { - if (metricsConfig.getProtocol() != null && !StringUtils.isEquals(metricsConfig.getProtocol(), PROTOCOL_PROMETHEUS)) { + String protocol = Optional.ofNullable(metricsConfig.getProtocol()).orElse(PROTOCOL_PROMETHEUS); + if (!StringUtils.isEquals(protocol, PROTOCOL_PROMETHEUS)) { Assert.notEmptyString(metricsConfig.getPort(), "Metrics port cannot be null"); - map.put("metrics.protocol", metricsConfig.getProtocol()); + map.put("metrics.protocol", protocol); map.put("metrics.port", metricsConfig.getPort()); } } @@ -376,8 +377,9 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig { } /** - * it is used for skipping the check of interface since dubbo 3.2 - * rest protocol allow the service is implement class + * it is used for skipping the check of interface since dubbo 3.2 + * rest protocol allow the service is implement class + * * @return */ protected boolean canSkipInterfaceCheck() { diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java index c904ed39c7..c770e5350a 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultMetricsServiceExporter.java @@ -54,10 +54,11 @@ public class DefaultMetricsServiceExporter implements MetricsServiceExporter, Sc MetricsConfig metricsConfig = applicationModel.getApplicationConfigManager().getMetrics().orElse(null); // TODO compatible with old usage of metrics, remove protocol check after new metrics is ready for use. if (metricsConfig != null && metricsService == null) { - if (PROTOCOL_PROMETHEUS.equals(metricsConfig.getProtocol()) ) { + String protocol = Optional.ofNullable(metricsConfig.getProtocol()).orElse(PROTOCOL_PROMETHEUS); + if (PROTOCOL_PROMETHEUS.equals(protocol) ) { this.metricsService = applicationModel.getExtensionLoader(MetricsService.class).getDefaultExtension(); } else { - logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "Protocol " + metricsConfig.getProtocol() + " not support for new metrics mechanism. " + + logger.warn(COMMON_METRICS_COLLECTOR_EXCEPTION, "", "", "Protocol " + protocol + " not support for new metrics mechanism. " + "Using old metrics mechanism instead."); } } diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java index c7a152c12e..872f77df1a 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/HistogramMetricsCollector.java @@ -53,10 +53,16 @@ public class HistogramMetricsCollector extends AbstractMetricsListener Date: Thu, 1 Jun 2023 18:46:17 +0800 Subject: [PATCH 13/30] Fix invoker recovery (#12445) --- .../support/AbstractClusterInvoker.java | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java index 43c9e9b294..89c58a6dc9 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/AbstractClusterInvoker.java @@ -16,11 +16,6 @@ */ package org.apache.dubbo.rpc.cluster.support; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.atomic.AtomicBoolean; - import org.apache.dubbo.common.URL; import org.apache.dubbo.common.Version; import org.apache.dubbo.common.config.Configuration; @@ -37,6 +32,7 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; +import org.apache.dubbo.rpc.RpcServiceContext; import org.apache.dubbo.rpc.cluster.ClusterInvoker; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; @@ -44,6 +40,11 @@ import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ScopeModelUtil; import org.apache.dubbo.rpc.support.RpcUtils; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.atomic.AtomicBoolean; + import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_LOADBALANCE; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_RESELECT_COUNT; import static org.apache.dubbo.common.constants.CommonConstants.ENABLE_CONNECTIVITY_VALIDATION; @@ -372,7 +373,7 @@ public abstract class AbstractClusterInvoker implements ClusterInvoker { } protected Result invokeWithContext(Invoker invoker, Invocation invocation) { - setContext(invoker); + Invoker originInvoker = setContext(invoker); Result result; try { if (ProfilerSwitch.isEnableSimpleProfiler()) { @@ -381,7 +382,7 @@ public abstract class AbstractClusterInvoker implements ClusterInvoker { invocation.addInvokedInvoker(invoker); result = invoker.invoke(invocation); } finally { - clearContext(invoker); + clearContext(originInvoker); InvocationProfilerUtils.releaseSimpleProfiler(invocation); } return result; @@ -394,12 +395,12 @@ public abstract class AbstractClusterInvoker implements ClusterInvoker { * @return */ protected Result invokeWithContextAsync(Invoker invoker, Invocation invocation, URL consumerUrl) { - setContext(invoker, consumerUrl); + Invoker originInvoker = setContext(invoker, consumerUrl); Result result; try { result = invoker.invoke(invocation); } finally { - clearContext(invoker); + clearContext(originInvoker); } return result; } @@ -436,19 +437,21 @@ public abstract class AbstractClusterInvoker implements ClusterInvoker { } - private void setContext(Invoker invoker) { - setContext(invoker, null); + private Invoker setContext(Invoker invoker) { + return setContext(invoker, null); } - private void setContext(Invoker invoker, URL consumerUrl) { - RpcContext context = RpcContext.getServiceContext(); + private Invoker setContext(Invoker invoker, URL consumerUrl) { + RpcServiceContext context = RpcContext.getServiceContext(); + Invoker originInvoker = context.getInvoker(); context.setInvoker(invoker) .setConsumerUrl(null != consumerUrl ? consumerUrl : RpcContext.getServiceContext().getConsumerUrl()); + return (Invoker) originInvoker; } private void clearContext(Invoker invoker) { // do nothing RpcContext context = RpcContext.getServiceContext(); - context.setInvoker(null); + context.setInvoker(invoker); } } From f60ac914f463034df4a50e6f871ddfb146c3b541 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 1 Jun 2023 18:46:29 +0800 Subject: [PATCH 14/30] Use Dubbo Proxy instead of Spring Proxy (#12439) * Use Dubbo Proxy instead of Spring Proxy * Fix exception --- .../dubbo/config/spring/ReferenceBean.java | 80 +++++++++---- .../util/LazyTargetInvocationHandler.java | 69 +++++++++++ .../config/spring/util/LazyTargetSource.java | 21 ++++ .../JavaConfigReferenceBeanTest.java | 110 ++++++++++++++++-- 4 files changed, 252 insertions(+), 28 deletions(-) create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetInvocationHandler.java create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetSource.java diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java index c22a280f0b..975df8a2b2 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java @@ -16,6 +16,10 @@ */ package org.apache.dubbo.config.spring; +import org.apache.dubbo.common.bytecode.Proxy; +import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; +import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.common.utils.ClassUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -25,11 +29,11 @@ import org.apache.dubbo.config.spring.reference.ReferenceAttributes; import org.apache.dubbo.config.spring.reference.ReferenceBeanManager; import org.apache.dubbo.config.spring.reference.ReferenceBeanSupport; import org.apache.dubbo.config.spring.schema.DubboBeanDefinitionParser; +import org.apache.dubbo.config.spring.util.LazyTargetInvocationHandler; +import org.apache.dubbo.config.spring.util.LazyTargetSource; import org.apache.dubbo.config.support.Parameter; import org.apache.dubbo.rpc.proxy.AbstractProxyFactory; -import org.springframework.aop.framework.ProxyFactory; -import org.springframework.aop.target.AbstractLazyCreationTargetSource; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.BeanNameAware; @@ -44,10 +48,13 @@ import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.PROXY_FAILED; + /** *

@@ -99,7 +106,7 @@ import java.util.Map; */ public class ReferenceBean implements FactoryBean, ApplicationContextAware, BeanClassLoaderAware, BeanNameAware, InitializingBean, DisposableBean { - + private final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass()); private transient ApplicationContext applicationContext; private ClassLoader beanClassLoader; @@ -124,6 +131,9 @@ public class ReferenceBean implements FactoryBean, // 'interfaceName' field for compatible with seata-1.4.0: io.seata.rm.tcc.remoting.parser.DubboRemotingParser#getServiceDesc() private String interfaceName; + // proxy style + private String proxy; + //from annotation attributes private Map referenceProps; @@ -235,6 +245,10 @@ public class ReferenceBean implements FactoryBean, propertyValues = beanDefinition.getPropertyValues(); } } + + if (referenceProps != null) { + this.proxy = (String) referenceProps.get(ReferenceAttributes.PROXY); + } Assert.notNull(this.interfaceName, "The interface name of ReferenceBean is not initialized"); ReferenceBeanManager referenceBeanManager = beanFactory.getBean(ReferenceBeanManager.BEAN_NAME, ReferenceBeanManager.class); @@ -319,24 +333,56 @@ public class ReferenceBean implements FactoryBean, //set proxy interfaces //see also: org.apache.dubbo.rpc.proxy.AbstractProxyFactory.getProxy(org.apache.dubbo.rpc.Invoker, boolean) - ProxyFactory proxyFactory = new ProxyFactory(); - proxyFactory.setTargetSource(new DubboReferenceLazyInitTargetSource()); - proxyFactory.addInterface(interfaceClass); + List> interfaces = new ArrayList<>(); + interfaces.add(interfaceClass); Class[] internalInterfaces = AbstractProxyFactory.getInternalInterfaces(); - for (Class anInterface : internalInterfaces) { - proxyFactory.addInterface(anInterface); - } + Collections.addAll(interfaces, internalInterfaces); if (!StringUtils.isEquals(interfaceClass.getName(), interfaceName)) { //add service interface try { Class serviceInterface = ClassUtils.forName(interfaceName, beanClassLoader); - proxyFactory.addInterface(serviceInterface); + interfaces.add(serviceInterface); } catch (ClassNotFoundException e) { // generic call maybe without service interface class locally } } - this.lazyProxy = proxyFactory.getProxy(this.beanClassLoader); + if (StringUtils.isEmpty(this.proxy) || CommonConstants.DEFAULT_PROXY.equalsIgnoreCase(this.proxy)) { + generateFromJavassistFirst(interfaces); + } + + if (this.lazyProxy == null) { + generateFromJdk(interfaces); + } + } + + private void generateFromJavassistFirst(List> interfaces) { + try { + this.lazyProxy = Proxy.getProxy(interfaces.toArray(new Class[0])).newInstance(new LazyTargetInvocationHandler(new DubboReferenceLazyInitTargetSource())); + } catch (Throwable fromJavassist) { + // try fall back to JDK proxy factory + try { + this.lazyProxy = java.lang.reflect.Proxy.newProxyInstance(beanClassLoader, interfaces.toArray(new Class[0]), new LazyTargetInvocationHandler(new DubboReferenceLazyInitTargetSource())); + logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy success. " + + "Interfaces: " + interfaces, fromJavassist); + } catch (Throwable fromJdk) { + logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + + "Interfaces: " + interfaces + " Javassist Error.", fromJavassist); + logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + + "Interfaces: " + interfaces + " JDK Error.", fromJdk); + throw fromJavassist; + } + } + } + + private void generateFromJdk(List> interfaces) { + try { + this.lazyProxy = java.lang.reflect.Proxy.newProxyInstance(beanClassLoader, interfaces.toArray(new Class[0]), new LazyTargetInvocationHandler(new DubboReferenceLazyInitTargetSource())); + } catch (Throwable fromJdk) { + logger.error(PROXY_FAILED, "", "", "Failed to generate proxy by Javassist failed. Fallback to use JDK proxy is also failed. " + + "Interfaces: " + interfaces + " JDK Error.", fromJdk); + throw fromJdk; + } } private Object getCallProxy() throws Exception { @@ -344,7 +390,7 @@ public class ReferenceBean implements FactoryBean, throw new IllegalStateException("ReferenceBean is not ready yet, please make sure to call reference interface method after dubbo is started."); } //get reference proxy - //Subclasses should synchronize on the given Object if they perform any sort of extended singleton creation phase. + //Subclasses should synchronize on the given Object if they perform any sort of extended singleton creation phase. // In particular, subclasses should not have their own mutexes involved in singleton creation, to avoid the potential for deadlocks in lazy-init situations. //The redundant type cast is to be compatible with earlier than spring-4.2 synchronized (((DefaultSingletonBeanRegistry)getBeanFactory()).getSingletonMutex()) { @@ -352,17 +398,11 @@ public class ReferenceBean implements FactoryBean, } } - private class DubboReferenceLazyInitTargetSource extends AbstractLazyCreationTargetSource { - + private class DubboReferenceLazyInitTargetSource implements LazyTargetSource { @Override - protected Object createObject() throws Exception { + public Object getTarget() throws Exception { return getCallProxy(); } - - @Override - public synchronized Class getTargetClass() { - return getInterfaceClass(); - } } } diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetInvocationHandler.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetInvocationHandler.java new file mode 100644 index 0000000000..cb414f93f0 --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetInvocationHandler.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class LazyTargetInvocationHandler implements InvocationHandler { + private final LazyTargetSource lazyTargetSource; + private volatile Object target; + + public LazyTargetInvocationHandler(LazyTargetSource lazyTargetSource) { + this.lazyTargetSource = lazyTargetSource; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + String methodName = method.getName(); + Class[] parameterTypes = method.getParameterTypes(); + if (parameterTypes.length == 0) { + if ("toString".equals(methodName)) { + if (target != null) { + return target.toString(); + } else { + return this.toString(); + } + } else if ("hashCode".equals(methodName)) { + return this.hashCode(); + } + } else if (parameterTypes.length == 1 && "equals".equals(methodName)) { + return this.equals(args[0]); + } + + if (target == null) { + synchronized (this) { + if (target == null) { + target = lazyTargetSource.getTarget(); + } + } + } + if (method.getDeclaringClass().isInstance(target)) { + try { + return method.invoke(target, args); + } catch (InvocationTargetException exception) { + Throwable targetException = exception.getTargetException(); + if (targetException != null) { + throw targetException; + } + } + } + throw new IllegalStateException("The proxied interface [" + method.getDeclaringClass() + + "] contains a method [" + method + "] that is not implemented by the proxy class [" + target.getClass() + "]"); + } +} diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetSource.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetSource.java new file mode 100644 index 0000000000..57f58e1ecd --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/util/LazyTargetSource.java @@ -0,0 +1,21 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.util; + +public interface LazyTargetSource { + Object getTarget() throws Exception; +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java index af379ca7fe..d951dd03df 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java @@ -41,6 +41,7 @@ import org.springframework.context.annotation.PropertySource; import java.io.PrintWriter; import java.io.StringWriter; +import java.lang.reflect.Modifier; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -97,6 +98,63 @@ class JavaConfigReferenceBeanTest { } } + @Test + void testLazyProxy1() { + AnnotationConfigApplicationContext context = null; + try { + context = new AnnotationConfigApplicationContext(CommonConfig.class, + LazyProxyConfiguration1.class); + HelloService helloServiceClient = context.getBean("helloServiceClient", HelloService.class); + Assertions.assertNotNull(helloServiceClient); + Assertions.assertInstanceOf(HelloService.class, helloServiceClient); + Class clientClass = helloServiceClient.getClass(); + Assertions.assertFalse(Modifier.isFinal(clientClass.getModifiers())); + Assertions.assertEquals("Hello, dubbo", helloServiceClient.sayHello("dubbo")); + } finally { + if (context != null) { + context.close(); + } + } + } + + @Test + void testLazyProxy2() { + AnnotationConfigApplicationContext context = null; + try { + context = new AnnotationConfigApplicationContext(CommonConfig.class, + LazyProxyConfiguration2.class); + HelloService helloServiceClient = context.getBean("helloServiceClient", HelloService.class); + Assertions.assertNotNull(helloServiceClient); + Assertions.assertInstanceOf(HelloService.class, helloServiceClient); + Class clientClass = helloServiceClient.getClass(); + Assertions.assertFalse(Modifier.isFinal(clientClass.getModifiers())); + Assertions.assertEquals("Hello, dubbo", helloServiceClient.sayHello("dubbo")); + } finally { + if (context != null) { + context.close(); + } + } + } + + @Test + void testLazyProxy3() { + AnnotationConfigApplicationContext context = null; + try { + context = new AnnotationConfigApplicationContext(CommonConfig.class, + LazyProxyConfiguration3.class); + HelloService helloServiceClient = context.getBean("helloServiceClient", HelloService.class); + Assertions.assertNotNull(helloServiceClient); + Assertions.assertInstanceOf(HelloService.class, helloServiceClient); + Class clientClass = helloServiceClient.getClass(); + Assertions.assertTrue(Modifier.isFinal(clientClass.getModifiers())); + Assertions.assertEquals("Hello, dubbo", helloServiceClient.sayHello("dubbo")); + } finally { + if (context != null) { + context.close(); + } + } + } + private String getStackTrace(Throwable ex) { StringWriter stringWriter = new StringWriter(); ex.printStackTrace(new PrintWriter(stringWriter)); @@ -106,7 +164,7 @@ class JavaConfigReferenceBeanTest { @Test void testAnnotationBean() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CommonConfig.class, - AnnotationBeanConfiguration.class); + AnnotationBeanConfiguration.class); try { Map helloServiceMap = context.getBeansOfType(HelloService.class); @@ -165,7 +223,7 @@ class JavaConfigReferenceBeanTest { @Test void testReferenceBean() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CommonConfig.class, - ReferenceBeanConfiguration.class); + ReferenceBeanConfiguration.class); try { Map helloServiceMap = context.getBeansOfType(HelloService.class); @@ -316,6 +374,42 @@ class JavaConfigReferenceBeanTest { } + @Configuration + public static class LazyProxyConfiguration1 { + + @DubboReference(group = "${myapp.group}") + private HelloService helloService; + + @Bean(name = "helloServiceClient") + public HelloService helloService() { + return helloService; + } + } + + @Configuration + public static class LazyProxyConfiguration2 { + + @DubboReference(group = "${myapp.group}", proxy = "javassist") + private HelloService helloService; + + @Bean(name = "helloServiceClient") + public HelloService helloService() { + return helloService; + } + } + + @Configuration + public static class LazyProxyConfiguration3 { + + @DubboReference(group = "${myapp.group}", proxy = "jdk") + private HelloService helloService; + + @Bean(name = "helloServiceClient") + public HelloService helloService() { + return helloService; + } + } + @Configuration public static class AnnotationAtFieldConfiguration { @@ -365,8 +459,8 @@ class JavaConfigReferenceBeanTest { @Bean public ReferenceBean helloService() { return new ReferenceBeanBuilder() - .setGroup("${myapp.group}") - .build(); + .setGroup("${myapp.group}") + .build(); } @Bean @@ -394,9 +488,9 @@ class JavaConfigReferenceBeanTest { @Bean public ReferenceBean helloService() { return new ReferenceBeanBuilder() - .setGroup("${myapp.group}") - .setInterface(HelloService.class) - .build(); + .setGroup("${myapp.group}") + .setInterface(HelloService.class) + .build(); } } @@ -435,4 +529,4 @@ class JavaConfigReferenceBeanTest { } } -} \ No newline at end of file +} From 74315babbeb4513c8b4ded4b40b0c254060ae3ca Mon Sep 17 00:00:00 2001 From: icodening Date: Sat, 3 Jun 2023 14:47:23 +0800 Subject: [PATCH 15/30] fix build string error (#12427) * fix build string error * Update dubbo-common/src/main/java/org/apache/dubbo/common/utils/ToStringUtils.java Co-authored-by: Albumen Kevin --------- Co-authored-by: Albumen Kevin --- .../dubbo/common/utils/ToStringUtils.java | 39 +++++++++++++++++++ .../dubbo/rpc/support/AccessLogData.java | 4 +- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/utils/ToStringUtils.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ToStringUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ToStringUtils.java new file mode 100644 index 0000000000..d405703098 --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ToStringUtils.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.common.utils; + +import java.util.Arrays; + +public class ToStringUtils { + + private ToStringUtils() { + } + + public static String printToString(Object obj) { + if (obj == null) { + return "null"; + } + try { + return JsonUtils.toJson(obj); + } catch (Throwable throwable) { + if (obj instanceof Object[]) { + return Arrays.toString((Object[]) obj); + } + return obj.toString(); + } + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java index 957e318fa7..0265517eae 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java @@ -17,8 +17,8 @@ package org.apache.dubbo.rpc.support; -import org.apache.dubbo.common.utils.JsonUtils; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.common.utils.ToStringUtils; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcContext; @@ -248,7 +248,7 @@ public final class AccessLogData { Object[] args = get(ARGUMENTS) != null ? (Object[]) get(ARGUMENTS) : null; if (args != null && args.length > 0) { - sn.append(JsonUtils.toJson(args)); + sn.append(ToStringUtils.printToString(args)); } return sn.toString(); From 3d02e9c7892e8ab2becd906777ac8f698a1ebebe Mon Sep 17 00:00:00 2001 From: wxbty <38374721+wxbty@users.noreply.github.com> Date: Sat, 3 Jun 2023 14:52:52 +0800 Subject: [PATCH 16/30] serialization RpcException bug pr rebase (#12357) * rebase seri error * fix style * wrapper seriation exception by IOException * fix ci * use exception * Multiple encode/decode conversion exceptions * use wrapper to handle seri exp * add licence * move seriExp path * revert demo * use static proxy * fix ci * fix ci * Update dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/DefaultSerializationExceptionWrapper.java Co-authored-by: Albumen Kevin * simplefy throwable type * judge IOException --------- Co-authored-by: xuziyang <767637918@qq.com> Co-authored-by: x-shadow-man <1494445739@qq.com> Co-authored-by: Albumen Kevin --- .../dubbo/remoting/exchange/Response.java | 5 + .../exchange/codec/ExchangeCodec.java | 1 + .../exchange/support/DefaultFuture.java | 5 +- .../codec/DeprecatedExchangeCodec.java | 6 +- .../remoting/codec/ExchangeCodecTest.java | 2 +- .../transport/netty4/NettyChannel.java | 12 +- .../dubbo/rpc/protocol/AbstractInvoker.java | 6 +- .../rpc/protocol/dubbo/DubboInvoker.java | 9 +- .../DefaultSerializationExceptionWrapper.java | 363 ++++++++++++++++++ .../serialize/SerializationException.java | 35 ++ ...pache.dubbo.common.serialize.Serialization | 1 + .../fastjson2/FastJson2SerializationTest.java | 34 +- .../hessian2/Hessian2SerializationTest.java | 16 +- 13 files changed, 461 insertions(+), 34 deletions(-) create mode 100644 dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/DefaultSerializationExceptionWrapper.java create mode 100644 dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationException.java create mode 100644 dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java index 923ace1f93..1a4c15eb13 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java @@ -28,6 +28,11 @@ public class Response { */ public static final byte OK = 20; + /** + * serialization error + */ + public static final byte SERIALIZATION_ERROR = 25; + /** * client side timeout. */ diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java index 1aa2d8ad7e..717f894cc7 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java @@ -360,6 +360,7 @@ public class ExchangeCodec extends TelnetCodec { logger.warn(TRANSPORT_EXCEED_PAYLOAD_LIMIT, "", "", t.getMessage(), t); try { r.setErrorMessage(t.getMessage()); + r.setStatus(Response.SERIALIZATION_ERROR); channel.send(r); return; } catch (RemotingException e) { diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java index c35739a88e..3e38371d1e 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java @@ -26,6 +26,7 @@ import org.apache.dubbo.common.timer.TimerTask; import org.apache.dubbo.common.utils.NamedThreadFactory; import org.apache.dubbo.remoting.Channel; import org.apache.dubbo.remoting.RemotingException; +import org.apache.dubbo.common.serialize.SerializationException; import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Response; @@ -215,7 +216,9 @@ public class DefaultFuture extends CompletableFuture { this.complete(res.getResult()); } else if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) { this.completeExceptionally(new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage())); - } else { + } else if(res.getStatus() == Response.SERIALIZATION_ERROR){ + this.completeExceptionally(new SerializationException(res.getErrorMessage())); + }else { this.completeExceptionally(new RemotingException(channel, res.getErrorMessage())); } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/DeprecatedExchangeCodec.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/DeprecatedExchangeCodec.java index 9a8910708b..c747ea6eff 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/DeprecatedExchangeCodec.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/DeprecatedExchangeCodec.java @@ -282,7 +282,11 @@ final class DeprecatedExchangeCodec extends DeprecatedTelnetCodec implements Cod logger.warn(TRANSPORT_FAILED_RESPONSE, "", "", "Fail to encode response: " + res + ", send bad_response info instead, cause: " + t.getMessage(), t); Response r = new Response(res.getId(), res.getVersion()); - r.setStatus(Response.BAD_RESPONSE); + if (t instanceof IOException) { + r.setStatus(Response.SERIALIZATION_ERROR); + } else { + r.setStatus(Response.BAD_RESPONSE); + } r.setErrorMessage("Failed to send response: " + res + ", cause: " + StringUtils.toString(t)); channel.send(r); diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java index 09e1f6a341..ee5ea1134e 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java @@ -512,7 +512,7 @@ class ExchangeCodecTest extends TelnetCodecTest { codec.encode(channel, encodeBuffer, response); Assertions.assertTrue(channel.getReceivedMessage() instanceof Response); Response receiveMessage = (Response) channel.getReceivedMessage(); - Assertions.assertEquals(Response.BAD_RESPONSE, receiveMessage.getStatus()); + Assertions.assertEquals(Response.SERIALIZATION_ERROR, receiveMessage.getStatus()); Assertions.assertTrue(receiveMessage.getErrorMessage().contains("Data length too large: ")); } } diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java index b87c166a86..2ca031cdf4 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyChannel.java @@ -17,7 +17,10 @@ package org.apache.dubbo.remoting.transport.netty4; import io.netty.buffer.ByteBuf; +import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; +import io.netty.handler.codec.EncoderException; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -33,9 +36,6 @@ import org.apache.dubbo.remoting.exchange.Response; import org.apache.dubbo.remoting.transport.AbstractChannel; import org.apache.dubbo.remoting.transport.codec.CodecAdapter; import org.apache.dubbo.remoting.utils.PayloadDropper; - -import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; import org.apache.dubbo.rpc.model.FrameworkModel; import java.net.InetSocketAddress; @@ -344,7 +344,11 @@ final class NettyChannel extends AbstractChannel { */ private static Response buildErrorResponse(Request request, Throwable t) { Response response = new Response(request.getId(), request.getVersion()); - response.setStatus(Response.BAD_REQUEST); + if(t instanceof EncoderException){ + response.setStatus(Response.SERIALIZATION_ERROR); + }else{ + response.setStatus(Response.BAD_REQUEST); + } response.setErrorMessage(StringUtils.toString(t)); return response; } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java index 342f29e9ed..b875f4eb62 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java @@ -28,6 +28,7 @@ import org.apache.dubbo.common.utils.ArrayUtils; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.remoting.RemotingException; +import org.apache.dubbo.common.serialize.SerializationException; import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.utils.UrlUtils; import org.apache.dubbo.rpc.AsyncRpcResult; @@ -112,7 +113,7 @@ public abstract class AbstractInvoker implements Invoker { } this.type = type; this.url = url; - + this.attachment = attachment == null ? null : Collections.unmodifiableMap(attachment); @@ -293,6 +294,9 @@ public abstract class AbstractInvoker implements Invoker { throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); } else if (rootCause instanceof RemotingException) { throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); + } else if (rootCause instanceof SerializationException) { + throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, "Invoke remote method failed cause by serialization error. remote method: " + + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); } else { throw new RpcException(RpcException.UNKNOWN_EXCEPTION, "Fail to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); } diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java index 239f88d32d..613ee79d58 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java @@ -22,6 +22,7 @@ import org.apache.dubbo.common.config.ConfigurationUtils; import org.apache.dubbo.common.utils.AtomicPositiveInteger; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingException; +import org.apache.dubbo.common.serialize.SerializationException; import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.exchange.ExchangeClient; import org.apache.dubbo.remoting.exchange.Request; @@ -37,6 +38,7 @@ import org.apache.dubbo.rpc.RpcInvocation; import org.apache.dubbo.rpc.protocol.AbstractInvoker; import org.apache.dubbo.rpc.support.RpcUtils; +import java.io.IOException; import java.util.List; import java.util.Set; import java.util.concurrent.CompletableFuture; @@ -135,7 +137,12 @@ public class DubboInvoker extends AbstractInvoker { } catch (TimeoutException e) { throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); } catch (RemotingException e) { - throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); + String remoteExpMsg = "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(); + if (e.getCause() instanceof IOException && e.getCause().getCause() instanceof SerializationException) { + throw new RpcException(RpcException.SERIALIZATION_EXCEPTION, remoteExpMsg, e); + } else { + throw new RpcException(RpcException.NETWORK_EXCEPTION, remoteExpMsg, e); + } } } diff --git a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/DefaultSerializationExceptionWrapper.java b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/DefaultSerializationExceptionWrapper.java new file mode 100644 index 0000000000..6d7f4fabe8 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/DefaultSerializationExceptionWrapper.java @@ -0,0 +1,363 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.dubbo.common.serialize; + +import org.apache.dubbo.common.URL; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.reflect.Type; +import java.util.Map; + +public class DefaultSerializationExceptionWrapper implements Serialization { + + private final Serialization serialization; + + public DefaultSerializationExceptionWrapper(Serialization serialization) { + if (serialization == null) { + throw new IllegalArgumentException("serialization == null"); + } + this.serialization = serialization; + } + + @Override + public byte getContentTypeId() { + return serialization.getContentTypeId(); + } + + @Override + public String getContentType() { + return serialization.getContentType(); + } + + @Override + public ObjectOutput serialize(URL url, OutputStream output) throws IOException { + ObjectOutput objectOutput = serialization.serialize(url, output); + return new ProxyObjectOutput(objectOutput); + } + + @Override + public ObjectInput deserialize(URL url, InputStream input) throws IOException { + ObjectInput objectInput = serialization.deserialize(url, input); + return new ProxyObjectInput(objectInput); + } + + static class ProxyObjectInput implements ObjectInput { + + private final ObjectInput target; + + public ProxyObjectInput(ObjectInput target) { + this.target = target; + } + + @Override + public boolean readBool() throws IOException { + try { + return target.readBool(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public byte readByte() throws IOException { + try { + return target.readByte(); + } catch (Exception e) { + throw handleToIOException(e); + + } + } + + @Override + public short readShort() throws IOException { + try { + return target.readShort(); + } catch (Exception e) { + throw handleToIOException(e); + + } + } + + @Override + public int readInt() throws IOException { + try { + return target.readInt(); + } catch (Exception e) { + throw handleToIOException(e); + + } + } + + @Override + public long readLong() throws IOException { + try { + return target.readLong(); + } catch (Exception e) { + throw handleToIOException(e); + + } + } + + @Override + public float readFloat() throws IOException { + try { + return target.readFloat(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public double readDouble() throws IOException { + try { + return target.readDouble(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public String readUTF() throws IOException { + try { + return target.readUTF(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public byte[] readBytes() throws IOException { + try { + return target.readBytes(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public Object readObject() throws IOException, ClassNotFoundException { + try { + return target.readObject(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public T readObject(Class cls) throws IOException, ClassNotFoundException { + try { + return target.readObject(cls); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public T readObject(Class cls, Type type) throws IOException, ClassNotFoundException { + try { + return target.readObject(cls, type); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public Throwable readThrowable() throws IOException { + try { + return target.readThrowable(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public String readEvent() throws IOException { + try { + return target.readEvent(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public Map readAttachments() throws IOException, ClassNotFoundException { + try { + return target.readAttachments(); + } catch (Exception e) { + if (e instanceof ClassNotFoundException) { + throw e; + } + throw handleToIOException(e); + } + } + } + + static class ProxyObjectOutput implements ObjectOutput { + + private final ObjectOutput target; + + public ProxyObjectOutput(ObjectOutput target) { + this.target = target; + } + + @Override + public void writeBool(boolean v) throws IOException { + try { + target.writeBool(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeByte(byte v) throws IOException { + try { + target.writeByte(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeShort(short v) throws IOException { + try { + target.writeShort(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeInt(int v) throws IOException { + try { + target.writeInt(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeLong(long v) throws IOException { + try { + target.writeLong(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeFloat(float v) throws IOException { + try { + target.writeFloat(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeDouble(double v) throws IOException { + try { + target.writeDouble(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeUTF(String v) throws IOException { + try { + target.writeUTF(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeBytes(byte[] v) throws IOException { + try { + target.writeBytes(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeBytes(byte[] v, int off, int len) throws IOException { + try { + target.writeBytes(v); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void flushBuffer() throws IOException { + try { + target.flushBuffer(); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeObject(Object obj) throws IOException { + try { + target.writeObject(obj); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeThrowable(Throwable obj) throws IOException { + try { + target.writeThrowable(obj); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeEvent(String data) throws IOException { + try { + target.writeEvent(data); + } catch (Exception e) { + throw handleToIOException(e); + } + } + + @Override + public void writeAttachments(Map attachments) throws IOException { + try { + target.writeAttachments(attachments); + } catch (Exception e) { + throw handleToIOException(e); + } + } + } + + private static IOException handleToIOException(Exception e) { + if (!(e instanceof IOException)) { + return new IOException(new SerializationException(e)); + } + return (IOException) e; + } + +} diff --git a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationException.java b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationException.java new file mode 100644 index 0000000000..ed0c445562 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/SerializationException.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.common.serialize; + +/** + * Serialized runtime exceptions, internal flow, + * will be converted into general exceptions and added to serialization tags when returning to rpc + */ +public class SerializationException extends Exception { + + private static final long serialVersionUID = -3160452149606778709L; + + public SerializationException(String msg) { + super(msg); + } + + public SerializationException(Throwable cause) { + super(cause); + } + +} diff --git a/dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization b/dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization new file mode 100644 index 0000000000..69cf80ab99 --- /dev/null +++ b/dubbo-serialization/dubbo-serialization-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization @@ -0,0 +1 @@ +wrapper=org.apache.dubbo.common.serialize.DefaultSerializationExceptionWrapper diff --git a/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java index 447e3396aa..4a9dc6eb0a 100644 --- a/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java +++ b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java @@ -82,7 +82,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readUTF); + Assertions.assertThrows(IOException.class, objectInput::readUTF); } // write pojo, read failed @@ -108,7 +108,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readUTF); + Assertions.assertThrows(IOException.class, objectInput::readUTF); } // write list, read failed @@ -156,7 +156,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readEvent); + Assertions.assertThrows(IOException.class, objectInput::readEvent); } // write pojo, read failed @@ -182,7 +182,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readEvent); + Assertions.assertThrows(IOException.class, objectInput::readEvent); } // write list, read failed @@ -230,7 +230,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readByte); + Assertions.assertThrows(IOException.class, objectInput::readByte); } // write pojo, read failed @@ -243,7 +243,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readByte); + Assertions.assertThrows(IOException.class, objectInput::readByte); } // write map, read failed @@ -256,7 +256,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readByte); + Assertions.assertThrows(IOException.class, objectInput::readByte); } // write list, read failed @@ -269,7 +269,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readByte); + Assertions.assertThrows(IOException.class, objectInput::readByte); } frameworkModel.destroy(); @@ -381,7 +381,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(List.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(List.class)); } // write pojo, read list failed @@ -395,7 +395,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(LinkedList.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(LinkedList.class)); } // write pojo, read string failed @@ -423,7 +423,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(TrustedNotSerializable.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(TrustedNotSerializable.class)); } // write pojo, read same field failed @@ -437,7 +437,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(TrustedPojo2.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(TrustedPojo2.class)); } // write pojo, read map failed @@ -451,7 +451,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(Map.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(Map.class)); } // write list, read pojo failed @@ -468,7 +468,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(TrustedPojo.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(TrustedPojo.class)); } // write list, read map failed @@ -485,7 +485,7 @@ public class FastJson2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(Map.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(Map.class)); } frameworkModel.destroy(); @@ -542,7 +542,7 @@ public class FastJson2SerializationTest { frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readObject); + Assertions.assertThrows(IOException.class, objectInput::readObject); frameworkModel.destroy(); } } @@ -576,7 +576,7 @@ public class FastJson2SerializationTest { frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, objectInput::readObject); + Assertions.assertThrows(IOException.class, objectInput::readObject); frameworkModel.destroy(); } } diff --git a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java index b43e0a8c80..e94f41b350 100644 --- a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java +++ b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java @@ -379,7 +379,7 @@ class Hessian2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(List.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(List.class)); } // write pojo, read list failed @@ -393,7 +393,7 @@ class Hessian2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(LinkedList.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(LinkedList.class)); } // write pojo, read string failed @@ -407,7 +407,7 @@ class Hessian2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(String.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(String.class)); } // write pojo, read other failed @@ -421,7 +421,7 @@ class Hessian2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(TrustedNotSerializable.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(TrustedNotSerializable.class)); } // write pojo, read same field failed @@ -466,7 +466,7 @@ class Hessian2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(TrustedPojo.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(TrustedPojo.class)); } // write list, read map failed @@ -483,7 +483,7 @@ class Hessian2SerializationTest { byte[] bytes = outputStream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes); ObjectInput objectInput = serialization.deserialize(url, inputStream); - Assertions.assertThrows(RuntimeException.class, () -> objectInput.readObject(Map.class)); + Assertions.assertThrows(IOException.class, () -> objectInput.readObject(Map.class)); } frameworkModel.destroy(); @@ -523,7 +523,7 @@ class Hessian2SerializationTest { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutput objectOutput = serialization.serialize(url, outputStream); - Assertions.assertThrows(IllegalArgumentException.class, () -> objectOutput.writeObject(trustedPojo)); + Assertions.assertThrows(IOException.class, () -> objectOutput.writeObject(trustedPojo)); frameworkModel.destroy(); } @@ -539,7 +539,7 @@ class Hessian2SerializationTest { ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); ObjectOutput objectOutput = serialization.serialize(url, outputStream); - Assertions.assertThrows(IllegalArgumentException.class, () -> objectOutput.writeObject(trustedPojo)); + Assertions.assertThrows(IOException.class, () -> objectOutput.writeObject(trustedPojo)); frameworkModel.destroy(); } From d6661cf5018078738910a705a5d9bfbd5dcac541 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Mon, 5 Jun 2023 10:09:30 +0800 Subject: [PATCH 17/30] Introduce DelegateURL to proxy apache URL to alibaba URL (#12449) * Introduce DelegateURL to proxy apache URL to alibaba URL * Fix license --- .../com/alibaba/dubbo/cache/CacheFactory.java | 3 +- .../cache/support/AbstractCacheFactory.java | 3 +- .../com/alibaba/dubbo/common/DelegateURL.java | 1054 +++++++++++++++++ .../java/com/alibaba/dubbo/common/URL.java | 2 +- .../dubbo/common/serialize/Serialization.java | 5 +- .../dubbo/common/threadpool/ThreadPool.java | 2 +- .../alibaba/dubbo/common/utils/UrlUtils.java | 7 +- .../com/alibaba/dubbo/monitor/Monitor.java | 4 +- .../alibaba/dubbo/monitor/MonitorFactory.java | 2 +- .../dubbo/registry/NotifyListener.java | 3 +- .../com/alibaba/dubbo/registry/Registry.java | 10 +- .../dubbo/registry/RegistryFactory.java | 2 +- .../registry/support/AbstractRegistry.java | 22 +- .../support/AbstractRegistryFactory.java | 2 +- .../registry/support/FailbackRegistry.java | 21 +- .../alibaba/dubbo/remoting/Transporter.java | 3 +- .../java/com/alibaba/dubbo/rpc/Invoker.java | 3 +- .../java/com/alibaba/dubbo/rpc/Protocol.java | 3 +- .../com/alibaba/dubbo/rpc/ProxyFactory.java | 2 +- .../com/alibaba/dubbo/rpc/RpcContext.java | 5 +- .../dubbo/rpc/cluster/Configurator.java | 2 +- .../rpc/cluster/ConfiguratorFactory.java | 2 +- .../dubbo/rpc/cluster/LoadBalance.java | 8 +- .../com/alibaba/dubbo/rpc/cluster/Router.java | 5 +- .../dubbo/rpc/cluster/RouterFactory.java | 2 +- .../dubbo/rpc/cluster/RuleConverter.java | 2 +- 26 files changed, 1124 insertions(+), 55 deletions(-) create mode 100644 dubbo-compatible/src/main/java/com/alibaba/dubbo/common/DelegateURL.java diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/CacheFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/CacheFactory.java index d72661d2df..626eed2b4e 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/CacheFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/CacheFactory.java @@ -17,6 +17,7 @@ package com.alibaba.dubbo.cache; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.rpc.Invocation; @@ -26,6 +27,6 @@ public interface CacheFactory extends org.apache.dubbo.cache.CacheFactory { Cache getCache(URL url, Invocation invocation); default org.apache.dubbo.cache.Cache getCache(org.apache.dubbo.common.URL url, org.apache.dubbo.rpc.Invocation invocation) { - return this.getCache(new URL(url), new Invocation.CompatibleInvocation(invocation)); + return this.getCache(new DelegateURL(url), new Invocation.CompatibleInvocation(invocation)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/support/AbstractCacheFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/support/AbstractCacheFactory.java index e7a05fdebb..6ca184c660 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/support/AbstractCacheFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/cache/support/AbstractCacheFactory.java @@ -19,6 +19,7 @@ package com.alibaba.dubbo.cache.support; import com.alibaba.dubbo.cache.Cache; import com.alibaba.dubbo.cache.CacheFactory; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.rpc.Invocation; @@ -48,6 +49,6 @@ public abstract class AbstractCacheFactory implements CacheFactory { @Override public org.apache.dubbo.cache.Cache getCache(org.apache.dubbo.common.URL url, org.apache.dubbo.rpc.Invocation invocation) { - return getCache(new URL(url), new Invocation.CompatibleInvocation(invocation)); + return getCache(new DelegateURL(url), new Invocation.CompatibleInvocation(invocation)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/DelegateURL.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/DelegateURL.java new file mode 100644 index 0000000000..2825e89cea --- /dev/null +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/DelegateURL.java @@ -0,0 +1,1054 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.alibaba.dubbo.common; + +import org.apache.dubbo.common.config.Configuration; +import org.apache.dubbo.common.url.component.URLAddress; +import org.apache.dubbo.common.url.component.URLParam; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.FrameworkModel; +import org.apache.dubbo.rpc.model.ModuleModel; +import org.apache.dubbo.rpc.model.ScopeModel; +import org.apache.dubbo.rpc.model.ServiceModel; + +import java.net.InetSocketAddress; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +@Deprecated +public class DelegateURL extends com.alibaba.dubbo.common.URL { + protected final org.apache.dubbo.common.URL apacheUrl; + + public DelegateURL(org.apache.dubbo.common.URL apacheUrl) { + this.apacheUrl = apacheUrl; + } + + public static com.alibaba.dubbo.common.URL valueOf(String url) { + return new DelegateURL(org.apache.dubbo.common.URL.valueOf(url)); + } + + @Override + public String getProtocol() { + return apacheUrl.getProtocol(); + } + + @Override + public com.alibaba.dubbo.common.URL setProtocol(String protocol) { + return new DelegateURL(apacheUrl.setProtocol(protocol)); + } + + @Override + public String getUsername() { + return apacheUrl.getUsername(); + } + + @Override + public com.alibaba.dubbo.common.URL setUsername(String username) { + return new DelegateURL(apacheUrl.setUsername(username)); + } + + @Override + public String getPassword() { + return apacheUrl.getPassword(); + } + + @Override + public com.alibaba.dubbo.common.URL setPassword(String password) { + return new DelegateURL(apacheUrl.setPassword(password)); + } + + @Override + public String getAuthority() { + return apacheUrl.getAuthority(); + } + + @Override + public String getHost() { + return apacheUrl.getHost(); + } + + @Override + public com.alibaba.dubbo.common.URL setHost(String host) { + return new DelegateURL(apacheUrl.setHost(host)); + } + + @Override + public String getIp() { + return apacheUrl.getIp(); + } + + @Override + public int getPort() { + return apacheUrl.getPort(); + } + + @Override + public com.alibaba.dubbo.common.URL setPort(int port) { + return new DelegateURL(apacheUrl.setPort(port)); + } + + @Override + public int getPort(int defaultPort) { + return apacheUrl.getPort(defaultPort); + } + + @Override + public String getAddress() { + return apacheUrl.getAddress(); + } + + @Override + public com.alibaba.dubbo.common.URL setAddress(String address) { + return new DelegateURL(apacheUrl.setAddress(address)); + } + + @Override + public String getBackupAddress() { + return apacheUrl.getBackupAddress(); + } + + @Override + public String getBackupAddress(int defaultPort) { + return apacheUrl.getBackupAddress(defaultPort); + } + + @Override + public String getPath() { + return apacheUrl.getPath(); + } + + @Override + public com.alibaba.dubbo.common.URL setPath(String path) { + return new DelegateURL(apacheUrl.setPath(path)); + } + + @Override + public String getAbsolutePath() { + return apacheUrl.getAbsolutePath(); + } + + @Override + public Map getParameters() { + return apacheUrl.getParameters(); + } + + @Override + public String getParameterAndDecoded(String key) { + return apacheUrl.getParameterAndDecoded(key); + } + + @Override + public String getParameterAndDecoded(String key, String defaultValue) { + return apacheUrl.getParameterAndDecoded(key, defaultValue); + } + + @Override + public String getParameter(String key) { + return apacheUrl.getParameter(key); + } + + @Override + public String getParameter(String key, String defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public String[] getParameter(String key, String[] defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public com.alibaba.dubbo.common.URL getUrlParameter(String key) { + return new DelegateURL(apacheUrl.getUrlParameter(key)); + } + + @Override + public double getParameter(String key, double defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public float getParameter(String key, float defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public long getParameter(String key, long defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public int getParameter(String key, int defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public short getParameter(String key, short defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public byte getParameter(String key, byte defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public float getPositiveParameter(String key, float defaultValue) { + return apacheUrl.getPositiveParameter(key, defaultValue); + } + + @Override + public double getPositiveParameter(String key, double defaultValue) { + return apacheUrl.getPositiveParameter(key, defaultValue); + } + + @Override + public long getPositiveParameter(String key, long defaultValue) { + return apacheUrl.getPositiveParameter(key, defaultValue); + } + + @Override + public int getPositiveParameter(String key, int defaultValue) { + return apacheUrl.getPositiveParameter(key, defaultValue); + } + + @Override + public short getPositiveParameter(String key, short defaultValue) { + return apacheUrl.getPositiveParameter(key, defaultValue); + } + + @Override + public byte getPositiveParameter(String key, byte defaultValue) { + return apacheUrl.getPositiveParameter(key, defaultValue); + } + + @Override + public char getParameter(String key, char defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public boolean getParameter(String key, boolean defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public boolean hasParameter(String key) { + return apacheUrl.hasParameter(key); + } + + @Override + public String getMethodParameterAndDecoded(String method, String key) { + return apacheUrl.getMethodParameterAndDecoded(method, key); + } + + @Override + public String getMethodParameterAndDecoded(String method, String key, String defaultValue) { + return apacheUrl.getMethodParameterAndDecoded(method, key, defaultValue); + } + + @Override + public String getMethodParameter(String method, String key) { + return apacheUrl.getMethodParameter(method, key); + } + + @Override + public String getMethodParameter(String method, String key, String defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public double getMethodParameter(String method, String key, double defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public float getMethodParameter(String method, String key, float defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public long getMethodParameter(String method, String key, long defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public int getMethodParameter(String method, String key, int defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public short getMethodParameter(String method, String key, short defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public byte getMethodParameter(String method, String key, byte defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public double getMethodPositiveParameter(String method, String key, double defaultValue) { + return apacheUrl.getMethodPositiveParameter(method, key, defaultValue); + } + + @Override + public float getMethodPositiveParameter(String method, String key, float defaultValue) { + return apacheUrl.getMethodPositiveParameter(method, key, defaultValue); + } + + @Override + public long getMethodPositiveParameter(String method, String key, long defaultValue) { + return apacheUrl.getMethodPositiveParameter(method, key, defaultValue); + } + + @Override + public int getMethodPositiveParameter(String method, String key, int defaultValue) { + return apacheUrl.getMethodPositiveParameter(method, key, defaultValue); + } + + @Override + public short getMethodPositiveParameter(String method, String key, short defaultValue) { + return apacheUrl.getMethodPositiveParameter(method, key, defaultValue); + } + + @Override + public byte getMethodPositiveParameter(String method, String key, byte defaultValue) { + return apacheUrl.getMethodPositiveParameter(method, key, defaultValue); + } + + @Override + public char getMethodParameter(String method, String key, char defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public boolean getMethodParameter(String method, String key, boolean defaultValue) { + return apacheUrl.getMethodParameter(method, key, defaultValue); + } + + @Override + public boolean hasMethodParameter(String method, String key) { + return apacheUrl.hasMethodParameter(method, key); + } + + @Override + public boolean isLocalHost() { + return apacheUrl.isLocalHost(); + } + + @Override + public boolean isAnyHost() { + return apacheUrl.isAnyHost(); + } + + @Override + public com.alibaba.dubbo.common.URL addParameterAndEncoded(String key, String value) { + return new DelegateURL(apacheUrl.addParameterAndEncoded(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, boolean value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, char value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, byte value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, short value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, int value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, long value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, float value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, double value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, Enum value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, Number value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, CharSequence value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameter(String key, String value) { + return new DelegateURL(apacheUrl.addParameter(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameterIfAbsent(String key, String value) { + return new DelegateURL(apacheUrl.addParameterIfAbsent(key, value)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameters(Map parameters) { + return new DelegateURL(apacheUrl.addParameters(parameters)); + } + + @Override + public com.alibaba.dubbo.common.URL addParametersIfAbsent(Map parameters) { + return new DelegateURL(apacheUrl.addParametersIfAbsent(parameters)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameters(String... pairs) { + return new DelegateURL(apacheUrl.addParameters(pairs)); + } + + @Override + public com.alibaba.dubbo.common.URL addParameterString(String query) { + return new DelegateURL(apacheUrl.addParameterString(query)); + } + + @Override + public com.alibaba.dubbo.common.URL removeParameter(String key) { + return new DelegateURL(apacheUrl.removeParameter(key)); + } + + @Override + public com.alibaba.dubbo.common.URL removeParameters(Collection keys) { + return new DelegateURL(apacheUrl.removeParameters(keys)); + } + + @Override + public com.alibaba.dubbo.common.URL removeParameters(String... keys) { + return new DelegateURL(apacheUrl.removeParameters(keys)); + } + + @Override + public com.alibaba.dubbo.common.URL clearParameters() { + return new DelegateURL(apacheUrl.clearParameters()); + } + + @Override + public String getRawParameter(String key) { + return apacheUrl.getRawParameter(key); + } + + @Override + public Map toMap() { + return apacheUrl.toMap(); + } + + @Override + public String toString() { + return apacheUrl.toString(); + } + + @Override + public String toString(String... parameters) { + return apacheUrl.toString(parameters); + } + + @Override + public String toIdentityString() { + return apacheUrl.toIdentityString(); + } + + @Override + public String toIdentityString(String... parameters) { + return apacheUrl.toIdentityString(parameters); + } + + @Override + public String toFullString() { + return apacheUrl.toFullString(); + } + + @Override + public String toFullString(String... parameters) { + return apacheUrl.toFullString(parameters); + } + + @Override + public String toParameterString() { + return apacheUrl.toParameterString(); + } + + @Override + public String toParameterString(String... parameters) { + return apacheUrl.toParameterString(parameters); + } + + @Override + public java.net.URL toJavaURL() { + return apacheUrl.toJavaURL(); + } + + @Override + public InetSocketAddress toInetSocketAddress() { + return apacheUrl.toInetSocketAddress(); + } + + @Override + public String getServiceKey() { + return apacheUrl.getServiceKey(); + } + + @Override + public String toServiceStringWithoutResolving() { + return apacheUrl.toServiceStringWithoutResolving(); + } + + @Override + public String toServiceString() { + return apacheUrl.toServiceString(); + } + + @Override + public String getServiceInterface() { + return apacheUrl.getServiceInterface(); + } + + @Override + public com.alibaba.dubbo.common.URL setServiceInterface(String service) { + return new DelegateURL(apacheUrl.setServiceInterface(service)); + } + + @Override + public org.apache.dubbo.common.URL getOriginalURL() { + return apacheUrl; + } + + @Override + public URLAddress getUrlAddress() { + return apacheUrl.getUrlAddress(); + } + + @Override + public URLParam getUrlParam() { + return apacheUrl.getUrlParam(); + } + + @Override + public String getUserInformation() { + return apacheUrl.getUserInformation(); + } + + @Override + public List getBackupUrls() { + return apacheUrl.getBackupUrls(); + } + + @Override + public Map getOriginalParameters() { + return apacheUrl.getOriginalParameters(); + } + + @Override + public Map getAllParameters() { + return apacheUrl.getAllParameters(); + } + + @Override + public Map getParameters(Predicate nameToSelect) { + return apacheUrl.getParameters(nameToSelect); + } + + @Override + public String getOriginalParameter(String key) { + return apacheUrl.getOriginalParameter(key); + } + + @Override + public List getParameter(String key, List defaultValue) { + return apacheUrl.getParameter(key, defaultValue); + } + + @Override + public T getParameter(String key, Class valueType) { + return apacheUrl.getParameter(key, valueType); + } + + @Override + public T getParameter(String key, Class valueType, T defaultValue) { + return apacheUrl.getParameter(key, valueType, defaultValue); + } + + @Override + public org.apache.dubbo.common.URL setScopeModel(ScopeModel scopeModel) { + return apacheUrl.setScopeModel(scopeModel); + } + + @Override + public ScopeModel getScopeModel() { + return apacheUrl.getScopeModel(); + } + + @Override + public FrameworkModel getOrDefaultFrameworkModel() { + return apacheUrl.getOrDefaultFrameworkModel(); + } + + @Override + public ApplicationModel getOrDefaultApplicationModel() { + return apacheUrl.getOrDefaultApplicationModel(); + } + + @Override + public ApplicationModel getApplicationModel() { + return apacheUrl.getApplicationModel(); + } + + @Override + public ModuleModel getOrDefaultModuleModel() { + return apacheUrl.getOrDefaultModuleModel(); + } + + @Override + public org.apache.dubbo.common.URL setServiceModel(ServiceModel serviceModel) { + return apacheUrl.setServiceModel(serviceModel); + } + + @Override + public ServiceModel getServiceModel() { + return apacheUrl.getServiceModel(); + } + + @Override + public String getMethodParameterStrict(String method, String key) { + return apacheUrl.getMethodParameterStrict(method, key); + } + + @Override + public String getAnyMethodParameter(String key) { + return apacheUrl.getAnyMethodParameter(key); + } + + @Override + public boolean hasMethodParameter(String method) { + return apacheUrl.hasMethodParameter(method); + } + + @Override + public Map toOriginalMap() { + return apacheUrl.toOriginalMap(); + } + + @Override + public String getColonSeparatedKey() { + return apacheUrl.getColonSeparatedKey(); + } + + @Override + public String getDisplayServiceKey() { + return apacheUrl.getDisplayServiceKey(); + } + + @Override + public String getPathKey() { + return apacheUrl.getPathKey(); + } + + public static String buildKey(String path, String group, String version) { + return org.apache.dubbo.common.URL.buildKey(path, group, version); + } + + @Override + public String getProtocolServiceKey() { + return apacheUrl.getProtocolServiceKey(); + } + + @Override + @Deprecated + public String getServiceName() { + return apacheUrl.getServiceName(); + } + + @Override + @Deprecated + public int getIntParameter(String key) { + return apacheUrl.getIntParameter(key); + } + + @Override + @Deprecated + public int getIntParameter(String key, int defaultValue) { + return apacheUrl.getIntParameter(key, defaultValue); + } + + @Override + @Deprecated + public int getPositiveIntParameter(String key, int defaultValue) { + return apacheUrl.getPositiveIntParameter(key, defaultValue); + } + + @Override + @Deprecated + public boolean getBooleanParameter(String key) { + return apacheUrl.getBooleanParameter(key); + } + + @Override + @Deprecated + public boolean getBooleanParameter(String key, boolean defaultValue) { + return apacheUrl.getBooleanParameter(key, defaultValue); + } + + @Override + @Deprecated + public int getMethodIntParameter(String method, String key) { + return apacheUrl.getMethodIntParameter(method, key); + } + + @Override + @Deprecated + public int getMethodIntParameter(String method, String key, int defaultValue) { + return apacheUrl.getMethodIntParameter(method, key, defaultValue); + } + + @Override + @Deprecated + public int getMethodPositiveIntParameter(String method, String key, int defaultValue) { + return apacheUrl.getMethodPositiveIntParameter(method, key, defaultValue); + } + + @Override + @Deprecated + public boolean getMethodBooleanParameter(String method, String key) { + return apacheUrl.getMethodBooleanParameter(method, key); + } + + @Override + @Deprecated + public boolean getMethodBooleanParameter(String method, String key, boolean defaultValue) { + return apacheUrl.getMethodBooleanParameter(method, key, defaultValue); + } + + @Override + public Configuration toConfiguration() { + return apacheUrl.toConfiguration(); + } + + @Override + public int hashCode() { + return apacheUrl.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return apacheUrl.equals(obj); + } + + public static void putMethodParameter(String method, String key, String value, Map> methodParameters) { + org.apache.dubbo.common.URL.putMethodParameter(method, key, value, methodParameters); + } + + @Override + public String getApplication(String defaultValue) { + return apacheUrl.getApplication(defaultValue); + } + + @Override + public String getApplication() { + return apacheUrl.getApplication(); + } + + @Override + public String getRemoteApplication() { + return apacheUrl.getRemoteApplication(); + } + + @Override + public String getGroup() { + return apacheUrl.getGroup(); + } + + @Override + public String getGroup(String defaultValue) { + return apacheUrl.getGroup(defaultValue); + } + + @Override + public String getVersion() { + return apacheUrl.getVersion(); + } + + @Override + public String getVersion(String defaultValue) { + return apacheUrl.getVersion(defaultValue); + } + + @Override + public String getConcatenatedParameter(String key) { + return apacheUrl.getConcatenatedParameter(key); + } + + @Override + public String getCategory(String defaultValue) { + return apacheUrl.getCategory(defaultValue); + } + + @Override + public String[] getCategory(String[] defaultValue) { + return apacheUrl.getCategory(defaultValue); + } + + @Override + public String getCategory() { + return apacheUrl.getCategory(); + } + + @Override + public String getSide(String defaultValue) { + return apacheUrl.getSide(defaultValue); + } + + @Override + public String getSide() { + return apacheUrl.getSide(); + } + + @Override + public Map getAttributes() { + return apacheUrl.getAttributes(); + } + + @Override + public org.apache.dubbo.common.URL addAttributes(Map attributes) { + return apacheUrl.addAttributes(attributes); + } + + @Override + public Object getAttribute(String key) { + return apacheUrl.getAttribute(key); + } + + @Override + public Object getAttribute(String key, Object defaultValue) { + return apacheUrl.getAttribute(key, defaultValue); + } + + @Override + public org.apache.dubbo.common.URL putAttribute(String key, Object obj) { + return apacheUrl.putAttribute(key, obj); + } + + @Override + public org.apache.dubbo.common.URL removeAttribute(String key) { + return apacheUrl.removeAttribute(key); + } + + @Override + public boolean hasAttribute(String key) { + return apacheUrl.hasAttribute(key); + } + + @Override + public Map getOriginalServiceParameters(String service) { + return apacheUrl.getOriginalServiceParameters(service); + } + + @Override + public Map getServiceParameters(String service) { + return apacheUrl.getServiceParameters(service); + } + + @Override + public String getOriginalServiceParameter(String service, String key) { + return apacheUrl.getOriginalServiceParameter(service, key); + } + + @Override + public String getServiceParameter(String service, String key) { + return apacheUrl.getServiceParameter(service, key); + } + + @Override + public String getServiceParameter(String service, String key, String defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public int getServiceParameter(String service, String key, int defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public double getServiceParameter(String service, String key, double defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public float getServiceParameter(String service, String key, float defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public long getServiceParameter(String service, String key, long defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public short getServiceParameter(String service, String key, short defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public byte getServiceParameter(String service, String key, byte defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public char getServiceParameter(String service, String key, char defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public boolean getServiceParameter(String service, String key, boolean defaultValue) { + return apacheUrl.getServiceParameter(service, key, defaultValue); + } + + @Override + public boolean hasServiceParameter(String service, String key) { + return apacheUrl.hasServiceParameter(service, key); + } + + @Override + public float getPositiveServiceParameter(String service, String key, float defaultValue) { + return apacheUrl.getPositiveServiceParameter(service, key, defaultValue); + } + + @Override + public double getPositiveServiceParameter(String service, String key, double defaultValue) { + return apacheUrl.getPositiveServiceParameter(service, key, defaultValue); + } + + @Override + public long getPositiveServiceParameter(String service, String key, long defaultValue) { + return apacheUrl.getPositiveServiceParameter(service, key, defaultValue); + } + + @Override + public int getPositiveServiceParameter(String service, String key, int defaultValue) { + return apacheUrl.getPositiveServiceParameter(service, key, defaultValue); + } + + @Override + public short getPositiveServiceParameter(String service, String key, short defaultValue) { + return apacheUrl.getPositiveServiceParameter(service, key, defaultValue); + } + + @Override + public byte getPositiveServiceParameter(String service, String key, byte defaultValue) { + return apacheUrl.getPositiveServiceParameter(service, key, defaultValue); + } + + @Override + public String getServiceMethodParameterAndDecoded(String service, String method, String key) { + return apacheUrl.getServiceMethodParameterAndDecoded(service, method, key); + } + + @Override + public String getServiceMethodParameterAndDecoded(String service, String method, String key, String defaultValue) { + return apacheUrl.getServiceMethodParameterAndDecoded(service, method, key, defaultValue); + } + + @Override + public String getServiceMethodParameterStrict(String service, String method, String key) { + return apacheUrl.getServiceMethodParameterStrict(service, method, key); + } + + @Override + public String getServiceMethodParameter(String service, String method, String key) { + return apacheUrl.getServiceMethodParameter(service, method, key); + } + + @Override + public String getServiceMethodParameter(String service, String method, String key, String defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public double getServiceMethodParameter(String service, String method, String key, double defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public float getServiceMethodParameter(String service, String method, String key, float defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public long getServiceMethodParameter(String service, String method, String key, long defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public int getServiceMethodParameter(String service, String method, String key, int defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public short getServiceMethodParameter(String service, String method, String key, short defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public byte getServiceMethodParameter(String service, String method, String key, byte defaultValue) { + return apacheUrl.getServiceMethodParameter(service, method, key, defaultValue); + } + + @Override + public boolean hasServiceMethodParameter(String service, String method, String key) { + return apacheUrl.hasServiceMethodParameter(service, method, key); + } + + @Override + public boolean hasServiceMethodParameter(String service, String method) { + return apacheUrl.hasServiceMethodParameter(service, method); + } + + @Override + public org.apache.dubbo.common.URL toSerializableURL() { + return apacheUrl.toSerializableURL(); + } +} diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/URL.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/URL.java index 361cd0776d..3491c841d5 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/URL.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/URL.java @@ -73,7 +73,7 @@ public class URL extends org.apache.dubbo.common.URL { public static URL valueOf(String url) { org.apache.dubbo.common.URL result = org.apache.dubbo.common.URL.valueOf(url); - return new URL(result); + return new DelegateURL(result); } public static String encode(String value) { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/serialize/Serialization.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/serialize/Serialization.java index f5f59989bd..dc82b3195f 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/serialize/Serialization.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/serialize/Serialization.java @@ -17,6 +17,7 @@ package com.alibaba.dubbo.common.serialize; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import java.io.IOException; @@ -32,11 +33,11 @@ public interface Serialization extends org.apache.dubbo.common.serialize.Seriali @Override default org.apache.dubbo.common.serialize.ObjectOutput serialize(org.apache.dubbo.common.URL url, OutputStream output) throws IOException { - return this.serialize(new URL(url), output); + return this.serialize(new DelegateURL(url), output); } @Override default org.apache.dubbo.common.serialize.ObjectInput deserialize(org.apache.dubbo.common.URL url, InputStream input) throws IOException { - return this.deserialize(new URL(url), input); + return this.deserialize(new DelegateURL(url), input); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/threadpool/ThreadPool.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/threadpool/ThreadPool.java index 45bb6f4566..da4adf80ba 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/threadpool/ThreadPool.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/threadpool/ThreadPool.java @@ -28,6 +28,6 @@ public interface ThreadPool extends org.apache.dubbo.common.threadpool.ThreadPoo @Override default Executor getExecutor(URL url) { - return getExecutor(new com.alibaba.dubbo.common.URL(url)); + return getExecutor(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/utils/UrlUtils.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/utils/UrlUtils.java index 0fa26ef6e1..aec0f871b7 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/utils/UrlUtils.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/common/utils/UrlUtils.java @@ -16,6 +16,7 @@ */ package com.alibaba.dubbo.common.utils; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import java.util.List; @@ -30,11 +31,11 @@ import java.util.stream.Collectors; public class UrlUtils { public static URL parseURL(String address, Map defaults) { - return new URL(org.apache.dubbo.common.utils.UrlUtils.parseURL(address, defaults)); + return new DelegateURL(org.apache.dubbo.common.utils.UrlUtils.parseURL(address, defaults)); } public static List parseURLs(String address, Map defaults) { - return org.apache.dubbo.common.utils.UrlUtils.parseURLs(address, defaults).stream().map(e -> new URL(e)).collect(Collectors.toList()); + return org.apache.dubbo.common.utils.UrlUtils.parseURLs(address, defaults).stream().map(e -> new DelegateURL(e)).collect(Collectors.toList()); } public static Map> convertRegister(Map> register) { @@ -64,7 +65,7 @@ public class UrlUtils { } public static URL getEmptyUrl(String service, String category) { - return new URL(org.apache.dubbo.common.utils.UrlUtils.getEmptyUrl(service, category)); + return new DelegateURL(org.apache.dubbo.common.utils.UrlUtils.getEmptyUrl(service, category)); } public static boolean isMatchCategory(String category, String categories) { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/Monitor.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/Monitor.java index 3d4abb3cd6..6e1ed3767b 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/Monitor.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/Monitor.java @@ -34,11 +34,11 @@ public interface Monitor extends org.apache.dubbo.monitor.Monitor { @Override default void collect(URL statistics) { - this.collect(new com.alibaba.dubbo.common.URL(statistics)); + this.collect(new com.alibaba.dubbo.common.DelegateURL(statistics)); } @Override default List lookup(URL query) { - return this.lookup(new com.alibaba.dubbo.common.URL(query)).stream().map(url -> url.getOriginalURL()).collect(Collectors.toList()); + return this.lookup(new com.alibaba.dubbo.common.DelegateURL(query)).stream().map(url -> url.getOriginalURL()).collect(Collectors.toList()); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/MonitorFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/MonitorFactory.java index 22e1d3ac64..4f30d1f3c7 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/MonitorFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/monitor/MonitorFactory.java @@ -27,6 +27,6 @@ public interface MonitorFactory extends org.apache.dubbo.monitor.MonitorFactory @Override default Monitor getMonitor(URL url) { - return this.getMonitor(new com.alibaba.dubbo.common.URL(url)); + return this.getMonitor(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/NotifyListener.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/NotifyListener.java index 633dc1b656..ae262e1fa7 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/NotifyListener.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/NotifyListener.java @@ -17,6 +17,7 @@ package com.alibaba.dubbo.registry; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import java.util.List; @@ -54,7 +55,7 @@ public interface NotifyListener { @Override public void notify(List urls) { if (listener != null) { - listener.notify(urls.stream().map(url -> new URL(url)).collect(Collectors.toList())); + listener.notify(urls.stream().map(url -> new DelegateURL(url)).collect(Collectors.toList())); } } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/Registry.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/Registry.java index cc9ceb14ee..8256b368db 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/Registry.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/Registry.java @@ -41,29 +41,29 @@ public interface Registry extends org.apache.dubbo.registry.Registry { @Override default void register(URL url) { - this.register(new com.alibaba.dubbo.common.URL(url)); + this.register(new com.alibaba.dubbo.common.DelegateURL(url)); } @Override default void unregister(URL url) { - this.unregister(new com.alibaba.dubbo.common.URL(url)); + this.unregister(new com.alibaba.dubbo.common.DelegateURL(url)); } @Override default void subscribe(URL url, NotifyListener listener) { - this.subscribe(new com.alibaba.dubbo.common.URL(url), + this.subscribe(new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener)); } @Override default void unsubscribe(URL url, NotifyListener listener) { - this.unsubscribe(new com.alibaba.dubbo.common.URL(url), + this.unsubscribe(new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener)); } @Override default List lookup(URL url) { - return this.lookup(new com.alibaba.dubbo.common.URL(url)).stream().map(u -> u.getOriginalURL()). + return this.lookup(new com.alibaba.dubbo.common.DelegateURL(url)).stream().map(u -> u.getOriginalURL()). collect(Collectors.toList()); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/RegistryFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/RegistryFactory.java index 5c9361213b..e0eaf5c52b 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/RegistryFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/RegistryFactory.java @@ -27,6 +27,6 @@ public interface RegistryFactory extends org.apache.dubbo.registry.RegistryFacto @Override default Registry getRegistry(URL url) { - return this.getRegistry(new com.alibaba.dubbo.common.URL(url)); + return this.getRegistry(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistry.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistry.java index 0e271ed125..48a8cafc18 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistry.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistry.java @@ -39,7 +39,7 @@ public abstract class AbstractRegistry implements Registry { @Override public com.alibaba.dubbo.common.URL getUrl() { - return new com.alibaba.dubbo.common.URL(abstractRegistry.getUrl()); + return new com.alibaba.dubbo.common.DelegateURL(abstractRegistry.getUrl()); } protected void setUrl(com.alibaba.dubbo.common.URL url) { @@ -47,35 +47,35 @@ public abstract class AbstractRegistry implements Registry { } public Set getRegistered() { - return abstractRegistry.getRegistered().stream().map(url -> new com.alibaba.dubbo.common.URL(url)).collect(Collectors.toSet()); + return abstractRegistry.getRegistered().stream().map(url -> new com.alibaba.dubbo.common.DelegateURL(url)).collect(Collectors.toSet()); } public Map> getSubscribed() { return abstractRegistry.getSubscribed().entrySet() .stream() - .collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.URL(entry.getKey()), + .collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.DelegateURL(entry.getKey()), entry -> convertToNotifyListeners(entry.getValue()))); } public Map>> getNotified() { return abstractRegistry.getNotified().entrySet().stream() - .collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.URL(entry.getKey()), + .collect(Collectors.toMap(entry -> new com.alibaba.dubbo.common.DelegateURL(entry.getKey()), entry -> { return entry.getValue().entrySet() .stream() .collect(Collectors.toMap(e -> e.getKey(), e -> { - return e.getValue().stream().map(url -> new com.alibaba.dubbo.common.URL(url)).collect(Collectors.toList()); + return e.getValue().stream().map(url -> new com.alibaba.dubbo.common.DelegateURL(url)).collect(Collectors.toList()); })); })); } public List getCacheUrls(com.alibaba.dubbo.common.URL url) { - return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.URL(tmpUrl)).collect(Collectors.toList()); + return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.DelegateURL(tmpUrl)).collect(Collectors.toList()); } public List lookup(com.alibaba.dubbo.common.URL url) { - return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.URL(tmpUrl)).collect(Collectors.toList()); + return abstractRegistry.lookup(url.getOriginalURL()).stream().map(tmpUrl -> new com.alibaba.dubbo.common.DelegateURL(tmpUrl)).collect(Collectors.toList()); } protected void notify(com.alibaba.dubbo.common.URL url, com.alibaba.dubbo.registry.NotifyListener listener, List urls) { @@ -101,22 +101,22 @@ public abstract class AbstractRegistry implements Registry { @Override public void register(URL url) { - this.register(new com.alibaba.dubbo.common.URL(url)); + this.register(new com.alibaba.dubbo.common.DelegateURL(url)); } @Override public void unregister(URL url) { - this.unregister(new com.alibaba.dubbo.common.URL(url)); + this.unregister(new com.alibaba.dubbo.common.DelegateURL(url)); } @Override public void subscribe(URL url, NotifyListener listener) { - this.subscribe(new com.alibaba.dubbo.common.URL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener)); + this.subscribe(new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener)); } @Override public void unsubscribe(URL url, NotifyListener listener) { - this.unsubscribe(new com.alibaba.dubbo.common.URL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener)); + this.unsubscribe(new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.registry.NotifyListener.CompatibleNotifyListener(listener)); } final Set convertToNotifyListeners(Set notifyListeners) { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistryFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistryFactory.java index 231f9b50bd..badd9f082e 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistryFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/AbstractRegistryFactory.java @@ -36,6 +36,6 @@ public abstract class AbstractRegistryFactory extends org.apache.dubbo.registry. @Override protected Registry createRegistry(URL url) { - return createRegistry(new com.alibaba.dubbo.common.URL(url)); + return createRegistry(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/FailbackRegistry.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/FailbackRegistry.java index 4182ea65c5..f50c2c1fb4 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/FailbackRegistry.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/registry/support/FailbackRegistry.java @@ -16,6 +16,7 @@ */ package com.alibaba.dubbo.registry.support; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.registry.NotifyListener; import com.alibaba.dubbo.registry.Registry; @@ -87,12 +88,12 @@ public abstract class FailbackRegistry implements org.apache.dubbo.registry.Regi @Override public List lookup(URL url) { - return failbackRegistry.lookup(url.getOriginalURL()).stream().map(e -> new URL(e)).collect(Collectors.toList()); + return failbackRegistry.lookup(url.getOriginalURL()).stream().map(e -> new DelegateURL(e)).collect(Collectors.toList()); } @Override public URL getUrl() { - return new URL(failbackRegistry.getUrl()); + return new DelegateURL(failbackRegistry.getUrl()); } @Override @@ -112,22 +113,22 @@ public abstract class FailbackRegistry implements org.apache.dubbo.registry.Regi @Override public void register(org.apache.dubbo.common.URL url) { - this.register(new URL(url)); + this.register(new DelegateURL(url)); } @Override public void unregister(org.apache.dubbo.common.URL url) { - this.unregister(new URL(url)); + this.unregister(new DelegateURL(url)); } @Override public void subscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) { - this.subscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener)); + this.subscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener)); } @Override public void unsubscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) { - this.unsubscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener)); + this.unsubscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener)); } @Override @@ -147,22 +148,22 @@ public abstract class FailbackRegistry implements org.apache.dubbo.registry.Regi @Override public void doRegister(org.apache.dubbo.common.URL url) { - this.compatibleFailbackRegistry.doRegister(new URL(url)); + this.compatibleFailbackRegistry.doRegister(new DelegateURL(url)); } @Override public void doUnregister(org.apache.dubbo.common.URL url) { - this.compatibleFailbackRegistry.doUnregister(new URL(url)); + this.compatibleFailbackRegistry.doUnregister(new DelegateURL(url)); } @Override public void doSubscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) { - this.compatibleFailbackRegistry.doSubscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener)); + this.compatibleFailbackRegistry.doSubscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener)); } @Override public void doUnsubscribe(org.apache.dubbo.common.URL url, org.apache.dubbo.registry.NotifyListener listener) { - this.compatibleFailbackRegistry.doUnsubscribe(new URL(url), new NotifyListener.CompatibleNotifyListener(listener)); + this.compatibleFailbackRegistry.doUnsubscribe(new DelegateURL(url), new NotifyListener.CompatibleNotifyListener(listener)); } @Override diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/Transporter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/Transporter.java index 3dcc143102..b34aca3232 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/Transporter.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/Transporter.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.extension.Adaptive; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.remoting.RemotingServer; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; @Deprecated @@ -32,7 +33,7 @@ public interface Transporter extends org.apache.dubbo.remoting.Transporter { @Override default RemotingServer bind(org.apache.dubbo.common.URL url, org.apache.dubbo.remoting.ChannelHandler handler) throws org.apache.dubbo.remoting.RemotingException { - return bind(new URL(url), new ChannelHandler() { + return bind(new DelegateURL(url), new ChannelHandler() { @Override public void connected(Channel channel) throws RemotingException { try { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java index fc38498649..67d30ccdeb 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invoker.java @@ -19,6 +19,7 @@ package com.alibaba.dubbo.rpc; import org.apache.dubbo.rpc.AsyncRpcResult; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; @Deprecated @@ -77,7 +78,7 @@ public interface Invoker extends org.apache.dubbo.rpc.Invoker { @Override public URL getUrl() { - return new URL(invoker.getUrl()); + return new DelegateURL(invoker.getUrl()); } @Override diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Protocol.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Protocol.java index d0a1687b25..ba603d6b1b 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Protocol.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Protocol.java @@ -19,6 +19,7 @@ package com.alibaba.dubbo.rpc; import org.apache.dubbo.rpc.ProtocolServer; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import java.util.Collections; @@ -38,7 +39,7 @@ public interface Protocol extends org.apache.dubbo.rpc.Protocol { @Override default org.apache.dubbo.rpc.Invoker refer(Class aClass, org.apache.dubbo.common.URL url) throws RpcException { - return this.refer(aClass, new URL(url)); + return this.refer(aClass, new DelegateURL(url)); } @Override diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java index 4c3c51edf8..35ff7f0da9 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/ProxyFactory.java @@ -42,6 +42,6 @@ public interface ProxyFactory extends org.apache.dubbo.rpc.ProxyFactory { @Override default Invoker getInvoker(T proxy, Class type, URL url) throws RpcException { - return getInvoker(proxy, type, new com.alibaba.dubbo.common.URL(url)); + return getInvoker(proxy, type, new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java index d44f33f2b9..4c49bc1793 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.rpc.FutureContext; import com.alibaba.dubbo.common.Constants; +import com.alibaba.dubbo.common.DelegateURL; import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.rpc.protocol.dubbo.FutureAdapter; @@ -134,7 +135,7 @@ public class RpcContext { if (CollectionUtils.isNotEmpty(newUrls)) { List urls = new ArrayList<>(newUrls.size()); for (org.apache.dubbo.common.URL newUrl : newUrls) { - urls.add(new URL(newUrl)); + urls.add(new DelegateURL(newUrl)); } return urls; } @@ -152,7 +153,7 @@ public class RpcContext { } public URL getUrl() { - return new URL(newRpcContext.getUrl()); + return new DelegateURL(newRpcContext.getUrl()); } public void setUrl(URL url) { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Configurator.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Configurator.java index 9a847ca281..4ebf5f1d74 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Configurator.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Configurator.java @@ -37,6 +37,6 @@ public interface Configurator extends org.apache.dubbo.rpc.cluster.Configurator @Override default URL configure(URL url) { - return this.configure(new com.alibaba.dubbo.common.URL(url)); + return this.configure(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java index 087f8c6e8d..888064104d 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/ConfiguratorFactory.java @@ -28,6 +28,6 @@ public interface ConfiguratorFactory extends org.apache.dubbo.rpc.cluster.Config @Override default Configurator getConfigurator(URL url) { - return this.getConfigurator(new com.alibaba.dubbo.common.URL(url)); + return this.getConfigurator(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/LoadBalance.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/LoadBalance.java index 4c215e4e5f..d0f978afa6 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/LoadBalance.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/LoadBalance.java @@ -22,6 +22,8 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcException; +import com.alibaba.dubbo.common.DelegateURL; + import java.util.List; import java.util.stream.Collectors; @@ -38,7 +40,9 @@ public interface LoadBalance extends org.apache.dubbo.rpc.cluster.LoadBalance { map(invoker -> new com.alibaba.dubbo.rpc.Invoker.CompatibleInvoker(invoker)). collect(Collectors.toList()); - return select(invs, new com.alibaba.dubbo.common.URL(url), - new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation)); + com.alibaba.dubbo.rpc.Invoker selected = select(invs, new DelegateURL(url), + new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation)); + + return selected == null ? null : selected.getOriginal(); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java index d8822bcd86..2bc4aabd18 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/Router.java @@ -23,6 +23,7 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.RpcException; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; @Deprecated @@ -44,9 +45,9 @@ public interface Router extends org.apache.dubbo.rpc.cluster.Router{ List> invs = invokers.stream().map(invoker -> new com.alibaba.dubbo.rpc.Invoker.CompatibleInvoker(invoker)). collect(Collectors.toList()); - List> res = this.route(invs, new com.alibaba.dubbo.common.URL(url), new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation)); + List> res = this.route(invs, new com.alibaba.dubbo.common.DelegateURL(url), new com.alibaba.dubbo.rpc.Invocation.CompatibleInvocation(invocation)); - return res.stream().map(inv -> inv.getOriginal()).collect(Collectors.toList()); + return res.stream().map(inv -> inv.getOriginal()).filter(Objects::nonNull).collect(Collectors.toList()); } @Override diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RouterFactory.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RouterFactory.java index e0416b5a3d..f57a0023d5 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RouterFactory.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RouterFactory.java @@ -27,6 +27,6 @@ public interface RouterFactory extends org.apache.dubbo.rpc.cluster.RouterFactor @Override default Router getRouter(URL url) { - return this.getRouter(new com.alibaba.dubbo.common.URL(url)); + return this.getRouter(new com.alibaba.dubbo.common.DelegateURL(url)); } } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java index 0c53e6c7a7..acf6c8797b 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/cluster/RuleConverter.java @@ -29,7 +29,7 @@ public interface RuleConverter extends org.apache.dubbo.rpc.cluster.RuleConverte @Override default List convert(URL subscribeUrl, Object source) { - return this.convert(new com.alibaba.dubbo.common.URL(subscribeUrl), source). + return this.convert(new com.alibaba.dubbo.common.DelegateURL(subscribeUrl), source). stream().map(url -> url.getOriginalURL()).collect(Collectors.toList()); } } From 8ac29d1c82004b3ecb42ba875e86749a15d9d650 Mon Sep 17 00:00:00 2001 From: songxiaosheng Date: Tue, 6 Jun 2023 15:35:29 +0800 Subject: [PATCH 18/30] add processing metric fun of name (#12461) * degist-concurrency-bugfix * stytle opt * fix i++ * revert demo * fix sonar * remove apache licence * add licence * add testcase&& fix notice * add notice * add notice * add notice * add notice * fix ci timeout * fix ci timeout * remove testcase because of timeout * remove testcase because of timeout * remove testcase because of timeout * fix ci * fix sonar * :fire: remove metricsPort config * :fire: remove metricsPath config * add processing metric fun --------- Co-authored-by: wxbty Co-authored-by: x-shadow-man <1494445739@qq.com> --- .../java/org/apache/dubbo/metrics/model/key/MetricsKey.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java index b4d7997a19..6b5329edc2 100644 --- a/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java +++ b/dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java @@ -27,7 +27,7 @@ public enum MetricsKey { METRIC_REQUESTS_SUCCEED("dubbo.%s.requests.succeed.total", "Total Succeed Requests"), METRIC_REQUEST_BUSINESS_FAILED("dubbo.%s.requests.business.failed.total", "Total Failed Business Requests"), - METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing", "Processing Requests"), + METRIC_REQUESTS_PROCESSING("dubbo.%s.requests.processing.total", "Processing Requests"), METRIC_REQUESTS_TIMEOUT("dubbo.%s.requests.timeout.total", "Total Timeout Failed Requests"), METRIC_REQUESTS_LIMIT("dubbo.%s.requests.limit.total", "Total Limit Failed Requests"), METRIC_REQUESTS_FAILED("dubbo.%s.requests.unknown.failed.total", "Total Unknown Failed Requests"), From 96662e0dc6e6a4b9d91fcee396c5bf53f8b1331f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 17:37:08 +0800 Subject: [PATCH 19/30] Bump byte-buddy from 1.14.4 to 1.14.5 (#12458) Bumps [byte-buddy](https://github.com/raphw/byte-buddy) from 1.14.4 to 1.14.5. - [Release notes](https://github.com/raphw/byte-buddy/releases) - [Changelog](https://github.com/raphw/byte-buddy/blob/master/release-notes.md) - [Commits](https://github.com/raphw/byte-buddy/compare/byte-buddy-1.14.4...byte-buddy-1.14.5) --- updated-dependencies: - dependency-name: net.bytebuddy:byte-buddy dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index b9dc95e2b0..62d6b32749 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -94,7 +94,7 @@ 5.3.25 5.8.3 3.29.2-GA - 1.14.4 + 1.14.5 3.2.10.Final 4.1.92.Final 2.2.1 From a9a579929f563779b4b77f15c42c4806d8c89af7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 17:37:20 +0800 Subject: [PATCH 20/30] Bump jackson_version from 2.15.1 to 2.15.2 (#12457) Bumps `jackson_version` from 2.15.1 to 2.15.2. Updates `jackson-core` from 2.15.1 to 2.15.2 - [Release notes](https://github.com/FasterXML/jackson-core/releases) - [Commits](https://github.com/FasterXML/jackson-core/compare/jackson-core-2.15.1...jackson-core-2.15.2) Updates `jackson-databind` from 2.15.1 to 2.15.2 - [Commits](https://github.com/FasterXML/jackson/commits) Updates `jackson-datatype-jsr310` from 2.15.1 to 2.15.2 Updates `jackson-annotations` from 2.15.1 to 2.15.2 - [Commits](https://github.com/FasterXML/jackson/commits) --- updated-dependencies: - dependency-name: com.fasterxml.jackson.core:jackson-core dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.core:jackson-databind dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.datatype:jackson-datatype-jsr310 dependency-type: direct:production update-type: version-update:semver-patch - dependency-name: com.fasterxml.jackson.core:jackson-annotations dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-dependencies-bom/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 62d6b32749..9c7a949730 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -184,7 +184,7 @@ 2.0.6 5.4.3 2.10.1 - 2.15.1 + 2.15.2 1.6 6.1.26 2.0 From 2227f0b4aafc78b9fc2f6643d715a81fc558bd06 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Jun 2023 17:37:33 +0800 Subject: [PATCH 21/30] Bump testcontainers from 1.18.1 to 1.18.3 (#12456) Bumps [testcontainers](https://github.com/testcontainers/testcontainers-java) from 1.18.1 to 1.18.3. - [Release notes](https://github.com/testcontainers/testcontainers-java/releases) - [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md) - [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.18.1...1.18.3) --- updated-dependencies: - dependency-name: org.testcontainers:testcontainers dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- dubbo-config/dubbo-config-api/pom.xml | 2 +- dubbo-dependencies-bom/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml index bd2b6b2422..fec3459350 100644 --- a/dubbo-config/dubbo-config-api/pom.xml +++ b/dubbo-config/dubbo-config-api/pom.xml @@ -229,7 +229,7 @@ org.testcontainers testcontainers - 1.18.1 + 1.18.3 test diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml index 9c7a949730..446cbae787 100644 --- a/dubbo-dependencies-bom/pom.xml +++ b/dubbo-dependencies-bom/pom.xml @@ -174,7 +174,7 @@ 2.2.7 1.2.0 - 1.18.1 + 1.18.3 0.7.5 3.2.13 1.6.11 From c8ef10e8a5cc6d470aa66125887c2d39ded97947 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Tue, 6 Jun 2023 19:39:50 +0800 Subject: [PATCH 22/30] Check if return AsyncRpcResult in Filter (#12467) * Check if return AsyncRpcResult in Filter * Fix compatible --- .../dubbo/rpc/cluster/filter/FilterChainBuilder.java | 9 +++++++++ .../src/main/java/com/alibaba/dubbo/rpc/Filter.java | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java index a837724819..815f8821dd 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/filter/FilterChainBuilder.java @@ -21,6 +21,7 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.SPI; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.BaseFilter; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; @@ -36,6 +37,7 @@ import java.util.List; import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.LoggerCodeConstants.CLUSTER_EXECUTE_FILTER_EXCEPTION; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.INTERNAL_ERROR; import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION; @SPI(value = "default", scope = APPLICATION) @@ -294,6 +296,7 @@ public interface FilterChainBuilder { @Experimental("Works for the same purpose as FilterChainNode, replace FilterChainNode with this one when proved stable enough") class CopyOfFilterChainNode, FILTER extends BaseFilter> implements Invoker { + private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(CopyOfFilterChainNode.class); TYPE originalInvoker; Invoker nextNode; FILTER filter; @@ -329,6 +332,12 @@ public interface FilterChainBuilder { try { InvocationProfilerUtils.enterDetailProfiler(invocation, () -> "Filter " + filter.getClass().getName() + " invoke."); asyncResult = filter.invoke(nextNode, invocation); + if (!(asyncResult instanceof AsyncRpcResult)) { + String msg = "The result of filter invocation must be AsyncRpcResult. (If you want to recreate a result, please use AsyncRpcResult.newDefaultAsyncResult.) " + + "Filter class: " + filter.getClass().getName() + ". Result class: " + asyncResult.getClass().getName() + "."; + LOGGER.error(INTERNAL_ERROR, "", "", msg); + throw new RpcException(msg); + } } catch (Exception e) { InvocationProfilerUtils.releaseDetailProfiler(invocation); if (filter instanceof ListenableFilter) { diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java index fa33393123..c196baa517 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Filter.java @@ -35,7 +35,7 @@ public interface Filter extends org.apache.dubbo.rpc.Filter { new Invocation.CompatibleInvocation(invocation)); if (invokeResult instanceof Result.CompatibleResult) { - return invokeResult; + return ((Result.CompatibleResult) invokeResult).getDelegate(); } AsyncRpcResult asyncRpcResult = AsyncRpcResult.newDefaultAsyncResult(invocation); From 00d8a46cd54dff3687f32ade67c0bcddc3285e07 Mon Sep 17 00:00:00 2001 From: icodening Date: Wed, 7 Jun 2023 11:01:33 +0800 Subject: [PATCH 23/30] support catch actual exception (#12446) --- .../tri/stream/TripleClientStream.java | 3 +-- .../tri/transport/TripleWriteQueue.java | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java index ab5816a34a..99f993566d 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/stream/TripleClientStream.java @@ -120,7 +120,6 @@ public class TripleClientStream extends AbstractStream implements ClientStream { Channel channel = ctx.channel(); channel.pipeline().addLast(new TripleCommandOutBoundHandler()); channel.pipeline().addLast(new TripleHttp2ClientResponseHandler(createTransportListener())); - channel.closeFuture().addListener(f -> transportException(f.cause())); } }); CreateStreamQueueCommand cmd = CreateStreamQueueCommand.create(bootstrap, streamChannelFuture); @@ -149,7 +148,7 @@ public class TripleClientStream extends AbstractStream implements ClientStream { private void transportException(Throwable cause) { final TriRpcStatus status = TriRpcStatus.INTERNAL.withDescription("Http2 exception") .withCause(cause); - listener.onComplete(status, null); + listener.onComplete(status, null, null, false); } public ChannelFuture cancelByLocal(TriRpcStatus status) { diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java index acbe859267..c659e9e708 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleWriteQueue.java @@ -23,6 +23,7 @@ import io.netty.channel.ChannelPromise; import org.apache.dubbo.common.BatchExecutorQueue; import org.apache.dubbo.rpc.protocol.tri.command.QueuedCommand; +import java.util.concurrent.CompletionException; import java.util.concurrent.Executor; public class TripleWriteQueue extends BatchExecutorQueue { @@ -55,13 +56,22 @@ public class TripleWriteQueue extends BatchExecutorQueue { @Override protected void prepare(QueuedCommand item) { - item.run(item.channel()); + try { + Channel channel = item.channel(); + item.run(channel); + } catch (CompletionException e) { + item.promise().tryFailure(e.getCause()); + } } @Override protected void flush(QueuedCommand item) { - Channel channel = item.channel(); - item.run(channel); - channel.flush(); + try { + Channel channel = item.channel(); + item.run(channel); + channel.flush(); + } catch (CompletionException e) { + item.promise().tryFailure(e.getCause()); + } } } From eba976fec63eb1ccbedd5751162e2f2a888391df Mon Sep 17 00:00:00 2001 From: icodening Date: Wed, 7 Jun 2023 11:03:26 +0800 Subject: [PATCH 24/30] reset all active stream on connection close (#12451) * reset all active stream on connection close * reset all active stream on connection close --- .../tri/call/BiStreamServerCallListener.java | 2 +- .../transport/TripleServerConnectionHandler.java | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/BiStreamServerCallListener.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/BiStreamServerCallListener.java index 8a7f169e9c..754ef77f3c 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/BiStreamServerCallListener.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/call/BiStreamServerCallListener.java @@ -52,7 +52,7 @@ public class BiStreamServerCallListener extends AbstractServerCallListener { @Override public void onCancel(TriRpcStatus status) { - responseObserver.onError(status.asException()); + requestObserver.onError(status.asException()); } diff --git a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleServerConnectionHandler.java b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleServerConnectionHandler.java index 7aefff58fc..9703cb287b 100644 --- a/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleServerConnectionHandler.java +++ b/dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/transport/TripleServerConnectionHandler.java @@ -17,6 +17,8 @@ package org.apache.dubbo.rpc.protocol.tri.transport; +import io.netty.handler.codec.http2.DefaultHttp2ResetFrame; +import io.netty.handler.codec.http2.Http2Error; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -67,6 +69,17 @@ public class TripleServerConnectionHandler extends Http2ChannelDuplexHandler { } } + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + super.channelInactive(ctx); + //reset all active stream on connection close + forEachActiveStream(stream -> { + DefaultHttp2ResetFrame resetFrame = new DefaultHttp2ResetFrame(Http2Error.NO_ERROR).stream(stream); + ctx.fireChannelRead(resetFrame); + return true; + }); + } + private boolean isQuiteException(Throwable t) { if (QUIET_EXCEPTIONS_CLASS.contains(t.getClass())) { return true; From ba308219c60e9faa943d85b1bbbbe0b7d1be30df Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Wed, 7 Jun 2023 13:49:49 +0800 Subject: [PATCH 25/30] Register services after module started (#12450) --- .../common/deploy/ApplicationDeployer.java | 5 + .../dubbo/config/ServiceConfigBase.java | 7 +- .../java/com/alibaba/dubbo/rpc/Exporter.java | 7 ++ .../apache/dubbo/config/ServiceConfig.java | 59 +++++++---- .../deploy/DefaultApplicationDeployer.java | 11 ++ .../config/deploy/DefaultModuleDeployer.java | 46 ++++++-- ...ryCenterExportProviderIntegrationTest.java | 4 +- .../JavaConfigReferenceBeanTest.java | 2 +- .../integration/RegistryProtocol.java | 100 ++++++++++++++---- .../java/org/apache/dubbo/rpc/Exporter.java | 5 + .../rpc/listener/ListenerExporterWrapper.java | 5 + .../dubbo/rpc/protocol/AbstractExporter.java | 5 + .../rpc/protocol/injvm/InjvmProtocol.java | 10 +- 13 files changed, 208 insertions(+), 58 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/deploy/ApplicationDeployer.java b/dubbo-common/src/main/java/org/apache/dubbo/common/deploy/ApplicationDeployer.java index 7cdd356872..0b0b9d4509 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/deploy/ApplicationDeployer.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/deploy/ApplicationDeployer.java @@ -89,6 +89,11 @@ public interface ApplicationDeployer extends Deployer { */ void notifyModuleChanged(ModuleModel moduleModel, DeployState state); + /** + * refresh service instance + */ + void refreshServiceInstance(); + /** * Increase the count of service update threads. * NOTE: should call ${@link ApplicationDeployer#decreaseServiceRefreshCount()} after update finished diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java index 78e6bf1c16..0db03d0208 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ServiceConfigBase.java @@ -415,7 +415,9 @@ public abstract class ServiceConfigBase extends AbstractServiceConfig { /** * export service and auto start application instance */ - public abstract void export(); + public final void export() { + export(true); + } public abstract void unexport(); @@ -423,4 +425,7 @@ public abstract class ServiceConfigBase extends AbstractServiceConfig { public abstract boolean isUnexported(); + public abstract void export(boolean register); + + public abstract void register(); } diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Exporter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Exporter.java index 5da68a3b20..d89fe3aa5c 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Exporter.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Exporter.java @@ -23,6 +23,8 @@ public interface Exporter extends org.apache.dubbo.rpc.Exporter { @Override Invoker getInvoker(); + default void register() {} + default void unregister() {} class CompatibleExporter implements Exporter { @@ -43,6 +45,11 @@ public interface Exporter extends org.apache.dubbo.rpc.Exporter { delegate.unexport(); } + @Override + public void register() { + delegate.register(); + } + @Override public void unregister() { delegate.unregister(); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java index 291296240b..7fad3c8359 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java @@ -280,7 +280,7 @@ public class ServiceConfig extends ServiceConfigBase { } @Override - public void export() { + public void export(boolean register) { if (this.exported) { return; } @@ -300,19 +300,37 @@ public class ServiceConfig extends ServiceConfigBase { this.init(); if (shouldDelay()) { - doDelayExport(); + // should register if delay export + doDelayExport(true); } else { - doExport(); + doExport(register); } } } } - protected void doDelayExport() { + @Override + public void register() { + if (!this.exported) { + return; + } + + synchronized (this) { + if (!this.exported) { + return; + } + + for (Exporter exporter : exporters) { + exporter.register(); + } + } + } + + protected void doDelayExport(boolean register) { ExecutorRepository.getInstance(getScopeModel().getApplicationModel()).getServiceExportExecutor() .schedule(() -> { try { - doExport(); + doExport(register); } catch (Exception e) { logger.error(CONFIG_FAILED_EXPORT_SERVICE, "configuration server disconnected", "", "Failed to (async)export service config: " + interfaceName, e); } @@ -439,7 +457,7 @@ public class ServiceConfig extends ServiceConfigBase { checkAndUpdateSubConfigs(); } - protected synchronized void doExport() { + protected synchronized void doExport(boolean register) { if (unexported) { throw new IllegalStateException("The service " + interfaceClass.getName() + " has already unexported!"); } @@ -450,12 +468,12 @@ public class ServiceConfig extends ServiceConfigBase { if (StringUtils.isEmpty(path)) { path = interfaceName; } - doExportUrls(); + doExportUrls(register); exported(); } @SuppressWarnings({"unchecked", "rawtypes"}) - private void doExportUrls() { + private void doExportUrls(boolean register) { ModuleServiceRepository repository = getScopeModel().getServiceRepository(); ServiceDescriptor serviceDescriptor; final boolean serverService = ref instanceof ServerService; @@ -490,7 +508,7 @@ public class ServiceConfig extends ServiceConfigBase { // In case user specified path, register service one more time to map it to path. repository.registerService(pathKey, interfaceClass); } - doExportUrlsFor1Protocol(protocolConfig, registryURLs); + doExportUrlsFor1Protocol(protocolConfig, registryURLs, register); } return null; } @@ -499,7 +517,7 @@ public class ServiceConfig extends ServiceConfigBase { providerModel.setServiceUrls(urls); } - private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List registryURLs) { + private void doExportUrlsFor1Protocol(ProtocolConfig protocolConfig, List registryURLs, boolean register) { Map map = buildAttributes(protocolConfig); // remove null key and null value @@ -511,7 +529,7 @@ public class ServiceConfig extends ServiceConfigBase { processServiceExecutor(url); - exportUrl(url, registryURLs); + exportUrl(url, registryURLs, register); } private void processServiceExecutor(URL url) { @@ -695,7 +713,7 @@ public class ServiceConfig extends ServiceConfigBase { return url; } - private void exportUrl(URL url, List registryURLs) { + private void exportUrl(URL url, List registryURLs, boolean register) { String scope = url.getParameter(SCOPE_KEY); // don't export when none is configured if (!SCOPE_NONE.equalsIgnoreCase(scope)) { @@ -719,7 +737,7 @@ public class ServiceConfig extends ServiceConfigBase { build(); } - url = exportRemote(url, registryURLs); + url = exportRemote(url, registryURLs, register); if (!isGeneric(generic) && !getScopeModel().isInternal()) { MetadataUtils.publishServiceDefinition(url, providerModel.getServiceModel(), getApplicationModel()); } @@ -734,7 +752,7 @@ public class ServiceConfig extends ServiceConfigBase { URL localUrl = URLBuilder.from(url). setProtocol(protocol). build(); - localUrl = exportRemote(localUrl, registryURLs); + localUrl = exportRemote(localUrl, registryURLs, register); if (!isGeneric(generic) && !getScopeModel().isInternal()) { MetadataUtils.publishServiceDefinition(localUrl, providerModel.getServiceModel(), getApplicationModel()); } @@ -746,7 +764,7 @@ public class ServiceConfig extends ServiceConfigBase { this.urls.add(url); } - private URL exportRemote(URL url, List registryURLs) { + private URL exportRemote(URL url, List registryURLs, boolean register) { if (CollectionUtils.isNotEmpty(registryURLs)) { for (URL registryURL : registryURLs) { if (SERVICE_REGISTRY_PROTOCOL.equals(registryURL.getProtocol())) { @@ -778,7 +796,7 @@ public class ServiceConfig extends ServiceConfigBase { } } - doExportUrl(registryURL.putAttribute(EXPORT_KEY, url), true); + doExportUrl(registryURL.putAttribute(EXPORT_KEY, url), true, register); } } else { @@ -787,7 +805,7 @@ public class ServiceConfig extends ServiceConfigBase { logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url); } - doExportUrl(url, true); + doExportUrl(url, true, register); } @@ -795,7 +813,10 @@ public class ServiceConfig extends ServiceConfigBase { } @SuppressWarnings({"unchecked", "rawtypes"}) - private void doExportUrl(URL url, boolean withMetaData) { + private void doExportUrl(URL url, boolean withMetaData, boolean register) { + if (!register) { + url = url.addParameter(REGISTER_KEY, false); + } Invoker invoker = proxyFactory.getInvoker(ref, (Class) interfaceClass, url); if (withMetaData) { invoker = new DelegateProviderMetaDataInvoker(invoker, this); @@ -817,7 +838,7 @@ public class ServiceConfig extends ServiceConfigBase { local = local.setScopeModel(getScopeModel()) .setServiceModel(providerModel); local = local.addParameter(EXPORTER_LISTENER_KEY, LOCAL_PROTOCOL); - doExportUrl(local, false); + doExportUrl(local, false, true); logger.info("Export dubbo service " + interfaceClass.getName() + " to local registry url : " + local); } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java index 06579caa9b..ca597f2ee9 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java @@ -936,6 +936,17 @@ public class DefaultApplicationDeployer extends AbstractDeployer impleme // if no async export/refer services, just set started if (asyncExportingFutures.isEmpty() && asyncReferringFutures.isEmpty()) { + // publish module started event onModuleStarted(); + + // register services to registry + registerServices(); + + // complete module start future after application state changed + completeStartFuture(true); } else { frameworkExecutorRepository.getSharedExecutor().submit(() -> { try { @@ -182,17 +189,27 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme waitExportFinish(); // wait for refer finish waitReferFinish(); + + // publish module started event + onModuleStarted(); + + // register services to registry + registerServices(); } catch (Throwable e) { logger.warn(CONFIG_FAILED_WAIT_EXPORT_REFER, "", "", "wait for export/refer services occurred an exception", e); + onModuleFailed(getIdentifier() + " start failed: " + e, e); } finally { - onModuleStarted(); + // complete module start future after application state changed + completeStartFuture(true); } }); } + } catch (Throwable e) { onModuleFailed(getIdentifier() + " start failed: " + e, e); throw e; } + return startFuture; } @@ -300,16 +317,11 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme } private void onModuleStarted() { - try { if (isStarting()) { setStarted(); logger.info(getIdentifier() + " has started."); applicationDeployer.notifyModuleChanged(moduleModel, DeployState.STARTED); } - } finally { - // complete module start future after application state changed - completeStartFuture(true); - } } private void onModuleFailed(String msg, Throwable ex) { @@ -366,6 +378,15 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme } } + private void registerServices() { + for (ServiceConfigBase sc : configManager.getServices()) { + if (!Boolean.FALSE.equals(sc.isRegister())) { + registerServiceInternal(sc); + } + } + applicationDeployer.refreshServiceInstance(); + } + private void exportServiceInternal(ServiceConfigBase sc) { ServiceConfig serviceConfig = (ServiceConfig) sc; if (!serviceConfig.isRefreshed()) { @@ -390,12 +411,23 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme asyncExportingFutures.add(future); } else { if (!sc.isExported()) { - sc.export(); + sc.export(false); exportedServices.add(sc); } } } + private void registerServiceInternal(ServiceConfigBase sc) { + ServiceConfig serviceConfig = (ServiceConfig) sc; + if (!serviceConfig.isRefreshed()) { + serviceConfig.refresh(); + } + if (!sc.isExported()) { + return; + } + sc.register(); + } + private void unexportServices() { exportedServices.forEach(sc -> { try { diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/integration/multiple/exportprovider/MultipleRegistryCenterExportProviderIntegrationTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/integration/multiple/exportprovider/MultipleRegistryCenterExportProviderIntegrationTest.java index bbf5277ebc..7ed2e63358 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/integration/multiple/exportprovider/MultipleRegistryCenterExportProviderIntegrationTest.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/integration/multiple/exportprovider/MultipleRegistryCenterExportProviderIntegrationTest.java @@ -188,7 +188,7 @@ class MultipleRegistryCenterExportProviderIntegrationTest implements Integration // 1. InjvmExporter // 2. DubboExporter with service-discovery-registry protocol // 3. DubboExporter with registry protocol - Assertions.assertEquals(exporterListener.getExportedExporters().size(), 3); + Assertions.assertEquals(exporterListener.getExportedExporters().size(), 5); // The exported exporter contains MultipleRegistryCenterExportProviderFilter Assertions.assertTrue(exporterListener.getFilters().contains(filter)); @@ -244,4 +244,4 @@ class MultipleRegistryCenterExportProviderIntegrationTest implements Integration logger.info(getClass().getSimpleName() + " testcase is ending..."); registryProtocolListener = null; } -} \ No newline at end of file +} diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java index d951dd03df..2d020d8c8b 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/reference/javaconfig/JavaConfigReferenceBeanTest.java @@ -447,7 +447,7 @@ class JavaConfigReferenceBeanTest { } @Bean - @Reference(group = "${myapp.group}", interfaceName = "org.apache.dubbo.config.spring.api.LocalMissClass") + @DubboReference(group = "${myapp.group}", interfaceName = "org.apache.dubbo.config.spring.api.LocalMissClass", scope = "local") public ReferenceBean genericServiceWithoutInterface() { return new ReferenceBean(); } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java index c0b3dc116d..33f872ac75 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryProtocol.java @@ -70,6 +70,7 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; +import java.util.stream.Collectors; import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY; import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; @@ -162,8 +163,8 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { private final Map serviceConfigurationListeners = new ConcurrentHashMap<>(); //To solve the problem of RMI repeated exposure port conflicts, the services that have been exposed are no longer exposed. - //provider url <--> exporter - private final ConcurrentMap> bounds = new ConcurrentHashMap<>(); + //provider url <--> registry url <--> exporter + private final Map>> bounds = new ConcurrentHashMap<>(); protected Protocol protocol; protected ProxyFactory proxyFactory; @@ -217,7 +218,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { return map; } - private void register(Registry registry, URL registeredProviderUrl) { + private static void register(Registry registry, URL registeredProviderUrl) { ApplicationDeployer deployer = registeredProviderUrl.getOrDefaultApplicationModel().getDeployer(); try { deployer.increaseServiceRefreshCount(); @@ -272,6 +273,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { exporter.setRegisterUrl(registeredProviderUrl); exporter.setSubscribeUrl(overrideSubscribeUrl); exporter.setNotifyListener(overrideSubscribeListener); + exporter.setRegistered(register); ApplicationModel applicationModel = getApplicationModel(providerUrl.getScopeModel()); if (applicationModel.getModelEnvironment().getConfiguration().convert(Boolean.class, ENABLE_26X_CONFIGURATION_LISTEN, true)) { @@ -308,12 +310,14 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { @SuppressWarnings("unchecked") private ExporterChangeableWrapper doLocalExport(final Invoker originInvoker, URL providerUrl) { - String key = getCacheKey(originInvoker); + String providerUrlKey = getProviderUrlKey(originInvoker); + String registryUrlKey = getRegistryUrlKey(originInvoker); - return (ExporterChangeableWrapper) bounds.computeIfAbsent(key, s -> { - Invoker invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl); - return new ExporterChangeableWrapper<>((Exporter) protocol.export(invokerDelegate), originInvoker); - }); + return (ExporterChangeableWrapper) bounds.computeIfAbsent(providerUrlKey, _k -> new ConcurrentHashMap<>()) + .computeIfAbsent(registryUrlKey, s ->{ + Invoker invokerDelegate = new InvokerDelegate<>(originInvoker, providerUrl); + return new ExporterChangeableWrapper<>((Exporter) protocol.export(invokerDelegate), originInvoker); + }); } public void reExport(Exporter exporter, URL newInvokerUrl) { @@ -333,8 +337,18 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { */ @SuppressWarnings("unchecked") public void reExport(final Invoker originInvoker, URL newInvokerUrl) { - String key = getCacheKey(originInvoker); - ExporterChangeableWrapper exporter = (ExporterChangeableWrapper) bounds.get(key); + String providerUrlKey = getProviderUrlKey(originInvoker); + String registryUrlKey = getRegistryUrlKey(originInvoker); + Map> registryMap = bounds.get(providerUrlKey); + if (registryMap == null) { + logger.warn(INTERNAL_ERROR, "error state, exporterMap can not be null", "", "error state, exporterMap can not be null", new IllegalStateException("error state, exporterMap can not be null")); + return; + } + ExporterChangeableWrapper exporter = (ExporterChangeableWrapper) registryMap.get(registryUrlKey); + if (exporter == null) { + logger.warn(INTERNAL_ERROR, "error state, exporterMap can not be null", "", "error state, exporterMap can not be null", new IllegalStateException("error state, exporterMap can not be null")); + return; + } URL registeredUrl = exporter.getRegisterUrl(); URL registryUrl = getRegistryUrl(originInvoker); @@ -369,7 +383,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { private void doReExport(final Invoker originInvoker, ExporterChangeableWrapper exporter, URL registryUrl, URL oldProviderUrl, URL newProviderUrl) { - if (getProviderUrl(originInvoker).getParameter(REGISTER_KEY, true)) { + if (exporter.isRegistered()) { Registry registry; try { registry = getRegistry(getRegistryUrl(originInvoker)); @@ -480,12 +494,18 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { * @param originInvoker * @return */ - private String getCacheKey(final Invoker originInvoker) { + private String getProviderUrlKey(final Invoker originInvoker) { URL providerUrl = getProviderUrl(originInvoker); String key = providerUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString(); return key; } + private String getRegistryUrlKey(final Invoker originInvoker) { + URL registryUrl = getRegistryUrl(originInvoker); + String key = registryUrl.removeParameters(DYNAMIC_KEY, ENABLED_KEY).toFullString(); + return key; + } + @Override @SuppressWarnings("unchecked") public Invoker refer(Class type, URL url) throws RpcException { @@ -653,7 +673,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { } } - List> exporters = new ArrayList<>(bounds.values()); + List> exporters = bounds.values().stream().flatMap(e -> e.values().stream()).collect(Collectors.toList()); for (Exporter exporter : exporters) { exporter.unexport(); } @@ -712,6 +732,11 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { exporter.unexport(); } + @Override + public void register() { + exporter.register(); + } + @Override public void unregister() { exporter.unregister(); @@ -777,8 +802,14 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { } //The origin invoker URL originUrl = RegistryProtocol.this.getProviderUrl(invoker); - String key = getCacheKey(originInvoker); - ExporterChangeableWrapper exporter = bounds.get(key); + String providerUrlKey = getProviderUrlKey(originInvoker); + String registryUrlKey = getRegistryUrlKey(originInvoker); + Map> exporterMap = bounds.get(providerUrlKey); + if (exporterMap == null) { + logger.warn(INTERNAL_ERROR, "error state, exporterMap can not be null", "", "error state, exporterMap can not be null", new IllegalStateException("error state, exporterMap can not be null")); + return; + } + ExporterChangeableWrapper exporter = exporterMap.get(registryUrlKey); if (exporter == null) { logger.warn(INTERNAL_ERROR, "unknown error in registry module", "", "error state, exporter should not be null", new IllegalStateException("error state, exporter should not be null")); return; @@ -920,7 +951,7 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { private URL registerUrl; private NotifyListener notifyListener; - private final AtomicBoolean unregistered = new AtomicBoolean(false); + private final AtomicBoolean registered = new AtomicBoolean(false); public ExporterChangeableWrapper(Exporter exporter, Invoker originInvoker) { this.exporter = exporter; @@ -943,9 +974,28 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { this.exporter = exporter; } + @Override + public void register() { + if (registered.compareAndSet(false, true)) { + URL registryUrl = getRegistryUrl(originInvoker); + Registry registry = getRegistry(registryUrl); + RegistryProtocol.register(registry, getRegisterUrl()); + + ProviderModel providerModel = frameworkModel.getServiceRepository() + .lookupExportedService(getRegisterUrl().getServiceKey()); + + List statedUrls = providerModel.getStatedUrl(); + statedUrls.stream() + .filter(u -> u.getRegistryUrl().equals(registryUrl) + && u.getProviderUrl().getProtocol().equals(getRegisterUrl().getProtocol())) + .forEach(u -> u.setRegistered(true)); + logger.info("Registered dubbo service " + getRegisterUrl().getServiceKey() + " url " + getRegisterUrl() + " to registry " + registryUrl); + } + } + @Override public synchronized void unregister() { - if (unregistered.compareAndSet(false, true)) { + if (registered.compareAndSet(true, false)) { Registry registry = RegistryProtocol.this.getRegistry(getRegistryUrl(originInvoker)); try { registry.unregister(registerUrl); @@ -987,13 +1037,25 @@ public class RegistryProtocol implements Protocol, ScopeModelAware { @Override public synchronized void unexport() { - String key = getCacheKey(this.originInvoker); - bounds.remove(key); + String providerUrlKey = getProviderUrlKey(this.originInvoker); + String registryUrlKey = getRegistryUrlKey(this.originInvoker); + Map> exporterMap = bounds.remove(providerUrlKey); + if (exporterMap != null) { + exporterMap.remove(registryUrlKey); + } unregister(); doUnExport(); } + public void setRegistered(boolean registered) { + this.registered.set(registered); + } + + public boolean isRegistered() { + return registered.get(); + } + private void doUnExport() { try { exporter.unexport(); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Exporter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Exporter.java index 9b87ddb5d9..fd3d58bc8e 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Exporter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Exporter.java @@ -41,6 +41,11 @@ public interface Exporter { */ void unexport(); + /** + * register to registry + */ + void register(); + /** * unregister from registry */ diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerExporterWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerExporterWrapper.java index 025459588d..b5eb3c52cb 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerExporterWrapper.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerExporterWrapper.java @@ -62,6 +62,11 @@ public class ListenerExporterWrapper implements Exporter { } } + @Override + public void register() { + exporter.register(); + } + @Override public void unregister() { exporter.unregister(); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractExporter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractExporter.java index b7f6c03e30..a9fd653bfa 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractExporter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractExporter.java @@ -60,6 +60,11 @@ public abstract class AbstractExporter implements Exporter { afterUnExport(); } + @Override + public void register() { + + } + @Override public void unregister() { diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java index 46fc957e66..9f361054f3 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java @@ -25,7 +25,6 @@ import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.model.ScopeModel; import org.apache.dubbo.rpc.protocol.AbstractProtocol; -import org.apache.dubbo.rpc.support.ProtocolUtils; import java.util.Map; @@ -66,14 +65,7 @@ public class InjvmProtocol extends AbstractProtocol { } } - if (result == null) { - return null; - } else if (ProtocolUtils.isGeneric( - result.getInvoker().getUrl().getParameter(GENERIC_KEY))) { - return null; - } else { - return result; - } + return result; } @Override From 9af6fbf1d0d1456c18bd23bc10e447589616e98c Mon Sep 17 00:00:00 2001 From: conghuhu <56248584+conghuhu@users.noreply.github.com> Date: Wed, 7 Jun 2023 15:54:40 +0800 Subject: [PATCH 26/30] feat: add Duration as SIMPLE_TYPE (#12469) --- .../convert/StringToDurationConverter.java | 243 ++++++++++++++++++ .../apache/dubbo/common/utils/ClassUtils.java | 4 +- .../dubbo/config/context/ConfigManager.java | 1 + .../org.apache.dubbo.common.convert.Converter | 3 +- .../StringToDurationConverterTest.java | 62 +++++ 5 files changed, 311 insertions(+), 2 deletions(-) create mode 100644 dubbo-common/src/main/java/org/apache/dubbo/common/convert/StringToDurationConverter.java create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDurationConverterTest.java diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/convert/StringToDurationConverter.java b/dubbo-common/src/main/java/org/apache/dubbo/common/convert/StringToDurationConverter.java new file mode 100644 index 0000000000..edd1cf297f --- /dev/null +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/convert/StringToDurationConverter.java @@ -0,0 +1,243 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.common.convert; + +import org.apache.dubbo.common.utils.Assert; +import org.apache.dubbo.common.utils.StringUtils; + +import java.time.Duration; +import java.time.temporal.ChronoUnit; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty; + +public class StringToDurationConverter implements StringConverter { + + @Override + public Duration convert(String source) { + return isNotEmpty(source) ? DurationStyle.detectAndParse(source) : null; + } + + @Override + public int getPriority() { + return NORMAL_PRIORITY + 10; + } + + /** + * @author Phillip Webb + * @author Valentine Wu + * @link {org.springframework.boot.convert.DurationStyle} + */ + enum DurationStyle { + + /** + * Simple formatting, for example '1s'. + */ + SIMPLE("^([+-]?\\d+)([a-zA-Z]{0,2})$") { + @Override + public Duration parse(String value, ChronoUnit unit) { + try { + Matcher matcher = matcher(value); + Assert.assertTrue(matcher.matches(), "Does not match simple duration pattern"); + String suffix = matcher.group(2); + return (StringUtils.isNotBlank(suffix) ? TimeUnit.fromSuffix(suffix) : TimeUnit.fromChronoUnit(unit)) + .parse(matcher.group(1)); + } catch (Exception ex) { + throw new IllegalArgumentException("'" + value + "' is not a valid simple duration", ex); + } + } + + }, + + /** + * ISO-8601 formatting. + */ + ISO8601("^[+-]?[pP].*$") { + @Override + public Duration parse(String value, ChronoUnit unit) { + try { + return Duration.parse(value); + } catch (Exception ex) { + throw new IllegalArgumentException("'" + value + "' is not a valid ISO-8601 duration", ex); + } + } + + }; + + private final Pattern pattern; + + DurationStyle(String pattern) { + this.pattern = Pattern.compile(pattern); + } + + protected final boolean matches(String value) { + return this.pattern.matcher(value).matches(); + } + + protected final Matcher matcher(String value) { + return this.pattern.matcher(value); + } + + /** + * Parse the given value to a duration. + * + * @param value the value to parse + * @return a duration + */ + public Duration parse(String value) { + return parse(value, null); + } + + /** + * Parse the given value to a duration. + * + * @param value the value to parse + * @param unit the duration unit to use if the value doesn't specify one ({@code null} + * will default to ms) + * @return a duration + */ + public abstract Duration parse(String value, ChronoUnit unit); + + /** + * Detect the style then parse the value to return a duration. + * + * @param value the value to parse + * @return the parsed duration + * @throws IllegalArgumentException if the value is not a known style or cannot be + * parsed + */ + public static Duration detectAndParse(String value) { + return detectAndParse(value, null); + } + + /** + * Detect the style then parse the value to return a duration. + * + * @param value the value to parse + * @param unit the duration unit to use if the value doesn't specify one ({@code null} + * will default to ms) + * @return the parsed duration + * @throws IllegalArgumentException if the value is not a known style or cannot be + * parsed + */ + public static Duration detectAndParse(String value, ChronoUnit unit) { + return detect(value).parse(value, unit); + } + + /** + * Detect the style from the given source value. + * + * @param value the source value + * @return the duration style + * @throws IllegalArgumentException if the value is not a known style + */ + public static DurationStyle detect(String value) { + Assert.notNull(value, "Value must not be null"); + for (DurationStyle candidate : values()) { + if (candidate.matches(value)) { + return candidate; + } + } + throw new IllegalArgumentException("'" + value + "' is not a valid duration"); + } + + /** + * Time Unit that support. + */ + enum TimeUnit { + + /** + * Nanoseconds. + */ + NANOS(ChronoUnit.NANOS, "ns", Duration::toNanos), + + /** + * Microseconds. + */ + MICROS(ChronoUnit.MICROS, "us", (duration) -> duration.toNanos() / 1000L), + + /** + * Milliseconds. + */ + MILLIS(ChronoUnit.MILLIS, "ms", Duration::toMillis), + + /** + * Seconds. + */ + SECONDS(ChronoUnit.SECONDS, "s", Duration::getSeconds), + + /** + * Minutes. + */ + MINUTES(ChronoUnit.MINUTES, "m", Duration::toMinutes), + + /** + * Hours. + */ + HOURS(ChronoUnit.HOURS, "h", Duration::toHours), + + /** + * Days. + */ + DAYS(ChronoUnit.DAYS, "d", Duration::toDays); + + private final ChronoUnit chronoUnit; + + private final String suffix; + + private final Function longValue; + + TimeUnit(ChronoUnit chronoUnit, String suffix, Function toUnit) { + this.chronoUnit = chronoUnit; + this.suffix = suffix; + this.longValue = toUnit; + } + + public Duration parse(String value) { + return Duration.of(Long.parseLong(value), this.chronoUnit); + } + + public long longValue(Duration value) { + return this.longValue.apply(value); + } + + public static TimeUnit fromChronoUnit(ChronoUnit chronoUnit) { + if (chronoUnit == null) { + return TimeUnit.MILLIS; + } + for (TimeUnit candidate : values()) { + if (candidate.chronoUnit == chronoUnit) { + return candidate; + } + } + throw new IllegalArgumentException("Unknown unit " + chronoUnit); + } + + public static TimeUnit fromSuffix(String suffix) { + for (TimeUnit candidate : values()) { + if (candidate.suffix.equalsIgnoreCase(suffix)) { + return candidate; + } + } + throw new IllegalArgumentException("Unknown unit '" + suffix + "'"); + } + + } + } +} diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java index d07d01f3a5..845296e98a 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java @@ -24,6 +24,7 @@ import java.lang.reflect.Array; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.BigInteger; +import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -87,7 +88,8 @@ public class ClassUtils { BigDecimal.class, BigInteger.class, Date.class, - Object.class + Object.class, + Duration.class ); /** * Prefix for internal array class names: "[L" diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java index ec7629bbf6..e737e8971e 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/context/ConfigManager.java @@ -254,6 +254,7 @@ public class ConfigManager extends AbstractConfigManager implements ApplicationE // load dubbo.metrics.xxx loadConfigsOfTypeFromProps(MetricsConfig.class); + //load dubbo.tracing.xxx loadConfigsOfTypeFromProps(TracingConfig.class); // load multiple config types: diff --git a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.convert.Converter b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.convert.Converter index abfd3d49b4..1f7b33ca20 100644 --- a/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.convert.Converter +++ b/dubbo-common/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.common.convert.Converter @@ -9,4 +9,5 @@ string-to-long=org.apache.dubbo.common.convert.StringToLongConverter string-to-optional=org.apache.dubbo.common.convert.StringToOptionalConverter string-to-short=org.apache.dubbo.common.convert.StringToShortConverter string-to-string=org.apache.dubbo.common.convert.StringToStringConverter -string-to-byte=org.apache.dubbo.common.convert.StringToByteConverter \ No newline at end of file +string-to-byte=org.apache.dubbo.common.convert.StringToByteConverter +string-to-duration=org.apache.dubbo.common.convert.StringToDurationConverter \ No newline at end of file diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDurationConverterTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDurationConverterTest.java new file mode 100644 index 0000000000..b8fe980dc0 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/convert/StringToDurationConverterTest.java @@ -0,0 +1,62 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.common.convert; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.time.Duration; + +import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * {@link StringToDurationConverter} Test + * + * @since 3.2.3 + */ +class StringToDurationConverterTest { + + private StringToDurationConverter converter; + + @BeforeEach + public void init() { + converter = (StringToDurationConverter) getExtensionLoader(Converter.class).getExtension("string-to-duration"); + } + + @Test + void testAccept() { + assertTrue(converter.accept(String.class, Duration.class)); + } + + @Test + void testConvert() { + assertEquals(Duration.ofMillis(1000), converter.convert("1000ms")); + assertEquals(Duration.ofSeconds(1), converter.convert("1s")); + assertEquals(Duration.ofMinutes(1), converter.convert("1m")); + assertEquals(Duration.ofHours(1), converter.convert("1h")); + assertEquals(Duration.ofDays(1), converter.convert("1d")); + + assertNull(converter.convert(null)); + assertThrows(IllegalArgumentException.class, () -> { + converter.convert("ttt"); + }); + } +} \ No newline at end of file From c4702142bffaf39d8a58578c35de89db65cf7bb6 Mon Sep 17 00:00:00 2001 From: TomlongTK Date: Wed, 7 Jun 2023 18:54:20 +0800 Subject: [PATCH 27/30] add metrics enable switch (#12389) * add metrics enable switch * default false * default false * set default true and fix unit test * xsd set default true * rename enabled to enableRpc * make enableRpc default value to true * fix camel name * remove default value --------- Co-authored-by: songxiaosheng --- .../apache/dubbo/config/MetricsConfig.java | 9 +++++++++ .../src/main/resources/META-INF/dubbo.xsd | 6 ++++++ .../dubbo/metrics/filter/MetricsFilter.java | 19 +++++++++++-------- .../metrics/filter/MetricsFilterTest.java | 1 - 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java index a7540dc63e..067833b2b0 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/MetricsConfig.java @@ -92,6 +92,7 @@ public class MetricsConfig extends AbstractConfig { */ private Boolean useGlobalRegistry; + private Boolean enableRpc; public MetricsConfig() { } @@ -214,4 +215,12 @@ public class MetricsConfig extends AbstractConfig { public void setUseGlobalRegistry(Boolean useGlobalRegistry) { this.useGlobalRegistry = useGlobalRegistry; } + + public Boolean getEnableRpc() { + return enableRpc; + } + + public void setEnableRpc(Boolean enableRpc) { + this.enableRpc = enableRpc; + } } diff --git a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd index ff36236df0..73e059465a 100644 --- a/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd +++ b/dubbo-config/dubbo-config-spring/src/main/resources/META-INF/dubbo.xsd @@ -1098,6 +1098,12 @@ + + + + + + diff --git a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java index 4b5cd74502..7b92276f33 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java +++ b/dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/filter/MetricsFilter.java @@ -19,6 +19,7 @@ package org.apache.dubbo.metrics.filter; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.config.MetricsConfig; import org.apache.dubbo.metrics.event.MetricsEventBus; import org.apache.dubbo.metrics.event.RequestEvent; import org.apache.dubbo.rpc.BaseFilter; @@ -40,20 +41,24 @@ import static org.apache.dubbo.metrics.DefaultConstants.METRIC_THROWABLE; public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAware { private ApplicationModel applicationModel; - private final static ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(MetricsFilter.class); + private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(MetricsFilter.class); + private boolean rpcMetricsEnable; @Override public void setApplicationModel(ApplicationModel applicationModel) { this.applicationModel = applicationModel; + this.rpcMetricsEnable = applicationModel.getApplicationConfigManager().getMetrics().map(MetricsConfig::getEnableRpc).orElse(true); } @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - try { - RequestEvent requestEvent = RequestEvent.toRequestEvent(applicationModel, invocation); - MetricsEventBus.before(requestEvent, () -> invocation.put(METRIC_FILTER_EVENT, requestEvent)); - } catch (Throwable t) { - LOGGER.warn(INTERNAL_ERROR, "", "", "Error occurred when invoke.", t); + if (rpcMetricsEnable) { + try { + RequestEvent requestEvent = RequestEvent.toRequestEvent(applicationModel, invocation); + MetricsEventBus.before(requestEvent, () -> invocation.put(METRIC_FILTER_EVENT, requestEvent)); + } catch (Throwable t) { + LOGGER.warn(INTERNAL_ERROR, "", "", "Error occurred when invoke.", t); + } } return invoker.invoke(invocation); } @@ -84,6 +89,4 @@ public class MetricsFilter implements Filter, BaseFilter.Listener, ScopeModelAwa } } - - } diff --git a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java index 488986afeb..76db78dfe0 100644 --- a/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java +++ b/dubbo-metrics/dubbo-metrics-default/src/test/java/org/apache/dubbo/metrics/filter/MetricsFilterTest.java @@ -82,7 +82,6 @@ class MetricsFilterTest { config.setName("MockMetrics"); applicationModel = ApplicationModel.defaultModel(); applicationModel.getApplicationConfigManager().setApplication(config); - invocation = new RpcInvocation(); filter = new MetricsFilter(); From 04d132fee1cf23f6c0eada7131c9b5ab18b8ded7 Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 8 Jun 2023 10:13:55 +0800 Subject: [PATCH 28/30] Check reference after register (#12472) * Check reference after register * Add logs * Fix method * Fix style * Fix remove * Fix remove --- .../dubbo/common/config/ReferenceCache.java | 12 +- .../dubbo/config/ReferenceConfigBase.java | 10 +- .../apache/dubbo/config/ReferenceConfig.java | 107 +++++++++++++----- .../config/deploy/DefaultModuleDeployer.java | 20 +++- .../config/utils/CompositeReferenceCache.java | 18 ++- .../config/utils/SimpleReferenceCache.java | 27 ++++- .../config/utils/MockReferenceConfig.java | 4 +- .../config/utils/XxxMockReferenceConfig.java | 4 +- 8 files changed, 160 insertions(+), 42 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ReferenceCache.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ReferenceCache.java index a7f23d9f22..c396fe0270 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/ReferenceCache.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/ReferenceCache.java @@ -22,7 +22,12 @@ import java.util.List; public interface ReferenceCache { @SuppressWarnings("unchecked") - T get(ReferenceConfigBase referenceConfig); + default T get(ReferenceConfigBase referenceConfig) { + return get(referenceConfig, true); + } + + @SuppressWarnings("unchecked") + T get(ReferenceConfigBase referenceConfig, boolean check); @SuppressWarnings("unchecked") T get(String key, Class type); @@ -36,6 +41,11 @@ public interface ReferenceCache { @SuppressWarnings("unchecked") T get(Class type); + @SuppressWarnings("unchecked") + void check(ReferenceConfigBase referenceConfig, long timeout); + + void check(String key, Class type, long timeout); + void destroy(String key, Class type); void destroy(Class type); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java index 867e195561..bfeacacba5 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/config/ReferenceConfigBase.java @@ -368,7 +368,15 @@ public abstract class ReferenceConfigBase extends AbstractReferenceConfig { } @Transient - public abstract T get(); + public abstract T get(boolean check); + + @Transient + public abstract void checkOrDestroy(long timeout); + + @Transient + public final T get() { + return get(true); + } public void destroy() { getModuleConfigManager().removeConfig(this); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java index fd2868864b..0794718538 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java @@ -19,6 +19,7 @@ package org.apache.dubbo.config; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.Version; import org.apache.dubbo.common.constants.CommonConstants; +import org.apache.dubbo.common.constants.LoggerCodeConstants; import org.apache.dubbo.common.constants.RegistryConstants; import org.apache.dubbo.common.extension.ExtensionLoader; import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; @@ -220,7 +221,7 @@ public class ReferenceConfig extends ReferenceConfigBase { @Override @Transient - public T get() { + public T get(boolean check) { if (destroyed) { throw new IllegalStateException("The invoker of ReferenceConfig(" + url + ") has already destroyed!"); } @@ -229,12 +230,53 @@ public class ReferenceConfig extends ReferenceConfigBase { // ensure start module, compatible with old api usage getScopeModel().getDeployer().start(); - init(); + init(check); } return ref; } + @Override + public void checkOrDestroy(long timeout) { + if (!initialized || ref == null) { + return; + } + try { + checkInvokerAvailable(timeout); + } catch (Throwable t) { + logAndCleanup(t); + throw t; + } + } + + private void logAndCleanup(Throwable t) { + try { + if (invoker != null) { + invoker.destroy(); + } + } catch (Throwable destroy) { + logger.warn(CONFIG_FAILED_DESTROY_INVOKER, "", "", "Unexpected error occurred when destroy invoker of ReferenceConfig(" + url + ").", t); + } + if (consumerModel != null) { + ModuleServiceRepository repository = getScopeModel().getServiceRepository(); + repository.unregisterConsumer(consumerModel); + } + initialized = false; + invoker = null; + ref = null; + consumerModel = null; + serviceMetadata.setTarget(null); + serviceMetadata.getAttributeMap().remove(PROXY_CLASS_REF); + + // Thrown by checkInvokerAvailable(). + if (t.getClass() == IllegalStateException.class && + t.getMessage().contains("No provider available for the service")) { + + // 2-2 - No provider available. + logger.error(CLUSTER_NO_VALID_PROVIDER, "server crashed", "", "No provider available.", t); + } + } + @Override public synchronized void destroy() { super.destroy(); @@ -258,6 +300,10 @@ public class ReferenceConfig extends ReferenceConfigBase { } protected synchronized void init() { + init(true); + } + + protected synchronized void init(boolean check) { if (initialized && ref != null) { return; } @@ -308,33 +354,11 @@ public class ReferenceConfig extends ReferenceConfigBase { consumerModel.setProxyObject(ref); consumerModel.initMethodModels(); - checkInvokerAvailable(); + if (check) { + checkInvokerAvailable(0); + } } catch (Throwable t) { - try { - if (invoker != null) { - invoker.destroy(); - } - } catch (Throwable destroy) { - logger.warn(CONFIG_FAILED_DESTROY_INVOKER, "", "", "Unexpected error occurred when destroy invoker of ReferenceConfig(" + url + ").", t); - } - if (consumerModel != null) { - ModuleServiceRepository repository = getScopeModel().getServiceRepository(); - repository.unregisterConsumer(consumerModel); - } - initialized = false; - invoker = null; - ref = null; - consumerModel = null; - serviceMetadata.setTarget(null); - serviceMetadata.getAttributeMap().remove(PROXY_CLASS_REF); - - // Thrown by checkInvokerAvailable(). - if (t.getClass() == IllegalStateException.class && - t.getMessage().contains("No provider available for the service")) { - - // 2-2 - No provider available. - logger.error(CLUSTER_NO_VALID_PROVIDER, "server crashed", "", "No provider available.", t); - } + logAndCleanup(t); throw t; } @@ -631,8 +655,31 @@ public class ReferenceConfig extends ReferenceConfigBase { } } - private void checkInvokerAvailable() throws IllegalStateException { - if (shouldCheck() && !invoker.isAvailable()) { + private void checkInvokerAvailable(long timeout) throws IllegalStateException { + if (!shouldCheck()) { + return; + } + boolean available = invoker.isAvailable(); + if (available) { + return; + } + + long startTime = System.currentTimeMillis(); + long checkDeadline = startTime + timeout; + do { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + break; + } + available = invoker.isAvailable(); + } while (!available && checkDeadline > System.currentTimeMillis()); + logger.warn(LoggerCodeConstants.REGISTRY_EMPTY_ADDRESS, "", "", + "Check reference of [" + getUniqueServiceName() + "] failed very beginning. " + + "After " + (System.currentTimeMillis() - startTime) + "ms reties, finally " + + (available ? "succeed" : "failed") + "."); + if (!available) { // 2-2 - No provider available. IllegalStateException illegalStateException = new IllegalStateException("Failed to check the status of the service " diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultModuleDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultModuleDeployer.java index 3bfaf4ea02..7c4eaf6baa 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultModuleDeployer.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultModuleDeployer.java @@ -32,6 +32,7 @@ import org.apache.dubbo.config.ConsumerConfig; import org.apache.dubbo.config.ModuleConfig; import org.apache.dubbo.config.ProviderConfig; import org.apache.dubbo.config.ReferenceConfig; +import org.apache.dubbo.config.ReferenceConfigBase; import org.apache.dubbo.config.ServiceConfig; import org.apache.dubbo.config.ServiceConfigBase; import org.apache.dubbo.config.context.ModuleConfigManager; @@ -180,6 +181,9 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme // register services to registry registerServices(); + // check reference config + checkReferences(); + // complete module start future after application state changed completeStartFuture(true); } else { @@ -195,6 +199,9 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme // register services to registry registerServices(); + + // check reference config + checkReferences(); } catch (Throwable e) { logger.warn(CONFIG_FAILED_WAIT_EXPORT_REFER, "", "", "wait for export/refer services occurred an exception", e); onModuleFailed(getIdentifier() + " start failed: " + e, e); @@ -387,6 +394,12 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme applicationDeployer.refreshServiceInstance(); } + private void checkReferences() { + for (ReferenceConfigBase rc : configManager.getReferences()) { + referenceCache.check(rc, 3000); + } + } + private void exportServiceInternal(ServiceConfigBase sc) { ServiceConfig serviceConfig = (ServiceConfig) sc; if (!serviceConfig.isRefreshed()) { @@ -460,7 +473,7 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme ExecutorService executor = executorRepository.getServiceReferExecutor(); CompletableFuture future = CompletableFuture.runAsync(() -> { try { - referenceCache.get(rc); + referenceCache.get(rc, false); } catch (Throwable t) { logger.error(CONFIG_FAILED_EXPORT_SERVICE, "", "", "Failed to async export service config: " + getIdentifier() + " , catch error : " + t.getMessage(), t); } @@ -468,7 +481,7 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme asyncReferringFutures.add(future); } else { - referenceCache.get(rc); + referenceCache.get(rc, false); } } } catch (Throwable t) { @@ -488,6 +501,9 @@ public class DefaultModuleDeployer extends AbstractDeployer impleme }); asyncReferringFutures.clear(); referenceCache.destroyAll(); + for (ReferenceConfigBase rc : configManager.getReferences()) { + rc.destroy(); + } } catch (Exception ignored) { } } diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/CompositeReferenceCache.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/CompositeReferenceCache.java index fef648e5d0..5ae8f010a6 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/CompositeReferenceCache.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/CompositeReferenceCache.java @@ -43,7 +43,7 @@ public class CompositeReferenceCache implements ReferenceCache { } @Override - public T get(ReferenceConfigBase referenceConfig) { + public T get(ReferenceConfigBase referenceConfig, boolean check) { Class type = referenceConfig.getInterfaceClass(); String key = BaseServiceMetadata.buildServiceKey(type.getName(), referenceConfig.getGroup(), referenceConfig.getVersion()); @@ -57,7 +57,7 @@ public class CompositeReferenceCache implements ReferenceCache { "Call ReferenceConfig#get() directly for non-singleton ReferenceConfig instead of using ReferenceCache#get(ReferenceConfig)"); } if (proxy == null) { - proxy = referenceConfig.get(); + proxy = referenceConfig.get(check); } return proxy; } @@ -111,6 +111,20 @@ public class CompositeReferenceCache implements ReferenceCache { } } + @Override + public void check(String key, Class type, long timeout) { + for (ModuleModel moduleModel : applicationModel.getModuleModels()) { + moduleModel.getDeployer().getReferenceCache().check(key, type, timeout); + } + } + + @Override + public void check(ReferenceConfigBase referenceConfig, long timeout) { + for (ModuleModel moduleModel : applicationModel.getModuleModels()) { + moduleModel.getDeployer().getReferenceCache().check(referenceConfig, timeout); + } + } + @Override public void destroy(Class type) { for (ModuleModel moduleModel : applicationModel.getModuleModels()) { diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SimpleReferenceCache.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SimpleReferenceCache.java index 29d3514127..7e798004fc 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SimpleReferenceCache.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/utils/SimpleReferenceCache.java @@ -110,7 +110,7 @@ public class SimpleReferenceCache implements ReferenceCache { @Override @SuppressWarnings("unchecked") - public T get(ReferenceConfigBase rc) { + public T get(ReferenceConfigBase rc, boolean check) { String key = generator.generateKey(rc); Class type = rc.getInterfaceClass(); @@ -129,7 +129,7 @@ public class SimpleReferenceCache implements ReferenceCache { referencesOfType.add(rc); List> referenceConfigList = ConcurrentHashMapUtils.computeIfAbsent(referenceKeyMap, key, _k -> Collections.synchronizedList(new ArrayList<>())); referenceConfigList.add(rc); - proxy = rc.get(); + proxy = rc.get(check); } return proxy; @@ -203,6 +203,29 @@ public class SimpleReferenceCache implements ReferenceCache { return null; } + @Override + public void check(String key, Class type, long timeout) { + List> referencesOfKey = referenceKeyMap.get(key); + if (CollectionUtils.isEmpty(referencesOfKey)) { + return; + } + List> referencesOfType = referenceTypeMap.get(type); + if (CollectionUtils.isEmpty(referencesOfType)) { + return; + } + for (ReferenceConfigBase rc : referencesOfKey) { + rc.checkOrDestroy(timeout); + } + + } + + @Override + public void check(ReferenceConfigBase referenceConfig, long timeout) { + String key = generator.generateKey(referenceConfig); + Class type = referenceConfig.getInterfaceClass(); + check(key, type, timeout); + } + @Override public void destroy(String key, Class type) { List> referencesOfKey = referenceKeyMap.remove(key); diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java index f6d0967368..1bb4519f90 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/MockReferenceConfig.java @@ -40,11 +40,11 @@ public class MockReferenceConfig extends ReferenceConfig { } @Override - public synchronized FooService get() { + public synchronized FooService get(boolean check) { if (value != null) return value; counter.getAndIncrement(); - value = super.get(); + value = super.get(check); return value; } diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/XxxMockReferenceConfig.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/XxxMockReferenceConfig.java index fbddd6db52..69fa54312a 100644 --- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/XxxMockReferenceConfig.java +++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/utils/XxxMockReferenceConfig.java @@ -40,11 +40,11 @@ public class XxxMockReferenceConfig extends ReferenceConfig { } @Override - public synchronized XxxService get() { + public synchronized XxxService get(boolean check) { if (value != null) return value; counter.getAndIncrement(); - value = super.get(); + value = super.get(check); return value; } From a758a1e7e0efd5d9465cde6088c04f25fa11aa4a Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 8 Jun 2023 12:47:57 +0800 Subject: [PATCH 29/30] Resolve conflicts of spring bean (#12474) * Resolve conflicts of spring bean * Fix import * Fix uts * Fix uts * Fix uts --- .../spring/schema/DubboBeanDefinitionParser.java | 15 +++++++++------ .../spring/schema/DubboNamespaceHandlerTest.java | 5 +++-- .../resources/META-INF/spring/dubbo-context.xml | 4 ++-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java index 9f0c8c7d90..31dbb290bf 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/schema/DubboBeanDefinitionParser.java @@ -32,8 +32,8 @@ import org.apache.dubbo.config.ProviderConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.nested.AggregationConfig; -import org.apache.dubbo.config.nested.PrometheusConfig; import org.apache.dubbo.config.nested.HistogramConfig; +import org.apache.dubbo.config.nested.PrometheusConfig; import org.apache.dubbo.config.spring.Constants; import org.apache.dubbo.config.spring.ReferenceBean; import org.apache.dubbo.config.spring.ServiceBean; @@ -103,9 +103,11 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser { if (StringUtils.isNotEmpty(configId)) { beanDefinition.getPropertyValues().addPropertyValue("id", configId); } - // get id from name + + String configName = ""; + // get configName from name if (StringUtils.isEmpty(configId)) { - configId = resolveAttribute(element, "name", parserContext); + configName = resolveAttribute(element, "name", parserContext); } String beanName = configId; @@ -113,13 +115,14 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser { // generate bean name String prefix = beanClass.getName(); int counter = 0; - beanName = prefix + "#" + counter; + beanName = prefix + (StringUtils.isEmpty(configName) ? "#" : ("#" + configName + "#")) + counter; while (parserContext.getRegistry().containsBeanDefinition(beanName)) { - beanName = prefix + "#" + (counter++); + beanName = prefix + (StringUtils.isEmpty(configName) ? "#" : ("#" + configName + "#")) + (counter++); } } beanDefinition.setAttribute(BEAN_NAME, beanName); + if (ProtocolConfig.class.equals(beanClass)) { // for (String name : parserContext.getRegistry().getBeanDefinitionNames()) { // BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name); @@ -184,7 +187,7 @@ public class DubboBeanDefinitionParser implements BeanDefinitionParser { * For 'provider' 'protocol' 'registry', keep literal value (should be id/name) and set the value to 'registryIds' 'providerIds' protocolIds' * The following process should make sure each id refers to the corresponding instance, here's how to find the instance for different use cases: * 1. Spring, check existing bean by id, see{@link ServiceBean#afterPropertiesSet()}; then try to use id to find configs defined in remote Config Center - * 2. API, directly use id to find configs defined in remote Config Center; if all config instances are defined locally, please use {@link ServiceConfig#setRegistries(List)} + * 2. API, directly use id to find configs defined in remote Config Center; if all config instances are defined locally, please use {@link org.apache.dubbo.config.ServiceConfig#setRegistries(List)} */ beanDefinition.getPropertyValues().addPropertyValue(beanProperty + "Ids", value); } else { diff --git a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java index d910996fd2..33efb6f9e4 100644 --- a/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java +++ b/dubbo-config/dubbo-config-spring/src/test/java/org/apache/dubbo/config/spring/schema/DubboNamespaceHandlerTest.java @@ -99,11 +99,12 @@ class DubboNamespaceHandlerTest { private void testProviderXml(ApplicationContext context) { String appName = "demo-provider"; + String configId = ApplicationConfig.class.getName() + "#" + appName + "#0"; Map applicationConfigMap = context.getBeansOfType(ApplicationConfig.class); - ApplicationConfig providerAppConfig = context.getBean(appName, ApplicationConfig.class); + ApplicationConfig providerAppConfig = context.getBean(configId, ApplicationConfig.class); assertNotNull(providerAppConfig); assertEquals(appName, providerAppConfig.getName()); - assertEquals(appName, providerAppConfig.getId()); +// assertEquals(configId, providerAppConfig.getId()); ProtocolConfig protocolConfig = context.getBean(ProtocolConfig.class); assertThat(protocolConfig, not(nullValue())); diff --git a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/test/resources/META-INF/spring/dubbo-context.xml b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/test/resources/META-INF/spring/dubbo-context.xml index 87b6505cf3..960a899abb 100644 --- a/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/test/resources/META-INF/spring/dubbo-context.xml +++ b/dubbo-spring-boot/dubbo-spring-boot-compatible/autoconfigure/src/test/resources/META-INF/spring/dubbo-context.xml @@ -7,8 +7,8 @@ http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> - + - \ No newline at end of file + From f35ac093539a1e49dd371bab5b8c6b38dc214cac Mon Sep 17 00:00:00 2001 From: Albumen Kevin Date: Thu, 8 Jun 2023 12:48:55 +0800 Subject: [PATCH 30/30] Publish Module deployer state event (#12477) Co-authored-by: songxiaosheng --- .../DubboDeployApplicationListener.java | 61 +++++++++++++++---- .../context/event/DubboModuleStateEvent.java | 55 +++++++++++++++++ 2 files changed, 104 insertions(+), 12 deletions(-) create mode 100644 dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboModuleStateEvent.java diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboDeployApplicationListener.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboDeployApplicationListener.java index 37c2343604..72cfa1b387 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboDeployApplicationListener.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboDeployApplicationListener.java @@ -16,11 +16,6 @@ */ package org.apache.dubbo.config.spring.context; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_STOP_DUBBO_ERROR; -import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_START_MODEL; -import static org.springframework.util.ObjectUtils.nullSafeEquals; - -import java.util.concurrent.Future; import org.apache.dubbo.common.deploy.DeployListenerAdapter; import org.apache.dubbo.common.deploy.DeployState; import org.apache.dubbo.common.deploy.ModuleDeployer; @@ -28,10 +23,12 @@ import org.apache.dubbo.common.logger.ErrorTypeAwareLogger; import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.Assert; import org.apache.dubbo.config.spring.context.event.DubboApplicationStateEvent; +import org.apache.dubbo.config.spring.context.event.DubboModuleStateEvent; import org.apache.dubbo.config.spring.util.DubboBeanUtils; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ModelConstants; import org.apache.dubbo.rpc.model.ModuleModel; + import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @@ -41,6 +38,12 @@ import org.springframework.context.event.ContextClosedEvent; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.core.Ordered; +import java.util.concurrent.Future; + +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_FAILED_START_MODEL; +import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_STOP_DUBBO_ERROR; +import static org.springframework.util.ObjectUtils.nullSafeEquals; + /** * An ApplicationListener to control Dubbo application. */ @@ -62,39 +65,73 @@ public class DubboDeployApplicationListener implements ApplicationListener(){ @Override public void onStarting(ApplicationModel scopeModel) { - publishEvent(DeployState.STARTING); + publishApplicationEvent(DeployState.STARTING); } @Override public void onStarted(ApplicationModel scopeModel) { - publishEvent(DeployState.STARTED); + publishApplicationEvent(DeployState.STARTED); } @Override public void onStopping(ApplicationModel scopeModel) { - publishEvent(DeployState.STOPPING); + publishApplicationEvent(DeployState.STOPPING); } @Override public void onStopped(ApplicationModel scopeModel) { - publishEvent(DeployState.STOPPED); + publishApplicationEvent(DeployState.STOPPED); } @Override public void onFailure(ApplicationModel scopeModel, Throwable cause) { - publishEvent(DeployState.FAILED, cause); + publishApplicationEvent(DeployState.FAILED, cause); + } + }); + moduleModel.getDeployer().addDeployListener(new DeployListenerAdapter(){ + @Override + public void onStarting(ModuleModel scopeModel) { + publishModuleEvent(DeployState.STARTING); + } + + @Override + public void onStarted(ModuleModel scopeModel) { + publishModuleEvent(DeployState.STARTED); + } + + @Override + public void onStopping(ModuleModel scopeModel) { + publishModuleEvent(DeployState.STOPPING); + } + + @Override + public void onStopped(ModuleModel scopeModel) { + publishModuleEvent(DeployState.STOPPED); + } + + @Override + public void onFailure(ModuleModel scopeModel, Throwable cause) { + publishModuleEvent(DeployState.FAILED, cause); } }); } - private void publishEvent(DeployState state) { + private void publishApplicationEvent(DeployState state) { applicationContext.publishEvent(new DubboApplicationStateEvent(applicationModel, state)); } - private void publishEvent(DeployState state, Throwable cause) { + private void publishApplicationEvent(DeployState state, Throwable cause) { applicationContext.publishEvent(new DubboApplicationStateEvent(applicationModel, state, cause)); } + private void publishModuleEvent(DeployState state) { + applicationContext.publishEvent(new DubboModuleStateEvent(moduleModel, state)); + } + + private void publishModuleEvent(DeployState state, Throwable cause) { + applicationContext.publishEvent(new DubboModuleStateEvent(moduleModel, state, cause)); + } + @Override public void onApplicationEvent(ApplicationContextEvent event) { if (nullSafeEquals(applicationContext, event.getSource())) { diff --git a/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboModuleStateEvent.java b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboModuleStateEvent.java new file mode 100644 index 0000000000..81b59aa14e --- /dev/null +++ b/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/event/DubboModuleStateEvent.java @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.config.spring.context.event; + +import org.apache.dubbo.common.deploy.DeployState; +import org.apache.dubbo.rpc.model.ModuleModel; + +import org.springframework.context.ApplicationEvent; + +/** + * Dubbo's module state event on starting/started/stopping/stopped + */ +public class DubboModuleStateEvent extends ApplicationEvent { + + private final DeployState state; + + private Throwable cause; + + public DubboModuleStateEvent(ModuleModel applicationModel, DeployState state) { + super(applicationModel); + this.state = state; + } + + public DubboModuleStateEvent(ModuleModel applicationModel, DeployState state, Throwable cause) { + super(applicationModel); + this.state = state; + this.cause = cause; + } + + public ModuleModel getModule() { + return (ModuleModel) getSource(); + } + + public DeployState getState() { + return state; + } + + public Throwable getCause() { + return cause; + } +}