Compare commits

...

82 Commits

Author SHA1 Message Date
namelessssssssssss f020f3e3d1
Remaining works of config-api refactor (#13045)
* * Move Configurator & Factory to common

* * Move ServiceNameMapping & MappingListener & MappingChangedEvent to common
* Add ServiceNameMappingUtils

* * Move ClusterUtils to common

* * Add ClusterInvokerFactory

* * Move InterfaceConfigValidator & MethodConfigValidator to cluster
* Move ConfigCenterConfigValidator to configcenter-api

* * Move DefaultMetricsServiceExporter to metrics-default

* * Move Lifecycles

* * Fix a part cyclic dependencies problem

* * Move ApplicationPostOfflineLifecycle to dubbo-registry

* * Fix a part cycle dependencies problem

* * Fix ut about MetadataReportInstance & Move Prometheus ut to metrics
* Move ClusterInvokerFactory to rpc-api

* * Update config-api pom

* * Add license

* * Fix module version of metadata-api

* * Move some MetadataService API to registry-api

* Add interface ApplicationMetadataUpdater to reduce the depedencies of  dubbo-metadata on dubbo-registry

* Temporary remove some tests that caused cyclic reference

* Temporary remove some tests that caused cyclic reference

* Add license

* Add test-config module for test

* Add license

* Fix pom

* Tests fix

* Pom fix

* Fix a bean registry problem

* Move config-test to dubbo-config

* Fix pom

* Add removed test

* Add removed test

* Remove application.yaml

* Fix version

* Fix codestyle

* Fix spi file

* Fix dependencies of dubbo-demo-native

* Fix dependencies of dubbo-demo-native

* Fix dependencies of dubbo-demo-native

* Fix dependencies of dubbo-demo-native

* Fix dependencies of dubbo-demo-native

* Fix dependencies of dubbo-demo-native

* Fix dependencies of dubbo-rpc

* Fix dependencies of dubbo-rpc-rest

* Fix dependencies of dubbo-rpc-rest

* Fix dependencies of dubbo-rpc-rest

* Fix dependencies of dubbo-rpc-rest

* Fix spi file of ApplicationDeployListener

* Fix test about exporter count

* Fix test about exporter count

* Update pom

* Add test msg

* Change MetadataUpdater init process

* Change MetadataUpdater init process

* Change MetadataUpdater init process

* Change MetadataUpdater init process

* Fix dependencies of dubbo-rpc-rest

* Using lifecycle instead of ApplicationDeployListener

* Update doc

* Update log

* Fix pom of dubbo-config-spring & dubbo-plugin-security & dubbo-rpc-rest

* Add scope for ApplicationLifecycle

* Fix pom of dubbo-config-spring

* Fix ut of rpc-rest(PR#13087)

* Fix bug of DefaultClusterInvokerFactory

* Fix bug of DefaultClusterInvokerFactory

* Fix bug of DefaultClusterInvokerFactory

* Fix bug of ServiceInstanceCustomizer

* Add dubbo-config-test to ignore list

* Code style & bug fix

* Remove unused import

* Add zookeeper-curator for test

* Test zookeeper version

* Test zookeeper version

* Test fix zookeeper

* Remove unnecessary modification

* Add test props

* Remove unused dependencies

* Code style fix

* Remove unnecessary dependencies & Code style fix

* Fix dependencies

* Update pom.xml

* Add dubbo-config-test as ignored

* Refactor ClusterInvokerFactory

* Refactor ClusterInvokerFactory

* Refactor ClusterInvokerFactory
2023-10-03 22:40:12 +08:00
namelessssssssssss 9eb83d16bb
Refactor service metadata export process (#12990)
* * Migrate service metadata export process to MetadataPublisher

* * Fix ut

* * Move metadata API out of dubbo-config-api

* * Move metadata API spi file out of dubbo-config-api

* * Merge remote branch

* * Merge remote branch

* * Add license

* Add license

* Update MetadataPublisherRegister.java

* Update DefaultMetadataPublisher.java

* Update MetadataServiceExporterTest.java

* * Bug fix

* Update MetadataPublisher.java

* * Remove unnecessary SPI for MetadataPublisher

* * Update pom

* * Move spi file back

* * Add MetadataPublisherRegister

* * Add license

* Update MetadataPublisherRegister.java

* * Bug fix
2023-09-11 11:15:27 +08:00
namelessssssssssss 98e7313e71
Split DefaultConfigValidator to SPI implements (#12948)
* * Simplify responsibilities of ConfigValidationUtils

* * Update validators

* * Bug fix

* * Bug fix
* Add ut

* * Add license

* * Rename folder

* * Fix pom & name

* * Code style fix

* * Bug fix

* * Bug fix

* * Update validator init process

* * Refactor ConfigValidateFacade init method

* * Bug fix
* Add license

* * Fix test

* * Fix ut

* * Update ConfigValidateFacade init process

* * Bug fix

* * Bug fix

* * Bug fix

* * Doc fix

* * Bug fix

* * Bug fix

* * Bug fix

* * Bug fix

* * Bug fix

* * Test fix

* * refactor validator mapping

* * Code style fix

* * Fix conflict

* * Fix conflict

* * Remove default instance of ConfigValidateFacade

* * Remove default instance of ConfigValidateFacade

* * Add license
2023-09-10 20:56:10 +08:00
namelessssssssssss a6a6d57dd7
Add SPI Interface ApplicationLifecycleManager for dubbo-core refactor (#12750)
* Add SPI ApplicationLifecycleManager and its implements

* Add new protocol for publishing registry event

* Migrate DefaultApplicationDeployer to 3.3

* Add SPI file

* Code style fix

* Code style fix

* Remove DefaultApplicationLifecycle

* * Add start() for ApplicationLifecycle
* Code style fix
* Remove unused dependencies from dubbo-config-api

* Implement ApplicationLifecycle.start for MetadataApplicationLifecycle and MetricsApplicationLifecycle

* Using @Activate with order instead of dependOnXXX in ApplicationLifecycle

* Move all ApplicationLifecycle implements back to dubbo-config

* * Move all lifecycle implements back to config-api for test

* Code style & bug fix

* Bug fix

* Add license

* Remove unused codes

* Add license

* Add license

* Add license

* Remove unused import

* Update test and pom

* Bug fix

* Update pom.xml

* Bug fix

* Bug fix

* Add SPI ApplicationLifecycleManager and its implements

* Add new protocol for publishing registry event

* Migrate DefaultApplicationDeployer to 3.3

* Add SPI file

* Code style fix

* Code style fix

* Remove DefaultApplicationLifecycle

* * Add start() for ApplicationLifecycle
* Code style fix
* Remove unused dependencies from dubbo-config-api

* Implement ApplicationLifecycle.start for MetadataApplicationLifecycle and MetricsApplicationLifecycle

* Using @Activate with order instead of dependOnXXX in ApplicationLifecycle

* Move all ApplicationLifecycle implements back to dubbo-config

* * Move all lifecycle implements back to config-api for test

* Code style & bug fix

* Bug fix

* Add license

* Remove unused codes

* Add license

* Add license

* Add license

* Remove unused import

* Update test and pom

* Bug fix

* Bug fix

* Update pom.xml

* Bug fix

* Bug and codestyle fix

* Codestyle fix

* Fix accessibility issues in AbstractDeployer

* Bug fix

* Add new ApplicationLifecycle to fix application config initialize issue

* Bug fix

* Remove unused codes

* Remove ProtocolRegistryEventWrapper

* Fix wrong call sequences in initialize() and postModuleChanged()

* Add spi config

* Fix order issues for lifecycle impl

* Cache lifecycle impls to BeanFactory

* * Refactor lifecycle to event-based
* Add ApplicationEvent and its implements
* Simplify deployers
* Add ModelContext and its implements

* * Add license & bug fix

* * Bug fix

* * Move contexts

* * Add license

* Update doc

* Update docs

* Remove unused methods

* Remove unused methods & Bug fix

* Bug fix

* * Remove events
* Add lifecycles

* * Add license

* * Add license

* * Fix spi file name
* Add log for ApplicationLifecycleManager

* Update pom.xml

* * Bug fix
* Remove unused import

* Update pom.xml

* * Simply codes relate to ApplicationContext

* * Codestyle fix

* * Fix conflict ut

* * Migrate module offline process to ModuleOfflineLifecycle

* * Add new lifecycle

* * Add license

* * Ut & codestyle fix

* * Call sequence bug fix

* * Add doc

* * npe fix

* * Codestyle & doc fix

* * Fix the usage of Lifecycle.needInitialize

* Update org.apache.dubbo.metadata.ServiceNameMapping

* * Fix ut

* Update DefaultCollectorTest.java

* * Update test

* * Move AbstractDeployer back to dubbo-common
2023-09-10 09:59:03 +08:00
huazhongming 8009c72030
Ignore class loading failure when native is compiled (#13009)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-09-05 11:31:54 +08:00
namelessssssssssss 7e6a32ba68
* Fix conflict (#12991) 2023-09-01 10:26:02 +08:00
Albumen Kevin 36a80e4db7 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/DefaultMetricsCollector.java
#	dubbo-metrics/dubbo-metrics-default/src/main/java/org/apache/dubbo/metrics/collector/sample/ThreadRejectMetricsCountSampler.java
#	dubbo-metrics/dubbo-metrics-event/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java
2023-08-31 18:59:20 +08:00
namelessssssssssss bf3d4f4ca3
Metrics event split (#12888)
* Split event-related api out of dubbo-metrics-api.

* Add new module to .artifacts

* Temporary remove dubbo-plugin-metrics

* Fix pom

* * Remove the use of dispatcher name

* * Bug fix

* * Bug fix

* Update ScopeClusterInvokerTest.java

* * Trigger test

* * Fix ut

---------

Co-authored-by: songxiaosheng <songxiaosheng@elastic.link>
2023-08-31 08:02:41 +08:00
hjyp f91246ab09
【OSPP】Json check compatiblity (#12910)
* Initialize

* update code style

* delete redundant file

* Change position

* delete redundant import

* Add JsonCompatibilityUtils

* Delete unused import

* change funcs

* Add test case

* update color class

* add license

* fix style

* check interface

* Fix log style

* Add attribbute of check-json-level

* Update log style

* Update log style

* Fix bugs

* Add test and document

* Fix bugs

* Delete yaml

* Delete xml

* Add license

* Add license

* Merge upstream branch

* Update IllegalStateException
2023-08-29 11:53:15 +08:00
carlvine500 679ce4496c
tag support multi level (#12673) 2023-08-24 16:51:06 +08:00
Albumen Kevin 4e9a0a41fc Fix callback consumer context package 2023-08-22 15:08:23 +08:00
Albumen Kevin 7a4ec6c525 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	README.md
#	dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	dubbo-metadata/dubbo-metadata-rest/src/main/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolver.java
#	dubbo-metadata/dubbo-metadata-rest/src/test/java/org/apache/dubbo/metadata/rest/NoAnnotationApiDemoResolverTest.java
#	dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/model/key/MetricsKey.java
#	dubbo-monitor/dubbo-monitor-common/src/main/java/org/apache/dubbo/monitor/support/CallbackConsumerContextFilter.java
#	pom.xml
2023-08-22 15:05:41 +08:00
Ken Liu ae150c01e5
3.3 readme (#12898) 2023-08-17 09:53:09 +08:00
conghuhu 629bee3987
feat: add brave to core (#12814) 2023-08-14 15:42:40 +08:00
namelessssssssssss 5ae875d951
Add support for error code metrics (#12125) (#12661)
* Add metrics support of error code

* Add metrics support of error code

* Add metrics support of error code

* add license

* remove hashcode override

* Update DefaultSubDispatcher.java

* Update ErrorCodeSampleTest.java

* Update DefaultMetricsCollector.java

---------

Co-authored-by: songxiaosheng <songxiaosheng@elastic.link>
2023-08-09 17:56:47 +08:00
胡俊 04f3fe7d2b
add netty4 metrics. (#12695) 2023-08-09 15:46:03 +08:00
chaicho 059fdf2613
Add module dubbo-all-shaded to avoid netty version conflict. (#12864) 2023-08-08 16:40:24 +08:00
suncairong163 7c971ca1bd
feign client service name cover dubbo provided by (#12838)
Co-authored-by: suncr <suncairong@moresec.cn>
2023-08-07 17:06:39 +08:00
hjyp b18eeb7077
[OSPP 2023] JSON Compatibility Check (#12776)
* Initialize

* update code style

* delete redundant file

* Change position

* delete redundant import

* Add JsonCompatibilityUtils

* Delete unused import

* change funcs

* Add test case

* update color class

* add license

* fix style
2023-08-04 10:42:38 +08:00
suncairong163 6c5a876f31
Feature/dubbo3.3 add reserence providedby by springcloud feignclient (#12823) 2023-08-01 15:43:20 +08:00
Albumen Kevin ce65317207 Fix conflicts 2023-07-29 20:52:35 +08:00
Albumen Kevin 046898bbc8 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java
#	dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosDetector.java
#	dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/QosHTTP1Detector.java
#	dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/pu/TelnetDetector.java
#	dubbo-plugin/dubbo-qos/src/test/java/org/apache/dubbo/qos/pu/QosWireProtocolTest.java
#	dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
2023-07-29 20:52:17 +08:00
huazhongming 29d9c070d4
Upgrade spring version 6.0.7 to 6.0.11 and upgrade spring-boot version 3.0.4 to 3.0.9 (#12797)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-07-26 15:26:06 +08:00
Albumen Kevin 8fefd95a98 Merge branch 'apache-3.2' into apache-3.3 2023-07-26 11:22:21 +08:00
Albumen Kevin 2973426b2a Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-demo/dubbo-demo-spring-boot/pom.xml
#	dubbo-dependencies-bom/pom.xml
2023-07-26 10:58:32 +08:00
huazhongming 70605f4dd0
Fix native image compilation failure due to missing parameterless constructs of ServiceBean (#12733)
* Fix native image compilation failure due to missing parameterless constructs of ServiceBean

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Add ServiceBean constructorArgumentValues

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* remove unused import

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* autowired moduleModel

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* remove unused import

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

---------

Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-07-25 21:16:49 +08:00
Albumen Kevin d1719c5358 Remove -1 delay usage (#12767) 2023-07-25 20:57:39 +08:00
dependabot[bot] 0e17f4f168 Bump micrometer-core from 1.11.1 to 1.11.2 (#12746)
Bumps [micrometer-core](https://github.com/micrometer-metrics/micrometer) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/micrometer-metrics/micrometer/releases)
- [Commits](https://github.com/micrometer-metrics/micrometer/compare/v1.11.1...v1.11.2)

---
updated-dependencies:
- dependency-name: io.micrometer:micrometer-core
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
2023-07-25 20:57:39 +08:00
dependabot[bot] 72e5d20ce9 Bump micrometer-tracing-bom from 1.1.2 to 1.1.3 (#12743)
Bumps [micrometer-tracing-bom](https://github.com/micrometer-metrics/tracing) from 1.1.2 to 1.1.3.
- [Release notes](https://github.com/micrometer-metrics/tracing/releases)
- [Commits](https://github.com/micrometer-metrics/tracing/compare/v1.1.2...v1.1.3)

---
updated-dependencies:
- dependency-name: io.micrometer:micrometer-tracing-bom
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-07-25 20:57:38 +08:00
promiseChan 0db8605974
fix_win11_aot_compile_NoSuchFileException,because of File.separator (#12769) 2023-07-21 11:27:57 +08:00
Albumen Kevin 80d496c5b1 Fix conflicts 2023-07-19 15:37:20 +08:00
Albumen Kevin 093fb7c208 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-cluster/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.cluster.filter.ClusterFilter
#	dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
#	dubbo-config/dubbo-config-api/pom.xml
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
#	dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
#	dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/NettyHttpRestServer.java
#	dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/deploy/ServiceDeployer.java
#	dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/handler/NettyHttpHandler.java
#	dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/message/codec/JsonCodec.java
#	pom.xml
2023-07-19 15:18:51 +08:00
suncairong163 f78b4f5dea
add rest provider body multipart json that JsonUtils supports ut (#12716) 2023-07-17 13:29:10 +08:00
suncairong163 1f8a0fa5ec
add feign client annotation support (#12736) 2023-07-17 12:34:28 +08:00
MartinDai f2ec217f54
log messages support use placeholders and parameters (#12365)
* log messages support use placeholders and parameters

* mockLogger add implements method

* reformat file

* fix unit test error

* fix sonar security

* remove unnecessary util

* update file license

* update file license

* add checkstyle ignore

---------

Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
2023-07-13 19:52:23 +08:00
suncairong163 c7d411c3cb
Feature/dubbo rest no annotation support (#12700) 2023-07-11 13:38:49 +08:00
TomlongTK 8bb17b85f2
GsonUtils provide toJson method, GenericFilter use gson mode support toJson (#12633)
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
2023-07-11 12:49:07 +08:00
conghuhu 4b62513dff
chore: add seata sentinel starter & rename tracing starter (#12543)
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
Co-authored-by: Ken Liu <ken.lj.hz@gmail.com>
2023-07-07 10:22:48 +08:00
Albumen Kevin 9bbf7625a8 Merge branch 'apache-3.2' into apache-3.3 2023-07-03 16:07:41 +08:00
qinliujie 0d4e8304bc
refactor dubbo module (#12276)
* refactor:extract MergeableCluster as a single module

* fix:add license header

* fix:add dubbo-plugin-cluster-mergeable to .artifacts

* refactor:extract module from dubbo-cluster

* refactor:extract dubbo-plugin-router-condition module

* refactor:extract dubbo-plugin-router-tag module

* refactor:move metric filter out from dubbo-cluster

* refactor:add pom dependency

* fix:ut and dependency

* fix:ut

* refactor:extract dubbo-plugin-loadbalance-adaptive

* refactor:extract dubbo-remoting-zookeeper-api module

* refactor:extract dubbo-configcenter-file module

* refactor:extract dubbo-metadata-rest module

* refactor:extract dubbo-monitor-common module

* refactor: extrace dubbo-plugin-access-log module

* refactor: extrace dubbo-plugin-tps module

* refactor: extrace dubbo-plugin-token module

* refactor: extract dubbo-plugin-generic-invoke module

* refactor: extract dubbo-plugin-context module

* refactor: extract dubbo-plugin-classloader-filter module

* refactor: extract dubbo-plugin-proxy-bytebuddy module

* refactor: extract dubbo-plugin-qos-trace module

* refactor: extract FutureFilter from dubbo protocol module

* refactor: add modules to pom

* ut:fix ut dependency
2023-07-03 15:55:42 +08:00
Albumen Kevin 48cc5b24de Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	pom.xml
2023-06-30 22:45:24 +08:00
Albumen Kevin 37f150263a
Disable subscribe nacos legacy name in 3.3 (#12617) 2023-06-29 14:50:00 +08:00
conghuhu 95207b9079
fix: fix missing metrics filter & recover #12453 (#12577)
* recover "refactor: migrate tracing core from boot-start to dubbo deployer (#12453)"

This reverts commit ea35f7ed5c.

* fix: fix missing metrics filter

---------

Co-authored-by: songxiaosheng <songxiaosheng@elastic.link>
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
2023-06-28 20:36:38 +08:00
Albumen Kevin da8d0cd994 Merge branch 'apache-3.2' into apache-3.3 2023-06-28 20:35:33 +08:00
carlvine500 27e6838c3b
add spring boot interceptor to copy header(dubbo-tag)/cookie(dubbo.tag) (#12514)
* add spring boot interceptor to copy header(dubbo-tag)/cookie(dubbo.tag)

* copy dubbo.tag in urlParameter

* copy dubbo.tag in urlParameter

* remove dubbo.tag in interceptor

* add dubbo-spring-boot-interceptor to dubbo-dependencies-all/.artifacts/dubbo-bom

---------

Co-authored-by: liutingfeng <tingfeng.liu@successchannel.com>
Co-authored-by: songxiaosheng <songxiaosheng@elastic.link>
Co-authored-by: Albumen Kevin <jhq0812@gmail.com>
2023-06-28 20:30:45 +08:00
songxiaosheng 1c65617fb1
add framework metrics (#12576)
* add framework metric

*  add framework metrics

*  add framework metrics
2023-06-28 20:27:08 +08:00
Albumen Kevin cf2a63580e
Service not register to registry if specify register=false (#12584) 2023-06-22 14:35:41 +08:00
Albumen Kevin d6776e4008 Merge branch 'apache-3.2' into apache-3.3 2023-06-22 14:30:33 +08:00
Albumen Kevin b14201f393 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/context/DubboInfraBeanRegisterPostProcessor.java
#	dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/RegistryScopeModelInitializer.java
#	dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
2023-06-22 10:18:31 +08:00
foghost c96a06eba1
add tri native image support (#12536)
Co-authored-by: huazhongming <crazyhzm@gmail.com>
2023-06-19 11:26:50 +08:00
huazhongming 1e59ab524a
In native scenarios, Compiler and Proxy are set to jdk by default (#12530)
* In native scenarios, Compiler and Proxy are set to jdk by default

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Fix UT

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

---------

Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-06-15 10:11:44 +08:00
Albumen Kevin fd14e7b76f Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
#	dubbo-test/dubbo-test-modules/src/test/java/org/apache/dubbo/dependency/FileTest.java
2023-06-12 20:52:32 +08:00
Albumen Kevin 642f741dba Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ReferenceBean.java
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ServiceAnnotationPostProcessor.java
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/reference/ReferenceBeanSupport.java
2023-06-08 16:16:15 +08:00
suncairong163 85bc6ea472
http protocol detector (#12452)
* http protocol detector

* make differnece between rest and qos http

* set rest http wire protocol spi order  after qos http detector

* make differnce between rest and qos http detector

* add differnt  service to server  url

* adjust code position

* complete some change request

* passing ServiceDeployer to  PortUnificationServer through URL

* merge code and add qos detect ut
2023-06-08 11:13:35 +08:00
icodening 391d3cdb35
support passing detect context to help build netty handlers (#12460) 2023-06-07 15:19:06 +08:00
huazhongming 2031a4c531
Remove NativeUtils (#12454)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-06-06 17:42:12 +08:00
huazhongming e642e72ce8
Fixed the issue of superclass and filed not being loaded automatically in the native serialization config scenario (#12435)
* Fixed the issue of superclass and filed not being loaded automatically in the native serialization config scenario

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Add license

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Fix test

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Fix test

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* add log

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* add log

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Fix AotUtilsTest

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

---------

Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-06-01 15:01:20 +08:00
huazhongming 4604b8074a
Support for automatic identification of serialization classes and generation of native image configuration (#12433)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-31 16:05:54 +08:00
Albumen Kevin 30daba2d74 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector
#	dubbo-plugin/dubbo-qos/pom.xml
#	pom.xml
2023-05-29 16:01:02 +08:00
huazhongming 1f39543632
Skip security and xds module javadoc plugin (#12413)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-28 18:45:36 +08:00
huazhongming 71046bdd6f
skip demo javadoc (#12411)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-28 15:07:30 +08:00
huazhongming ae4899a462
Override the maven-javadoc-plugin configuration that depends on the pass (#12410)
* Override the maven-javadoc-plugin configuration that depends on the pass

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* Fix maven-javadoc-plugin

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* skip maven javadoc plugin

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

---------

Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-28 09:43:18 +08:00
huazhongming 7661cab6f5
Javadoc ingore missing excpetion (#12405)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-26 23:34:19 +08:00
crazyhzm d798e7c3be Merge branch '3.2' into 3.3 2023-05-26 11:34:53 +08:00
crazyhzm 34eb252178 Merge branch '3.2' into 3.3 2023-05-24 22:24:10 +08:00
Albumen Kevin 59758f4b58 Merge branch 'apache-3.2' into apache-3.3 2023-05-23 20:00:42 +08:00
huazhongming 52e4e4e301
remove dubbo-native-plugin module (#12358)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-21 21:00:46 +08:00
crazyhzm 71cc51bf69 Merge branch '3.2' into 3.3
# Conflicts:
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	pom.xml
2023-05-17 14:07:55 +08:00
huazhongming a80ad7f505
fix license check (#12268)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-09 17:26:48 +08:00
Albumen Kevin 9f0e1589a5 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	.licenserc.yaml
2023-05-08 08:07:10 +08:00
XIACYBING 471f44b52d
fix: fix inappropriate invoke in unsubscribe retry task (#12231) 2023-05-05 20:26:34 +08:00
Albumen Kevin 992abd2d34 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-config/dubbo-config-api/pom.xml
#	dubbo-distribution/dubbo-all/pom.xml
#	dubbo-metrics/dubbo-metrics-default/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metrics.collector.MetricsCollector
#	pom.xml
2023-05-05 13:07:25 +08:00
huazhongming 9d9df82194
Fix the dubbo-config-spring6 module is lost (#12228)
Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-05-05 11:31:07 +08:00
huazhongming 6c8f79c889
Native Support Springboot3 (#12072)
* Support native with springboot3

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* fix checkstyle

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* remove useless imports

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* remove useless imports

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* change java version of  build-source actions to jdk17

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* dubbo-serialization-fastjson2 support native

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* fix xml config

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* fix singleton bean

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* ignore test

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* ignore dubbo-config-spring6 module in dubbo all

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* remove @ignore

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* add dubbo-config-spring6 to dubbo-bom

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* add dubbo-config-spring6 to dubbo-test

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* add transformer

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* ignore  dubbo-config-spring6

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* fix JsonUtilsTest

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

* fix JsonUtilsTest

Signed-off-by: crazyhzm <crazyhzm@gmail.com>

---------

Signed-off-by: crazyhzm <crazyhzm@gmail.com>
2023-04-25 11:30:17 +08:00
Andy Cheung 2997fa6a2e
Make Annotation Processor's Dependency optional. (#12112) 2023-04-19 10:10:10 +08:00
Andy Cheung 13558a8e6a
Add ignorance of FileTest.java. (#12105) 2023-04-16 17:00:25 +08:00
Albumen Kevin 59832d45d4 Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	pom.xml
2023-04-15 07:28:32 +08:00
Albumen Kevin fe55491d4a Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
2023-04-13 20:32:44 +08:00
Andy Cheung b23bae38cc
[3.3] Remove deprecated method invocation in tests (Common Module). (#11934)
* Remove setJson() method.

* Remove test only methods in FileCacheStore, FileCacheStoreFactory.
2023-03-28 15:27:38 +08:00
Andy Cheung 0b6f2e4a8d
Add Dubbo Annotation Processor (Add deprecated method warn when called by user, #10850) (#11513) 2023-03-24 09:48:08 +08:00
Albumen Kevin 414785c05b Merge branch 'apache-3.2' into apache-3.3
# Conflicts:
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper-curator5/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	pom.xml
2023-03-21 17:49:14 +08:00
Albumen Kevin 52611099ab Bump version to 3.3.0-beta.1-SNAPSHOT 2023-02-20 16:24:28 +08:00
1072 changed files with 23947 additions and 7587 deletions

View File

@ -19,6 +19,7 @@
dubbo
dubbo-auth
dubbo-apache-release
dubbo-all-shaded
dubbo-bom
dubbo-build-tools
dubbo-cluster
@ -28,7 +29,11 @@ dubbo-compiler
dubbo-config
dubbo-config-api
dubbo-config-spring
dubbo-config-spring6
dubbo-config-test
dubbo-configcenter
dubbo-configcenter-api
dubbo-configcenter-file
dubbo-configcenter-apollo
dubbo-configcenter-nacos
dubbo-configcenter-zookeeper
@ -49,6 +54,7 @@ dubbo-kubernetes
dubbo-maven-plugin
dubbo-metadata
dubbo-metadata-api
dubbo-metadata-rest
dubbo-metadata-definition-protobuf
dubbo-metadata-processor
dubbo-metadata-report-nacos
@ -61,11 +67,13 @@ dubbo-metrics-metadata
dubbo-metrics-prometheus
dubbo-metrics-registry
dubbo-metrics-config-center
dubbo-metrics-netty
dubbo-metrics-event
dubbo-monitor
dubbo-monitor-api
dubbo-monitor-common
dubbo-monitor-default
dubbo-native
dubbo-native-plugin
dubbo-parent
dubbo-plugin
dubbo-qos
@ -82,6 +90,7 @@ dubbo-remoting-api
dubbo-remoting-http
dubbo-remoting-netty
dubbo-remoting-netty4
dubbo-remoting-zookeeper-api
dubbo-remoting-zookeeper
dubbo-remoting-zookeeper-curator5
dubbo-rpc
@ -102,16 +111,35 @@ dubbo-spring-boot-actuator-compatible
dubbo-spring-boot-autoconfigure
dubbo-spring-boot-autoconfigure-compatible
dubbo-spring-boot-compatible
dubbo-spring-boot-observability-starters
dubbo-spring-boot-observability-autoconfigure
dubbo-spring-boot-tracing-brave-zipkin-starter
dubbo-spring-boot-tracing-otel-zipkin-starter
dubbo-spring-boot-tracing-otel-otlp-starter
dubbo-spring-boot-observability-starter
dubbo-observability-spring-boot-starters
dubbo-observability-spring-boot-autoconfigure
dubbo-tracing-brave-zipkin-spring-boot-starter
dubbo-tracing-otel-zipkin-spring-boot-starter
dubbo-tracing-otel-otlp-spring-boot-starter
dubbo-observability-spring-boot-starter
dubbo-spring-boot-starter
dubbo-spring-boot-starters
dubbo-spring-boot-interceptor
dubbo-nacos-spring-boot-starter
dubbo-zookeeper-spring-boot-starter
dubbo-zookeeper-curator5-spring-boot-starter
dubbo-sentinel-spring-boot-starter
dubbo-seata-spring-boot-starter
dubbo-spring-security
dubbo-tracing
dubbo-xds
dubbo-plugin-cluster-mergeable
dubbo-plugin-mock
dubbo-plugin-router-script
dubbo-plugin-router-mesh
dubbo-plugin-router-condition
dubbo-plugin-router-tag
dubbo-plugin-loadbalance-adaptive
dubbo-plugin-access-log
dubbo-plugin-tps
dubbo-plugin-token
dubbo-plugin-generic-invoke
dubbo-plugin-context
dubbo-plugin-classloader-filter
dubbo-plugin-proxy-bytebuddy
dubbo-plugin-qos-trace

View File

@ -54,7 +54,7 @@ jobs:
- uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 8
java-version: 17
- uses: actions/cache@v3
name: "Cache local Maven repository"
with:

View File

@ -97,10 +97,13 @@ header:
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunArguments.java'
- 'dubbo-maven-plugin/src/main/java/org/apache/dubbo/maven/plugin/aot/RunProcess.java'
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/BasicJsonWriter.java'
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/ExecutableMode.java'
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/generate/MemberCategory.java'
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/api/ExecutableMode.java'
- 'dubbo-native/src/main/java/org/apache/dubbo/aot/api/MemberCategory.java'
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboMergingDigest.java'
- 'dubbo-metrics/dubbo-metrics-api/src/main/java/org/apache/dubbo/metrics/aggregate/DubboAbstractTDigest.java'
- 'dubbo-annotation-processor/src/main/java/org/apache/dubbo/annotation/permit/**'
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/FormattingTuple.java'
- 'dubbo-common/src/main/java/org/apache/dubbo/common/logger/helpers/MessageFormatter.java'
comment: on-failure
@ -199,10 +202,26 @@ dependency:
license: Apache-2.0
- name: org.sonatype.plexus:plexus-cipher
license: Apache-2.0
- name: com.alibaba.csp:sentinel-apache-dubbo3-adapter
license: Apache-2.0
- name: com.alibaba.csp:sentinel-transport-simple-http
license: Apache-2.0
- name: com.alibaba.csp:sentinel-transport-common
license: Apache-2.0
- name: com.alibaba.csp:sentinel-datasource-extension
license: Apache-2.0
- name: com.alibaba.csp:sentinel-core
license: Apache-2.0
- name: com.google.protobuf:protobuf-java
license: BSD 3-clause
- name: com.google.protobuf:protobuf-java-util
license: BSD 3-clause
- name: org.antlr:antlr4
license: BSD 3-clause
- name: org.antlr:antlr-runtime
license: BSD 3-clause
- name: org.antlr:ST4
license: BSD 3-clause
# multi license
- name: org.javassist:javassist
license: Apache-2.0

2
NOTICE
View File

@ -4,7 +4,7 @@ Copyright 2018-2023 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (http://www.apache.org/).
This product contains code form the Netty Project:
This product contains code from the Netty Project:
The Netty Project
=================

View File

@ -1,21 +1,8 @@
## What is the purpose of the change
## What is the purpose of the change?
## Brief changelog
## Verifying this change
<!-- Follow this checklist to help us incorporate your contribution quickly and easily: -->
## Checklist
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change (usually before you start working on it). Trivial changes like typos do not require a GitHub issue. Your pull request should address just this issue, without pulling in other changes - one PR resolves one issue.
- [ ] Each commit in the pull request should have a meaningful subject line and body.
- [ ] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [ ] Check if is necessary to patch to Dubbo 3 if you are work on Dubbo 2.7
- [ ] Write necessary unit-test to verify your logic correction, more mock a little better when cross module dependency exist. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
- [ ] Add some description to [dubbo-website](https://github.com/apache/dubbo-website) project if you are requesting to add a feature.
- [ ] GitHub Actions works fine on your own branch.
- [ ] If this contribution is large, please follow the [Software Donation Guide](https://github.com/apache/dubbo/wiki/Software-donation-guide).
- [x] Make sure there is a [GitHub_issue](https://github.com/apache/dubbo/issues) field for the change.
- [x] Write a pull request description that is detailed enough to understand what the pull request does, how, and why.
- [x] Write necessary unit-test to verify your logic correction. If the new feature or significant change is committed, please remember to add sample in [dubbo samples](https://github.com/apache/dubbo-samples) project.
- [x] Make sure gitHub actions can pass. [Why the workflow is failing and how to fix it?](./CONTRIBUTING.md)

255
README.md
View File

@ -10,236 +10,69 @@
[![Twitter Follow](https://img.shields.io/twitter/follow/ApacheDubbo.svg?label=Follow&style=social&logoWidth=0)](https://twitter.com/intent/follow?screen_name=ApacheDubbo)
[![Gitter](https://badges.gitter.im/alibaba/dubbo.svg)](https://gitter.im/alibaba/dubbo?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Apache Dubbo is a high-performance, Java-based open-source RPC framework. Please visit the [official site](http://dubbo.apache.org) for the quick start guide and documentation, as well as the [wiki](https://github.com/apache/dubbo/wiki) for news, FAQ, and release notes.
Apache Dubbo is an easy-to-use Web and RPC framework that provides multiple
language implementations(Java, [Go](https://github.com/apache/dubbo-go), [Rust](https://github.com/apache/dubbo-rust), [Node.js](https://github.com/apache/dubbo-js), [Web](https://github.com/apache/dubbo-js)) for communication, service discovery, traffic management,
observability, security, tools, and best practices for building enterprise-ready microservices.
We are now collecting Dubbo user info to help us to improve Dubbo further. Kindly support us by providing your usage information on [issue#9436: Wanted: who's using dubbo](https://github.com/apache/dubbo/issues/9436), thanks :)
Visit [the official website](https://dubbo.apache.org/) for more information.
## Architecture
![Architecture](https://dubbo.apache.org/imgs/architecture.png)
## Features
* Transparent interface based RPC
* Intelligent load balancing
* Automatic service registration and discovery
* High extensibility
* Runtime traffic routing
* Visualized service governance
* Consumer and provider communicate with each other using RPC protocol like triple, tcp, rest, etc.
* Consumers automatically trace provider instances registered in registries(Zookeeper, Nacos) and distribute traffic among them by following traffic strategies.
* Rich features for monitoring and managing the cluster with dynamic configuration, metrics, tracing, security, and visualized console.
## Getting started
Follow the instructions below to learn how to:
The following code snippet comes from [Dubbo Samples](https://github.com/apache/dubbo-samples.git). You may clone the sample project and step into the `dubbo-samples-api` subdirectory before proceeding.
### Programming with lightweight RPC API
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/rpc/java)
```bash
git clone https://github.com/apache/dubbo-samples.git
cd dubbo-samples/1-basic/dubbo-samples-api
```
There's a [README](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/README.md) file under `dubbo-samples-api` directory. We recommend referencing the samples in that directory by following the below-mentioned instructions:
### Maven dependency
```xml
<properties>
<dubbo.version>3.2.5</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
</dependency>
</dependencies>
```
### Define service interfaces
```java
package org.apache.dubbo.samples.api;
public interface GreetingsService {
String sayHi(String name);
}
```
*See [api/GreetingsService.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/api/GreetingsService.java) on GitHub.*
### Implement service interface for the provider
```java
package org.apache.dubbo.samples.provider;
import org.apache.dubbo.samples.api.GreetingsService;
public class GreetingsServiceImpl implements GreetingsService {
@Override
public String sayHi(String name) {
return "hi, " + name;
}
}
```
*See [provider/GreetingsServiceImpl.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/provider/GreetingsServiceImpl.java) on GitHub.*
### Start service provider
```java
package org.apache.dubbo.samples.provider;
Dubbo supports building RPC services with only a few lines of code while depending only on a lightweight SDK (<10MB). The protocol on the wire can be [Triple](https://dubbo.apache.org/zh-cn/overview/reference/protocols/triple/)(fully gRPC compatible and HTTP-friendly), Dubbo2(TCP), REST, or any protocol of your choice.
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.samples.api.GreetingsService;
### Building a microservice application with Spring Boot
[5 minutes step-by-step guide](https://dubbo.apache.org/zh-cn/overview/quickstart/microservice)
import java.util.concurrent.CountDownLatch;
It's highly recommended to start your microservice application with the Spring Boot Starter `dubbo-spring-boot-starter` provided by Dubbo. With only a single dependency and yaml file, and optionally a bunch of other useful spring boot starters, you can enable all of the Dubo features like service discovery, observability, tracing, etc.
public class Application {
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
Next, learn how to [deploy](https://dubbo.apache.org/zh-cn/overview/tasks/deploy/), [monitor](https://dubbo.apache.org/zh-cn/overview/tasks/observability/), and [manage the traffic](https://dubbo.apache.org/zh-cn/overview/tasks/traffic-management/) of your Dubbo application and cluster.
public static void main(String[] args) throws Exception {
ServiceConfig<GreetingsService> service = new ServiceConfig<>();
service.setApplication(new ApplicationConfig("first-dubbo-provider"));
service.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
service.setInterface(GreetingsService.class);
service.setRef(new GreetingsServiceImpl());
service.export();
## More Features
Get more details by visiting the links below to get your hands dirty with some well-designed tasks on our website.
System.out.println("dubbo service started");
new CountDownLatch(1).await();
}
}
```
* [Launch a Dubbo project](https://dubbo.apache.org/zh-cn/overview/tasks/develop/template/)
* [RPC protocols](https://dubbo.apache.org/zh-cn/overview/core-features/protocols/)
* [Traffic management](https://dubbo.apache.org/zh-cn/overview/core-features/traffic/)
* [Service discovery](https://dubbo.apache.org/zh-cn/overview/core-features/service-discovery/)
* [Observability](https://dubbo.apache.org/zh-cn/overview/core-features/observability/)
* [Extensibility](https://dubbo.apache.org/zh-cn/overview/core-features/extensibility/)
* [Security](https://dubbo.apache.org/zh-cn/overview/core-features/security/)
* [Visualized console and control plane](https://dubbo.apache.org/zh-cn/overview/reference/admin/)
* [Kubernetes and Service mesh](https://dubbo.apache.org/zh-cn/overview/core-features/service-mesh/)
*See [provider/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-spring-xml/src/main/java/org/apache/dubbo/samples/provider/Application.java) on GitHub.*
## Which Dubbo version should I use?
| **Dubbo3** | **JDK** | **Dependencies** | **Description** |
| --- | --- | --- | --- |
| 3.3.0-beta| 1.8 17 | [dependency list](https://github.com/apache/dubbo/blob/3.3/dubbo-dependencies-bom/pom.xml#L94) | **- Unstable version** <br/> **- Features** <br/> &nbsp;&nbsp; - Triple - gRPC and cURL compatible.<br/> &nbsp;&nbsp; - Rest-style programming support.<br/> &nbsp;&nbsp; - Spring Boot Starters. |
| 3.2.5 | 1.8 17 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.5/dubbo-dependencies-bom/pom.xml#L94) | **- Stable version (active)** <br/> **- Features** <br/> &nbsp;&nbsp;- Out-of-box metrics and tracing support.<br/> &nbsp;&nbsp;- Threadpool Isolation<br/> &nbsp;&nbsp;- 30% performance<br/> &nbsp;&nbsp;- Native Image|
| 3.1.11 | 1.8 11 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-3.2.11/dubbo-dependencies-bom/pom.xml#L94) | **Stable version (not active)** |
### Build and run the provider
```bash
mvn clean package
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.provider.Application exec:java
```
### Call remote service in the consumer
```java
package org.apache.dubbo.samples.client;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.samples.api.GreetingsService;
public class Application {
private static String zookeeperHost = System.getProperty("zookeeper.address", "127.0.0.1");
public static void main(String[] args) {
ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
reference.setInterface(GreetingsService.class);
GreetingsService service = reference.get();
String message = service.sayHi("dubbo");
System.out.println(message);
}
}
```
*See [client/Application.java](https://github.com/apache/dubbo-samples/blob/389cd612f1ea57ee6e575005b32f195c442c35a2/1-basic/dubbo-samples-api/src/main/java/org/apache/dubbo/samples/client/Application.java) on GitHub.*
### Build and run the consumer
```bash
mvn clean package
mvn -Djava.net.preferIPv4Stack=true -Dexec.mainClass=org.apache.dubbo.samples.client.Application exec:java
```
The consumer will print out `hi, dubbo` on the screen.
### Next steps
* [Your first Dubbo application](https://dubbo.apache.org/en/blog/2018/08/07/dubbo-101/) - A 101 tutorial to reveal more details, with the same code above.
* [Dubbo user manual](https://dubbo.apache.org/en/overview/what/) - How to use Dubbo and all its features.
* [Dubbo developer guide](https://dubbo.apache.org/en/docs3-v2/java-sdk/) - How to involve in Dubbo development.
* [Dubbo admin manual](https://dubbo.apache.org/en/docs/v2.7/admin/ops/) - How to admin and manage Dubbo services.
## Building
If you want to try out the cutting-edge features, you can build with the following commands. (Java 1.8 is needed to build the master branch)
```
mvn clean install
```
## Recommended Test Environment
To avoid intermittent test failures (i.e., flaky tests), it is recommended to have a machine or virtual machine with the following specifications:
* Minimum of 2CPUs.
* Minimum of 2Gb of RAM.
## Contact
* Mailing list:
* dev list: for dev/user discussion. [subscribe](mailto:dev-subscribe@dubbo.apache.org), [unsubscribe](mailto:dev-unsubscribe@dubbo.apache.org), [archive](https://lists.apache.org/list.html?dev@dubbo.apache.org), [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide)
* Bugs: [Issues](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md)
* Gitter: [Gitter channel](https://gitter.im/alibaba/dubbo)
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
| **Dubbo2** | **JDK** | **Dependencies** | **Description** |
| --- | --- | --- | --- |
| 2.7.23 | 1.8 | [dependency list](https://github.com/apache/dubbo/blob/dubbo-2.7.23/dubbo-dependencies-bom/pom.xml#L92) | EOL |
| 2.6.x, 2.5.x | 1.6 1.7 | | EOL |
## Contributing
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
See [CONTRIBUTING](https://github.com/apache/dubbo/blob/master/CONTRIBUTING.md) for details on submitting patches and the contribution workflow.
### How can I contribute?
* Take a look at issues with tags marked [`Good first issue`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22) or [`Help wanted`](https://github.com/apache/dubbo/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22).
* Join the discussion on the mailing list, subscription [guide](https://github.com/apache/dubbo/wiki/Mailing-list-subscription-guide).
* Answer questions on [issues](https://github.com/apache/dubbo/issues).
* Fix bugs reported on [issues](https://github.com/apache/dubbo/issues), and send us a pull request.
* Review the existing [pull request](https://github.com/apache/dubbo/pulls).
* Improve the [website](https://github.com/apache/dubbo-website), typically we need
* blog post
* translation on documentation
* use cases around the integration of Dubbo in enterprise systems.
* Improve the [dubbo-admin/dubbo-monitor](https://github.com/apache/dubbo-admin).
* Contribute to the projects listed in [ecosystem](https://github.com/dubbo).
* Other forms of contribution not explicitly enumerated above.
* If you would like to contribute, please send an email to dev@dubbo.apache.org to let us know!
## Reporting bugs
Please follow the [template](https://github.com/apache/dubbo/issues/new?template=dubbo-issue-report-template.md) for reporting any issues.
## Reporting a security vulnerability
Please report security vulnerabilities to [us](mailto:security@dubbo.apache.org) privately.
## Dubbo ecosystem
* [Dubbo Ecosystem Entry](https://github.com/apache?utf8=%E2%9C%93&q=dubbo&type=&language=) - A GitHub group `dubbo` to gather all Dubbo relevant projects not appropriate in [apache](https://github.com/apache) group yet
* [Dubbo Website](https://github.com/apache/dubbo-website) - Apache Dubbo official website
* [Dubbo Samples](https://github.com/apache/dubbo-samples) - samples for Apache Dubbo
* [Dubbo Spring Boot](https://github.com/apache/dubbo-spring-boot-project) - Spring Boot Project for Dubbo
* [Dubbo Admin](https://github.com/apache/dubbo-admin) - The reference implementation for Dubbo admin
* [Dubbo Awesome](https://github.com/apache/dubbo-awesome) - Dubbo's slides and video links in Meetup
#### Language
* [Go](https://github.com/dubbo/dubbo-go) (recommended)
* [Node.js](https://github.com/apache/dubbo-js)
* [Python](https://github.com/dubbo/py-client-for-apache-dubbo)
* [PHP](https://github.com/apache/dubbo-php-framework)
* [Erlang](https://github.com/apache/dubbo-erlang)
## Contact
* WeChat: apachedubbo
* DingTalk group: 37290003945
* Mailing list: [guide](https://dubbo.apache.org/zh-cn/contact/)
* Twitter: [@ApacheDubbo](https://twitter.com/ApacheDubbo)
* Security issues: please mail to [us](mailto:security@dubbo.apache.org) privately.
## License
Apache Dubbo software is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.
Apache Dubbo is licensed under the Apache License Version 2.0. See the [LICENSE](https://github.com/apache/dubbo/blob/master/LICENSE) file for details.

View File

@ -29,7 +29,6 @@ ignore:
- "**/dubbo-test/**"
- "**/dubbo-compatible/**"
- "**/dubbo-native/**"
- "**/dubbo-native-plugin/**"
- "**/dubbo-common/src/main/java/org/apache/dubbo/common/json/*.java" # internal JSON impl is deprecate, ignore test coverage for them
- "**/dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/AnnotationBean.java" # Deprecated
- "**/dubbo-rpc/dubbo-rpc-thrift/**"

View File

@ -0,0 +1,165 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-annotation-processor</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- System dependencies may cause problems in checkstyle. -->
<checkstyle.skip>true</checkstyle.skip>
<checkstyle_unix.skip>true</checkstyle_unix.skip>
<rat.skip>true</rat.skip>
<jacoco.skip>true</jacoco.skip>
<maven.deploy.skip>true</maven.deploy.skip>
<junit_jupiter_version>5.9.0</junit_jupiter_version>
<javassist_version>3.29.2-GA</javassist_version>
</properties>
<packaging>jar</packaging>
<dependencies>
<!-- JUnit Jupiter Engine to depend on the JUnit5 engine and JUnit 5 API -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit_jupiter_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit_jupiter_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>${junit_jupiter_version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>${javassist_version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<proc>none</proc>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>default-profile-in-jdk-8</id>
<activation>
<file>
<exists>${java.home}/../lib/tools.jar</exists>
</file>
<jdk>(, 9)</jdk>
</activation>
<properties>
<toolsjar>${java.home}/../lib/tools.jar</toolsjar>
</properties>
<dependencies>
<dependency>
<groupId>javac</groupId>
<artifactId>javac</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${toolsjar}</systemPath>
</dependency>
</dependencies>
</profile>
<profile>
<id>legacy-apple-jdk-profile</id>
<activation>
<activeByDefault>false</activeByDefault>
<file>
<exists>${java.home}/../Classes/classes.jar</exists>
</file>
<jdk>(, 9)</jdk>
</activation>
<properties>
<toolsjar>${java.home}/../Classes/classes.jar</toolsjar>
</properties>
<dependencies>
<dependency>
<groupId>javac</groupId>
<artifactId>javac</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${toolsjar}</systemPath>
</dependency>
</dependencies>
</profile>
<profile>
<id>add-export-greater-than-9</id>
<activation>
<activeByDefault>false</activeByDefault>
<jdk>[9, )</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
<configuration>
<fork>true</fork>
<proc>none</proc>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,44 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.annotation;
import javax.lang.model.element.Element;
import java.lang.annotation.Annotation;
import java.util.Set;
/**
* Represents an annotation processing handler, which is invoked by DispatchingAnnotationProcessor.
*/
public interface AnnotationProcessingHandler {
/**
* Set the annotations that this handler will handle.
*
* @return annotations to handle
*/
Set<Class<? extends Annotation>> getAnnotationsToHandle();
/**
* Formal processing method.
*
* @param elements the elements that annotated by the annotations of getAnnotationsToHandle()
* @param annotationProcessorContext the annotation processor context object (Javac object encapsulation)
*/
void process(Set<Element> elements,
AnnotationProcessorContext annotationProcessorContext);
}

View File

@ -0,0 +1,139 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.annotation;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names;
import javax.annotation.processing.ProcessingEnvironment;
import java.lang.reflect.Method;
import java.util.Objects;
/**
* The Context Object of Annotation Processor, which stores objects related to javac.
*/
public class AnnotationProcessorContext {
private JavacProcessingEnvironment javacProcessingEnvironment;
private JavacTrees javacTrees;
private TreeMaker treeMaker;
private Names names;
private Context javacContext;
private Trees trees;
private AnnotationProcessorContext() { }
private static <T> T jbUnwrap(Class<? extends T> iface, T wrapper) {
T unwrapped = null;
try {
final Class<?> apiWrappers = wrapper.getClass().getClassLoader().loadClass("org.jetbrains.jps.javac.APIWrappers");
final Method unwrapMethod = apiWrappers.getDeclaredMethod("unwrap", Class.class, Object.class);
unwrapped = iface.cast(unwrapMethod.invoke(null, iface, wrapper));
} catch (Throwable ignored) {
}
return unwrapped != null ? unwrapped : wrapper;
}
public static AnnotationProcessorContext fromProcessingEnvironment(ProcessingEnvironment processingEnv) {
AnnotationProcessorContext apContext = new AnnotationProcessorContext();
Object procEnvToUnwrap = processingEnv.getClass() == JavacProcessingEnvironment.class ?
processingEnv : jbUnwrap(JavacProcessingEnvironment.class, processingEnv);
JavacProcessingEnvironment jcProcessingEnvironment = (JavacProcessingEnvironment) procEnvToUnwrap;
Context context = jcProcessingEnvironment.getContext();
apContext.javacProcessingEnvironment = jcProcessingEnvironment;
apContext.javacContext = context;
apContext.javacTrees = JavacTrees.instance(jcProcessingEnvironment);
apContext.treeMaker = TreeMaker.instance(context);
apContext.names = Names.instance(context);
apContext.trees = Trees.instance(jcProcessingEnvironment);
return apContext;
}
// Auto-generated methods.
public JavacTrees getJavacTrees() {
return javacTrees;
}
public TreeMaker getTreeMaker() {
return treeMaker;
}
public Names getNames() {
return names;
}
public Context getJavacContext() {
return javacContext;
}
public Trees getTrees() {
return trees;
}
public JavacProcessingEnvironment getJavacProcessingEnvironment() {
return javacProcessingEnvironment;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AnnotationProcessorContext context = (AnnotationProcessorContext) o;
if (!Objects.equals(javacTrees, context.javacTrees)) return false;
if (!Objects.equals(treeMaker, context.treeMaker)) return false;
if (!Objects.equals(names, context.names)) return false;
if (!Objects.equals(javacContext, context.javacContext))
return false;
return Objects.equals(trees, context.trees);
}
@Override
public int hashCode() {
int result = javacTrees != null ? javacTrees.hashCode() : 0;
result = 31 * result + (treeMaker != null ? treeMaker.hashCode() : 0);
result = 31 * result + (names != null ? names.hashCode() : 0);
result = 31 * result + (javacContext != null ? javacContext.hashCode() : 0);
result = 31 * result + (trees != null ? trees.hashCode() : 0);
return result;
}
@Override
public String toString() {
return "AnnotationProcessorContext{" +
"javacTrees=" + javacTrees +
", treeMaker=" + treeMaker +
", names=" + names +
", javacContext=" + javacContext +
", trees=" + trees +
'}';
}
}

View File

@ -0,0 +1,162 @@
/*
* 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.annotation;
import org.apache.dubbo.annotation.permit.Permit;
import org.apache.dubbo.annotation.util.FileUtils;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.processing.JavacRoundEnvironment;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Dispatching annotation processor, which uses a file to locate handlers and invoke them.
*/
@SupportedAnnotationTypes("*")
public class DispatchingAnnotationProcessor extends AbstractProcessor {
private static Set<AnnotationProcessingHandler> handlers;
private static Set<AnnotationProcessingHandler> loadHandlers() {
List<String> classNames = FileUtils.loadConfigurationFileInResources("handlers.cfg");
Set<AnnotationProcessingHandler> tempHandlers = new HashSet<>();
for (String clsName : classNames) {
try {
Class<? extends AnnotationProcessingHandler> cls = (Class<? extends AnnotationProcessingHandler>) Class.forName(clsName);
AnnotationProcessingHandler r = cls.getConstructor().newInstance();
tempHandlers.add(r);
} catch (InstantiationException | NoSuchMethodException | InvocationTargetException |
IllegalAccessException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
return Collections.unmodifiableSet(tempHandlers);
}
private AnnotationProcessorContext apContext;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
Permit.addOpens();
super.init(processingEnv);
if (processingEnv.getClass().getName().startsWith("org.eclipse.jdt.")) {
// Don't run on ECJ, since this processor is javac based.
processingEnv
.getMessager()
.printMessage(Diagnostic.Kind.WARNING, "The Annotation processor doesn't support ECJ.");
return;
}
if (handlers == null) {
handlers = loadHandlers();
}
apContext = AnnotationProcessorContext.fromProcessingEnvironment(processingEnv);
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (processingEnv.getClass().getName().startsWith("org.eclipse.jdt.")) {
// Don't run on ECJ, since this processor is javac based.
return false;
}
for (AnnotationProcessingHandler i : handlers) {
Set<Element> elements = new HashSet<>(16);
for (Class<? extends Annotation> annotationClass : i.getAnnotationsToHandle()) {
elements.addAll(getElementsAnnotatedWith(annotationClass, roundEnv));
}
i.process(elements, apContext);
}
return false;
}
/**
* A hack to make comment only .java file pass the compilation by skipping package symbol scan.
*
* @param annotationClass the annotation class to find
* @param roundEnvironment the javac's round environment
* @return the elements annotated with specified annotation
*/
private Set<? extends Element> getElementsAnnotatedWith(Class<? extends Annotation> annotationClass, RoundEnvironment roundEnvironment) {
TypeElement a = processingEnv.getElementUtils().getTypeElement(annotationClass.getCanonicalName());
// Detect the Javac's version.
if (Integer.parseInt(SourceVersion.latest().name().split("_")[1]) > 8) {
return roundEnvironment.getElementsAnnotatedWith(a);
}
Set<Element> result = Collections.emptySet();
try {
Class annotationSetScannerClass = Class.forName("com.sun.tools.javac.processing.JavacRoundEnvironment$AnnotationSetScanner");
Constructor scannerConstructor = Permit.getConstructor(annotationSetScannerClass, JavacRoundEnvironment.class, Set.class);
Object scanner = scannerConstructor.newInstance(roundEnvironment, result);
Set<? extends Element> rootElements1 = roundEnvironment
.getRootElements()
.stream()
.filter(x -> x.getClass() != Symbol.PackageSymbol.class)
.collect(Collectors.toSet());
for (Element element : rootElements1) {
Method scanningMethod = Permit.getMethod(annotationSetScannerClass, "scan", Element.class, TypeElement.class);
result = (Set<Element>) scanningMethod.invoke(scanner, element, a);
}
} catch (InstantiationException | NoSuchMethodException | ClassNotFoundException | InvocationTargetException |
IllegalAccessException e) {
throw new RuntimeException(e);
}
return result;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}

View File

@ -0,0 +1,110 @@
/*
* 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.annotation.handler;
import org.apache.dubbo.annotation.AnnotationProcessingHandler;
import org.apache.dubbo.annotation.AnnotationProcessorContext;
import org.apache.dubbo.annotation.util.ASTUtils;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.TreeTranslator;
import javax.lang.model.element.Element;
import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Handles @Deprecated annotation and adds logger warn call to the methods that are annotated with it.
*/
public class DeprecatedHandler implements AnnotationProcessingHandler {
@Override
public Set<Class<? extends Annotation>> getAnnotationsToHandle() {
return new HashSet<>(
Collections.singletonList(Deprecated.class)
);
}
@Override
public void process(Set<Element> elements, AnnotationProcessorContext apContext) {
for (Element element : elements) {
// Only interested in methods.
if (!(element instanceof Symbol.MethodSymbol)) {
continue;
}
Symbol.ClassSymbol classSymbol = (Symbol.ClassSymbol) element.getEnclosingElement();
ASTUtils.addImportStatement(apContext, classSymbol, "org.apache.dubbo.common", "DeprecatedMethodInvocationCounter");
JCTree methodTree = apContext.getJavacTrees().getTree(element);
methodTree.accept(new TreeTranslator() {
@Override
public void visitMethodDef(JCTree.JCMethodDecl jcMethodDecl) {
JCTree.JCBlock block = jcMethodDecl.body;
if (block == null) {
// No method body. (i.e. interface method declaration.)
return;
}
ASTUtils.insertStatementToHeadOfMethod(block, jcMethodDecl, generateCounterStatement(apContext, classSymbol, jcMethodDecl));
}
});
}
}
/**
* Generate an expression statement like this:
* <code>DeprecatedMethodInvocationCounter.onDeprecatedMethodCalled("....");
*
* @param originalMethodDecl the method declaration that will add logger statement
* @param apContext annotation processor context
* @param classSymbol the enclosing class that will be the logger's name
* @return generated expression statement
*/
private JCTree.JCExpressionStatement generateCounterStatement(AnnotationProcessorContext apContext,
Symbol.ClassSymbol classSymbol,
JCTree.JCMethodDecl originalMethodDecl) {
JCTree.JCExpression fullStatement = apContext.getTreeMaker().Apply(
com.sun.tools.javac.util.List.nil(),
apContext.getTreeMaker().Select(
apContext.getTreeMaker().Ident(apContext.getNames().fromString("DeprecatedMethodInvocationCounter")),
apContext.getNames().fromString("onDeprecatedMethodCalled")
),
com.sun.tools.javac.util.List.of(
apContext.getTreeMaker().Literal(getMethodDefinition(classSymbol, originalMethodDecl))
)
);
return apContext.getTreeMaker().Exec(fullStatement);
}
private String getMethodDefinition(Symbol.ClassSymbol classSymbol, JCTree.JCMethodDecl originalMethodDecl) {
return classSymbol.getQualifiedName() + "."
+ originalMethodDecl.name.toString() + "(" + originalMethodDecl.params.toString() + ")";
}
}

View File

@ -0,0 +1,429 @@
/*
* Authored by Project Lombok and licensed by MIT License, which is attached below:
*
* Copyright (C) 2018-2021 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.apache.dubbo.annotation.permit;
import org.apache.dubbo.annotation.permit.dummy.Parent;
import sun.misc.Unsafe;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
// sunapi suppresses javac's warning about using Unsafe; 'all' suppresses eclipse's warning about the unspecified 'sunapi' key. Leave them both.
// Yes, javac's definition of the word 'all' is quite contrary to what the dictionary says it means. 'all' does NOT include 'sunapi' according to javac.
@SuppressWarnings({"sunapi", "all"})
public class Permit {
private Permit() {
}
private static final long ACCESSIBLE_OVERRIDE_FIELD_OFFSET;
private static final IllegalAccessException INIT_ERROR;
private static final sun.misc.Unsafe UNSAFE = (sun.misc.Unsafe) reflectiveStaticFieldAccess(sun.misc.Unsafe.class, "theUnsafe");
static {
Field f;
long g;
Throwable ex;
try {
g = getOverrideFieldOffset();
ex = null;
} catch (Throwable t) {
f = null;
g = -1L;
ex = t;
}
ACCESSIBLE_OVERRIDE_FIELD_OFFSET = g;
if (ex == null) INIT_ERROR = null;
else if (ex instanceof IllegalAccessException) INIT_ERROR = (IllegalAccessException) ex;
else {
INIT_ERROR = new IllegalAccessException("Cannot initialize Unsafe-based permit");
INIT_ERROR.initCause(ex);
}
}
public static <T extends AccessibleObject> T setAccessible(T accessor) {
if (INIT_ERROR == null) {
UNSAFE.putBoolean(accessor, ACCESSIBLE_OVERRIDE_FIELD_OFFSET, true);
} else {
accessor.setAccessible(true);
}
return accessor;
}
private static long getOverrideFieldOffset() throws Throwable {
Field f = null;
Throwable saved = null;
try {
f = AccessibleObject.class.getDeclaredField("override");
} catch (Throwable t) {
saved = t;
}
if (f != null) {
return UNSAFE.objectFieldOffset(f);
}
// The below seems very risky, but for all AccessibleObjects in java today it does work, and starting with JDK12, making the field accessible is no longer possible.
try {
return UNSAFE.objectFieldOffset(Fake.class.getDeclaredField("override"));
} catch (Throwable t) {
throw saved;
}
}
static class Fake {
boolean override;
Object accessCheckCache;
}
public static Method getMethod(Class<?> c, String mName, Class<?>... parameterTypes) throws NoSuchMethodException {
Method m = null;
Class<?> oc = c;
while (c != null) {
try {
m = c.getDeclaredMethod(mName, parameterTypes);
break;
} catch (NoSuchMethodException e) {
}
c = c.getSuperclass();
}
if (m == null) throw new NoSuchMethodException(oc.getName() + " :: " + mName + "(args)");
return setAccessible(m);
}
public static Method permissiveGetMethod(Class<?> c, String mName, Class<?>... parameterTypes) {
try {
return getMethod(c, mName, parameterTypes);
} catch (Exception ignore) {
return null;
}
}
public static Field getField(Class<?> c, String fName) throws NoSuchFieldException {
Field f = null;
Class<?> oc = c;
while (c != null) {
try {
f = c.getDeclaredField(fName);
break;
} catch (NoSuchFieldException e) {
}
c = c.getSuperclass();
}
if (f == null) throw new NoSuchFieldException(oc.getName() + " :: " + fName);
return setAccessible(f);
}
public static Field permissiveGetField(Class<?> c, String fName) {
try {
return getField(c, fName);
} catch (Exception ignore) {
return null;
}
}
public static <T> T permissiveReadField(Class<T> type, Field f, Object instance) {
try {
return type.cast(f.get(instance));
} catch (Exception ignore) {
return null;
}
}
public static <T> Constructor<T> getConstructor(Class<T> c, Class<?>... parameterTypes) throws NoSuchMethodException {
return setAccessible(c.getDeclaredConstructor(parameterTypes));
}
private static Object reflectiveStaticFieldAccess(Class<?> c, String fName) {
try {
Field f = c.getDeclaredField(fName);
f.setAccessible(true);
return f.get(null);
} catch (Exception e) {
return null;
}
}
public static boolean isDebugReflection() {
return !"false".equals(System.getProperty("lombok.debug.reflection", "false"));
}
public static void handleReflectionDebug(Throwable t, Throwable initError) {
if (!isDebugReflection()) return;
System.err.println("** LOMBOK REFLECTION exception: " + t.getClass() + ": " + (t.getMessage() == null ? "(no message)" : t.getMessage()));
t.printStackTrace(System.err);
if (initError != null) {
System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: ");
initError.printStackTrace(System.err);
}
}
public static Object invoke(Method m, Object receiver, Object... args) throws IllegalAccessException, InvocationTargetException {
return invoke(null, m, receiver, args);
}
public static Object invoke(Throwable initError, Method m, Object receiver, Object... args) throws IllegalAccessException, InvocationTargetException {
try {
return m.invoke(receiver, args);
} catch (IllegalAccessException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (RuntimeException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (Error e) {
handleReflectionDebug(e, initError);
throw e;
}
}
public static Object invokeSneaky(Method m, Object receiver, Object... args) {
return invokeSneaky(null, m, receiver, args);
}
public static Object invokeSneaky(Throwable initError, Method m, Object receiver, Object... args) {
try {
return m.invoke(receiver, args);
} catch (NoClassDefFoundError e) {
handleReflectionDebug(e, initError);
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
//do anything useful here.
return null;
} catch (NullPointerException e) {
handleReflectionDebug(e, initError);
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
//do anything useful here.
return null;
} catch (IllegalAccessException e) {
handleReflectionDebug(e, initError);
throw sneakyThrow(e);
} catch (InvocationTargetException e) {
throw sneakyThrow(e.getCause());
} catch (RuntimeException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (Error e) {
handleReflectionDebug(e, initError);
throw e;
}
}
public static <T> T newInstance(Constructor<T> c, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
return newInstance(null, c, args);
}
public static <T> T newInstance(Throwable initError, Constructor<T> c, Object... args) throws IllegalAccessException, InvocationTargetException, InstantiationException {
try {
return c.newInstance(args);
} catch (IllegalAccessException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (InstantiationException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (RuntimeException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (Error e) {
handleReflectionDebug(e, initError);
throw e;
}
}
public static <T> T newInstanceSneaky(Constructor<T> c, Object... args) {
return newInstanceSneaky(null, c, args);
}
public static <T> T newInstanceSneaky(Throwable initError, Constructor<T> c, Object... args) {
try {
return c.newInstance(args);
} catch (NoClassDefFoundError e) {
handleReflectionDebug(e, initError);
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
//do anything useful here.
return null;
} catch (NullPointerException e) {
handleReflectionDebug(e, initError);
//ignore, we don't have access to the correct ECJ classes, so lombok can't possibly
//do anything useful here.
return null;
} catch (IllegalAccessException e) {
handleReflectionDebug(e, initError);
throw sneakyThrow(e);
} catch (InstantiationException e) {
handleReflectionDebug(e, initError);
throw sneakyThrow(e);
} catch (InvocationTargetException e) {
throw sneakyThrow(e.getCause());
} catch (RuntimeException e) {
handleReflectionDebug(e, initError);
throw e;
} catch (Error e) {
handleReflectionDebug(e, initError);
throw e;
}
}
public static Object get(Field f, Object receiver) throws IllegalAccessException {
try {
return f.get(receiver);
} catch (IllegalAccessException e) {
handleReflectionDebug(e, null);
throw e;
} catch (RuntimeException e) {
handleReflectionDebug(e, null);
throw e;
} catch (Error e) {
handleReflectionDebug(e, null);
throw e;
}
}
public static void set(Field f, Object receiver, Object newValue) throws IllegalAccessException {
try {
f.set(receiver, newValue);
} catch (IllegalAccessException e) {
handleReflectionDebug(e, null);
throw e;
} catch (RuntimeException e) {
handleReflectionDebug(e, null);
throw e;
} catch (Error e) {
handleReflectionDebug(e, null);
throw e;
}
}
public static void reportReflectionProblem(Throwable initError, String msg) {
if (!isDebugReflection()) return;
System.err.println("** LOMBOK REFLECTION issue: " + msg);
if (initError != null) {
System.err.println("*** ADDITIONALLY, exception occurred setting up reflection: ");
initError.printStackTrace(System.err);
}
}
public static RuntimeException sneakyThrow(Throwable t) {
if (t == null) throw new NullPointerException("t");
return Permit.<RuntimeException>sneakyThrow0(t);
}
@SuppressWarnings("unchecked")
private static <T extends Throwable> T sneakyThrow0(Throwable t) throws T {
throw (T) t;
}
private static Object getJdkCompilerModule() {
/* call public api: ModuleLayer.boot().findModule("jdk.compiler").get();
but use reflection because we don't want this code to crash on jdk1.7 and below.
In that case, none of this stuff was needed in the first place, so we just exit via
the catch block and do nothing.
*/
try {
Class<?> cModuleLayer = Class.forName("java.lang.ModuleLayer");
Method mBoot = cModuleLayer.getDeclaredMethod("boot");
Object bootLayer = mBoot.invoke(null);
Class<?> cOptional = Class.forName("java.util.Optional");
Method mFindModule = cModuleLayer.getDeclaredMethod("findModule", String.class);
Object oCompilerO = mFindModule.invoke(bootLayer, "jdk.compiler");
return cOptional.getDeclaredMethod("get").invoke(oCompilerO);
} catch (Exception e) {
return null;
}
}
private static Object getOwnModule() {
try {
Method m = Permit.getMethod(Class.class, "getModule");
return m.invoke(Permit.class);
} catch (Exception e) {
return null;
}
}
private static long getFirstFieldOffset(Unsafe unsafe) {
try {
return unsafe.objectFieldOffset(Parent.class.getDeclaredField("first"));
} catch (NoSuchFieldException e) {
// can't happen.
throw new RuntimeException(e);
} catch (SecurityException e) {
// can't happen
throw new RuntimeException(e);
}
}
public static void addOpens() {
Class<?> cModule;
try {
cModule = Class.forName("java.lang.Module");
} catch (ClassNotFoundException e) {
return; //jdk8-; this is not needed.
}
Unsafe unsafe = UNSAFE;
Object jdkCompilerModule = getJdkCompilerModule();
Object ownModule = getOwnModule();
String[] allPkgs = {
"com.sun.tools.javac.code",
"com.sun.tools.javac.comp",
"com.sun.tools.javac.file",
"com.sun.tools.javac.main",
"com.sun.tools.javac.model",
"com.sun.tools.javac.parser",
"com.sun.tools.javac.processing",
"com.sun.tools.javac.tree",
"com.sun.tools.javac.util",
"com.sun.tools.javac.jvm",
"com.sun.tools.javac.api"
};
try {
Method m = cModule.getDeclaredMethod("implAddOpens", String.class, cModule);
long firstFieldOffset = getFirstFieldOffset(unsafe);
unsafe.putBooleanVolatile(m, firstFieldOffset, true);
for (String p : allPkgs) m.invoke(jdkCompilerModule, p, ownModule);
} catch (Exception ignore) {}
try {
Method m = cModule.getDeclaredMethod("implAddExports", String.class, cModule);
long firstFieldOffset = getFirstFieldOffset(unsafe);
unsafe.putBooleanVolatile(m, firstFieldOffset, true);
for (String p : allPkgs) m.invoke(jdkCompilerModule, p, ownModule);
} catch (Exception ignore) {}
}
}

View File

@ -0,0 +1,33 @@
/*
* Authored by Project Lombok and licensed by MIT License, which is attached below:
*
* Copyright (C) 2018-2021 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.apache.dubbo.annotation.permit.dummy;
@SuppressWarnings("all")
public abstract class Child extends Parent {
private transient volatile boolean foo;
private transient volatile Object[] bar;
private transient volatile Object baz;
}

View File

@ -0,0 +1,43 @@
/*
* Authored by Project Lombok and licensed by MIT License, which is attached below:
*
* Copyright (C) 2018-2021 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.apache.dubbo.annotation.permit.dummy;
@SuppressWarnings("all")
public final class GrandChild extends Child {
private Class<?> a;
private int b;
private String c;
private Class<?> d;
private Class<?>[] e;
private Class<?>[] f;
private int g;
private transient String h;
private transient Object i;
private byte[] j;
private byte[] k;
private byte[] l;
private volatile Object m;
private Object n;
}

View File

@ -0,0 +1,36 @@
/*
* Authored by Project Lombok and licensed by MIT License, which is attached below:
*
* Copyright (C) 2018-2021 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.apache.dubbo.annotation.permit.dummy;
import java.io.OutputStream;
@SuppressWarnings("all")
public class Parent {
boolean first;
static final Object staticObj = OutputStream.class;
volatile Object second;
private static volatile boolean staticSecond;
private static volatile boolean staticThird;
}

View File

@ -0,0 +1,32 @@
/*
* Authored by Project Lombok and licensed by MIT License, which is attached below:
*
* Copyright (C) 2018-2021 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* This package recreates the type hierarchy of {@code java.lang.reflect.AccessibleObject} and friends (such as {@code java.lang.reflect.Method});
* its purpose is to allow us to ask {@code sun.misc.internal.Unsafe} about the exact offset of the {@code override} field of {@code AccessibleObject};
* asking about that field directly doesn't work after jdk14, presumably because the fields of AO are expressly hidden somehow.
* <p>
* NB: It's usually 12, on the vast majority of OS, VM, and architecture combos.
*/
package org.apache.dubbo.annotation.permit.dummy;

View File

@ -0,0 +1,32 @@
/*
* Authored by Project Lombok and licensed by MIT License, which is attached below:
*
* Copyright (C) 2018-2021 The Project Lombok Authors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* This is a reduced copy of the nqzero Permit-reflect project.
* https://github.com/nqzero/permit-reflect
* <p>
* Many thanks to nqzero. The permit-reflect project is, like lombok itself, licensed under the MIT license.
* See https://github.com/nqzero/permit-reflect/blob/master/License for license info.
*/
package org.apache.dubbo.annotation.permit;

View File

@ -0,0 +1,111 @@
/*
* 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.annotation.util;
import org.apache.dubbo.annotation.AnnotationProcessorContext;
import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.ListBuffer;
import java.util.List;
/**
* Some utils about AST manipulating.
*/
public final class ASTUtils {
private ASTUtils() {
throw new UnsupportedOperationException("No instance of 'ASTUtils' for you! ");
}
public static void addImportStatement(AnnotationProcessorContext apContext,
Symbol.ClassSymbol classSymbol,
String packageName,
String className) {
JCTree.JCImport jcImport = apContext.getTreeMaker().Import(
apContext.getTreeMaker().Select(
apContext.getTreeMaker().Ident(apContext.getNames().fromString(packageName)),
apContext.getNames().fromString(className)
), false);
TreePath treePath = apContext.getTrees().getPath(classSymbol);
TreePath parentPath = treePath.getParentPath();
JCTree.JCCompilationUnit compilationUnit = (JCTree.JCCompilationUnit) parentPath.getCompilationUnit();
List<JCTree.JCImport> imports = compilationUnit.getImports();
if (imports.stream().noneMatch(x -> x.qualid.toString().contains(packageName + "." + className))) {
compilationUnit.accept(new JCTree.Visitor() {
@Override
public void visitTopLevel(JCTree.JCCompilationUnit that) {
List<JCTree> defs = compilationUnit.defs;
ListBuffer<JCTree> newDefs = new ListBuffer<>();
newDefs.add(defs.get(0));
newDefs.add(jcImport);
newDefs.addAll(defs.subList(1, defs.size()));
compilationUnit.defs = newDefs.toList();
}
});
}
}
/**
* Insert statement to head of the method.
*
* @param block the method body
* @param originalMethodDecl the method declaration that will add logger statement
* @param fullExpressionStatement the statement to insert.
*/
public static void insertStatementToHeadOfMethod(JCTree.JCBlock block,
JCTree.JCMethodDecl originalMethodDecl,
JCTree.JCStatement fullExpressionStatement) {
boolean isConstructor = originalMethodDecl.name.toString().equals("<init>");
ListBuffer<JCTree.JCStatement> statements = new ListBuffer<>();
// In constructor, super(...) or this(...) should be the first statement.
if (isConstructor && !block.stats.isEmpty()) {
boolean startsWithSuper = block.stats.get(0).toString().startsWith("super(");
boolean startsWithThis = block.stats.get(0).toString().startsWith("this(");
if (startsWithSuper || startsWithThis) {
statements.add(block.stats.get(0));
statements.add(fullExpressionStatement);
statements.addAll(block.stats.subList(1, block.stats.size()));
} else {
statements.add(fullExpressionStatement);
statements.addAll(block.stats);
}
} else {
statements.add(fullExpressionStatement);
statements.addAll(block.stats);
}
block.stats = statements.toList();
}
}

View File

@ -0,0 +1,155 @@
/*
* 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.annotation.util;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Utilities of iterating file.
*/
public final class FileUtils {
private static final Pattern WINDOWS_PATH_PATTERN = Pattern.compile("file:/\\w:/.*");
private FileUtils() {
throw new UnsupportedOperationException("No instance of FileUtils for you! ");
}
public static List<Path> getAllClassFilePaths(String rootPath) {
List<Path> targetFolders;
try (Stream<Path> filesStream = Files.walk(Paths.get(rootPath))) {
targetFolders = filesStream.filter(x -> !x.toFile().isFile())
.filter(x -> x.toString().contains("classes") && !x.toString().contains("test-classes"))
.filter(x -> x.toString().contains("\\org\\apache\\dubbo".replace('\\', File.separatorChar)))
.collect(Collectors.toList());
return targetFolders;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static byte[] openFileAsByteArray(String filePath) {
try (FileChannel fileChannel = FileChannel.open(Paths.get(filePath))) {
ByteBuffer byteBuffer = ByteBuffer.allocate((int) fileChannel.size());
fileChannel.read(byteBuffer);
return byteBuffer.array();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static String openFileAsString(String filePath) {
return new String(openFileAsByteArray(filePath));
}
public static String getSourceFilePathFromClassFilePath(String classFilePath) {
String classesPathString = "\\target\\classes\\".replace("\\", File.separator);
String sourcesPathString = "\\src\\main\\java\\".replace("\\", File.separator);
String sourceFilePathByReplace = classFilePath.replace(classesPathString, sourcesPathString)
.replace(".class", ".java");
// Inner classes.
if (sourceFilePathByReplace.lastIndexOf('$') != -1) {
int dollarCharIndex = sourceFilePathByReplace.lastIndexOf('$');
String outerClassPath = sourceFilePathByReplace.substring(0, dollarCharIndex);
return outerClassPath + ".java";
}
return sourceFilePathByReplace;
}
public static List<String> loadConfigurationFileInResources(String path) {
ReadableByteChannel resourceReadableByteChannel = Channels.newChannel(
Objects.requireNonNull(FileUtils.class.getClassLoader().getResourceAsStream(path)));
List<String> lines = new ArrayList<>();
try (Scanner scanner = new Scanner(resourceReadableByteChannel)) {
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.startsWith("#") && !line.isEmpty()) {
lines.add(line);
}
}
return lines;
}
}
/**
* <p>Get absolute path of resource.
*
* <p>Retained for testing. It won't work in JAR.
*
* @param path relative path of resources folder.
* @return absolute path of resource
*/
public static String getResourceFilePath(String path) {
String resourceFilePath = FileUtils.class.getClassLoader().getResource(path).toString();
if (WINDOWS_PATH_PATTERN.matcher(resourceFilePath).matches()) {
resourceFilePath = resourceFilePath.replace("file:/", "");
} else {
resourceFilePath = resourceFilePath.replace("file:", "");
}
return resourceFilePath;
}
public static List<Path> getAllFilesInDirectory(Path targetFolder) {
try (Stream<Path> classFilesStream = Files.walk(targetFolder)) {
return classFilesStream
.filter(x -> x.toFile().isFile())
.collect(Collectors.toList());
} catch (IOException e) {
return Collections.emptyList();
}
}
}

View File

@ -0,0 +1 @@
org.apache.dubbo.annotation.DispatchingAnnotationProcessor

View File

@ -0,0 +1,17 @@
#
# 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.
org.apache.dubbo.annotation.handler.DeprecatedHandler

View File

@ -0,0 +1,64 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.annotation;
import org.apache.dubbo.annotation.util.FileUtils;
import org.apache.dubbo.eci.extractor.JavassistUtils;
import javassist.bytecode.ClassFile;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Real invocation test of DispatchingAnnotationProcessor (and DeprecatedHandler).
*/
class RealInvocationTest {
/**
* [File name, Should the counter exist in the class file? ]
*/
private static final Map<String, Boolean> FILES = new HashMap<>(5, 1);
static {
FILES.put("TestConstructorMethod.java", true);
FILES.put("TestDeprecatedMethod.java", true);
FILES.put("TestInterfaceDeprecatedMethod.java", false);
FILES.put("TestConstructorMethodParentClass.java", false);
FILES.put("TestConstructorMethodSubClass.java", true);
}
@Test
void test() {
for (Map.Entry<String, Boolean> i : FILES.entrySet()) {
String filePath = FileUtils.getResourceFilePath("org/testing/dm/" + i.getKey());
Assertions.assertTrue(TestingCommons.compileTheSource(filePath), "Compile failed! ");
String classFilePath = filePath.replace(".java", ".class");
ClassFile classFile = JavassistUtils.openClassFile(classFilePath);
List<String> stringItems = JavassistUtils.getConstPoolStringItems(classFile.getConstPool());
Assertions.assertEquals(i.getValue(), stringItems.contains("org/apache/dubbo/common/DeprecatedMethodInvocationCounter"));
}
}
}

View File

@ -0,0 +1,71 @@
/*
* 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.annotation;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Locale;
import static java.util.Arrays.asList;
/**
* Common code of annotation processor testing.
*/
public final class TestingCommons {
private TestingCommons() {
throw new UnsupportedOperationException("No instance of TestingCommons for you! ");
}
private static class ObjectHolders {
static final JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
static final StandardJavaFileManager javaFileManager = javaCompiler.getStandardFileManager(
null,
Locale.ROOT,
StandardCharsets.UTF_8
);
}
public static boolean compileTheSource(String filePath) {
JavaCompiler.CompilationTask compilationTask = ObjectHolders.javaCompiler.getTask(
null,
ObjectHolders.javaFileManager,
null,
asList("-parameters", "-Xlint:unchecked", "-nowarn", "-Xlint:deprecation"),
null,
getSourceFileJavaFileObject(filePath)
);
compilationTask.setProcessors(
Collections.singletonList(new DispatchingAnnotationProcessor())
);
return compilationTask.call();
}
private static Iterable<? extends JavaFileObject> getSourceFileJavaFileObject(String filePath) {
return ObjectHolders.javaFileManager.getJavaFileObjects(filePath);
}
}

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common;
/**
* Reduced mock of Deprecated method invocation counter.
*/
public final class DeprecatedMethodInvocationCounter {
private DeprecatedMethodInvocationCounter() {
throw new UnsupportedOperationException("No instance of DeprecatedMethodInvocationCounter for you! ");
}
/**
* Invoked by (modified) deprecated method.
*
* @param methodDefinition filled by annotation processor. (like 'org.apache.dubbo.common.URL.getServiceName()')
*/
public static void onDeprecatedMethodCalled(String methodDefinition) {
// Intended to be empty.
}
}

View File

@ -0,0 +1,151 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.eci.extractor;
import org.apache.dubbo.annotation.util.FileUtils;
import javassist.bytecode.ClassFile;
import javassist.bytecode.ConstPool;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Utilities of Javassist.
*/
public class JavassistUtils {
private static final Map<Class, Field> stringFieldCache = new HashMap<>(2, 1);
private static Method getItemMethodCache = null;
private JavassistUtils() {
throw new UnsupportedOperationException("No instance of JavassistUtils for you! ");
}
public static ClassFile openClassFile(String classFilePath) {
try {
byte[] clsB = FileUtils.openFileAsByteArray(classFilePath);
return new ClassFile(new DataInputStream(new ByteArrayInputStream(clsB)));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
static List<Object> getConstPoolItems(ConstPool cp) {
List<Object> objects = new ArrayList<>(cp.getSize());
for (int i = 0; i < cp.getSize(); i++) {
objects.add(getConstPoolItem(cp, i));
}
return objects;
}
/**
* Calls ConstPool.getItem() method reflectively.
*
* @param cp The ConstPool object.
* @param index The index of items.
* @return The XXXInfo Object. Since it's invisible, return Object instead.
*/
static Object getConstPoolItem(ConstPool cp, int index) {
if (getItemMethodCache == null) {
Class<ConstPool> cpc = ConstPool.class;
Method getItemMethod;
try {
getItemMethod = cpc.getDeclaredMethod("getItem", int.class);
getItemMethod.setAccessible(true);
getItemMethodCache = getItemMethod;
} catch (NoSuchMethodException e) {
throw new RuntimeException("Javassist internal method changed.", e);
}
}
try {
return getItemMethodCache.invoke(cp, index);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException("Javassist internal method changed.", e);
}
}
public static List<String> getConstPoolStringItems(ConstPool cp) {
List<Object> objects = getConstPoolItems(cp);
List<String> stringItems = new ArrayList<>(cp.getSize());
for (Object item : objects) {
Field stringField;
if (item != null) {
stringField = getStringFieldInConstPoolItems(item);
if (stringField == null) {
continue;
}
Object fieldData;
try {
fieldData = stringField.get(item);
} catch (IllegalAccessException e) {
throw new RuntimeException("Javassist internal field changed.", e);
}
if (fieldData.getClass() == String.class) {
stringItems.add((String) fieldData);
}
}
}
return stringItems;
}
/**
* Obtain the 'string' field in Utf8Info and StringInfo.
*
* @param item The instance of Utf8Info and StringInfo.
* @return 'string' field's value
*/
static Field getStringFieldInConstPoolItems(Object item) {
if (stringFieldCache.containsKey(item.getClass())) {
return stringFieldCache.get(item.getClass());
} else {
try {
Field stringField = item.getClass().getDeclaredField("string");
stringField.setAccessible(true);
stringFieldCache.put(item.getClass(), stringField);
return stringField;
} catch (NoSuchFieldException ignored) {
}
}
return null;
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.eci.util;
import java.lang.reflect.Field;
/**
* Tools of reflective operations.
*/
public final class ReflectUtils {
private ReflectUtils() {
throw new UnsupportedOperationException("No instance of ReflectUtils for you! ");
}
/**
* Searches (a private) field in super classes recursively.
*
* @param cls the actual type
* @param name the field name
* @return the corresponding Field object, or null if the field does not exist.
*/
public static Field getDeclaredFieldRecursively(Class cls, String name) {
try {
Field indexField = cls.getDeclaredField(name);
indexField.setAccessible(true);
return indexField;
} catch (NoSuchFieldException e) {
if (cls == Object.class) {
return null;
}
return getDeclaredFieldRecursively(cls.getSuperclass(), name);
}
}
}

View File

@ -0,0 +1,28 @@
/*
* 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.testing.dm;
public class TestConstructorMethod {
@Deprecated
TestConstructorMethod() {
this("1");
}
TestConstructorMethod(String s) {
}
}

View File

@ -15,14 +15,13 @@
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
package org.testing.dm;
import static org.apache.dubbo.common.constants.CommonConstants.NATIVE;
public class TestConstructorMethodParentClass {
public abstract class NativeUtils {
public static boolean isNative() {
return Boolean.parseBoolean(System.getProperty(NATIVE, "false"));
public TestConstructorMethodParentClass() {
}
public TestConstructorMethodParentClass(String s) {
}
}

View File

@ -15,16 +15,16 @@
* limitations under the License.
*/
package org.apache.dubbo.maven.plugin;
package org.testing.dm;
import java.util.Set;
public class TestConstructorMethodSubClass extends TestConstructorMethodParentClass {
public class Test {
@Deprecated
public TestConstructorMethodSubClass(int i) {
super();
}
public static void main(String[] args) {
ClassFinder finder = new ClassFinder();
Set<String> set = finder.findClassSet("org.apache.dubbo", msg -> {
});
System.out.println(set.size());
public TestConstructorMethodSubClass(String s) {
super(s);
}
}

View File

@ -0,0 +1,26 @@
/*
* 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.testing.dm;
public class TestDeprecatedMethod {
@Deprecated
public void m1() {
System.out.println("M1! ");
}
}

View File

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

View File

@ -13,8 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
@ -24,7 +24,7 @@
<packaging>jar</packaging>
<properties>
<maven.deploy.skip>true</maven.deploy.skip>
<maven.deploy.skip>true</maven.deploy.skip>
</properties>
</project>
</project>

View File

@ -86,10 +86,5 @@
<version>${project.parent.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-integration-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,68 @@
/*
* 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.validator;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.AbstractInterfaceConfig;
import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.context.ConfigValidator;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.filter.ClusterFilter;
import java.util.Arrays;
import java.util.List;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.FILTER_KEY;
import static org.apache.dubbo.config.Constants.LAYER_KEY;
import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
import static org.apache.dubbo.rpc.Constants.PROXY_KEY;
@Activate
public class InterfaceConfigValidator implements ConfigValidator<AbstractInterfaceConfig> {
public static void validateAbstractInterfaceConfig(AbstractInterfaceConfig config) {
ConfigValidationUtils.checkName(LOCAL_KEY, config.getLocal());
ConfigValidationUtils.checkName("stub", config.getStub());
ConfigValidationUtils.checkMultiName("owner", config.getOwner());
ConfigValidationUtils.checkExtension(config.getScopeModel(), ProxyFactory.class, PROXY_KEY, config.getProxy());
ConfigValidationUtils.checkExtension(config.getScopeModel(), Cluster.class, CLUSTER_KEY, config.getCluster());
ConfigValidationUtils.checkMultiExtension(config.getScopeModel(), Arrays.asList(Filter.class, ClusterFilter.class), FILTER_KEY, config.getFilter());
ConfigValidationUtils.checkNameHasSymbol(LAYER_KEY, config.getLayer());
List<MethodConfig> methods = config.getMethods();
if (CollectionUtils.isNotEmpty(methods)) {
methods.forEach(MethodConfig::validate);
}
}
@Override
public boolean validate(AbstractInterfaceConfig config) {
validateAbstractInterfaceConfig(config);
return true;
}
@Override
public boolean isSupport(Class<?> configClass) {
return AbstractInterfaceConfig.class.isAssignableFrom(configClass);
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.validator;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.context.ConfigValidator;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
import static org.apache.dubbo.rpc.Constants.FAIL_PREFIX;
import static org.apache.dubbo.rpc.Constants.FORCE_PREFIX;
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
@Activate
public class MethodConfigValidator implements ConfigValidator<MethodConfig> {
public static void validateMethodConfig(MethodConfig config) {
ConfigValidationUtils.checkExtension(config.getScopeModel(), LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
ConfigValidationUtils.checkParameterName(config.getParameters());
ConfigValidationUtils.checkMethodName("name", config.getName());
String mock = config.getMock();
if (isNotEmpty(mock)) {
if (mock.startsWith(RETURN_PREFIX) || mock.startsWith(THROW_PREFIX + " ")) {
ConfigValidationUtils.checkLength(MOCK_KEY, mock);
} else if (mock.startsWith(FAIL_PREFIX) || mock.startsWith(FORCE_PREFIX)) {
ConfigValidationUtils.checkNameHasSymbol(MOCK_KEY, mock);
} else {
ConfigValidationUtils.checkName(MOCK_KEY, mock);
}
}
}
@Override
public boolean validate(MethodConfig config) {
validateMethodConfig(config);
return true;
}
@Override
public boolean isSupport(Class<?> configClass) {
return MethodConfig.class.equals(configClass);
}
}

View File

@ -24,6 +24,8 @@ import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import static org.apache.dubbo.rpc.cluster.Constants.DEFAULT_CLUSTER;
/**
* Cluster. (SPI, Singleton, ThreadSafe)
* <p>
@ -31,11 +33,9 @@ import org.apache.dubbo.rpc.model.ScopeModelUtil;
* <a href="http://en.wikipedia.org/wiki/Fault-tolerant_system">Fault-Tolerant</a>
*
*/
@SPI(Cluster.DEFAULT)
@SPI(DEFAULT_CLUSTER)
public interface Cluster {
String DEFAULT = "failover";
/**
* Merge the directory invokers to a virtual invoker.
*
@ -53,7 +53,7 @@ public interface Cluster {
static Cluster getCluster(ScopeModel scopeModel, String name, boolean wrap) {
if (StringUtils.isEmpty(name)) {
name = Cluster.DEFAULT;
name = DEFAULT_CLUSTER;
}
return ScopeModelUtil.getApplicationModel(scopeModel).getExtensionLoader(Cluster.class).getExtension(name, wrap);
}

View File

@ -17,10 +17,9 @@
package org.apache.dubbo.rpc.cluster;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.rpc.AdaptiveMetrics;
import org.apache.dubbo.rpc.cluster.merger.MergerFactory;
import org.apache.dubbo.rpc.cluster.factory.DefaultClusterInvokerFactory;
import org.apache.dubbo.rpc.cluster.factory.StaticDirectoryStrategy;
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
@ -28,23 +27,22 @@ import org.apache.dubbo.rpc.model.ModuleModel;
import org.apache.dubbo.rpc.model.ScopeModelInitializer;
public class ClusterScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeFrameworkModel(FrameworkModel frameworkModel) {
ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
beanFactory.registerBean(RouterSnapshotSwitcher.class);
beanFactory.registerBean(StaticDirectoryStrategy.class);
beanFactory.registerBean(DefaultClusterInvokerFactory.class);
}
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
beanFactory.registerBean(MergerFactory.class);
beanFactory.registerBean(ClusterUtils.class);
beanFactory.registerBean(AdaptiveMetrics.class);
}
@Override
public void initializeModuleModel(ModuleModel moduleModel) {
ScopeBeanFactory beanFactory = moduleModel.getBeanFactory();
beanFactory.registerBean(MeshRuleManager.class);
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.rpc.cluster.factory;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.cluster.ClusterInvokerFactory;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.model.ScopeModel;
import java.util.List;
import static org.apache.dubbo.rpc.cluster.Cluster.getCluster;
public class DefaultClusterInvokerFactory implements ClusterInvokerFactory {
private final List<DirectoryStrategy> strategies;
public DefaultClusterInvokerFactory(ScopeModel scopeModel) {
this.strategies = scopeModel.getBeanFactory().getBeansOfType(DirectoryStrategy.class);
}
/**
* Build an Invoker with StaticDirectory.
*
* @param config config
* @return ClusterInvoker
*/
@Override
public Invoker<?> getInvoker(ClusterInvokerConfig config) {
Directory<?> directory = null;
for (DirectoryStrategy strategy : strategies) {
if (strategy.name().equals(config.getDirectoryName())) {
directory = strategy.createDirectory(config);
break;
}
}
return getCluster(config.getScopeModel(), config.getClusterName(), config.isWrappedCluster())
.join(directory,config.isWrappedInvoker());
}
}

View File

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

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.factory;
import org.apache.dubbo.rpc.cluster.ClusterInvokerFactory;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
public class StaticDirectoryStrategy implements DirectoryStrategy {
@Override
public ClusterInvokerFactory.DirectoryNames name() {
return ClusterInvokerFactory.DirectoryNames.STATIC;
}
@Override
public <T> Directory<T> createDirectory(ClusterInvokerFactory.ClusterInvokerConfig clusterInvokerConfig) {
return new StaticDirectory(clusterInvokerConfig.getServiceUrl(),clusterInvokerConfig.getInvokersToJoin());
}
}

View File

@ -23,8 +23,6 @@ import org.apache.dubbo.rpc.cluster.support.wrapper.AbstractCluster;
public class ZoneAwareCluster extends AbstractCluster {
public final static String NAME = "zone-aware";
@Override
protected <T> AbstractClusterInvoker<T> doJoin(Directory<T> directory) throws RpcException {
return new ZoneAwareClusterInvoker<T>(directory);

View File

@ -49,6 +49,7 @@ import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
import static org.apache.dubbo.rpc.cluster.Constants.DEFAULT_CLUSTER;
import static org.apache.dubbo.rpc.cluster.Constants.PEER_KEY;
/**
@ -291,7 +292,7 @@ public class ScopeClusterInvoker<T> implements ClusterInvoker<T>, ExporterChange
Invoker<?> invoker = protocolSPI.refer(getInterface(), consumerUrl);
List<Invoker<?>> invokers = new ArrayList<>();
invokers.add(invoker);
injvmInvoker = Cluster.getCluster(url.getScopeModel(), Cluster.DEFAULT, false).join(new StaticDirectory(url, invokers), true);
injvmInvoker = Cluster.getCluster(url.getScopeModel(), DEFAULT_CLUSTER, false).join(new StaticDirectory(url, invokers), true);
}
}
}

View File

@ -0,0 +1,2 @@
interface=org.apache.dubbo.config.validator.InterfaceConfigValidator
method=org.apache.dubbo.config.validator.MethodConfigValidator

View File

@ -1,4 +1,3 @@
mock=org.apache.dubbo.rpc.cluster.support.wrapper.MockClusterWrapper
scope=org.apache.dubbo.rpc.cluster.support.wrapper.ScopeClusterWrapper
failover=org.apache.dubbo.rpc.cluster.support.FailoverCluster
failfast=org.apache.dubbo.rpc.cluster.support.FailfastCluster
@ -6,6 +5,5 @@ failsafe=org.apache.dubbo.rpc.cluster.support.FailsafeCluster
failback=org.apache.dubbo.rpc.cluster.support.FailbackCluster
forking=org.apache.dubbo.rpc.cluster.support.ForkingCluster
available=org.apache.dubbo.rpc.cluster.support.AvailableCluster
mergeable=org.apache.dubbo.rpc.cluster.support.MergeableCluster
broadcast=org.apache.dubbo.rpc.cluster.support.BroadcastCluster
zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster
zone-aware=org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster

View File

@ -3,4 +3,3 @@ roundrobin=org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance
leastactive=org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance
consistenthash=org.apache.dubbo.rpc.cluster.loadbalance.ConsistentHashLoadBalance
shortestresponse=org.apache.dubbo.rpc.cluster.loadbalance.ShortestResponseLoadBalance
adaptive=org.apache.dubbo.rpc.cluster.loadbalance.AdaptiveLoadBalance

View File

@ -1,6 +1,2 @@
consumercontext=org.apache.dubbo.rpc.cluster.filter.support.ConsumerContextFilter
consumer-classloader=org.apache.dubbo.rpc.cluster.filter.support.ConsumerClassLoaderFilter
router-snapshot=org.apache.dubbo.rpc.cluster.router.RouterSnapshotFilter
observationsender=org.apache.dubbo.rpc.cluster.filter.support.ObservationSenderFilter
metricsClusterFilter=org.apache.dubbo.rpc.cluster.filter.support.MetricsClusterFilter
metricsConsumerFilter=org.apache.dubbo.rpc.cluster.filter.support.MetricsConsumerFilter

View File

@ -1,253 +1,253 @@
/*
* 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.rpc.cluster;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.cluster.filter.DemoService;
import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
import org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouter;
import org.apache.dubbo.rpc.cluster.router.condition.config.ListenableStateRouter;
import org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouter;
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener;
import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
import org.apache.dubbo.rpc.cluster.router.state.BitList;
import org.apache.dubbo.rpc.model.FrameworkModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
import static org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleConstants.MESH_RULE_DATA_ID_SUFFIX;
import static org.mockito.Mockito.when;
class RouterChainTest {
/**
* verify the router and state router loaded by default
*/
@Test
void testBuildRouterChain() {
RouterChain<DemoService> routerChain = createRouterChanin();
Assertions.assertEquals(0, routerChain.getRouters().size());
Assertions.assertEquals(7, routerChain.getStateRouters().size());
}
private RouterChain<DemoService> createRouterChanin() {
Map<String, String> parameters = new HashMap<>();
parameters.put(INTERFACE_KEY, DemoService.class.getName());
parameters.put("registry", "zookeeper");
URL url = new ServiceConfigURL("dubbo",
"127.0.0.1",
20881,
DemoService.class.getName(),
parameters);
RouterChain<DemoService> routerChain = RouterChain.buildChain(DemoService.class, url);
return routerChain;
}
@Test
void testRoute() {
RouterChain<DemoService> routerChain = createRouterChanin();
// mockInvoker will be filtered out by MockInvokersSelector
Invoker<DemoService> mockInvoker = createMockInvoker();
// invoker1 will be filtered out by MeshStateRouter
Map<String, String> map1 = new HashMap<>();
map1.put("env-sign", "yyyyyyy");
Invoker<DemoService> invoker1 = createNormalInvoker(map1);
// invoker2 will be filtered out by TagStateRouter
Map<String, String> map2 = new HashMap<>();
map2.put("env-sign", "xxx");
map2.put("tag1", "hello");
Invoker<DemoService> invoker2 = createNormalInvoker(map2);
// invoker3 will be filtered out by AppStateRouter
Map<String, String> map3 = new HashMap<>();
map3.put("env-sign", "xxx");
map3.put("tag1", "hello");
map3.put(TAG_KEY, "TAG_");
Invoker<DemoService> invoker3 = createNormalInvoker(map3);
// invoker4 will be filtered out by ServiceStateRouter
Map<String, String> map4 = new HashMap<>();
map4.put("env-sign", "xxx");
map4.put("tag1", "hello");
map4.put(TAG_KEY, "TAG_");
map4.put("timeout", "5000");
Invoker<DemoService> invoker4 = createNormalInvoker(map4);
// invoker5 is the only one returned at the end that is not filtered out
Map<String, String> map5 = new HashMap<>();
map5.put("env-sign", "xxx");
map5.put("tag1", "hello");
map5.put(TAG_KEY, "TAG_");
map5.put("timeout", "5000");
map5.put("serialization", "hessian2");
Invoker<DemoService> invoker5 = createNormalInvoker(map5);
BitList<Invoker<DemoService>> invokers = new BitList<>(Arrays.asList(mockInvoker, invoker1, invoker2, invoker3, invoker4, invoker5));
routerChain.setInvokers(invokers, () -> {});
// mesh rule for MeshStateRouter
MeshRuleManager meshRuleManager = mockInvoker.getUrl().getOrDefaultModuleModel().getBeanFactory().getBean(MeshRuleManager.class);
ConcurrentHashMap<String, MeshAppRuleListener> appRuleListeners = meshRuleManager.getAppRuleListeners();
MeshAppRuleListener meshAppRuleListener = appRuleListeners.get(invoker1.getUrl().getRemoteApplication());
ConfigChangedEvent configChangedEvent = new ConfigChangedEvent("demo-route" + MESH_RULE_DATA_ID_SUFFIX, DynamicConfiguration.DEFAULT_GROUP,
MESH_RULE1 + "---\n" + MESH_RULE2, ConfigChangeType.ADDED);
meshAppRuleListener.process(configChangedEvent);
// condition rule for AppStateRouter&ServiceStateRouter
ListenableStateRouter serviceRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof ServiceStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
ConfigChangedEvent serviceConditionEvent = new ConfigChangedEvent(DynamicConfiguration.getRuleKey(mockInvoker.getUrl()) + ".condition-router", DynamicConfiguration.DEFAULT_GROUP,
SERVICE_CONDITION_RULE, ConfigChangeType.ADDED);
serviceRouter.process(serviceConditionEvent);
ListenableStateRouter appRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof AppStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
ConfigChangedEvent appConditionEvent = new ConfigChangedEvent("app.condition-router", DynamicConfiguration.DEFAULT_GROUP,
APP_CONDITION_RULE, ConfigChangeType.ADDED);
appRouter.process(appConditionEvent);
// prepare consumerUrl and RpcInvocation
URL consumerUrl = URL.valueOf("consumer://localhost/DemoInterface?remote.application=app1");
RpcInvocation rpcInvocation = new RpcInvocation();
rpcInvocation.setServiceName("DemoService");
rpcInvocation.setObjectAttachment("trafficLabel", "xxx");
rpcInvocation.setObjectAttachment(TAG_KEY, "TAG_");
RpcContext.getServiceContext().setNeedPrintRouterSnapshot(true);
RouterSnapshotSwitcher routerSnapshotSwitcher = FrameworkModel.defaultModel().getBeanFactory().getBean(RouterSnapshotSwitcher.class);
routerSnapshotSwitcher.addEnabledService("org.apache.dubbo.demo.DemoService");
// route
List<Invoker<DemoService>> result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
.route(consumerUrl, invokers, rpcInvocation);
Assertions.assertEquals(result.size(), 1);
Assertions.assertTrue(result.contains(invoker5));
String snapshotLog =
"[ Parent (Input: 6) (Current Node Output: 6) (Chain Node Output: 1) ] Input: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103 -> Chain Node Output: localhost:9103...\n" +
" [ MockInvokersSelector (Input: 6) (Current Node Output: 5) (Chain Node Output: 1) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
" [ StandardMeshRuleRouter (Input: 5) (Current Node Output: 4) (Chain Node Output: 1) Router message: Match App: app Subset: isolation ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
" [ TagStateRouter (Input: 4) (Current Node Output: 3) (Chain Node Output: 1) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
" [ ServiceStateRouter (Input: 3) (Current Node Output: 3) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
" [ ConditionStateRouter (Input: 3) (Current Node Output: 2) (Chain Node Output: 2) Router message: Match return. ] Current Node Output: localhost:9103,localhost:9103\n" +
" [ ProviderAppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: localhost:9103,localhost:9103\n" +
" [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103\n" +
" [ ConditionStateRouter (Input: 2) (Current Node Output: 1) (Chain Node Output: 1) Router message: Match return. ] Current Node Output: localhost:9103\n" +
" [ AppScriptStateRouter (Input: 1) (Current Node Output: 1) (Chain Node Output: 1) Router message: Directly return from script router. Reason: Invokers from previous router is empty or script is not enabled. Script rule is: null ] Current Node Output: localhost:9103";
String[] snapshot = routerSnapshotSwitcher.cloneSnapshot();
Assertions.assertTrue(snapshot[0].contains(snapshotLog));
RpcContext.getServiceContext().setNeedPrintRouterSnapshot(false);
result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
.route(consumerUrl, invokers, rpcInvocation);
Assertions.assertEquals(result.size(), 1);
Assertions.assertTrue(result.contains(invoker5));
routerChain.destroy();
Assertions.assertEquals(routerChain.getRouters().size(), 0);
Assertions.assertEquals(routerChain.getStateRouters().size(), 0);
}
private Invoker<DemoService> createMockInvoker() {
URL url = URL.valueOf("mock://localhost:9103/DemoInterface?remote.application=app");
Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
when(invoker.getUrl()).thenReturn(url);
return invoker;
}
private Invoker<DemoService> createNormalInvoker(Map<String, String> parameters) {
URL url = URL.valueOf("dubbo://localhost:9103/DemoInterface?remote.application=app");
if (CollectionUtils.isNotEmptyMap(parameters)) {
url = url.addParameters(parameters);
}
Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
when(invoker.getUrl()).thenReturn(url);
return invoker;
}
private final static String MESH_RULE1 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
"kind: DestinationRule\n" +
"metadata: { name: demo-route }\n" +
"spec:\n" +
" host: demo\n" +
" subsets:\n" +
" - labels: { env-sign: xxx, tag1: hello }\n" +
" name: isolation\n" +
" - labels: { env-sign: yyy }\n" +
" name: testing-trunk\n" +
" - labels: { env-sign: zzz }\n" +
" name: testing\n" +
" trafficPolicy:\n" +
" loadBalancer: { simple: ROUND_ROBIN }\n" +
"\n";
private final static String MESH_RULE2 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
"kind: VirtualService\n" +
"metadata: { name: demo-route }\n" +
"spec:\n" +
" dubbo:\n" +
" - routedetail:\n" +
" - match:\n" +
" - attachments: \n" +
" dubboContext: {trafficLabel: {regex: xxx}}\n" +
" name: xxx-project\n" +
" route:\n" +
" - destination: {host: demo, subset: isolation}\n" +
" services:\n" +
" - {regex: DemoService}\n" +
" hosts: [demo]\n";
private static final String APP_CONDITION_RULE = "scope: application\n" +
"force: true\n" +
"runtime: false\n" +
"enabled: true\n" +
"priority: 1\n" +
"key: demo-consumer\n" +
"conditions:\n" +
"- => serialization=hessian2";
private static final String SERVICE_CONDITION_RULE = "scope: service\n" +
"force: true\n" +
"runtime: false\n" +
"enabled: true\n" +
"priority: 1\n" +
"key: org.apache.dubbo.demo.DemoService\n" +
"conditions:\n" +
"- => timeout=5000";
}
///*
// * 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.rpc.cluster;
//
//
//import java.util.Arrays;
//import java.util.HashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
//import org.apache.dubbo.common.URL;
//import org.apache.dubbo.common.config.configcenter.ConfigChangeType;
//import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
//import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
//import org.apache.dubbo.common.url.component.ServiceConfigURL;
//import org.apache.dubbo.common.utils.CollectionUtils;
//import org.apache.dubbo.rpc.Invoker;
//import org.apache.dubbo.rpc.RpcContext;
//import org.apache.dubbo.rpc.RpcInvocation;
//import org.apache.dubbo.rpc.cluster.filter.DemoService;
//import org.apache.dubbo.rpc.cluster.router.RouterSnapshotSwitcher;
//import org.apache.dubbo.rpc.cluster.router.condition.config.AppStateRouter;
//import org.apache.dubbo.rpc.cluster.router.condition.config.ListenableStateRouter;
//import org.apache.dubbo.rpc.cluster.router.condition.config.ServiceStateRouter;
//import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener;
//import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleManager;
//import org.apache.dubbo.rpc.cluster.router.state.BitList;
//import org.apache.dubbo.rpc.model.FrameworkModel;
//import org.junit.jupiter.api.Assertions;
//import org.junit.jupiter.api.Test;
//import org.mockito.Mockito;
//
//import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
//import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
//import static org.apache.dubbo.rpc.cluster.router.mesh.route.MeshRuleConstants.MESH_RULE_DATA_ID_SUFFIX;
//import static org.mockito.Mockito.when;
//
//class RouterChainTest {
//
// /**
// * verify the router and state router loaded by default
// */
// @Test
// void testBuildRouterChain() {
// RouterChain<DemoService> routerChain = createRouterChanin();
// Assertions.assertEquals(0, routerChain.getRouters().size());
// Assertions.assertEquals(7, routerChain.getStateRouters().size());
// }
//
// private RouterChain<DemoService> createRouterChanin() {
// Map<String, String> parameters = new HashMap<>();
// parameters.put(INTERFACE_KEY, DemoService.class.getName());
// parameters.put("registry", "zookeeper");
// URL url = new ServiceConfigURL("dubbo",
// "127.0.0.1",
// 20881,
// DemoService.class.getName(),
// parameters);
//
// RouterChain<DemoService> routerChain = RouterChain.buildChain(DemoService.class, url);
// return routerChain;
// }
//
// @Test
// void testRoute() {
// RouterChain<DemoService> routerChain = createRouterChanin();
//
// // mockInvoker will be filtered out by MockInvokersSelector
// Invoker<DemoService> mockInvoker = createMockInvoker();
//
// // invoker1 will be filtered out by MeshStateRouter
// Map<String, String> map1 = new HashMap<>();
// map1.put("env-sign", "yyyyyyy");
// Invoker<DemoService> invoker1 = createNormalInvoker(map1);
//
// // invoker2 will be filtered out by TagStateRouter
// Map<String, String> map2 = new HashMap<>();
// map2.put("env-sign", "xxx");
// map2.put("tag1", "hello");
// Invoker<DemoService> invoker2 = createNormalInvoker(map2);
//
// // invoker3 will be filtered out by AppStateRouter
// Map<String, String> map3 = new HashMap<>();
// map3.put("env-sign", "xxx");
// map3.put("tag1", "hello");
// map3.put(TAG_KEY, "TAG_");
// Invoker<DemoService> invoker3 = createNormalInvoker(map3);
//
// // invoker4 will be filtered out by ServiceStateRouter
// Map<String, String> map4 = new HashMap<>();
// map4.put("env-sign", "xxx");
// map4.put("tag1", "hello");
// map4.put(TAG_KEY, "TAG_");
// map4.put("timeout", "5000");
// Invoker<DemoService> invoker4 = createNormalInvoker(map4);
//
// // invoker5 is the only one returned at the end that is not filtered out
// Map<String, String> map5 = new HashMap<>();
// map5.put("env-sign", "xxx");
// map5.put("tag1", "hello");
// map5.put(TAG_KEY, "TAG_");
// map5.put("timeout", "5000");
// map5.put("serialization", "hessian2");
// Invoker<DemoService> invoker5 = createNormalInvoker(map5);
//
// BitList<Invoker<DemoService>> invokers = new BitList<>(Arrays.asList(mockInvoker, invoker1, invoker2, invoker3, invoker4, invoker5));
// routerChain.setInvokers(invokers, () -> {});
//
// // mesh rule for MeshStateRouter
// MeshRuleManager meshRuleManager = mockInvoker.getUrl().getOrDefaultModuleModel().getBeanFactory().getBean(MeshRuleManager.class);
// ConcurrentHashMap<String, MeshAppRuleListener> appRuleListeners = meshRuleManager.getAppRuleListeners();
// MeshAppRuleListener meshAppRuleListener = appRuleListeners.get(invoker1.getUrl().getRemoteApplication());
// ConfigChangedEvent configChangedEvent = new ConfigChangedEvent("demo-route" + MESH_RULE_DATA_ID_SUFFIX, DynamicConfiguration.DEFAULT_GROUP,
// MESH_RULE1 + "---\n" + MESH_RULE2, ConfigChangeType.ADDED);
// meshAppRuleListener.process(configChangedEvent);
//
//
// // condition rule for AppStateRouter&ServiceStateRouter
// ListenableStateRouter serviceRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof ServiceStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
// ConfigChangedEvent serviceConditionEvent = new ConfigChangedEvent(DynamicConfiguration.getRuleKey(mockInvoker.getUrl()) + ".condition-router", DynamicConfiguration.DEFAULT_GROUP,
// SERVICE_CONDITION_RULE, ConfigChangeType.ADDED);
// serviceRouter.process(serviceConditionEvent);
//
// ListenableStateRouter appRouter = routerChain.getStateRouters().stream().filter(s -> s instanceof AppStateRouter).map(s -> (ListenableStateRouter) s).findAny().orElse(null);
// ConfigChangedEvent appConditionEvent = new ConfigChangedEvent("app.condition-router", DynamicConfiguration.DEFAULT_GROUP,
// APP_CONDITION_RULE, ConfigChangeType.ADDED);
// appRouter.process(appConditionEvent);
//
// // prepare consumerUrl and RpcInvocation
// URL consumerUrl = URL.valueOf("consumer://localhost/DemoInterface?remote.application=app1");
// RpcInvocation rpcInvocation = new RpcInvocation();
// rpcInvocation.setServiceName("DemoService");
// rpcInvocation.setObjectAttachment("trafficLabel", "xxx");
// rpcInvocation.setObjectAttachment(TAG_KEY, "TAG_");
//
// RpcContext.getServiceContext().setNeedPrintRouterSnapshot(true);
// RouterSnapshotSwitcher routerSnapshotSwitcher = FrameworkModel.defaultModel().getBeanFactory().getBean(RouterSnapshotSwitcher.class);
// routerSnapshotSwitcher.addEnabledService("org.apache.dubbo.demo.DemoService");
// // route
// List<Invoker<DemoService>> result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
// .route(consumerUrl, invokers, rpcInvocation);
// Assertions.assertEquals(result.size(), 1);
// Assertions.assertTrue(result.contains(invoker5));
//
// String snapshotLog =
// "[ Parent (Input: 6) (Current Node Output: 6) (Chain Node Output: 1) ] Input: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103 -> Chain Node Output: localhost:9103...\n" +
// " [ MockInvokersSelector (Input: 6) (Current Node Output: 5) (Chain Node Output: 1) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
// " [ StandardMeshRuleRouter (Input: 5) (Current Node Output: 4) (Chain Node Output: 1) Router message: Match App: app Subset: isolation ] Current Node Output: localhost:9103,localhost:9103,localhost:9103,localhost:9103\n" +
// " [ TagStateRouter (Input: 4) (Current Node Output: 3) (Chain Node Output: 1) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
// " [ ServiceStateRouter (Input: 3) (Current Node Output: 3) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103,localhost:9103\n" +
// " [ ConditionStateRouter (Input: 3) (Current Node Output: 2) (Chain Node Output: 2) Router message: Match return. ] Current Node Output: localhost:9103,localhost:9103\n" +
// " [ ProviderAppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: localhost:9103,localhost:9103\n" +
// " [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 1) Router message: null ] Current Node Output: localhost:9103,localhost:9103\n" +
// " [ ConditionStateRouter (Input: 2) (Current Node Output: 1) (Chain Node Output: 1) Router message: Match return. ] Current Node Output: localhost:9103\n" +
// " [ AppScriptStateRouter (Input: 1) (Current Node Output: 1) (Chain Node Output: 1) Router message: Directly return from script router. Reason: Invokers from previous router is empty or script is not enabled. Script rule is: null ] Current Node Output: localhost:9103";
// String[] snapshot = routerSnapshotSwitcher.cloneSnapshot();
// Assertions.assertTrue(snapshot[0].contains(snapshotLog));
//
// RpcContext.getServiceContext().setNeedPrintRouterSnapshot(false);
// result = routerChain.getSingleChain(consumerUrl, invokers, rpcInvocation)
// .route(consumerUrl, invokers, rpcInvocation);
// Assertions.assertEquals(result.size(), 1);
// Assertions.assertTrue(result.contains(invoker5));
//
// routerChain.destroy();
// Assertions.assertEquals(routerChain.getRouters().size(), 0);
// Assertions.assertEquals(routerChain.getStateRouters().size(), 0);
//
// }
//
// private Invoker<DemoService> createMockInvoker() {
// URL url = URL.valueOf("mock://localhost:9103/DemoInterface?remote.application=app");
// Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
// when(invoker.getUrl()).thenReturn(url);
// return invoker;
// }
//
// private Invoker<DemoService> createNormalInvoker(Map<String, String> parameters) {
// URL url = URL.valueOf("dubbo://localhost:9103/DemoInterface?remote.application=app");
// if (CollectionUtils.isNotEmptyMap(parameters)) {
// url = url.addParameters(parameters);
// }
// Invoker<DemoService> invoker = Mockito.mock(Invoker.class);
// when(invoker.getUrl()).thenReturn(url);
// return invoker;
// }
//
//
// private final static String MESH_RULE1 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
// "kind: DestinationRule\n" +
// "metadata: { name: demo-route }\n" +
// "spec:\n" +
// " host: demo\n" +
// " subsets:\n" +
// " - labels: { env-sign: xxx, tag1: hello }\n" +
// " name: isolation\n" +
// " - labels: { env-sign: yyy }\n" +
// " name: testing-trunk\n" +
// " - labels: { env-sign: zzz }\n" +
// " name: testing\n" +
// " trafficPolicy:\n" +
// " loadBalancer: { simple: ROUND_ROBIN }\n" +
// "\n";
//
// private final static String MESH_RULE2 = "apiVersion: service.dubbo.apache.org/v1alpha1\n" +
// "kind: VirtualService\n" +
// "metadata: { name: demo-route }\n" +
// "spec:\n" +
// " dubbo:\n" +
// " - routedetail:\n" +
// " - match:\n" +
// " - attachments: \n" +
// " dubboContext: {trafficLabel: {regex: xxx}}\n" +
// " name: xxx-project\n" +
// " route:\n" +
// " - destination: {host: demo, subset: isolation}\n" +
// " services:\n" +
// " - {regex: DemoService}\n" +
// " hosts: [demo]\n";
//
// private static final String APP_CONDITION_RULE = "scope: application\n" +
// "force: true\n" +
// "runtime: false\n" +
// "enabled: true\n" +
// "priority: 1\n" +
// "key: demo-consumer\n" +
// "conditions:\n" +
// "- => serialization=hessian2";
//
// private static final String SERVICE_CONDITION_RULE = "scope: service\n" +
// "force: true\n" +
// "runtime: false\n" +
// "enabled: true\n" +
// "priority: 1\n" +
// "key: org.apache.dubbo.demo.DemoService\n" +
// "conditions:\n" +
// "- => timeout=5000";
//}

View File

@ -1,84 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.rpc.cluster.filter;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.TracingConfig;
import org.apache.dubbo.rpc.AppResponse;
import org.apache.dubbo.rpc.BaseFilter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcInvocation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import io.micrometer.tracing.test.SampleTestRunner;
import org.junit.jupiter.api.AfterEach;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
abstract class AbstractObservationFilterTest extends SampleTestRunner {
ApplicationModel applicationModel;
RpcInvocation invocation;
BaseFilter filter;
Invoker<?> invoker = mock(Invoker.class);
static final String INTERFACE_NAME = "org.apache.dubbo.MockInterface";
static final String METHOD_NAME = "mockMethod";
static final String GROUP = "mockGroup";
static final String VERSION = "1.0.0";
@AfterEach
public void teardown() {
if (applicationModel != null) {
applicationModel.destroy();
}
}
abstract BaseFilter createFilter(ApplicationModel applicationModel);
void setupConfig() {
ApplicationConfig config = new ApplicationConfig();
config.setName("MockObservations");
applicationModel = ApplicationModel.defaultModel();
applicationModel.getApplicationConfigManager().setApplication(config);
invocation = new RpcInvocation(new MockInvocation());
invocation.addInvokedInvoker(invoker);
applicationModel.getBeanFactory().registerBean(getObservationRegistry());
TracingConfig tracingConfig = new TracingConfig();
tracingConfig.setEnabled(true);
applicationModel.getApplicationConfigManager().setTracing(tracingConfig);
filter = createFilter(applicationModel);
given(invoker.invoke(invocation)).willReturn(new AppResponse("success"));
initParam();
}
private void initParam() {
invocation.setTargetServiceUniqueName(GROUP + "/" + INTERFACE_NAME + ":" + VERSION);
invocation.setMethodName(METHOD_NAME);
invocation.setParameterTypes(new Class[] {String.class});
}
}

View File

@ -60,7 +60,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.rpc.cluster.Constants.CLUSTER_AVAILABLE_CHECK_KEY;
import static org.apache.dubbo.rpc.cluster.Constants.INVOCATION_NEED_MOCK;
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
@ -576,26 +575,6 @@ class AbstractClusterInvokerTest {
}
}
/**
* Test mock invoker selector works as expected
*/
@Test
void testMockedInvokerSelect() {
initlistsize5();
invokers.add(mockedInvoker1);
initDic();
RpcInvocation mockedInvocation = new RpcInvocation();
mockedInvocation.setMethodName("sayHello");
mockedInvocation.setAttachment(INVOCATION_NEED_MOCK, "true");
List<Invoker<IHelloService>> mockedInvokers = dic.list(mockedInvocation);
Assertions.assertEquals(1, mockedInvokers.size());
List<Invoker<IHelloService>> invokers = dic.list(invocation);
Assertions.assertEquals(5, invokers.size());
}
public static interface IHelloService {
}
}

View File

@ -0,0 +1,83 @@
/*
* 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;
import org.apache.dubbo.common.constants.DeprecatedMethodInvocationCounterConstants;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.LongAdder;
/**
* Deprecated method invocation counter, which is used by annotation processor.
* <p>
* If an IDE says it is unused, just ignore it.
*/
public final class DeprecatedMethodInvocationCounter {
private DeprecatedMethodInvocationCounter() {
throw new UnsupportedOperationException("No instance of DeprecatedMethodInvocationCounter for you! ");
}
private static final ConcurrentHashMap<String, LongAdder> COUNTERS = new ConcurrentHashMap<>();
private static final ErrorTypeAwareLogger LOGGER = LoggerFactory.getErrorTypeAwareLogger(DeprecatedMethodInvocationCounter.class);
/**
* Invoked by (modified) deprecated method.
*
* @param methodDefinition filled by annotation processor. (like 'org.apache.dubbo.common.URL.getServiceName()')
*/
public static void onDeprecatedMethodCalled(String methodDefinition) {
if (!hasThisMethodInvoked(methodDefinition)) {
LOGGER.warn(
DeprecatedMethodInvocationCounterConstants.ERROR_CODE,
DeprecatedMethodInvocationCounterConstants.POSSIBLE_CAUSE,
DeprecatedMethodInvocationCounterConstants.EXTENDED_MESSAGE,
DeprecatedMethodInvocationCounterConstants.LOGGER_MESSAGE_PREFIX + methodDefinition
);
}
increaseInvocationCount(methodDefinition);
}
private static void increaseInvocationCount(String methodDefinition) {
COUNTERS.computeIfAbsent(methodDefinition, k -> new LongAdder());
LongAdder adder = COUNTERS.get(methodDefinition);
adder.increment();
}
public static boolean hasThisMethodInvoked(String methodDefinition) {
return COUNTERS.containsKey(methodDefinition);
}
public static Map<String, Integer> getInvocationRecord() {
// Perform a deep-copy to avoid concurrent issues.
HashMap<String, Integer> copyOfCounters = new HashMap<>();
for (Map.Entry<String, LongAdder> entry : COUNTERS.entrySet()) {
copyOfCounters.put(entry.getKey(), entry.getValue().intValue());
}
return Collections.unmodifiableMap(copyOfCounters);
}
}

View File

@ -0,0 +1,34 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.aot;
public abstract class NativeDetector {
/**
* See https://github.com/oracle/graal/blob/master/sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/ImageInfo.java
*/
private static final boolean IMAGE_CODE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
/**
* Returns {@code true} if invoked in the context of image building or during image runtime, else {@code false}.
*/
public static boolean inNativeImage() {
return IMAGE_CODE;
}
}

View File

@ -158,14 +158,6 @@ public class FileCacheStore {
FileCacheStoreFactory.removeCache(cacheFilePath);
}
/**
* for unit test only
*/
@Deprecated
protected String getCacheFilePath() {
return cacheFilePath;
}
public static Builder newBuilder() {
return new Builder();
}

View File

@ -31,7 +31,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@ -197,14 +196,6 @@ public final class FileCacheStoreFactory {
cacheMap.remove(cacheFileName);
}
/**
* for unit test only
*/
@Deprecated
static Map<String, FileCacheStore> getCacheMap() {
return cacheMap;
}
private static class PathNotExclusiveException extends Exception {
public PathNotExclusiveException(String msg) {
super(msg);

View File

@ -17,7 +17,6 @@
package org.apache.dubbo.common.config.configcenter;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration;
import org.apache.dubbo.common.utils.StringUtils;
import java.util.Collection;
@ -30,7 +29,7 @@ import static org.apache.dubbo.common.utils.PathUtils.normalize;
/**
* An abstract implementation of {@link DynamicConfiguration} is like "tree-structure" path :
* <ul>
* <li>{@link FileSystemDynamicConfiguration "file"}</li>
* <li>{@link org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration "file"}</li>
* <li>{@link org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration "zookeeper"}</li>
* <li>{@link org.apache.dubbo.configcenter.consul.ConsulDynamicConfiguration "consul"}</li>
* </ul>

View File

@ -32,7 +32,7 @@ public interface CommonConstants {
String PROVIDER = "provider";
String CONSUMER = "consumer";
String CALLBACK = "callback";
String APPLICATION_KEY = "application";
@ -128,6 +128,8 @@ public interface CommonConstants {
String THREAD_POOL_EXHAUSTED_LISTENERS_KEY = "thread-pool-exhausted-listeners";
String JSON_CHECK_LEVEL_KEY = "jsonCheckLevel";
String THREADS_KEY = "threads";
String QUEUES_KEY = "queues";
@ -285,6 +287,7 @@ public interface CommonConstants {
String MONITOR_KEY = "monitor";
String BACKGROUND_KEY = "background";
String CLUSTER_KEY = "cluster";
String MERGEABLE_CLUSTER_NAME = "mergeable";
String USERNAME_KEY = "username";
String PASSWORD_KEY = "password";
String HOST_KEY = "host";
@ -334,6 +337,8 @@ public interface CommonConstants {
String REGISTRY_PROTOCOL_LISTENER_KEY = "registry.protocol.listener";
String REGISTRY_SERVICE_CLASS_NAME = "org.apache.dubbo.registry.RegistryService";
String DUBBO_VERSION_KEY = "dubbo";
String TAG_KEY = "dubbo.tag";
@ -500,11 +505,6 @@ public interface CommonConstants {
*/
String URL_MERGE_PROCESSOR_KEY = "url-merge-processor";
/**
* use native image to compile dubbo's identifier
*/
String NATIVE = "native";
String DUBBO_MONITOR_ADDRESS = "dubbo.monitor.address";
String SERVICE_NAME_MAPPING_KEY = "service-name-mapping";
@ -618,9 +618,7 @@ public interface CommonConstants {
/**
*
* used in JVMUtil.java ,Control stack print lines, default is 32 lines
*
*/
String DUBBO_JSTACK_MAXLINE = "dubbo.jstack-dump.max-line";
@ -643,7 +641,11 @@ public interface CommonConstants {
String DUBBO_PACKABLE_METHOD_FACTORY = "dubbo.application.parameters." + PACKABLE_METHOD_FACTORY_KEY;
String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
String DUBBO_TAG_HEADER = "dubbo-tag";
String REST_SERVICE_DEPLOYER_URL_ATTRIBUTE_KEY = "restServiceDeployerAttributeKey";
String SERVICE_DEPLOYER_ATTRIBUTE_KEY = "serviceDeployer"; String RESTEASY_NETTY_HTTP_REQUEST_ATTRIBUTE_KEY = "resteasyNettyHttpRequest";
String DUBBO_MANUAL_REGISTER_KEY = "dubbo.application.manual-register";
}

View File

@ -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.constants;
/**
* Constants of Deprecated Method Invocation Counter.
*/
public final class DeprecatedMethodInvocationCounterConstants {
private DeprecatedMethodInvocationCounterConstants() {
throw new UnsupportedOperationException("No instance of DeprecatedMethodInvocationCounterConstants for you! ");
}
public static final String ERROR_CODE = LoggerCodeConstants.COMMON_DEPRECATED_METHOD_INVOKED;
public static final String POSSIBLE_CAUSE = "invocation of deprecated method";
public static final String EXTENDED_MESSAGE = "";
public static final String LOGGER_MESSAGE_PREFIX = "Deprecated method invoked. The method is ";
}

View File

@ -92,6 +92,12 @@ public interface LoggerCodeConstants {
String VULNERABILITY_WARNING = "0-28";
String COMMON_NOT_FOUND_TRACER_DEPENDENCY = "0-29";
/**
* Used in annotation processor to indicate a deprecated method is invoked.
*/
String COMMON_DEPRECATED_METHOD_INVOKED = "0-99";
// Registry module

View File

@ -47,6 +47,8 @@ public interface MetricsConstants {
String TAG_CHANGE_TYPE = "change.type";
String TAG_ERROR_CODE = "error";
String ENABLE_JVM_METRICS_KEY = "enable.jvm";
String AGGREGATION_COLLECTOR_KEY = "aggregation";

View File

@ -22,6 +22,8 @@ import org.apache.dubbo.rpc.model.ScopeModel;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_MONITOR_EXCEPTION;
import static org.apache.dubbo.common.deploy.DeployState.FAILED;
@ -31,18 +33,17 @@ import static org.apache.dubbo.common.deploy.DeployState.STARTING;
import static org.apache.dubbo.common.deploy.DeployState.STOPPED;
import static org.apache.dubbo.common.deploy.DeployState.STOPPING;
public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer<E> {
public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer<E>{
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(AbstractDeployer.class);
private volatile DeployState state = PENDING;
protected AtomicReference<DeployState> state = new AtomicReference<>(PENDING);
private volatile Throwable lastError;
protected AtomicReference<Throwable> lastError = new AtomicReference<>();
protected volatile boolean initialized = false;
protected AtomicBoolean initialized = new AtomicBoolean(false);
protected List<DeployListener<E>> listeners = new CopyOnWriteArrayList<>();
private E scopeModel;
public AbstractDeployer(E scopeModel) {
@ -51,46 +52,47 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
@Override
public boolean isPending() {
return state == PENDING;
return state.get().equals(PENDING);
}
@Override
public boolean isRunning() {
return state == STARTING || state == STARTED;
return state.get().equals(STARTING) || state.get().equals(STARTED);
}
@Override
public boolean isStarted() {
return state == STARTED;
return state.get().equals(STARTED);
}
@Override
public boolean isStarting() {
return state == STARTING;
return state.get().equals(STARTING);
}
@Override
public boolean isStopping() {
return state == STOPPING;
return state.get().equals(STOPPING);
}
@Override
public boolean isStopped() {
return state == STOPPED;
return state.get().equals(STOPPED);
}
@Override
public boolean isFailed() {
return state == FAILED;
return state.get().equals(FAILED);
}
@Override
public DeployState getState() {
return state;
return state.get();
}
@Override
public void addDeployListener(DeployListener<E> listener) {
scopeModel.getBeanFactory().registerBean(listener);
listeners.add(listener);
}
@ -100,11 +102,11 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
}
public void setPending() {
this.state = PENDING;
this.state.set(PENDING);
}
protected void setStarting() {
this.state = STARTING;
this.state.set(STARTING);
for (DeployListener<E> listener : listeners) {
try {
listener.onStarting(scopeModel);
@ -115,7 +117,7 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
}
protected void setStarted() {
this.state = STARTED;
this.state.set(STARTED);
for (DeployListener<E> listener : listeners) {
try {
listener.onStarted(scopeModel);
@ -126,7 +128,7 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
}
protected void setStopping() {
this.state = STOPPING;
this.state.set(STOPPING);
for (DeployListener<E> listener : listeners) {
try {
listener.onStopping(scopeModel);
@ -137,7 +139,7 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
}
protected void setStopped() {
this.state = STOPPED;
this.state.set(STOPPED);
for (DeployListener<E> listener : listeners) {
try {
listener.onStopped(scopeModel);
@ -148,8 +150,8 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
}
protected void setFailed(Throwable error) {
this.state = FAILED;
this.lastError = error;
this.state.set(FAILED);
this.lastError.set(error);
for (DeployListener<E> listener : listeners) {
try {
listener.onFailure(scopeModel, error);
@ -161,14 +163,26 @@ public abstract class AbstractDeployer<E extends ScopeModel> implements Deployer
@Override
public Throwable getError() {
return lastError;
return lastError.get();
}
public boolean isInitialized() {
return initialized;
return initialized.get();
}
protected String getIdentifier() {
return scopeModel.getDesc();
}
public AtomicBoolean getInitialized() {
return initialized;
}
public AtomicReference<Throwable> getErrorRef() {
return lastError;
}
public AtomicReference<DeployState> getStateRef(){
return state;
}
}

View File

@ -18,6 +18,7 @@ package org.apache.dubbo.common.extension;
import org.apache.dubbo.common.Extension;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.aot.NativeDetector;
import org.apache.dubbo.common.beans.support.InstantiationStrategy;
import org.apache.dubbo.common.context.Lifecycle;
import org.apache.dubbo.common.extension.support.ActivateComparator;
@ -33,7 +34,6 @@ import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.Holder;
import org.apache.dubbo.common.utils.NativeUtils;
import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
@ -108,8 +108,8 @@ public class ExtensionLoader<T> {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(
ExtensionLoader.class);
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
private static final String SPECIAL_SPI_PROPERTIES = "special_spi.properties";
private static final Pattern NAME_SEPARATOR = Pattern.compile("\\s*[,]+\\s*");
private static final String SPECIAL_SPI_PROPERTIES = "special_spi.properties";
private final ConcurrentMap<Class<?>, Object> extensionInstances = new ConcurrentHashMap<>(64);
@ -121,17 +121,17 @@ public class ExtensionLoader<T> {
private final Holder<Map<String, Class<?>>> cachedClasses = new Holder<>();
private final Map<String, Object> cachedActivates = Collections.synchronizedMap(
private final Map<String, Object> cachedActivates = Collections.synchronizedMap(
new LinkedHashMap<>());
private final Map<String, Set<String>> cachedActivateGroups = Collections.synchronizedMap(
private final Map<String, Set<String>> cachedActivateGroups = Collections.synchronizedMap(
new LinkedHashMap<>());
private final Map<String, String[][]> cachedActivateValues = Collections.synchronizedMap(
private final Map<String, String[][]> cachedActivateValues = Collections.synchronizedMap(
new LinkedHashMap<>());
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
private volatile Class<?> cachedAdaptiveClass = null;
private String cachedDefaultName;
private volatile Throwable createAdaptiveInstanceError;
private final ConcurrentMap<String, Holder<Object>> cachedInstances = new ConcurrentHashMap<>();
private final Holder<Object> cachedAdaptiveInstance = new Holder<>();
private volatile Class<?> cachedAdaptiveClass = null;
private String cachedDefaultName;
private volatile Throwable createAdaptiveInstanceError;
private Set<Class<?>> cachedWrapperClasses;
@ -149,13 +149,13 @@ public class ExtensionLoader<T> {
/**
* Record all unacceptable exceptions when using SPI
*/
private final Set<String> unacceptableExceptions = new ConcurrentHashSet<>();
private final ExtensionDirector extensionDirector;
private final Set<String> unacceptableExceptions = new ConcurrentHashSet<>();
private final ExtensionDirector extensionDirector;
private final List<ExtensionPostProcessor> extensionPostProcessors;
private InstantiationStrategy instantiationStrategy;
private final ActivateComparator activateComparator;
private final ScopeModel scopeModel;
private final AtomicBoolean destroyed = new AtomicBoolean();
private InstantiationStrategy instantiationStrategy;
private final ActivateComparator activateComparator;
private final ScopeModel scopeModel;
private final AtomicBoolean destroyed = new AtomicBoolean();
public static void setLoadingStrategies(LoadingStrategy... strategies) {
if (ArrayUtils.isNotEmpty(strategies)) {
@ -1412,7 +1412,7 @@ public class ExtensionLoader<T> {
// Adaptive Classes' ClassLoader should be the same with Real SPI interface classes' ClassLoader
ClassLoader classLoader = type.getClassLoader();
try {
if (NativeUtils.isNative()) {
if (NativeDetector.inNativeImage()) {
return classLoader.loadClass(type.getName() + "$Adaptive");
}
} catch (Throwable ignore) {

View File

@ -60,6 +60,17 @@ public class GsonUtils {
}
}
public static String toJson(Object obj) throws RuntimeException {
if (!isSupportGson()) {
throw new RuntimeException("Gson is not supported. Please import Gson in JVM env.");
}
try {
return getGson().toJson(obj);
} catch (JsonSyntaxException ex) {
throw new RuntimeException(String.format("Generic serialization [%s] Json syntax exception thrown when parsing (object:%s ) error:%s", GENERIC_SERIALIZATION_GSON, obj, ex.getMessage()));
}
}
private static Gson getGson() {
if (gsonCache == null || !(gsonCache instanceof Gson)) {
synchronized (GsonUtils.class) {

View File

@ -16,11 +16,14 @@
*/
package org.apache.dubbo.common.json;
import org.apache.dubbo.common.extension.SPI;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public interface JSON {
@SPI
public interface JsonUtil {
boolean isSupport();
<T> T toJavaObject(String json, Type type);

View File

@ -16,7 +16,7 @@
*/
package org.apache.dubbo.common.json.impl;
import org.apache.dubbo.common.json.JSON;
import org.apache.dubbo.common.json.JsonUtil;
import org.apache.dubbo.common.utils.CollectionUtils;
import java.util.HashMap;
@ -24,7 +24,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public abstract class AbstractJSONImpl implements JSON {
public abstract class AbstractJsonUtilImpl implements JsonUtil {
@Override
public boolean isSupport() {
try {

View File

@ -21,7 +21,7 @@ import com.alibaba.fastjson2.JSONWriter;
import java.lang.reflect.Type;
import java.util.List;
public class FastJson2Impl extends AbstractJSONImpl {
public class FastJson2Impl extends AbstractJsonUtilImpl {
@Override
public <T> T toJavaObject(String json, Type type) {
return com.alibaba.fastjson2.JSON.parseObject(json, type);

View File

@ -21,7 +21,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
import java.lang.reflect.Type;
import java.util.List;
public class FastJsonImpl extends AbstractJSONImpl {
public class FastJsonImpl extends AbstractJsonUtilImpl {
@Override
public <T> T toJavaObject(String json, Type type) {

View File

@ -22,7 +22,7 @@ import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;
public class GsonImpl extends AbstractJSONImpl {
public class GsonImpl extends AbstractJsonUtilImpl {
// weak reference of com.google.gson.Gson, prevent throw exception when init
private volatile Object gsonCache = null;

View File

@ -26,7 +26,7 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import java.lang.reflect.Type;
import java.util.List;
public class JacksonImpl extends AbstractJSONImpl {
public class JacksonImpl extends AbstractJsonUtilImpl {
private final ObjectMapper objectMapper = new ObjectMapper();
private volatile Object jacksonCache = null;

View File

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.logger;
/**
* Loggers that can register to listen to log messages.
*/
public interface ListenableLogger extends ErrorTypeAwareLogger{
/**
* Register a listener to this loggerand get notified when a log happens.
*
* @param listener log listener
*/
void registerListen(LogListener listener);
}

View File

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

View File

@ -30,6 +30,14 @@ public interface Logger {
*/
void trace(String msg);
/**
* Logs a message with trace log level.
*
* @param msg log this message
* @param arguments a list of arguments
*/
void trace(String msg, Object... arguments);
/**
* Logs an error with trace log level.
*
@ -52,6 +60,14 @@ public interface Logger {
*/
void debug(String msg);
/**
* Logs a message with debug log level.
*
* @param msg log this message
* @param arguments a list of arguments
*/
void debug(String msg, Object... arguments);
/**
* Logs an error with debug log level.
*
@ -74,6 +90,14 @@ public interface Logger {
*/
void info(String msg);
/**
* Logs a message with info log level.
*
* @param msg log this message
* @param arguments a list of arguments
*/
void info(String msg, Object... arguments);
/**
* Logs an error with info log level.
*
@ -96,6 +120,14 @@ public interface Logger {
*/
void warn(String msg);
/**
* Logs a message with warn log level.
*
* @param msg log this message
* @param arguments a list of arguments
*/
void warn(String msg, Object... arguments);
/**
* Logs a message with warn log level.
*
@ -118,6 +150,14 @@ public interface Logger {
*/
void error(String msg);
/**
* Logs a message with error log level.
*
* @param msg log this message
* @param arguments a list of arguments
*/
void error(String msg, Object... arguments);
/**
* Logs an error with error log level.
*

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2004-2011 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package org.apache.dubbo.common.logger.helpers;
/**
* Holds the results of formatting done by {@link MessageFormatter}.
* This is a copy of org.slf4j.helpers.FormattingTuple from slf4j-api.
*
* @author Joern Huxhorn
*/
public class FormattingTuple {
static public FormattingTuple NULL = new FormattingTuple(null);
private String message;
private Throwable throwable;
private Object[] argArray;
public FormattingTuple(String message) {
this(message, null, null);
}
public FormattingTuple(String message, Object[] argArray, Throwable throwable) {
this.message = message;
this.throwable = throwable;
this.argArray = argArray;
}
public String getMessage() {
return message;
}
public Object[] getArgArray() {
return argArray;
}
public Throwable getThrowable() {
return throwable;
}
}

View File

@ -0,0 +1,437 @@
/*
* Copyright (c) 2004-2011 QOS.ch
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
package org.apache.dubbo.common.logger.helpers;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
// contributors: lizongbo: proposed special treatment of array parameter values
// Joern Huxhorn: pointed out double[] omission, suggested deep array copy
/**
* This is a copy of org.slf4j.helpers.MessageFormatter from slf4j-api.
* Formats messages according to very simple substitution rules. Substitutions
* can be made 1, 2 or more arguments.
*
* <p>
* For example,
*
* <pre>
* MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;)
* </pre>
* <p>
* will return the string "Hi there.".
* <p>
* The {} pair is called the <em>formatting anchor</em>. It serves to designate
* the location where arguments need to be substituted within the message
* pattern.
* <p>
* In case your message contains the '{' or the '}' character, you do not have
* to do anything special unless the '}' character immediately follows '{'. For
* example,
*
* <pre>
* MessageFormatter.format(&quot;Set {1,2,3} is not equal to {}.&quot;, &quot;1,2&quot;);
* </pre>
* <p>
* will return the string "Set {1,2,3} is not equal to 1,2.".
*
* <p>
* If for whatever reason you need to place the string "{}" in the message
* without its <em>formatting anchor</em> meaning, then you need to escape the
* '{' character with '\', that is the backslash character. Only the '{'
* character should be escaped. There is no need to escape the '}' character.
* For example,
*
* <pre>
* MessageFormatter.format(&quot;Set \\{} is not equal to {}.&quot;, &quot;1,2&quot;);
* </pre>
* <p>
* will return the string "Set {} is not equal to 1,2.".
*
* <p>
* The escaping behavior just described can be overridden by escaping the escape
* character '\'. Calling
*
* <pre>
* MessageFormatter.format(&quot;File name is C:\\\\{}.&quot;, &quot;file.zip&quot;);
* </pre>
* <p>
* will return the string "File name is C:\file.zip".
*
* <p>
* The formatting conventions are different than those of {@link MessageFormat}
* which ships with the Java platform. This is justified by the fact that
* SLF4J's implementation is 10 times faster than that of {@link MessageFormat}.
* This local performance difference is both measurable and significant in the
* larger context of the complete logging processing chain.
*
* <p>
* See also {@link #format(String, Object)},
* {@link #format(String, Object, Object)} and
* {@link #arrayFormat(String, Object[])} methods for more details.
*
* @author Ceki G&uuml;lc&uuml;
* @author Joern Huxhorn
*/
final public class MessageFormatter {
static final char DELIM_START = '{';
static final char DELIM_STOP = '}';
static final String DELIM_STR = "{}";
private static final char ESCAPE_CHAR = '\\';
/**
* Performs single argument substitution for the 'messagePattern' passed as
* parameter.
* <p>
* For example,
*
* <pre>
* MessageFormatter.format(&quot;Hi {}.&quot;, &quot;there&quot;);
* </pre>
* <p>
* will return the string "Hi there.".
* <p>
*
* @param messagePattern The message pattern which will be parsed and formatted
* @param arg The argument to be substituted in place of the formatting anchor
* @return The formatted message
*/
final public static FormattingTuple format(String messagePattern, Object arg) {
return arrayFormat(messagePattern, new Object[]{arg});
}
/**
* Performs a two argument substitution for the 'messagePattern' passed as
* parameter.
* <p>
* For example,
*
* <pre>
* MessageFormatter.format(&quot;Hi {}. My name is {}.&quot;, &quot;Alice&quot;, &quot;Bob&quot;);
* </pre>
* <p>
* will return the string "Hi Alice. My name is Bob.".
*
* @param messagePattern The message pattern which will be parsed and formatted
* @param arg1 The argument to be substituted in place of the first formatting
* anchor
* @param arg2 The argument to be substituted in place of the second formatting
* anchor
* @return The formatted message
*/
final public static FormattingTuple format(final String messagePattern, Object arg1, Object arg2) {
return arrayFormat(messagePattern, new Object[]{arg1, arg2});
}
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray) {
Throwable throwableCandidate = MessageFormatter.getThrowableCandidate(argArray);
Object[] args = argArray;
if (throwableCandidate != null) {
args = MessageFormatter.trimmedCopy(argArray);
}
return arrayFormat(messagePattern, args, throwableCandidate);
}
final public static FormattingTuple arrayFormat(final String messagePattern, final Object[] argArray, Throwable throwable) {
if (messagePattern == null) {
return new FormattingTuple(null, argArray, throwable);
}
if (argArray == null) {
return new FormattingTuple(messagePattern);
}
int i = 0;
int j;
// use string builder for better multicore performance
StringBuilder sbuf = new StringBuilder(messagePattern.length() + 50);
int L;
for (L = 0; L < argArray.length; L++) {
j = messagePattern.indexOf(DELIM_STR, i);
if (j == -1) {
// no more variables
if (i == 0) { // this is a simple string
return new FormattingTuple(messagePattern, argArray, throwable);
} else { // add the tail string which contains no variables and return
// the result.
sbuf.append(messagePattern, i, messagePattern.length());
return new FormattingTuple(sbuf.toString(), argArray, throwable);
}
} else {
if (isEscapedDelimeter(messagePattern, j)) {
if (!isDoubleEscaped(messagePattern, j)) {
L--; // DELIM_START was escaped, thus should not be incremented
sbuf.append(messagePattern, i, j - 1);
sbuf.append(DELIM_START);
i = j + 1;
} else {
// The escape character preceding the delimiter start is
// itself escaped: "abc x:\\{}"
// we have to consume one backward slash
sbuf.append(messagePattern, i, j - 1);
deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
i = j + 2;
}
} else {
// normal case
sbuf.append(messagePattern, i, j);
deeplyAppendParameter(sbuf, argArray[L], new HashMap<Object[], Object>());
i = j + 2;
}
}
}
// append the characters following the last {} pair.
sbuf.append(messagePattern, i, messagePattern.length());
return new FormattingTuple(sbuf.toString(), argArray, throwable);
}
final static boolean isEscapedDelimeter(String messagePattern, int delimeterStartIndex) {
if (delimeterStartIndex == 0) {
return false;
}
char potentialEscape = messagePattern.charAt(delimeterStartIndex - 1);
if (potentialEscape == ESCAPE_CHAR) {
return true;
} else {
return false;
}
}
final static boolean isDoubleEscaped(String messagePattern, int delimeterStartIndex) {
if (delimeterStartIndex >= 2 && messagePattern.charAt(delimeterStartIndex - 2) == ESCAPE_CHAR) {
return true;
} else {
return false;
}
}
// special treatment of array values was suggested by 'lizongbo'
private static void deeplyAppendParameter(StringBuilder sbuf, Object o, Map<Object[], Object> seenMap) {
if (o == null) {
sbuf.append("null");
return;
}
if (!o.getClass().isArray()) {
safeObjectAppend(sbuf, o);
} else {
// check for primitive array types because they
// unfortunately cannot be cast to Object[]
if (o instanceof boolean[]) {
booleanArrayAppend(sbuf, (boolean[]) o);
} else if (o instanceof byte[]) {
byteArrayAppend(sbuf, (byte[]) o);
} else if (o instanceof char[]) {
charArrayAppend(sbuf, (char[]) o);
} else if (o instanceof short[]) {
shortArrayAppend(sbuf, (short[]) o);
} else if (o instanceof int[]) {
intArrayAppend(sbuf, (int[]) o);
} else if (o instanceof long[]) {
longArrayAppend(sbuf, (long[]) o);
} else if (o instanceof float[]) {
floatArrayAppend(sbuf, (float[]) o);
} else if (o instanceof double[]) {
doubleArrayAppend(sbuf, (double[]) o);
} else {
objectArrayAppend(sbuf, (Object[]) o, seenMap);
}
}
}
private static void safeObjectAppend(StringBuilder sbuf, Object o) {
try {
String oAsString = o.toString();
sbuf.append(oAsString);
} catch (Throwable t) {
System.err.println("SLF4J: Failed toString() invocation on an object of type [" + o.getClass().getName() + "]");
System.err.println("Reported exception:");
StackTraceElement[] stackTrace = t.getStackTrace();
StringBuilder stackBuilder = new StringBuilder();
for (StackTraceElement traceElement : stackTrace) {
stackBuilder.append("\tat ").append(traceElement).append("\n");
}
System.err.println(stackBuilder);
sbuf.append("[FAILED toString()]");
}
}
private static void objectArrayAppend(StringBuilder sbuf, Object[] a, Map<Object[], Object> seenMap) {
sbuf.append('[');
if (!seenMap.containsKey(a)) {
seenMap.put(a, null);
final int len = a.length;
for (int i = 0; i < len; i++) {
deeplyAppendParameter(sbuf, a[i], seenMap);
if (i != len - 1)
sbuf.append(", ");
}
// allow repeats in siblings
seenMap.remove(a);
} else {
sbuf.append("...");
}
sbuf.append(']');
}
private static void booleanArrayAppend(StringBuilder sbuf, boolean[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void byteArrayAppend(StringBuilder sbuf, byte[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void charArrayAppend(StringBuilder sbuf, char[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void shortArrayAppend(StringBuilder sbuf, short[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void intArrayAppend(StringBuilder sbuf, int[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void longArrayAppend(StringBuilder sbuf, long[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void floatArrayAppend(StringBuilder sbuf, float[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
private static void doubleArrayAppend(StringBuilder sbuf, double[] a) {
sbuf.append('[');
final int len = a.length;
for (int i = 0; i < len; i++) {
sbuf.append(a[i]);
if (i != len - 1)
sbuf.append(", ");
}
sbuf.append(']');
}
/**
* Helper method to determine if an {@link Object} array contains a {@link Throwable} as last element
*
* @param argArray The arguments off which we want to know if it contains a {@link Throwable} as last element
* @return if the last {@link Object} in argArray is a {@link Throwable} this method will return it,
* otherwise it returns null
*/
public static Throwable getThrowableCandidate(final Object[] argArray) {
if (argArray == null || argArray.length == 0) {
return null;
}
final Object lastEntry = argArray[argArray.length - 1];
if (lastEntry instanceof Throwable) {
return (Throwable) lastEntry;
}
return null;
}
/**
* Helper method to get all but the last element of an array
*
* @param argArray The arguments from which we want to remove the last element
* @return a copy of the array without the last element
*/
public static Object[] trimmedCopy(final Object[] argArray) {
if (argArray == null || argArray.length == 0) {
throw new IllegalStateException("non-sensical empty or null argument array");
}
final int trimmedLen = argArray.length - 1;
Object[] trimmed = new Object[trimmedLen];
if (trimmedLen > 0) {
System.arraycopy(argArray, 0, trimmed, 0, trimmedLen);
}
return trimmed;
}
}

View File

@ -19,6 +19,8 @@ package org.apache.dubbo.common.logger.jcl;
import org.apache.dubbo.common.logger.Logger;
import org.apache.commons.logging.Log;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
/**
* Adaptor to commons logging, depends on commons-logging.jar. For more information about commons logging, pls. refer to
@ -37,6 +39,12 @@ public class JclLogger implements Logger {
logger.trace(msg);
}
@Override
public void trace(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.trace(ft.getMessage(), ft.getThrowable());
}
@Override
public void trace(Throwable e) {
logger.trace(e);
@ -52,6 +60,12 @@ public class JclLogger implements Logger {
logger.debug(msg);
}
@Override
public void debug(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.debug(ft.getMessage(), ft.getThrowable());
}
@Override
public void debug(Throwable e) {
logger.debug(e);
@ -67,6 +81,12 @@ public class JclLogger implements Logger {
logger.info(msg);
}
@Override
public void info(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.info(ft.getMessage(), ft.getThrowable());
}
@Override
public void info(Throwable e) {
logger.info(e);
@ -82,6 +102,12 @@ public class JclLogger implements Logger {
logger.warn(msg);
}
@Override
public void warn(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.warn(ft.getMessage(), ft.getThrowable());
}
@Override
public void warn(Throwable e) {
logger.warn(e);
@ -97,6 +123,12 @@ public class JclLogger implements Logger {
logger.error(msg);
}
@Override
public void error(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.error(ft.getMessage(), ft.getThrowable());
}
@Override
public void error(Throwable e) {
logger.error(e);

View File

@ -17,6 +17,8 @@
package org.apache.dubbo.common.logger.jdk;
import org.apache.dubbo.common.logger.Logger;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import java.util.logging.Level;
@ -33,6 +35,12 @@ public class JdkLogger implements Logger {
logger.log(Level.FINER, msg);
}
@Override
public void trace(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(Level.FINER, ft.getMessage(), ft.getThrowable());
}
@Override
public void trace(Throwable e) {
logger.log(Level.FINER, e.getMessage(), e);
@ -48,6 +56,12 @@ public class JdkLogger implements Logger {
logger.log(Level.FINE, msg);
}
@Override
public void debug(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(Level.FINE, ft.getMessage(), ft.getThrowable());
}
@Override
public void debug(Throwable e) {
logger.log(Level.FINE, e.getMessage(), e);
@ -63,6 +77,12 @@ public class JdkLogger implements Logger {
logger.log(Level.INFO, msg);
}
@Override
public void info(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(Level.INFO, ft.getMessage(), ft.getThrowable());
}
@Override
public void info(String msg, Throwable e) {
logger.log(Level.INFO, msg, e);
@ -73,6 +93,12 @@ public class JdkLogger implements Logger {
logger.log(Level.WARNING, msg);
}
@Override
public void warn(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(Level.WARNING, ft.getMessage(), ft.getThrowable());
}
@Override
public void warn(String msg, Throwable e) {
logger.log(Level.WARNING, msg, e);
@ -83,6 +109,12 @@ public class JdkLogger implements Logger {
logger.log(Level.SEVERE, msg);
}
@Override
public void error(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(Level.SEVERE, ft.getMessage(), ft.getThrowable());
}
@Override
public void error(String msg, Throwable e) {
logger.log(Level.SEVERE, msg, e);

View File

@ -20,6 +20,8 @@ import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.support.FailsafeLogger;
import org.apache.log4j.Level;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
public class Log4jLogger implements Logger {
@ -36,6 +38,12 @@ public class Log4jLogger implements Logger {
logger.log(FQCN, Level.TRACE, msg, null);
}
@Override
public void trace(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(FQCN, Level.TRACE, ft.getMessage(), ft.getThrowable());
}
@Override
public void trace(Throwable e) {
logger.log(FQCN, Level.TRACE, e == null ? null : e.getMessage(), e);
@ -51,6 +59,12 @@ public class Log4jLogger implements Logger {
logger.log(FQCN, Level.DEBUG, msg, null);
}
@Override
public void debug(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(FQCN, Level.DEBUG, ft.getMessage(), ft.getThrowable());
}
@Override
public void debug(Throwable e) {
logger.log(FQCN, Level.DEBUG, e == null ? null : e.getMessage(), e);
@ -66,6 +80,12 @@ public class Log4jLogger implements Logger {
logger.log(FQCN, Level.INFO, msg, null);
}
@Override
public void info(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(FQCN, Level.INFO, ft.getMessage(), ft.getThrowable());
}
@Override
public void info(Throwable e) {
logger.log(FQCN, Level.INFO, e == null ? null : e.getMessage(), e);
@ -81,6 +101,12 @@ public class Log4jLogger implements Logger {
logger.log(FQCN, Level.WARN, msg, null);
}
@Override
public void warn(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(FQCN, Level.WARN, ft.getMessage(), ft.getThrowable());
}
@Override
public void warn(Throwable e) {
logger.log(FQCN, Level.WARN, e == null ? null : e.getMessage(), e);
@ -96,6 +122,12 @@ public class Log4jLogger implements Logger {
logger.log(FQCN, Level.ERROR, msg, null);
}
@Override
public void error(String msg, Object... arguments) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
logger.log(FQCN, Level.ERROR, ft.getMessage(), ft.getThrowable());
}
@Override
public void error(Throwable e) {
logger.log(FQCN, Level.ERROR, e == null ? null : e.getMessage(), e);

View File

@ -31,6 +31,11 @@ public class Log4j2Logger implements Logger {
logger.trace(msg);
}
@Override
public void trace(String msg, Object... arguments) {
logger.trace(msg, arguments);
}
@Override
public void trace(Throwable e) {
logger.trace(e == null ? null : e.getMessage(), e);
@ -46,6 +51,11 @@ public class Log4j2Logger implements Logger {
logger.debug(msg);
}
@Override
public void debug(String msg, Object... arguments) {
logger.debug(msg, arguments);
}
@Override
public void debug(Throwable e) {
logger.debug(e == null ? null : e.getMessage(), e);
@ -61,6 +71,11 @@ public class Log4j2Logger implements Logger {
logger.info(msg);
}
@Override
public void info(String msg, Object... arguments) {
logger.info(msg, arguments);
}
@Override
public void info(Throwable e) {
logger.info(e == null ? null : e.getMessage(), e);
@ -76,6 +91,11 @@ public class Log4j2Logger implements Logger {
logger.warn(msg);
}
@Override
public void warn(String msg, Object... arguments) {
logger.warn(msg, arguments);
}
@Override
public void warn(Throwable e) {
logger.warn(e == null ? null : e.getMessage(), e);
@ -91,6 +111,11 @@ public class Log4j2Logger implements Logger {
logger.error(msg);
}
@Override
public void error(String msg, Object... arguments) {
logger.error(msg, arguments);
}
@Override
public void error(Throwable e) {
logger.error(e == null ? null : e.getMessage(), e);

View File

@ -20,6 +20,8 @@ import org.apache.dubbo.common.logger.Level;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.support.FailsafeLogger;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MessageFormatter;
import org.slf4j.spi.LocationAwareLogger;
public class Slf4jLogger implements Logger {
@ -48,6 +50,16 @@ public class Slf4jLogger implements Logger {
logger.trace(msg);
}
@Override
public void trace(String msg, Object... arguments) {
if (locationAwareLogger != null) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
locationAwareLogger.log(null, FQCN, LocationAwareLogger.TRACE_INT, msg, ft.getArgArray(), ft.getThrowable());
return;
}
logger.trace(msg, arguments);
}
@Override
public void trace(Throwable e) {
if (locationAwareLogger != null) {
@ -75,6 +87,16 @@ public class Slf4jLogger implements Logger {
logger.debug(msg);
}
@Override
public void debug(String msg, Object... arguments) {
if (locationAwareLogger != null) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
locationAwareLogger.log(null, FQCN, LocationAwareLogger.DEBUG_INT, msg, ft.getArgArray(), ft.getThrowable());
return;
}
logger.debug(msg, arguments);
}
@Override
public void debug(Throwable e) {
if (locationAwareLogger != null) {
@ -102,6 +124,16 @@ public class Slf4jLogger implements Logger {
logger.info(msg);
}
@Override
public void info(String msg, Object... arguments) {
if (locationAwareLogger != null) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
locationAwareLogger.log(null, FQCN, LocationAwareLogger.INFO_INT, msg, ft.getArgArray(), ft.getThrowable());
return;
}
logger.info(msg, arguments);
}
@Override
public void info(Throwable e) {
if (locationAwareLogger != null) {
@ -129,6 +161,16 @@ public class Slf4jLogger implements Logger {
logger.warn(msg);
}
@Override
public void warn(String msg, Object... arguments) {
if (locationAwareLogger != null) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
locationAwareLogger.log(null, FQCN, LocationAwareLogger.WARN_INT, msg, ft.getArgArray(), ft.getThrowable());
return;
}
logger.warn(msg, arguments);
}
@Override
public void warn(Throwable e) {
if (locationAwareLogger != null) {
@ -156,6 +198,16 @@ public class Slf4jLogger implements Logger {
logger.error(msg);
}
@Override
public void error(String msg, Object... arguments) {
if (locationAwareLogger != null) {
FormattingTuple ft = MessageFormatter.arrayFormat(msg, arguments);
locationAwareLogger.log(null, FQCN, LocationAwareLogger.ERROR_INT, msg, ft.getArgArray(), ft.getThrowable());
return;
}
logger.error(msg, arguments);
}
@Override
public void error(Throwable e) {
if (locationAwareLogger != null) {

View File

@ -18,16 +18,22 @@
package org.apache.dubbo.common.logger.support;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.ListenableLogger;
import org.apache.dubbo.common.logger.LogListener;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.utils.NetUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
/**
* A fail-safe (ignoring exception thrown by logger) wrapper of error type aware logger.
*/
public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements ErrorTypeAwareLogger {
public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements ListenableLogger {
/**
* Template address for formatting.
@ -36,6 +42,16 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
private static final Pattern ERROR_CODE_PATTERN = Pattern.compile("\\d+-\\d+");
/**
* Listeners that listened to all Loggers.
*/
private static final List<LogListener> GLOBAL_LISTENERS = Collections.synchronizedList(new ArrayList<>());
/**
* Listeners that listened to this listener.
*/
private final AtomicReference<List<LogListener>> listeners = new AtomicReference<>();
public FailsafeErrorTypeAwareLogger(Logger logger) {
super(logger);
}
@ -80,6 +96,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
}
try {
onEvent(code, msg);
getLogger().warn(appendContextMessageWithInstructions(code, cause, extendedInformation, msg));
} catch (Throwable t) {
// ignored.
@ -93,6 +110,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
}
try {
onEvent(code, msg);
getLogger().warn(appendContextMessageWithInstructions(code, cause, extendedInformation, msg), e);
} catch (Throwable t) {
// ignored.
@ -106,6 +124,7 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
}
try {
onEvent(code, msg);
getLogger().error(appendContextMessageWithInstructions(code, cause, extendedInformation, msg));
} catch (Throwable t) {
// ignored.
@ -119,9 +138,45 @@ public class FailsafeErrorTypeAwareLogger extends FailsafeLogger implements Erro
}
try {
onEvent(code, msg);
getLogger().error(appendContextMessageWithInstructions(code, cause, extendedInformation, msg), e);
} catch (Throwable t) {
// ignored.
}
}
public static void registerGlobalListen(LogListener listener) {
GLOBAL_LISTENERS.add(listener);
}
@Override
public void registerListen(LogListener listener) {
listeners.getAndUpdate(logListeners -> {
if (logListeners == null) {
logListeners = Collections.synchronizedList(new ArrayList<>());
}
logListeners.add(listener);
return logListeners;
});
}
private void onEvent(String code, String msg) {
Optional.ofNullable(listeners.get()).ifPresent(
logListeners -> logListeners.forEach(logListener -> {
try {
logListener.onMessage(code, msg);
} catch (Exception e) {
// ignored.
}
}));
GLOBAL_LISTENERS.forEach(logListener -> {
try {
logListener.onMessage(code, msg);
} catch (Exception e) {
// ignored.
}
});
}
}

View File

@ -83,6 +83,17 @@ public class FailsafeLogger implements Logger {
}
}
@Override
public void trace(String msg, Object... arguments) {
if (disabled) {
return;
}
try {
logger.trace(appendContextMessage(msg), arguments);
} catch (Throwable t) {
}
}
@Override
public void debug(String msg, Throwable e) {
if (disabled) {
@ -116,6 +127,17 @@ public class FailsafeLogger implements Logger {
}
}
@Override
public void debug(String msg, Object... arguments) {
if (disabled) {
return;
}
try {
logger.debug(appendContextMessage(msg), arguments);
} catch (Throwable t) {
}
}
@Override
public void info(String msg, Throwable e) {
if (disabled) {
@ -138,6 +160,17 @@ public class FailsafeLogger implements Logger {
}
}
@Override
public void info(String msg, Object... arguments) {
if (disabled) {
return;
}
try {
logger.info(appendContextMessage(msg), arguments);
} catch (Throwable t) {
}
}
@Override
public void warn(String msg, Throwable e) {
if (disabled) {
@ -160,6 +193,17 @@ public class FailsafeLogger implements Logger {
}
}
@Override
public void warn(String msg, Object... arguments) {
if (disabled) {
return;
}
try {
logger.warn(appendContextMessage(msg), arguments);
} catch (Throwable t) {
}
}
@Override
public void error(String msg, Throwable e) {
if (disabled) {
@ -182,6 +226,17 @@ public class FailsafeLogger implements Logger {
}
}
@Override
public void error(String msg, Object... arguments) {
if (disabled) {
return;
}
try {
logger.error(appendContextMessage(msg), arguments);
} catch (Throwable t) {
}
}
@Override
public void error(Throwable e) {
if (disabled) {

View File

@ -132,6 +132,39 @@ public interface AnnotationUtils {
return getAttribute(annotation, "value");
}
/**
* Get the attribute from the specified {@link Annotation annotation}
*
* @param annotation the specified {@link Annotation annotation}
* @param attributeNames the multiply attribute name arrays
* @param <T> the type of attribute
* @return the attribute value
* @throws IllegalArgumentException If the attribute name can't be found
*/
static <T> T getAttribute(Annotation annotation, String... attributeNames) throws IllegalArgumentException {
if (attributeNames == null || attributeNames.length == 0) {
return null;
}
for (String attributeName : attributeNames) {
T attribute = getAttribute(annotation, attributeName);
if (attribute == null) {
continue;
}
// exclude string attribute default is empty
if ((attribute instanceof String) && ((String) attribute).length() == 0) {
continue;
}
return attribute;
}
return null;
}
/**
* Get the {@link Annotation} from the specified {@link AnnotatedElement the annotated element} and
* {@link Annotation annotation} class name

View File

@ -16,6 +16,7 @@
*/
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.aot.NativeDetector;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.resource.GlobalResourcesRepository;
@ -78,7 +79,7 @@ public class ClassLoaderResourceLoader {
Enumeration<URL> urls;
try {
urls = currentClassLoader.getResources(fileName);
boolean isNative = NativeUtils.isNative();
boolean isNative = NativeDetector.inNativeImage();
if (urls != null) {
while (urls.hasMoreElements()) {
URL url = urls.nextElement();

View File

@ -212,6 +212,20 @@ public class ClassUtils {
return forName(name, getClassLoader());
}
/**
* find class and don`t expect to throw exception
* @param name
* @return
*/
public static Class<?> forNameAndTryCatch(String name) {
try {
return forName(name, getClassLoader());
} catch (Throwable e) {
return null;
}
}
/**
* Replacement for <code>Class.forName()</code> that also returns Class
* instances for primitives (like "int") and array class names (like

View File

@ -0,0 +1,185 @@
/*
* 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 org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class JsonCompatibilityUtil {
private static final Logger logger = LoggerFactory.getLogger(JsonCompatibilityUtil.class);
private static final Set<String> unsupportedClasses = new HashSet<>(Arrays.asList("java.util.Optional", "java.util.Calendar", "java.util.Iterator", "java.io.InputStream", "java.io.OutputStream"));
/**
* Determine whether a Class can be serialized by JSON.
* @param clazz Incoming Class.
* @return If a Class can be serialized by JSON, return true;
* else return false.
*/
public static boolean checkClassCompatibility(Class<?> clazz) {
Method[] methods = clazz.getDeclaredMethods();
boolean result;
for (Method method : methods) {
result = checkMethodCompatibility(method);
if (!result) {
return false;
}
}
return true;
}
/**
* Determine whether a Method can be serialized by JSON.
* @param method Incoming Method.
* @return If a Method can be serialized by JSON, return true;
* else return false.
*/
public static boolean checkMethodCompatibility(Method method) {
boolean result;
Type[] types = method.getGenericParameterTypes();
List<Type> typeList = new ArrayList<>(Arrays.asList(types));
Type returnType = method.getGenericReturnType();
typeList.add(returnType);
for (Type type : typeList) {
result = checkType(type);
if (!result) {
return false;
}
}
return true;
}
/**
* Get unsupported methods.
* @param clazz
* @return If there are unsupported methods, return them by List;
* else return null.
*/
public static List<String> getUnsupportedMethods(Class<?> clazz) {
ArrayList<String> unsupportedMethods = new ArrayList<>();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (!checkMethodCompatibility(method)) {
unsupportedMethods.add(method.getName());
}
}
return unsupportedMethods.size() > 0 ? unsupportedMethods : null;
}
/**
* Determine whether a Type can be serialized by JSON.
* @param classType Incoming Type.
* @return If a Type can be serialized by JSON, return true;
* else return false.
*/
private static boolean checkType(Type classType) {
boolean result;
if (classType instanceof TypeVariable) {
return true;
}
if (classType instanceof ParameterizedType) {
Type[] types = ((ParameterizedType) classType).getActualTypeArguments();
List<Type> typeList = new ArrayList<>(Arrays.asList(types));
classType = ((ParameterizedType) classType).getRawType();
typeList.add(classType);
for (Type type : typeList) {
result = checkType(type);
if (!result) {
return false;
}
}
} else if (classType instanceof GenericArrayType) {
Type componentType = ((GenericArrayType) classType).getGenericComponentType();
result = checkType(componentType);
return result;
} else if (classType instanceof Class<?> ) {
Class<?> clazz = (Class<?>) classType;
String className = clazz.getName();
if (clazz.isArray()) {
Type componentType = clazz.getComponentType();
result = checkType(componentType);
return result;
} else if (clazz.isPrimitive()) {
// deal with case of basic byte
return !unsupportedClasses.contains(className);
} else if (className.startsWith("java") || className.startsWith("javax")) {
return !unsupportedClasses.contains(className);
} else {
// deal with case of interface
if (clazz.isInterface()) {
return false;
}
// deal with case of abstract
if (Modifier.isAbstract(clazz.getModifiers())) {
return false;
}
if (clazz.isEnum()) {
return true;
}
// deal with case of record
// if (clazz.isRecord()) {
// return false;
// }
// deal with field one by one
for (Field field : clazz.getDeclaredFields()) {
Type type = field.getGenericType();
Class<?> fieldClass = field.getType();
result = checkType(type);
if (!result) {
return false;
}
}
}
}
return true;
}
}

View File

@ -17,7 +17,7 @@
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.json.JSON;
import org.apache.dubbo.common.json.JsonUtil;
import org.apache.dubbo.common.json.impl.FastJson2Impl;
import org.apache.dubbo.common.json.impl.FastJsonImpl;
import org.apache.dubbo.common.json.impl.GsonImpl;
@ -29,17 +29,16 @@ import java.util.List;
import java.util.Map;
public class JsonUtils {
private static volatile JsonUtil jsonUtil;
private static volatile JSON json;
protected static JSON getJson() {
if (json == null) {
protected static JsonUtil getJson() {
if (jsonUtil == null) {
synchronized (JsonUtils.class) {
if (json == null) {
if (jsonUtil == null) {
String preferJsonFrameworkName = System.getProperty(CommonConstants.PREFER_JSON_FRAMEWORK_NAME);
if (StringUtils.isNotEmpty(preferJsonFrameworkName)) {
try {
JSON instance = null;
JsonUtil instance = null;
switch (preferJsonFrameworkName) {
case "fastjson2":
instance = new FastJson2Impl();
@ -55,23 +54,23 @@ public class JsonUtils {
break;
}
if (instance != null && instance.isSupport()) {
json = instance;
jsonUtil = instance;
}
} catch (Throwable ignore) {
}
}
if (json == null) {
List<Class<? extends JSON>> jsonClasses = Arrays.asList(
if (jsonUtil == null) {
List<Class<? extends JsonUtil>> jsonClasses = Arrays.asList(
FastJson2Impl.class,
FastJsonImpl.class,
GsonImpl.class,
JacksonImpl.class);
for (Class<? extends JSON> jsonClass : jsonClasses) {
for (Class<? extends JsonUtil> jsonClass : jsonClasses) {
try {
JSON instance = jsonClass.getConstructor().newInstance();
JsonUtil instance = jsonClass.getConstructor().newInstance();
if (instance.isSupport()) {
json = instance;
jsonUtil = instance;
break;
}
} catch (Throwable ignore) {
@ -79,22 +78,22 @@ public class JsonUtils {
}
}
}
if (json == null) {
if (jsonUtil == null) {
throw new IllegalStateException("Dubbo unable to find out any json framework (e.g. fastjson2, fastjson, gson, jackson) from jvm env. " +
"Please import at least one json framework.");
}
}
}
}
return json;
return jsonUtil;
}
/**
* @deprecated for uts only
*/
@Deprecated
protected static void setJson(JSON json) {
JsonUtils.json = json;
protected static void setJson(JsonUtil json) {
JsonUtils.jsonUtil = json;
}
public static <T> T toJavaObject(String json, Type type) {

View File

@ -856,6 +856,23 @@ public final class StringUtils {
return sb.toString();
}
public static String join(final Object[] array, final char delimiter, final int startIndex, final int endIndex) {
if (ArrayUtils.isEmpty(array)) {
return EMPTY_STRING;
}
if (endIndex - startIndex <= 0) {
return EMPTY_STRING;
}
StringBuilder sb = new StringBuilder();
for (int i = startIndex; i < endIndex; i++) {
if (i > 0) {
sb.append(delimiter);
}
sb.append(array[i]);
}
return sb.toString();
}
/**
* parse key-value pair.
*

View File

@ -172,6 +172,13 @@ public abstract class AbstractConfig implements Serializable {
appendParameters0(parameters, config, prefix, false);
}
public boolean validate() {
if(scopeModel == null || scopeModel.getBeanFactory() == null || scopeModel.getBeanFactory().isDestroyed()){
return ConfigValidateFacade.getDefaultInstance().validate(this);
}
return scopeModel.getBeanFactory().getOrRegisterBean(ConfigValidateFacade.class,clz -> new ConfigValidateFacade(scopeModel)).validate(this);
}
private static void appendParameters0(Map<String, String> parameters, Object config, String prefix, boolean asParameters) {
if (config == null) {
return;

View File

@ -18,6 +18,8 @@ package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.aot.NativeDetector;
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.config.InmemoryConfiguration;
@ -47,7 +49,6 @@ import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.NATIVE;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
@ -55,6 +56,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.TAG_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.CONFIG_NO_METHOD_FOUND;
import static org.apache.dubbo.common.constants.MetricsConstants.PROTOCOL_PROMETHEUS;
import static org.apache.dubbo.config.Constants.DEFAULT_NATIVE_PROXY;
/**
@ -255,7 +257,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
for (RegistryConfig registryConfig : registries) {
if (!registryConfig.isValid()) {
throw new IllegalStateException("No registry config found or it's not a valid config! " +
"The registry config is: " + registryConfig);
"The registry config is: " + registryConfig);
}
}
}
@ -293,8 +295,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
* @return
*/
protected String[] methods(Class<?> interfaceClass) {
boolean isNative = getEnvironment().getConfiguration().getBoolean(NATIVE, false);
if (isNative) {
if (NativeDetector.inNativeImage()) {
return Arrays.stream(interfaceClass.getMethods()).map(Method::getName).toArray(String[]::new);
} else {
return ClassUtils.getMethodNames(interfaceClass);
@ -344,7 +345,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
java.lang.reflect.Parameter[] arguments = method.getParameters();
for (int i = 0; i < arguments.length; i++) {
if (getArgumentByIndex(methodConfig, i) == null &&
hasArgumentConfigProps(configProperties, methodConfig.getName(), i)) {
hasArgumentConfigProps(configProperties, methodConfig.getName(), i)) {
ArgumentConfig argumentConfig = new ArgumentConfig();
argumentConfig.setIndex(i);
@ -359,7 +360,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
if (methodConfigs != null && methodConfigs.size() > 0) {
// whether ignore invalid method config
Object ignoreInvalidMethodConfigVal = getEnvironment().getConfiguration()
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_INVALID_METHOD_CONFIG, "false");
.getProperty(ConfigKeys.DUBBO_CONFIG_IGNORE_INVALID_METHOD_CONFIG, "false");
boolean ignoreInvalidMethodConfig = Boolean.parseBoolean(ignoreInvalidMethodConfigVal.toString());
Class<?> finalInterfaceClass = interfaceClass;
@ -390,8 +391,8 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
String methodName = methodConfig.getName();
if (StringUtils.isEmpty(methodName)) {
String msg = "<dubbo:method> name attribute is required! Please check: " +
"<dubbo:service interface=\"" + interfaceName + "\" ... >" +
"<dubbo:method name=\"\" ... /></<dubbo:reference>";
"<dubbo:service interface=\"" + interfaceName + "\" ... >" +
"<dubbo:method name=\"\" ... /></<dubbo:reference>";
if (ignoreInvalidMethodConfig) {
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", msg);
return false;
@ -403,7 +404,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
boolean hasMethod = Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> method.getName().equals(methodName));
if (!hasMethod) {
String msg = "Found invalid method config, the interface " + interfaceClass.getName() + " not found method \""
+ methodName + "\" : [" + methodConfig + "]";
+ methodName + "\" : [" + methodConfig + "]";
if (ignoreInvalidMethodConfig) {
logger.warn(CONFIG_NO_METHOD_FOUND, "", "", msg);
return false;
@ -465,7 +466,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
private void verifyStubAndLocal(String className, String label, Class<?> interfaceClass) {
if (ConfigUtils.isNotEmpty(className)) {
Class<?> localClass = ConfigUtils.isDefault(className) ?
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
ReflectUtils.forName(interfaceClass.getName() + label) : ReflectUtils.forName(className);
verify(interfaceClass, localClass);
}
}
@ -473,7 +474,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
private void verify(Class<?> interfaceClass, Class<?> localClass) {
if (!interfaceClass.isAssignableFrom(localClass)) {
throw new IllegalStateException("The local implementation class " + localClass.getName() +
" not implement interface " + interfaceClass.getName());
" not implement interface " + interfaceClass.getName());
}
try {
@ -481,7 +482,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
ReflectUtils.findConstructor(localClass, interfaceClass);
} catch (NoSuchMethodException e) {
throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() +
"(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
"(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
}
}
@ -613,11 +614,20 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
}
public String getProxy() {
return proxy;
if (NativeDetector.inNativeImage()) {
return DEFAULT_NATIVE_PROXY;
} else {
return this.proxy;
}
}
public void setProxy(String proxy) {
this.proxy = proxy;
if (NativeDetector.inNativeImage()) {
this.proxy = DEFAULT_NATIVE_PROXY;
AdaptiveCompiler.setDefaultCompiler(DEFAULT_NATIVE_PROXY);
} else {
this.proxy = proxy;
}
}
public Integer getConnections() {

View File

@ -16,6 +16,7 @@
*/
package org.apache.dubbo.config;
import org.apache.dubbo.common.aot.NativeDetector;
import org.apache.dubbo.common.compiler.support.AdaptiveCompiler;
import org.apache.dubbo.common.infra.InfraAdapter;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
@ -67,6 +68,7 @@ import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT_COMPATIBLE;
import static org.apache.dubbo.common.constants.RegistryConstants.ENABLE_EMPTY_PROTECTION_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTER_MODE_KEY;
import static org.apache.dubbo.config.Constants.DEFAULT_NATIVE_COMPILER;
import static org.apache.dubbo.config.Constants.DEVELOPMENT_ENVIRONMENT;
import static org.apache.dubbo.config.Constants.PRODUCTION_ENVIRONMENT;
import static org.apache.dubbo.config.Constants.TEST_ENVIRONMENT;
@ -281,7 +283,7 @@ public class ApplicationConfig extends AbstractConfig {
try {
hostname = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
LOGGER.warn(COMMON_UNEXPECTED_EXCEPTION,"","","Failed to get the hostname of current instance.", e);
LOGGER.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", "Failed to get the hostname of current instance.", e);
hostname = "UNKNOWN";
}
}
@ -341,15 +343,15 @@ public class ApplicationConfig extends AbstractConfig {
public void setEnvironment(String environment) {
if (environment != null && !(DEVELOPMENT_ENVIRONMENT.equals(environment)
|| TEST_ENVIRONMENT.equals(environment)
|| PRODUCTION_ENVIRONMENT.equals(environment))) {
|| TEST_ENVIRONMENT.equals(environment)
|| PRODUCTION_ENVIRONMENT.equals(environment))) {
throw new IllegalStateException(String.format("Unsupported environment: %s, only support %s/%s/%s, default is %s.",
environment,
DEVELOPMENT_ENVIRONMENT,
TEST_ENVIRONMENT,
PRODUCTION_ENVIRONMENT,
PRODUCTION_ENVIRONMENT));
environment,
DEVELOPMENT_ENVIRONMENT,
TEST_ENVIRONMENT,
PRODUCTION_ENVIRONMENT,
PRODUCTION_ENVIRONMENT));
}
this.environment = environment;
}
@ -395,12 +397,22 @@ public class ApplicationConfig extends AbstractConfig {
}
public String getCompiler() {
return compiler;
if (NativeDetector.inNativeImage()) {
return DEFAULT_NATIVE_COMPILER;
} else {
return compiler;
}
}
public void setCompiler(String compiler) {
this.compiler = compiler;
AdaptiveCompiler.setDefaultCompiler(compiler);
if (NativeDetector.inNativeImage()) {
this.compiler = DEFAULT_NATIVE_COMPILER;
AdaptiveCompiler.setDefaultCompiler(DEFAULT_NATIVE_COMPILER);
} else {
this.compiler = compiler;
AdaptiveCompiler.setDefaultCompiler(compiler);
}
}
public String getLogger() {

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
/**
* it will be call when reference or service config refresh
*/
@SPI(scope = ExtensionScope.MODULE)
public interface CommonConfigPostProcessor {
default void postProcessReferConfig(ReferenceConfigBase referenceConfig) {
}
default void postProcessServiceConfig(ServiceConfigBase serviceConfig) {
}
}

View File

@ -0,0 +1,115 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.context.ConfigValidator;
import org.apache.dubbo.config.exception.ConfigValidationException;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import java.util.Collections;
import java.util.List;
@SuppressWarnings({"rawtypes", "unchecked"})
public class ConfigValidateFacade implements ConfigValidator{
private static final Logger LOGGER = LoggerFactory.getErrorTypeAwareLogger(ConfigValidateFacade.class);
private final List<ConfigValidator> validators;
/**
* For test
*/
private static boolean enableValidate = true;
public ConfigValidateFacade(ScopeModel scopeModel) {
if(scopeModel != null) {
ExtensionLoader<ConfigValidator> extensionLoader = scopeModel.getExtensionLoader(ConfigValidator.class);
if (extensionLoader != null) {
this.validators = extensionLoader.getActivateExtensions();
this.validators.forEach(scopeModel.getBeanFactory()::registerBean);
} else {
this.validators = Collections.emptyList();
}
}else {
this.validators = Collections.emptyList();
}
}
public List<ConfigValidator> getValidators() {
return validators;
}
/**
* Auto choose a appropriate validator to validate config.
*
* @param config the config to validate
* @return TRUE if pass the validation.
* FALSE if no ConfigValidator found for this config,
* or one of the supported {@link ConfigValidator#validate(AbstractConfig)} returns FALSE.
*/
@Override
public boolean validate(AbstractConfig config) throws ConfigValidationException{
if(!enableValidate){
return true;
}
if (config == null) {
return false;
}
boolean validated = false;
try {
for (ConfigValidator validator : validators) {
if (validator.isSupport(config.getClass())) {
validated = true;
if(!validator.validate(config)){
return false;
}
}
}
}catch (Throwable t){
throw new ConfigValidationException(config.getClass().getSimpleName()+" validation failed: "+t.getMessage(),t);
}
if (!validated) {
LOGGER.info(config.getClass().getSimpleName()+" is not validated. This may caused by you did not imported the relevant module.");
}
return validated;
}
@Override
public boolean isSupport(Class configClass) {
return true;
}
/**
* For test
*/
@Deprecated
public static ConfigValidateFacade getDefaultInstance() {
return ApplicationModel.defaultModel().getBeanFactory().getOrRegisterBean(ConfigValidateFacade.class);
}
/**
* For test
*/
@Deprecated
public static void setEnableValidate(boolean enable){
enableValidate = enable;
}
}

View File

@ -152,4 +152,8 @@ public interface Constants {
String CLIENT_THREAD_POOL_NAME = "DubboClientHandler";
String REST_PROTOCOL="rest";
String DEFAULT_NATIVE_COMPILER="jdk";
String DEFAULT_NATIVE_PROXY="jdk";
}

View File

@ -61,6 +61,11 @@ public class MetricsConfig extends AbstractConfig {
*/
private Boolean exportMetricsService;
/**
* Enable netty metrics.
*/
private Boolean enableNetty;
/**
* @deprecated After metrics config is refactored.
* This parameter should no longer use and will be deleted in the future.
@ -223,4 +228,12 @@ public class MetricsConfig extends AbstractConfig {
public void setEnableRpc(Boolean enableRpc) {
this.enableRpc = enableRpc;
}
public Boolean getEnableNetty() {
return enableNetty;
}
public void setEnableNetty(Boolean enableNetty) {
this.enableNetty = enableNetty;
}
}

View File

@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Optional;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
import static org.apache.dubbo.common.constants.CommonConstants.JSON_CHECK_LEVEL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SSL_ENABLED_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.THREAD_POOL_EXHAUSTED_LISTENERS_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION;
@ -229,6 +230,8 @@ public class ProtocolConfig extends AbstractConfig {
*/
private String extProtocol;
private String jsonCheckLevel;
public ProtocolConfig() {
}
@ -331,6 +334,15 @@ public class ProtocolConfig extends AbstractConfig {
this.threadname = threadname;
}
@Parameter(key = JSON_CHECK_LEVEL_KEY)
public String getJsonCheckLevel() {
return jsonCheckLevel;
}
public void setJsonCheckLevel(String jsonCheckLevel) {
this.jsonCheckLevel = jsonCheckLevel;
}
@Parameter(key = THREAD_POOL_EXHAUSTED_LISTENERS_KEY)
public String getThreadPoolExhaustedListeners() {
return threadPoolExhaustedListeners;

View File

@ -31,6 +31,7 @@ import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConfigKeys;
import org.apache.dubbo.config.ConfigValidateFacade;
import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.MetricsConfig;
import org.apache.dubbo.config.ModuleConfig;
@ -585,10 +586,8 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
// validate configs
Collection<T> configs = this.getConfigs(configType);
if (getConfigValidator() != null) {
for (T config : configs) {
getConfigValidator().validate(config);
}
for (T config : configs) {
getConfigValidator().validate(config);
}
// check required default
@ -611,11 +610,11 @@ public abstract class AbstractConfigManager extends LifecycleAdapter {
return true;
}
private ConfigValidator getConfigValidator() {
private ConfigValidateFacade getConfigValidator() {
if (configValidator == null) {
configValidator = applicationModel.getBeanFactory().getBean(ConfigValidator.class);
configValidator = applicationModel.getBeanFactory().getOrRegisterBean(ConfigValidateFacade.class, clz -> new ConfigValidateFacade(scopeModel));
}
return configValidator;
return (ConfigValidateFacade) configValidator;
}
/**

View File

@ -16,10 +16,26 @@
*/
package org.apache.dubbo.config.context;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.exception.ConfigValidationException;
public interface ConfigValidator {
/**
* ConfigValidator. Allow provides an optional validation logic for a {@link AbstractConfig} impl.
* @param <T> type of {@link AbstractConfig} implement
*/
@SPI
public interface ConfigValidator<T extends AbstractConfig> {
void validate(AbstractConfig config);
/**
* Validate a config.
* If the config does not pass validation, returns false or throws exception, depends on implementation.
*
* @param config the config to validate
* @return TRUE if pass validation
*/
boolean validate(T config) throws ConfigValidationException;
boolean isSupport(Class<?> configClass);
}

View File

@ -0,0 +1,166 @@
/*
* 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.deploy.context;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.config.ReferenceCache;
import org.apache.dubbo.common.deploy.DeployListener;
import org.apache.dubbo.common.deploy.DeployState;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
import org.apache.dubbo.common.threadpool.manager.FrameworkExecutorRepository;
import org.apache.dubbo.config.deploy.lifecycle.manager.ApplicationLifecycleManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
/**
* The lifecycle attribute aggregate of application.
*/
public class ApplicationContext {
private final ApplicationModel applicationModel;
private final AtomicBoolean hasPreparedApplicationInstance;
private final AtomicBoolean registered ;
private final AtomicBoolean hasPreparedInternalModule;
private final ReferenceCache referenceCache;
/**
* Indicate that how many threads are updating service
*/
private final AtomicInteger serviceRefreshState;
private final ApplicationLifecycleManager lifecycleManager;
private final ExecutorRepository executorRepository;
private final FrameworkExecutorRepository frameworkExecutorRepository;
private final Environment environment;
private final ApplicationModel scopeModel;
private final AtomicReference<DeployState> modelState;
private final AtomicBoolean initialized;
private final AtomicReference<Throwable> lastError;
private final List<DeployListener<ApplicationModel>> deployListeners;
public ApplicationContext(ApplicationModel applicationModel, AtomicBoolean hasPreparedApplicationInstance, AtomicBoolean registered, AtomicBoolean hasPreparedInternalModule, ReferenceCache referenceCache, AtomicInteger serviceRefreshState, ApplicationLifecycleManager lifecycleManager, ExecutorRepository executorRepository, FrameworkExecutorRepository frameworkExecutorRepository, Environment environment, ApplicationModel scopeModel, AtomicReference<DeployState> modelState, AtomicBoolean initialized, AtomicReference<Throwable> lastError,List<DeployListener<ApplicationModel>> deployListeners) {
this.applicationModel = applicationModel;
this.hasPreparedApplicationInstance = hasPreparedApplicationInstance;
this.registered = registered;
this.hasPreparedInternalModule = hasPreparedInternalModule;
this.referenceCache = referenceCache;
this.serviceRefreshState = serviceRefreshState;
this.lifecycleManager = lifecycleManager;
this.executorRepository = executorRepository;
this.frameworkExecutorRepository = frameworkExecutorRepository;
this.environment = environment;
this.scopeModel = scopeModel;
this.modelState = modelState;
this.initialized = initialized;
this.lastError = lastError;
this.deployListeners = deployListeners;
}
public ApplicationModel getModel() {
return applicationModel;
}
public void setModelState(DeployState newState) {
this.modelState.set(newState);
}
public DeployState getCurrentState() {
return this.modelState.get();
}
public Throwable getLastError() {
return lastError.get();
}
public void setLastError(Throwable lastError) {
this.lastError.set(lastError);
}
public boolean initialized() {
return initialized.get();
}
public void setInitialized(boolean initialized) {
this.initialized.set(initialized);
}
public boolean hasPreparedInternalModule() {
return hasPreparedInternalModule.get();
}
public void setHasPreparedInternalModule(boolean hasPreparedInternalModule) {
this.hasPreparedInternalModule.set(hasPreparedInternalModule);
}
public boolean isHasPreparedApplicationInstance() {
return hasPreparedApplicationInstance.get();
}
public boolean isHasPreparedInternalModule() {
return hasPreparedInternalModule.get();
}
public AtomicBoolean getHasPreparedApplicationInstance() {
return hasPreparedApplicationInstance;
}
public void setRegistered(boolean registered){
this.registered.set(registered);
}
public boolean registered() {
return registered.get();
}
public AtomicBoolean getRegistered(){
return registered;
}
public ReferenceCache getReferenceCache() {
return referenceCache;
}
public AtomicInteger getServiceRefreshState() {
return serviceRefreshState;
}
public ExecutorRepository getExecutorRepository() {
return executorRepository;
}
public List<DeployListener<ApplicationModel>> getDeployListeners() {
return deployListeners;
}
}

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.deploy.lifecycle;
/**
* Lifecycle. The abstraction of dubbo model lifecycle operations.
*/
public interface Lifecycle<T>{
/**
* If this lifecycle need to initialize.
*/
boolean needInitialize();
default void start(T context){}
default void initialize(T context){}
default void preDestroy(T context) {}
default void postDestroy(T context) {}
}

View File

@ -0,0 +1,53 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.deploy.lifecycle.application;
import org.apache.dubbo.common.deploy.ApplicationDeployListener;
import org.apache.dubbo.common.deploy.DeployState;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.config.deploy.context.ApplicationContext;
import org.apache.dubbo.config.deploy.lifecycle.Lifecycle;
import org.apache.dubbo.rpc.model.ModuleModel;
/**
* ApplicationLifecycle.
* <br>
* Used in an application Lifecycle managing procedure, and dubbo packages
* can implement this interface to define what to do when application status changes.
* <p>
* Note: If you want to auto registry some extensions to BeanFactory that shared in an application, consider use {@link ApplicationDeployListener}.
* <br>
*/
@SPI(scope = ExtensionScope.APPLICATION)
public interface ApplicationLifecycle extends Lifecycle<ApplicationContext> {
/**
* @see org.apache.dubbo.config.deploy.lifecycle.manager.ApplicationLifecycleManager#preModuleChanged(ApplicationContext, ModuleModel, DeployState)
*/
default void preModuleChanged(ApplicationContext applicationContext,ModuleModel changedModule,DeployState moduleState){}
/**
* @see org.apache.dubbo.config.deploy.lifecycle.manager.ApplicationLifecycleManager#postModuleChanged(ApplicationContext, ModuleModel, DeployState, DeployState, DeployState)
*/
default void postModuleChanged(ApplicationContext applicationContext,ModuleModel changedModule,DeployState moduleNewState,DeployState applicationOldState,DeployState applicationNewState){}
/**
* @see org.apache.dubbo.config.deploy.lifecycle.manager.ApplicationLifecycleManager#runRefreshServiceInstance(ApplicationContext)
*/
default void refreshServiceInstance(ApplicationContext applicationContext){}
}

View File

@ -0,0 +1,98 @@
/*
* 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.deploy.lifecycle.manager;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
import org.apache.dubbo.common.deploy.DeployState;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.deploy.context.ApplicationContext;
import org.apache.dubbo.config.deploy.lifecycle.application.ApplicationLifecycle;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ModuleModel;
import java.util.List;
/**
* Application lifecycle manager
*/
public class ApplicationLifecycleManager{
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(ApplicationLifecycleManager.class);
private final List<ApplicationLifecycle> sequences;
private final ApplicationModel applicationModel;
public ApplicationLifecycleManager(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
sequences = loadAll();
}
public void start(ApplicationContext applicationContext){
getAll().forEach(applicationLifecycle -> applicationLifecycle.start(applicationContext));
}
public void initialize(ApplicationContext applicationContext) {
getAll().forEach(applicationLifecycle-> applicationLifecycle.initialize(applicationContext));
}
public void preDestroy(ApplicationContext applicationContext) {
getAll().forEach(applicationLifecycle-> applicationLifecycle.preDestroy(applicationContext));
}
public void postDestroy(ApplicationContext applicationContext) {
getAll().forEach(applicationLifecycle-> applicationLifecycle.postDestroy(applicationContext));
}
public void preModuleChanged(ApplicationContext applicationContext,ModuleModel changedModule, DeployState moduleNewState) {
getAll().forEach(applicationLifecycle -> applicationLifecycle.preModuleChanged(applicationContext,changedModule,moduleNewState));
}
public void postModuleChanged(ApplicationContext applicationContext,ModuleModel changedModule, DeployState moduleNewState,DeployState applicationOldState,DeployState applicationNewState) {
getAll().forEach(applicationLifecycle -> applicationLifecycle.postModuleChanged(applicationContext,changedModule,moduleNewState,applicationOldState,applicationNewState));
}
public void runRefreshServiceInstance(ApplicationContext applicationContext){
getAll().forEach(applicationLifecycle -> applicationLifecycle.refreshServiceInstance(applicationContext));
}
public List<ApplicationLifecycle> getAll(){
return this.sequences;
}
protected List<ApplicationLifecycle> loadAll() {
ExtensionLoader<ApplicationLifecycle> loader = applicationModel.getExtensionLoader(ApplicationLifecycle.class);
List<ApplicationLifecycle> lifecycles = loader.getActivateExtensions();
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
StringBuilder sequence = new StringBuilder("Loaded lifecycle sequences: [START]-> ");
lifecycles.forEach(applicationLifecycle -> {
if(applicationLifecycle.needInitialize()) {
beanFactory.registerBean(applicationLifecycle);
sequence.append(applicationLifecycle.getClass().getSimpleName()).append("-> ");
}
});
sequence.append(" [END]");
logger.info(sequence.toString());
return lifecycles;
}
}

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