Merge branch 'master-merged-performance-cloudnative'

# Conflicts:
#	dubbo-bootstrap/dubbo-bootstrap-spring/src/main/java/org/apache/dubbo/config/spring/beans/factory/annotation/ReferenceAnnotationBeanPostProcessor.java
#	dubbo-bootstrap/dubbo-bootstrap-spring/src/main/java/org/apache/dubbo/config/spring/util/ClassUtils.java
#	dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouter.java
#	dubbo-common/pom.xml
#	dubbo-common/src/main/java/org/apache/dubbo/common/URL.java
#	dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/Constants.java
#	dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
#	dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java
#	dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
#	dubbo-common/src/main/java/org/apache/dubbo/common/utils/UrlUtils.java
#	dubbo-common/src/main/java/org/apache/dubbo/config/AbstractConfig.java
#	dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
#	dubbo-common/src/main/java/org/apache/dubbo/config/AbstractReferenceConfig.java
#	dubbo-common/src/main/java/org/apache/dubbo/config/AbstractServiceConfig.java
#	dubbo-common/src/main/java/org/apache/dubbo/config/ConfigCenterConfig.java
#	dubbo-common/src/main/java/org/apache/dubbo/config/Constants.java
#	dubbo-common/src/main/java/org/apache/dubbo/rpc/support/ProtocolUtils.java
#	dubbo-compatible/src/main/java/com/alibaba/dubbo/common/Constants.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
#	dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractConfigTest.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractReferenceConfigTest.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/AbstractServiceConfigTest.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ConfigCenterConfigTest.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/builders/AbstractReferenceBuilderTest.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/builders/AbstractServiceBuilderTest.java
#	dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/url/UrlTestBase.java
#	dubbo-config/dubbo-config-spring/src/main/java/org/apache/dubbo/config/spring/ServiceBean.java
#	dubbo-configcenter/dubbo-configcenter-apollo/src/main/java/org/apache/dubbo/configcenter/support/apollo/ApolloDynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-consul/src/main/java/org/apache/dubbo/configcenter/consul/ConsulDynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-etcd/src/main/java/org/apache/dubbo/configcenter/support/etcd/EtcdDynamicConfiguration.java
#	dubbo-configcenter/dubbo-configcenter-zookeeper/src/main/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfiguration.java
#	dubbo-dependencies-bom/pom.xml
#	dubbo-dependencies/dubbo-dependencies-zookeeper/pom.xml
#	dubbo-metadata-report/dubbo-metadata-report-api/src/main/java/org/apache/dubbo/metadata/integration/MetadataReportService.java
#	dubbo-metadata-report/dubbo-metadata-report-api/src/test/java/org/apache/dubbo/metadata/integration/MetadataReportServiceTest.java
#	dubbo-metadata-report/dubbo-metadata-report-etcd/src/test/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReportTest.java
#	dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/Constants.java
#	dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyClientHandler.java
#	dubbo-remoting/dubbo-remoting-netty4/src/main/java/org/apache/dubbo/remoting/transport/netty4/NettyServerHandler.java
#	dubbo-remoting/dubbo-remoting-zookeeper/src/main/java/org/apache/dubbo/remoting/zookeeper/curator/CuratorZookeeperClient.java
#	dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Constants.java
#	dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
#	dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
#	dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/interceptors/ConsumerContextClusterInterceptor.java
#	dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/service/GenericServiceTest.java
#	dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/validation/ValidationTest.java
#	dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RpcContextFilter.java
#	dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java
#	pom.xml
This commit is contained in:
ken.lj 2019-10-28 21:39:34 +08:00
commit 39f84fe8fe
1298 changed files with 52673 additions and 29402 deletions

9
.gitignore vendored
View File

@ -6,6 +6,7 @@ target/
*.zip
*.tar
*.tar.gz
.flattened-pom.xml
# eclipse ignore
.settings/
@ -35,3 +36,11 @@ Thumbs.db
# license check result
license-list
# grpc compiler
compiler/gradle.properties
compiler/build/*
compiler/.gradle/*
# protobuf
dubbo-serialization/dubbo-serialization-protobuf/build/*

View File

@ -243,3 +243,6 @@ https://github.com/edazdarevic/CIDRUtils. The project is licensed under a MIT Li
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
This product contains a modified portion of 'proto-gen-grpc-java' - a protobuf plugin used to generate grpc-java stubs,
under a "Apache License 2.0" license, see https://github.com/grpc/grpc-java/blob/v1.22.1/NOTICE.txt. All files are placed
under '/dubbo/compiler'

10
NOTICE
View File

@ -12,3 +12,13 @@ Please visit the Netty web site for more information:
* http://netty.io/
Copyright 2014 The Netty Project
This product contains code for the gRPC Project:
The gRPC Project
=================
Please visit the gRPC web site for more information:
* http://grpc.io/
Copyright 2014 The gRPC Project

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,2 @@
#Tue Oct 09 11:40:48 CST 2018
gradle.version=4.9

Binary file not shown.

12
compiler/BUILD.bazel Normal file
View File

@ -0,0 +1,12 @@
cc_binary(
name = "grpc_java_plugin",
srcs = [
"src/java_plugin/cpp/java_generator.cpp",
"src/java_plugin/cpp/java_generator.h",
"src/java_plugin/cpp/java_plugin.cpp",
],
visibility = ["//visibility:public"],
deps = [
"@com_google_protobuf//:protoc_lib",
],
)

202
compiler/README.md Normal file
View File

@ -0,0 +1,202 @@
# Dubbo customized version
## Get Started, how to use
1. Add maven dependency
```xml
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.6.1</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.7.1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>org.apache.dubbo:protoc-gen-grpc-java:${proto_dubbo_plugin_version}:exe:${os.detected.classifier}</pluginArtifact>
<outputDirectory>build/generated/source/proto/main/java</outputDirectory>
<clearOutputDirectory>false</clearOutputDirectory>
<!-- supports 'dubbo' and 'grpc' -->
<pluginParameter>dubbo</pluginParameter>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
<goal>test-compile</goal>
<goal>test-compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>build/generated/source/proto/main/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
```
2. Decide which protocol to use: Dubbo or gRPC
* Dubbo, ` <pluginParameter>dubbo</pluginParameter>`
* gRPC, ` <pluginParameter>grpc</pluginParameter>`
3. Define service using IDL
```text
syntax = "proto3";
option java_multiple_files = true;
option java_package = "org.apache.dubbo.demo";
option java_outer_classname = "DemoServiceProto";
option objc_class_prefix = "DEMOSRV";
package demoservice;
// The demo service definition.
service DemoService {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
```
4. Build
mvn clean compile
## Customized
1. Dubbo Interface
```java
public interface IGreeter {
default public io.grpc.examples.helloworld.HelloReply sayHello(io.grpc.examples.helloworld.HelloRequest request) {
throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
}
default public com.google.common.util.concurrent.ListenableFuture<io.grpc.examples.helloworld.HelloReply> sayHelloAsync(
io.grpc.examples.helloworld.HelloRequest request) {
throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
}
public void sayHello(io.grpc.examples.helloworld.HelloRequest request,
io.grpc.stub.StreamObserver<io.grpc.examples.helloworld.HelloReply> responseObserver);
}
```
2. Dubbo Stub
```java
public static DubboGreeterStub getDubboStub(io.grpc.Channel channel) {
return new DubboGreeterStub(channel);
}
public static class DubboGreeterStub implements IGreeter {
private GreeterBlockingStub blockingStub;
private GreeterFutureStub futureStub;
private GreeterStub stub;
public DubboGreeterStub(io.grpc.Channel channel) {
blockingStub = GreeterGrpc.newBlockingStub(channel);
futureStub = GreeterGrpc.newFutureStub(channel);
stub = GreeterGrpc.newStub(channel);
}
public io.grpc.examples.helloworld.HelloReply sayHello(io.grpc.examples.helloworld.HelloRequest request) {
return blockingStub.sayHello(request);
}
public com.google.common.util.concurrent.ListenableFuture<io.grpc.examples.helloworld.HelloReply> sayHelloAsync(
io.grpc.examples.helloworld.HelloRequest request) {
return futureStub.sayHello(requesthttps://github.com/apache/dubbo-samples.git);
}
public void sayHello(io.grpc.examples.helloworld.HelloRequest request,
io.grpc.stub.StreamObserver<io.grpc.examples.helloworld.HelloReply> responseObserver){
stub.sayHello(request, responseObserver);
}
}
```
3. XxxImplBase implements DubboInterface
```java
public static abstract class GreeterImplBase implements io.grpc.BindableService, IGreeter {
@java.lang.Override
public final io.grpc.examples.helloworld.HelloReply sayHello(io.grpc.examples.helloworld.HelloRequest request) {
throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
}
@java.lang.Override
public final com.google.common.util.concurrent.ListenableFuture<io.grpc.examples.helloworld.HelloReply> sayHelloAsync(
io.grpc.examples.helloworld.HelloRequest request) {
throw new UnsupportedOperationException("No need to override this method, extend XxxImplBase and override all methods it allows.");
}
public void sayHello(io.grpc.examples.helloworld.HelloRequest request,
io.grpc.stub.StreamObserver<io.grpc.examples.helloworld.HelloReply> responseObserver) {
asyncUnimplementedUnaryCall(getSayHelloMethod(), responseObserver);
}
...
}
```
## Build locally
To compile the plugin:
```
$ ../gradlew java_pluginExecutable
```
To publish to local repository
```
$ ../gradlew publishToMavenLocal
```
## Publish to maven repository
Add gradle.properties
```properties
repositoryUser=user
repositoryPasword=pwd
```
Then, run
```
$ ../gradlew publishMavenPublicationToDubboRepository
```
Notice current groupId is `com.alibaba`.
Check [here](https://github.com/grpc/grpc-java/blob/master/compiler/README.md) for basic requirements and usage of protoc plugin.

399
compiler/build.gradle Normal file
View File

@ -0,0 +1,399 @@
apply plugin: "cpp"
apply plugin: "com.google.protobuf"
group = "org.apache.dubbo"
version = "1.19.0-SNAPSHOT" // CURRENT_GRPC_VERSION
description = 'The protoc plugin for gRPC Java'
apply plugin: "checkstyle"
apply plugin: "java"
apply plugin: "maven"
apply plugin: "maven-publish"
apply plugin: "idea"
apply plugin: "signing"
apply plugin: "jacoco"
apply plugin: "me.champeau.gradle.jmh"
apply plugin: "com.google.osdetector"
// The plugin only has an effect if a signature is specified
apply plugin: "ru.vyarus.animalsniffer"
apply plugin: "net.ltgt.errorprone"
buildscript {
repositories {
maven { // The google mirror is less flaky than mavenCentral()
url "https://maven-central.storage-download.googleapis.com/repos/central/data/" }
mavenLocal()
maven { url "https://plugins.gradle.org/m2/" }
}
dependencies {
classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.5"
classpath "com.diffplug.spotless:spotless-plugin-gradle:3.13.0"
classpath 'com.google.gradle:osdetector-gradle-plugin:1.4.0'
classpath 'ru.vyarus:gradle-animalsniffer-plugin:1.4.5'
classpath 'net.ltgt.gradle:gradle-errorprone-plugin:0.6'
classpath "me.champeau.gradle:jmh-gradle-plugin:0.4.5"
classpath 'me.champeau.gradle:japicmp-gradle-plugin:0.2.5'
}
}
import net.ltgt.gradle.errorprone.CheckSeverity
def artifactStagingPath = "$buildDir/artifacts" as File
// Adds space-delimited arguments from the environment variable env to the
// argList.
def addEnvArgs = { env, argList ->
def value = System.getenv(env)
if (value != null) {
value.split(' +').each() { it -> argList.add(it) }
}
}
// Adds corresponding "-l" option to the argList if libName is not found in
// LDFLAGS. This is only used for Mac because when building for uploadArchives
// artifacts, we add the ".a" files directly to LDFLAGS and without "-l" in
// order to get statically linked, otherwise we add the libraries through "-l"
// so that they can be searched for in default search paths.
def addLibraryIfNotLinked = { libName, argList ->
def ldflags = System.env.LDFLAGS
if (ldflags == null || !ldflags.contains('lib' + libName + '.a')) {
argList.add('-l' + libName)
}
}
def String arch = rootProject.hasProperty('targetArch') ? rootProject.targetArch : osdetector.arch
def boolean vcDisable = rootProject.hasProperty('vcDisable') ? rootProject.vcDisable : false
def boolean usingVisualCpp // Whether VisualCpp is actually available and selected
ext{
def exeSuffix = osdetector.os == 'windows' ? ".exe" : ""
protocPluginBaseName = 'protoc-gen-dubbo-java'
javaPluginPath = "$rootDir/build/exe/java_plugin/$protocPluginBaseName$exeSuffix"
nettyVersion = '4.1.32.Final'
googleauthVersion = '0.9.0'
guavaVersion = '26.0-android'
protobufVersion = '3.6.1'
protocVersion = protobufVersion
protobufNanoVersion = '3.0.0-alpha-5'
opencensusVersion = '0.19.2'
libraries = [
animalsniffer_annotations: "org.codehaus.mojo:animal-sniffer-annotations:1.17",
errorprone: "com.google.errorprone:error_prone_annotations:2.2.0",
gson: "com.google.code.gson:gson:2.7",
guava: "com.google.guava:guava:26.0-android",
hpack: 'com.twitter:hpack:0.10.1',
javax_annotation: 'javax.annotation:javax.annotation-api:1.2',
jsr305: 'com.google.code.findbugs:jsr305:3.0.2',
google_api_protos: 'com.google.api.grpc:proto-google-common-protos:1.12.0',
// Keep the following references of tcnative version in sync whenever it's updated
// SECURITY.md (multiple occurrences)
// examples/example-tls/build.gradle
// examples/example-tls/pom.xml
netty_tcnative: 'io.netty:netty-tcnative-boringssl-static:2.0.20.Final',
conscrypt: 'org.conscrypt:conscrypt-openjdk-uber:1.0.1',
re2j: 'com.google.re2j:re2j:1.2'
]
}
model {
toolChains {
// If you have both VC and Gcc installed, VC will be selected, unless you
// set 'vcDisable=true'
if (!vcDisable) {
visualCpp(VisualCpp) {
// Prefer vcvars-provided environment over registry-discovered environment
def String vsDir = System.getenv("VSINSTALLDIR")
def String winDir = System.getenv("WindowsSdkDir")
if (vsDir != null && winDir != null) {
installDir = vsDir
windowsSdkDir = winDir
}
}
}
gcc(Gcc) {
target("ppcle_64")
target("aarch_64")
}
clang(Clang) {
}
}
platforms {
x86_32 { architecture "x86" }
x86_64 { architecture "x86_64" }
ppcle_64 { architecture "ppcle_64" }
aarch_64 { architecture "aarch_64" }
}
components {
java_plugin(NativeExecutableSpec) {
if (arch in [
'x86_32',
'x86_64',
'ppcle_64',
'aarch_64'
]) {
// If arch is not within the defined platforms, we do not specify the
// targetPlatform so that Gradle will choose what is appropriate.
targetPlatform arch
}
baseName "$protocPluginBaseName"
}
}
binaries {
all {
if (toolChain in Gcc || toolChain in Clang) {
cppCompiler.define("GRPC_VERSION", version)
cppCompiler.args "--std=c++0x"
addEnvArgs("CXXFLAGS", cppCompiler.args)
addEnvArgs("CPPFLAGS", cppCompiler.args)
if (osdetector.os == "osx") {
cppCompiler.args "-mmacosx-version-min=10.7", "-stdlib=libc++"
addLibraryIfNotLinked('protoc', linker.args)
addLibraryIfNotLinked('protobuf', linker.args)
} else if (osdetector.os == "windows") {
linker.args "-static", "-lprotoc", "-lprotobuf", "-static-libgcc", "-static-libstdc++",
"-s"
} else {
// Link protoc, protobuf, libgcc and libstdc++ statically.
// Link other (system) libraries dynamically.
// Clang under OSX doesn't support these options.
linker.args "-Wl,-Bstatic", "-lprotoc", "-lprotobuf", "-static-libgcc",
"-static-libstdc++",
"-Wl,-Bdynamic", "-lpthread", "-s"
}
addEnvArgs("LDFLAGS", linker.args)
} else if (toolChain in VisualCpp) {
usingVisualCpp = true
cppCompiler.define("GRPC_VERSION", version)
cppCompiler.args "/EHsc", "/MT"
if (rootProject.hasProperty('vcProtobufInclude')) {
cppCompiler.args "/I${rootProject.vcProtobufInclude}"
}
linker.args "libprotobuf.lib", "libprotoc.lib"
if (rootProject.hasProperty('vcProtobufLibs')) {
linker.args "/LIBPATH:${rootProject.vcProtobufLibs}"
}
}
}
}
}
configurations {
testLiteCompile
testNanoCompile
}
sourceSets {
testLite {
proto { setSrcDirs(['src/test/proto']) }
}
testNano {
proto { setSrcDirs(['src/test/proto']) }
}
}
compileTestJava {
options.compilerArgs += [
"-Xlint:-cast"
]
options.errorprone.excludedPaths = ".*/build/generated/source/proto/.*"
}
compileTestLiteJava {
options.compilerArgs = compileTestJava.options.compilerArgs
// Protobuf-generated Lite produces quite a few warnings.
options.compilerArgs += [
"-Xlint:-rawtypes",
"-Xlint:-unchecked",
"-Xlint:-fallthrough"
]
options.errorprone.excludedPaths = ".*/build/generated/source/proto/.*"
}
compileTestNanoJava {
options.compilerArgs = compileTestJava.options.compilerArgs
options.errorprone.excludedPaths = ".*/build/generated/source/proto/.*"
}
protobuf {
protoc {
if (project.hasProperty('protoc')) {
path = project.protoc
} else {
// Since nano is removed from newer versions of protoc, use an older version for the
// while. This means we won't be able to test any descriptor.proto additions, but that
// should be fine for a while.
artifact = libraries.protoc_nano
}
}
plugins {
javalite {
if (project.hasProperty('protoc-gen-javalite')) {
path = project['protoc-gen-javalite']
} else {
artifact = libraries.protoc_lite
}
}
grpc { path = javaPluginPath }
}
generateProtoTasks {
all().each { task ->
task.dependsOn 'java_pluginExecutable'
task.inputs.file javaPluginPath
}
ofSourceSet('test')*.plugins { grpc {} }
ofSourceSet('testLite')*.each { task ->
task.builtins { remove java }
task.plugins {
javalite {}
grpc { option 'lite' }
}
}
ofSourceSet('testNano').each { task ->
task.builtins {
remove java
javanano { option 'ignore_services=true' }
}
task.plugins { grpc { option 'nano' } }
}
}
}
checkstyleTestNano {
source = fileTree(dir: "src/testNano", include: "**/*.java")
}
println "*** Building codegen requires Protobuf version ${protocVersion}"
println "*** Please refer to https://github.com/apache/dubbo/blob/master/compiler/README.md"
task buildArtifacts(type: Copy) {
dependsOn 'java_pluginExecutable'
from("$buildDir/exe") {
if (osdetector.os != 'windows') {
rename 'protoc-gen-dubbo-java', '$0.exe'
}
}
into artifactStagingPath
}
archivesBaseName = "$protocPluginBaseName"
task checkArtifacts {
dependsOn buildArtifacts
doLast {
if (!usingVisualCpp) {
def ret = exec {
executable 'bash'
args 'check-artifact.sh', osdetector.os, arch
}
if (ret.exitValue != 0) {
throw new GradleException("check-artifact.sh exited with " + ret.exitValue)
}
} else {
def exeName = "$artifactStagingPath/java_plugin/${protocPluginBaseName}.exe"
def os = new ByteArrayOutputStream()
def ret = exec {
executable 'dumpbin'
args '/nologo', '/dependents', exeName
standardOutput = os
}
if (ret.exitValue != 0) {
throw new GradleException("dumpbin exited with " + ret.exitValue)
}
def dlls = os.toString() =~ /Image has the following dependencies:\s+(.*)\s+Summary/
if (dlls[0][1] != "KERNEL32.dll") {
throw new Exception("unexpected dll deps: " + dlls[0][1]);
}
os.reset()
ret = exec {
executable 'dumpbin'
args '/nologo', '/headers', exeName
standardOutput = os
}
if (ret.exitValue != 0) {
throw new GradleException("dumpbin exited with " + ret.exitValue)
}
def machine = os.toString() =~ / machine \(([^)]+)\)/
def expectedArch = [x86_32: "x86", x86_64: "x64"][arch]
if (machine[0][1] != expectedArch) {
throw new Exception("unexpected architecture: " + machine[0][1]);
}
}
}
}
// Exe files are skipped by Maven by default. Override it.
// Also skip jar files that is generated by the java plugin.
publishing {
repositories {
maven {
name "dubbo"
credentials {
username repositoryUser //
password repositoryPassword //
}
if(project.version.endsWith('-SNAPSHOT')) {
url "https://repository.apache.org/content/repositories/snapshots"
} else {
url 'https://repository.apache.org/service/local/staging/deploy/maven2' //
}
}
}
publications {
maven(MavenPublication) {
// Removes all artifacts since grpc-compiler doesn't generates any Jar
artifacts = []
artifactId 'protoc-gen-dubbo-java'
artifact("$artifactStagingPath/java_plugin/${protocPluginBaseName}.exe" as File) {
classifier osdetector.os + "-" + arch
extension "exe"
builtBy checkArtifacts
}
pom.withXml {
// This isn't any sort of Java archive artifact, and OSSRH doesn't enforce
// javadoc for 'pom' packages. 'exe' would be a more appropriate packaging
// value, but it isn't clear how that will be interpreted. In addition,
// 'pom' is typically the value used when building an exe with Maven.
asNode().project.packaging*.value = 'pom'
}
}
}
}
def configureTestTask(Task task, String dep, String extraPackage, String serviceName) {
test.dependsOn task
task.dependsOn "generateTest${dep}Proto"
if (osdetector.os != 'windows') {
task.executable "diff"
task.args "-u"
} else {
task.executable "fc"
}
// File isn't found on Windows if last slash is forward-slash
def slash = System.getProperty("file.separator")
task.args "$buildDir/generated/source/proto/test${dep}/grpc/io/grpc/testing/compiler${extraPackage}${slash}${serviceName}Grpc.java",
"$projectDir/src/test${dep}/golden/${serviceName}.java.txt"
}
task testGolden(type: Exec)
task testLiteGolden(type: Exec)
task testNanoGolden(type: Exec)
task testDeprecatedGolden(type: Exec)
task testDeprecatedLiteGolden(type: Exec)
task testDeprecatedNanoGolden(type: Exec)
configureTestTask(testGolden, '', '', 'TestService')
configureTestTask(testLiteGolden, 'Lite', '', 'TestService')
configureTestTask(testNanoGolden, 'Nano', '/nano', 'TestService')
configureTestTask(testDeprecatedGolden, '', '', 'TestDeprecatedService')
configureTestTask(testDeprecatedLiteGolden, 'Lite', '', 'TestDeprecatedService')
configureTestTask(testDeprecatedNanoGolden, 'Nano', '/nano', 'TestDeprecatedService')

131
compiler/check-artifact.sh Executable file
View File

@ -0,0 +1,131 @@
#!/bin/bash
# Check that the codegen artifacts are of correct architecture and don't have
# unexpected dependencies.
# To be run from Gradle.
# Usage: check-artifact <OS> <ARCH>
# <OS> and <ARCH> are ${os.detected.name} and ${os.detected.arch} from
# osdetector-gradle-plugin
OS=$1
ARCH=$2
if [[ $# < 2 ]]; then
echo "No arguments provided. This script is intended to be run from Gradle."
exit 1
fi
# Under Cygwin, bash doesn't have these in PATH when called from Gradle which
# runs in Windows version of Java.
export PATH="/bin:/usr/bin:$PATH"
E_PARAM_ERR=98
E_ASSERT_FAILED=99
# Usage: fail ERROR_MSG
fail()
{
echo "ERROR: $1"
echo
exit $E_ASSERT_FAILED
}
# Usage: assertEq VAL1 VAL2 $LINENO
assertEq ()
{
lineno=$3
if [ -z "$lineno" ]; then
echo "lineno not given"
exit $E_PARAM_ERR
fi
if [[ "$1" != "$2" ]]; then
echo "Assertion failed: \"$1\" == \"$2\""
echo "File \"$0\", line $lineno" # Give name of file and line number.
exit $E_ASSERT_FAILED
fi
}
# Checks the artifact is for the expected architecture
# Usage: checkArch <path-to-protoc>
checkArch ()
{
echo
echo "Checking format of $1"
if [[ "$OS" == windows || "$OS" == linux ]]; then
format="$(objdump -f "$1" | grep -o "file format .*$" | grep -o "[^ ]*$")"
echo Format=$format
if [[ "$OS" == linux ]]; then
if [[ "$ARCH" == x86_32 ]]; then
assertEq "$format" "elf32-i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq "$format" "elf64-x86-64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
else
# $OS == windows
if [[ "$ARCH" == x86_32 ]]; then
assertEq "$format" "pei-i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq "$format" "pei-x86-64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
fi
elif [[ "$OS" == osx ]]; then
format="$(file -b "$1" | grep -o "[^ ]*$")"
echo Format=$format
if [[ "$ARCH" == x86_32 ]]; then
assertEq "$format" "i386" $LINENO
elif [[ "$ARCH" == x86_64 ]]; then
assertEq "$format" "x86_64" $LINENO
else
fail "Unsupported arch: $ARCH"
fi
else
fail "Unsupported system: $OS"
fi
echo
}
# Checks the dependencies of the artifact. Artifacts should only depend on
# system libraries.
# Usage: checkDependencies <path-to-protoc>
checkDependencies ()
{
echo "Checking dependencies of $1"
if [[ "$OS" == windows ]]; then
dump_cmd='objdump -x '"$1"' | fgrep "DLL Name"'
white_list="KERNEL32\.dll\|msvcrt\.dll\|USER32\.dll"
elif [[ "$OS" == linux ]]; then
dump_cmd='ldd '"$1"
if [[ "$ARCH" == x86_32 ]]; then
white_list="linux-gate\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux\.so\.2"
elif [[ "$ARCH" == x86_64 ]]; then
white_list="linux-vdso\.so\.1\|libpthread\.so\.0\|libm\.so\.6\|libc\.so\.6\|ld-linux-x86-64\.so\.2"
fi
elif [[ "$OS" == osx ]]; then
set +x
dump_cmd='otool -L '"$1"' | fgrep dylib'
white_list="libz\.1\.dylib\|libc++.1.dylib\|libstdc++\.6\.dylib\|libSystem\.B\.dylib"
set -x
fi
if [[ -z "$white_list" || -z "$dump_cmd" ]]; then
fail "Unsupported platform $OS-$ARCH."
fi
echo "Checking for expected dependencies ..."
eval $dump_cmd | grep -i "$white_list" || fail "doesn't show any expected dependencies"
echo "Checking for unexpected dependencies ..."
eval $dump_cmd | grep -i -v "$white_list"
ret=$?
if [[ $ret == 0 ]]; then
fail "found unexpected dependencies (listed above)."
elif [[ $ret != 1 ]]; then
fail "Error when checking dependencies."
fi # grep returns 1 when "not found", which is what we expect
echo "Dependencies look good."
echo
}
FILE="build/artifacts/java_plugin/protoc-gen-dubbo-java.exe"
checkArch "$FILE" && checkDependencies "$FILE"

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

172
compiler/gradlew vendored Executable file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
compiler/gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1,580 @@
#include "java_generator.h"
#include <algorithm>
#include <iostream>
#include <iterator>
#include <map>
#include <set>
#include <vector>
#include <google/protobuf/compiler/java/java_names.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
// Stringify helpers used solely to cast GRPC_VERSION
#ifndef STR
#define STR(s) #s
#endif
#ifndef XSTR
#define XSTR(s) STR(s)
#endif
#ifndef FALLTHROUGH_INTENDED
#define FALLTHROUGH_INTENDED
#endif
namespace java_dubbo_generator {
using google::protobuf::FileDescriptor;
using google::protobuf::ServiceDescriptor;
using google::protobuf::MethodDescriptor;
using google::protobuf::Descriptor;
using google::protobuf::io::Printer;
using google::protobuf::SourceLocation;
using std::to_string;
// java keywords from: https://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.9
static std::set<string> java_keywords = {
"abstract",
"assert",
"boolean",
"break",
"byte",
"case",
"catch",
"char",
"class",
"const",
"continue",
"default",
"do",
"double",
"else",
"enum",
"extends",
"final",
"finally",
"float",
"for",
"goto",
"if",
"implements",
"import",
"instanceof",
"int",
"interface",
"long",
"native",
"new",
"package",
"private",
"protected",
"public",
"return",
"short",
"static",
"strictfp",
"super",
"switch",
"synchronized",
"this",
"throw",
"throws",
"transient",
"try",
"void",
"volatile",
"while",
// additional ones added by us
"true",
"false",
};
// Adjust a method name prefix identifier to follow the JavaBean spec:
// - decapitalize the first letter
// - remove embedded underscores & capitalize the following letter
// Finally, if the result is a reserved java keyword, append an underscore.
static string MixedLower(const string& word) {
string w;
w += tolower(word[0]);
bool after_underscore = false;
for (size_t i = 1; i < word.length(); ++i) {
if (word[i] == '_') {
after_underscore = true;
} else {
w += after_underscore ? toupper(word[i]) : word[i];
after_underscore = false;
}
}
if (java_keywords.find(w) != java_keywords.end()) {
return w + "_";
}
return w;
}
// Converts to the identifier to the ALL_UPPER_CASE format.
// - An underscore is inserted where a lower case letter is followed by an
// upper case letter.
// - All letters are converted to upper case
static string ToAllUpperCase(const string& word) {
string w;
for (size_t i = 0; i < word.length(); ++i) {
w += toupper(word[i]);
if ((i < word.length() - 1) && islower(word[i]) && isupper(word[i + 1])) {
w += '_';
}
}
return w;
}
static inline string LowerMethodName(const MethodDescriptor* method) {
return MixedLower(method->name());
}
static inline string MethodPropertiesFieldName(const MethodDescriptor* method) {
return "METHOD_" + ToAllUpperCase(method->name());
}
static inline string MethodPropertiesGetterName(const MethodDescriptor* method) {
return MixedLower("get_" + method->name() + "_method");
}
static inline string MethodIdFieldName(const MethodDescriptor* method) {
return "METHODID_" + ToAllUpperCase(method->name());
}
static inline bool ShouldGenerateAsLite(const Descriptor* desc) {
return false;
}
static inline string MessageFullJavaName(bool nano, const Descriptor* desc) {
string name = google::protobuf::compiler::java::ClassName(desc);
if (nano && !ShouldGenerateAsLite(desc)) {
// XXX: Add "nano" to the original package
// (https://github.com/grpc/grpc-java/issues/900)
if (isupper(name[0])) {
// No java package specified.
return "nano." + name;
}
for (size_t i = 0; i < name.size(); ++i) {
if ((name[i] == '.') && (i < (name.size() - 1)) && isupper(name[i + 1])) {
return name.substr(0, i + 1) + "nano." + name.substr(i + 1);
}
}
}
return name;
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
template <typename ITR>
static void GrpcSplitStringToIteratorUsing(const string& full,
const char* delim,
ITR& result) {
// Optimize the common case where delim is a single character.
if (delim[0] != '\0' && delim[1] == '\0') {
char c = delim[0];
const char* p = full.data();
const char* end = p + full.size();
while (p != end) {
if (*p == c) {
++p;
} else {
const char* start = p;
while (++p != end && *p != c);
*result++ = string(start, p - start);
}
}
return;
}
string::size_type begin_index, end_index;
begin_index = full.find_first_not_of(delim);
while (begin_index != string::npos) {
end_index = full.find_first_of(delim, begin_index);
if (end_index == string::npos) {
*result++ = full.substr(begin_index);
return;
}
*result++ = full.substr(begin_index, (end_index - begin_index));
begin_index = full.find_first_not_of(delim, end_index);
}
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static void GrpcSplitStringUsing(const string& full,
const char* delim,
std::vector<string>* result) {
std::back_insert_iterator< std::vector<string> > it(*result);
GrpcSplitStringToIteratorUsing(full, delim, it);
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static std::vector<string> GrpcSplit(const string& full, const char* delim) {
std::vector<string> result;
GrpcSplitStringUsing(full, delim, &result);
return result;
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static string GrpcEscapeJavadoc(const string& input) {
string result;
result.reserve(input.size() * 2);
char prev = '*';
for (string::size_type i = 0; i < input.size(); i++) {
char c = input[i];
switch (c) {
case '*':
// Avoid "/*".
if (prev == '/') {
result.append("&#42;");
} else {
result.push_back(c);
}
break;
case '/':
// Avoid "*/".
if (prev == '*') {
result.append("&#47;");
} else {
result.push_back(c);
}
break;
case '@':
// '@' starts javadoc tags including the @deprecated tag, which will
// cause a compile-time error if inserted before a declaration that
// does not have a corresponding @Deprecated annotation.
result.append("&#64;");
break;
case '<':
// Avoid interpretation as HTML.
result.append("&lt;");
break;
case '>':
// Avoid interpretation as HTML.
result.append("&gt;");
break;
case '&':
// Avoid interpretation as HTML.
result.append("&amp;");
break;
case '\\':
// Java interprets Unicode escape sequences anywhere!
result.append("&#92;");
break;
default:
result.push_back(c);
break;
}
prev = c;
}
return result;
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
template <typename DescriptorType>
static string GrpcGetCommentsForDescriptor(const DescriptorType* descriptor) {
SourceLocation location;
if (descriptor->GetSourceLocation(&location)) {
return location.leading_comments.empty() ?
location.trailing_comments : location.leading_comments;
}
return string();
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static std::vector<string> GrpcGetDocLines(const string& comments) {
if (!comments.empty()) {
// TODO(kenton): Ideally we should parse the comment text as Markdown and
// write it back as HTML, but this requires a Markdown parser. For now
// we just use <pre> to get fixed-width text formatting.
// If the comment itself contains block comment start or end markers,
// HTML-escape them so that they don't accidentally close the doc comment.
string escapedComments = GrpcEscapeJavadoc(comments);
std::vector<string> lines = GrpcSplit(escapedComments, "\n");
while (!lines.empty() && lines.back().empty()) {
lines.pop_back();
}
return lines;
}
return std::vector<string>();
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
template <typename DescriptorType>
static std::vector<string> GrpcGetDocLinesForDescriptor(const DescriptorType* descriptor) {
return GrpcGetDocLines(GrpcGetCommentsForDescriptor(descriptor));
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static void GrpcWriteDocCommentBody(Printer* printer,
const std::vector<string>& lines,
bool surroundWithPreTag) {
if (!lines.empty()) {
if (surroundWithPreTag) {
printer->Print(" * <pre>\n");
}
for (size_t i = 0; i < lines.size(); i++) {
// Most lines should start with a space. Watch out for lines that start
// with a /, since putting that right after the leading asterisk will
// close the comment.
if (!lines[i].empty() && lines[i][0] == '/') {
printer->Print(" * $line$\n", "line", lines[i]);
} else {
printer->Print(" *$line$\n", "line", lines[i]);
}
}
if (surroundWithPreTag) {
printer->Print(" * </pre>\n");
}
}
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static void GrpcWriteDocComment(Printer* printer, const string& comments) {
printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLines(comments);
GrpcWriteDocCommentBody(printer, lines, false);
printer->Print(" */\n");
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
static void GrpcWriteServiceDocComment(Printer* printer,
const ServiceDescriptor* service) {
// Deviating from protobuf to avoid extraneous docs
// (see https://github.com/google/protobuf/issues/1406);
printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLinesForDescriptor(service);
GrpcWriteDocCommentBody(printer, lines, true);
printer->Print(" */\n");
}
// TODO(nmittler): Remove once protobuf includes javadoc methods in distribution.
void GrpcWriteMethodDocComment(Printer* printer,
const MethodDescriptor* method) {
// Deviating from protobuf to avoid extraneous docs
// (see https://github.com/google/protobuf/issues/1406);
printer->Print("/**\n");
std::vector<string> lines = GrpcGetDocLinesForDescriptor(method);
GrpcWriteDocCommentBody(printer, lines, true);
printer->Print(" */\n");
}
enum StubType {
ASYNC_INTERFACE = 0,
BLOCKING_CLIENT_INTERFACE = 1,
FUTURE_CLIENT_INTERFACE = 2,
BLOCKING_SERVER_INTERFACE = 3,
ASYNC_CLIENT_IMPL = 4,
BLOCKING_CLIENT_IMPL = 5,
FUTURE_CLIENT_IMPL = 6,
ABSTRACT_CLASS = 7,
};
enum CallType {
ASYNC_CALL = 0,
BLOCKING_CALL = 1,
FUTURE_CALL = 2
};
static void PrintMarshallerStaticBlock(const ServiceDescriptor* service,
std::map<string, string>* vars,
Printer* p) {
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
(*vars)["input_type"] = google::protobuf::compiler::java::ClassName(method->input_type());
(*vars)["output_type"] = google::protobuf::compiler::java::ClassName(method->output_type());
p->Print(
*vars,
"private static final AtomicBoolean registered = new AtomicBoolean();\n\n");
p->Print(
*vars,
"private static Class<?> init() {\n"
" Class<?> clazz = null;\n"
" try {\n"
" clazz = Class.forName(DemoServiceDubbo.class.getName());\n"
" if (registered.compareAndSet(false, true)) {\n"
" $ProtobufUtils$.marshaller(\n"
" $input_type$.getDefaultInstance());\n"
" $ProtobufUtils$.marshaller(\n"
" $output_type$.getDefaultInstance());\n"
" }\n"
" } catch (ClassNotFoundException e) {\n"
" // ignore \n"
" }\n"
" return clazz;\n"
"}\n\n");
}
}
static void PrintDubboInterface(
const ServiceDescriptor* service,
std::map<string, string>* vars,
Printer* p, bool generate_nano) {
const string service_name = service->name();
(*vars)["service_name"] = service_name;
(*vars)["dubbo_interface"] = "I" + service_name;
p->Print(
"/**\n "
"* Code generated for Dubbo\n "
"*/\n"
);
p->Print(
*vars,
"public interface $dubbo_interface$ {\n\n"
" static Class<?> clazz = init();\n\n");
for (int i = 0; i < service->method_count(); ++i) {
const MethodDescriptor* method = service->method(i);
(*vars)["input_type"] = MessageFullJavaName(generate_nano,
method->input_type());
(*vars)["output_type"] = MessageFullJavaName(generate_nano,
method->output_type());
(*vars)["lower_method_name"] = LowerMethodName(method);
// Simple RPC
p->Print(
*vars,
" $output_type$ $lower_method_name$($input_type$ request);\n\n");
// Simple Future RPC
p->Print(
*vars,
" $CompletableFuture$<$output_type$> $lower_method_name$Async(\n $input_type$ request);\n\n");
// p->Print(
// *vars,
// "default $CompletableFuture$<$output_type$> $lower_method_name$Async(\n"
// " $input_type$ request) {\n return CompletableFuture.completedFuture($lower_method_name$(request));\n}\n\n");
p->Outdent();
}
p->Outdent();
p->Print(" }\n\n");
}
static void PrintService(const ServiceDescriptor* service,
std::map<string, string>* vars,
Printer* p,
bool disable_version) {
(*vars)["service_name"] = service->name();
(*vars)["file_name"] = service->file()->name();
(*vars)["service_class_name"] = ServiceClassName(service);
(*vars)["grpc_version"] = "";
#ifdef GRPC_VERSION
if (!disable_version) {
(*vars)["grpc_version"] = " (version " XSTR(GRPC_VERSION) ")";
}
#endif
// TODO(nmittler): Replace with WriteServiceDocComment once included by protobuf distro.
GrpcWriteServiceDocComment(p, service);
p->Print(
*vars,
"@$Generated$(\n"
" value = \"by gRPC proto compiler$grpc_version$\",\n"
" comments = \"Source: $file_name$\")\n");
if (service->options().deprecated()) {
p->Print(*vars, "@$Deprecated$\n");
}
p->Print(
*vars,
"public final class $service_class_name$ {\n\n");
p->Indent();
PrintMarshallerStaticBlock(service, vars, p);
p->Print(
*vars,
"private $service_class_name$() {}\n\n");
p->Print(
*vars,
"public static final String SERVICE_NAME = "
"\"$Package$$service_name$\";\n\n");
PrintDubboInterface(service, vars, p, false);
p->Outdent();
p->Print("}\n");
}
void PrintImports(Printer* p) {
p->Print(
"import "
"java.util.concurrent.CompletableFuture;\n");
p->Print(
"import "
"java.util.concurrent.atomic.AtomicBoolean;\n");
}
void GenerateService(const ServiceDescriptor* service,
google::protobuf::io::ZeroCopyOutputStream* out,
ProtoFlavor flavor,
bool disable_version) {
// All non-generated classes must be referred by fully qualified names to
// avoid collision with generated classes.
std::map<string, string> vars;
vars["String"] = "java.lang.String";
vars["Deprecated"] = "java.lang.Deprecated";
vars["Override"] = "java.lang.Override";
vars["Iterator"] = "java.util.Iterator";
vars["Generated"] = "javax.annotation.Generated";
vars["CompletableFuture"] =
"java.util.concurrent.CompletableFuture";
vars["AtomicBoolean"] =
"java.util.concurrent.atomic.AtomicBoolean";
vars["ProtobufUtils"] =
"org.apache.dubbo.common.serialize.protobuf.support.ProtobufUtils";
Printer printer(out, '$');
string package_name = ServiceJavaPackage(service->file(),false);
if (!package_name.empty()) {
printer.Print(
"package $package_name$;\n\n",
"package_name", package_name);
}
PrintImports(&printer);
// Package string is used to fully qualify method names.
vars["Package"] = service->file()->package();
if (!vars["Package"].empty()) {
vars["Package"].append(".");
}
PrintService(service, &vars, &printer, false);
}
string ServiceJavaPackage(const FileDescriptor* file, bool nano) {
string result = google::protobuf::compiler::java::ClassName(file);
size_t last_dot_pos = result.find_last_of('.');
if (last_dot_pos != string::npos) {
result.resize(last_dot_pos);
} else {
result = "";
}
if (nano) {
if (!result.empty()) {
result += ".";
}
result += "nano";
}
return result;
}
string ServiceClassName(const google::protobuf::ServiceDescriptor* service) {
return service->name() + "Dubbo";
}
} // namespace java_dubbo_generator

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,78 @@
#ifndef NET_GRPC_COMPILER_JAVA_GENERATOR_H_
#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_
#include <stdlib.h> // for abort()
#include <iostream>
#include <string>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.h>
class LogHelper {
std::ostream* os;
public:
LogHelper(std::ostream* os) : os(os) {}
~LogHelper() {
*os << std::endl;
::abort();
}
std::ostream& get_os() {
return *os;
}
};
// Abort the program after logging the mesage if the given condition is not
// true. Otherwise, do nothing.
#define GRPC_CODEGEN_CHECK(x) !(x) && LogHelper(&std::cerr).get_os() \
<< "CHECK FAILED: " << __FILE__ << ":" \
<< __LINE__ << ": "
// Abort the program after logging the mesage.
#define GRPC_CODEGEN_FAIL GRPC_CODEGEN_CHECK(false)
using namespace std;
namespace java_grpc_generator {
enum ProtoFlavor {
NORMAL, LITE, NANO
};
// Returns the package name of the gRPC services defined in the given file.
string ServiceJavaPackage(const google::protobuf::FileDescriptor* file, bool nano);
// Returns the name of the outer class that wraps in all the generated code for
// the given service.
string ServiceClassName(const google::protobuf::ServiceDescriptor* service);
// Writes the generated service interface into the given ZeroCopyOutputStream
void GenerateService(const google::protobuf::ServiceDescriptor* service,
google::protobuf::io::ZeroCopyOutputStream* out,
ProtoFlavor flavor,
bool disable_version);
} // namespace java_grpc_generator
namespace java_dubbo_generator {
enum ProtoFlavor {
NORMAL
};
// Returns the package name of the Dubbo services defined in the given file.
string ServiceJavaPackage(const google::protobuf::FileDescriptor* file, bool nano);
// Returns the name of the outer class that wraps in all the generated code for
// the given service.
string ServiceClassName(const google::protobuf::ServiceDescriptor* service);
// Writes the generated service interface into the given ZeroCopyOutputStream
void GenerateService(const google::protobuf::ServiceDescriptor* service,
google::protobuf::io::ZeroCopyOutputStream* out,
ProtoFlavor flavor,
bool disable_version);
} // namespace java_dubbo_generator
#endif // NET_GRPC_COMPILER_JAVA_GENERATOR_H_

View File

@ -0,0 +1,87 @@
// Generates Java gRPC service interface out of Protobuf IDL.
//
// This is a Proto2 compiler plugin. See net/proto2/compiler/proto/plugin.proto
// and net/proto2/compiler/public/plugin.h for more information on plugins.
#include <memory>
#include "java_generator.h"
#include <google/protobuf/compiler/code_generator.h>
#include <google/protobuf/compiler/plugin.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/io/zero_copy_stream.h>
static string JavaPackageToDir(const string& package_name) {
string package_dir = package_name;
for (size_t i = 0; i < package_dir.size(); ++i) {
if (package_dir[i] == '.') {
package_dir[i] = '/';
}
}
if (!package_dir.empty()) package_dir += "/";
return package_dir;
}
class JavaGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
public:
JavaGrpcGenerator() {}
virtual ~JavaGrpcGenerator() {}
virtual bool Generate(const google::protobuf::FileDescriptor* file,
const string& parameter,
google::protobuf::compiler::GeneratorContext* context,
string* error) const {
std::vector<std::pair<string, string> > options;
google::protobuf::compiler::ParseGeneratorParameter(parameter, &options);
string DUBBO("dubbo");
if (DUBBO == parameter) {
string package_name = java_dubbo_generator::ServiceJavaPackage(
file, false);
string package_filename = JavaPackageToDir(package_name);
for (int i = 0; i < file->service_count(); ++i) {
const google::protobuf::ServiceDescriptor* service = file->service(i);
string filename = package_filename
+ java_dubbo_generator::ServiceClassName(service) + ".java";
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
context->Open(filename));
java_dubbo_generator::GenerateService(
service, output.get(), java_dubbo_generator::ProtoFlavor::NORMAL, false);
}
} else {
java_grpc_generator::ProtoFlavor flavor =
java_grpc_generator::ProtoFlavor::NORMAL;
bool disable_version = false;
for (size_t i = 0; i < options.size(); i++) {
if (options[i].first == "nano") {
flavor = java_grpc_generator::ProtoFlavor::NANO;
} else if (options[i].first == "lite") {
flavor = java_grpc_generator::ProtoFlavor::LITE;
} else if (options[i].first == "noversion") {
disable_version = true;
}
}
string package_name = java_grpc_generator::ServiceJavaPackage(
file, flavor == java_grpc_generator::ProtoFlavor::NANO);
string package_filename = JavaPackageToDir(package_name);
for (int i = 0; i < file->service_count(); ++i) {
const google::protobuf::ServiceDescriptor* service = file->service(i);
string filename = package_filename
+ java_grpc_generator::ServiceClassName(service) + ".java";
std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
context->Open(filename));
java_grpc_generator::GenerateService(
service, output.get(), flavor, disable_version);
}
}
return true;
}
};
int main(int argc, char* argv[]) {
JavaGrpcGenerator generator;
return google::protobuf::compiler::PluginMain(argc, argv, &generator);
}

View File

@ -30,6 +30,20 @@
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap-spring</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-cluster</artifactId>
@ -44,20 +58,6 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-spring</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-filter-cache</artifactId>
@ -219,6 +219,13 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-grpc</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-api</artifactId>
@ -267,6 +274,16 @@
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -403,14 +420,7 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf-json</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-api</artifactId>
<artifactId>dubbo-serialization-protobuf</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
@ -449,6 +459,16 @@
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -466,7 +486,7 @@
<!-- metadata -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-api</artifactId>
<artifactId>dubbo-metadata-api</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
@ -498,6 +518,16 @@
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -568,6 +598,8 @@
<artifactSet>
<includes>
<include>com.alibaba:hessian-lite</include>
<include>org.apache.dubbo:dubbo-bootstrap-api</include>
<include>org.apache.dubbo:dubbo-bootstrap-spring</include>
<include>org.apache.dubbo:dubbo-compatible</include>
<include>org.apache.dubbo:dubbo-common</include>
<include>org.apache.dubbo:dubbo-remoting-api</include>
@ -591,6 +623,7 @@
<include>org.apache.dubbo:dubbo-rpc-redis</include>
<include>org.apache.dubbo:dubbo-rpc-rest</include>
<include>org.apache.dubbo:dubbo-rpc-xml</include>
<include>org.apache.dubbo:dubbo-rpc-grpc</include>
<include>org.apache.dubbo:dubbo-filter-validation</include>
<include>org.apache.dubbo:dubbo-filter-cache</include>
<include>org.apache.dubbo:dubbo-cluster</include>
@ -606,8 +639,6 @@
<include>org.apache.dubbo:dubbo-registry-multiple</include>
<include>org.apache.dubbo:dubbo-monitor-api</include>
<include>org.apache.dubbo:dubbo-monitor-default</include>
<include>org.apache.dubbo:dubbo-config-api</include>
<include>org.apache.dubbo:dubbo-config-spring</include>
<include>org.apache.dubbo:dubbo-container-api</include>
<include>org.apache.dubbo:dubbo-container-spring</include>
<include>org.apache.dubbo:dubbo-container-log4j</include>
@ -622,7 +653,7 @@
<include>org.apache.dubbo:dubbo-serialization-jdk</include>
<include>org.apache.dubbo:dubbo-serialization-protostuff</include>
<include>org.apache.dubbo:dubbo-serialization-gson</include>
<include>org.apache.dubbo:dubbo-serialization-protobuf-json</include>
<include>org.apache.dubbo:dubbo-serialization-protobuf</include>
<include>org.apache.dubbo:dubbo-configcenter-api</include>
<include>org.apache.dubbo:dubbo-configcenter-definition</include>
<include>org.apache.dubbo:dubbo-configcenter-apollo</include>
@ -630,8 +661,7 @@
<include>org.apache.dubbo:dubbo-configcenter-consul</include>
<include>org.apache.dubbo:dubbo-configcenter-etcd</include>
<include>org.apache.dubbo:dubbo-configcenter-nacos</include>
<include>org.apache.dubbo:dubbo-metadata-report-api</include>
<include>org.apache.dubbo:dubbo-metadata-definition</include>
<include>org.apache.dubbo:dubbo-metadata-api</include>
<include>org.apache.dubbo:dubbo-metadata-report-redis</include>
<include>org.apache.dubbo:dubbo-metadata-report-zookeeper</include>
<include>org.apache.dubbo:dubbo-metadata-report-consul</include>
@ -642,8 +672,15 @@
</includes>
</artifactSet>
<transformers>
<!-- dubbo-common beginning -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
@ -651,18 +688,37 @@
META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.infra.InfraAdapter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
</resource>
</transformer>
<!-- dubbo-common end -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Dispatcher</resource>
</transformer>
@ -744,30 +800,65 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.configcenter.DynamicConfigurationFactory
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
</resource>
</transformer>
<!-- @since 2.7.4 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventDispatcher
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.store.MetadataReportFactory
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.MetadataServiceExporter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.ServiceNameMapping
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.proxy.MetadataServiceProxyFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.event.EventListener
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceInstanceCustomizer
</resource>
</transformer>
<transformer
implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.registry.client.metadata.MetadataServiceURLBuilder
</resource>
</transformer>
</transformers>
<filters>
<filter>

View File

@ -23,6 +23,7 @@
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-parent</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-bom</artifactId>
@ -99,12 +100,12 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
<artifactId>dubbo-bootstrap-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-spring</artifactId>
<artifactId>dubbo-bootstrap-spring</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
@ -227,6 +228,11 @@
<artifactId>dubbo-rpc-xml</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-grpc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-api</artifactId>
@ -354,7 +360,7 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-protobuf-json</artifactId>
<artifactId>dubbo-serialization-protobuf</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
@ -362,9 +368,15 @@
<artifactId>dubbo-compatible</artifactId>
<version>${project.version}</version>
</dependency>
<!-- metadata -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-api</artifactId>
<artifactId>dubbo-metadata-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
@ -392,11 +404,8 @@
<artifactId>dubbo-metadata-report-nacos</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-api</artifactId>
<version>${project.version}</version>
</dependency>
<!-- config-center -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-zookeeper</artifactId>
@ -422,11 +431,6 @@
<artifactId>dubbo-configcenter-nacos</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-definition</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-definition-protobuf</artifactId>

View File

@ -0,0 +1,187 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>dubbo-bootstrap-api</artifactId>
<packaging>jar</packaging>
<name>dubbo-bootstrap-api</name>
<description>The bootstrap module of Dubbo project</description>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-injvm</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-filter-validation</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-filter-cache</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- Test dependencies -->
<!-- Zookeeper dependencies for testing -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-etcd3</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-eureka</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-consul</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-zookeeper</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-etcd</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-nacos</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-redis</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-zookeeper</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<!-- Nacos dependencies for testing -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-nacos</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-dubbo</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-rest</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-hessian</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-netty4</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-hessian2</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,512 @@
/*
* 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.bootstrap;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.serialize.Serialization;
import org.apache.dubbo.common.status.StatusChecker;
import org.apache.dubbo.common.threadpool.ThreadPool;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.AbstractInterfaceConfig;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConfigCenterConfig;
import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.MonitorConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.SslConfig;
import org.apache.dubbo.monitor.MonitorFactory;
import org.apache.dubbo.monitor.MonitorService;
import org.apache.dubbo.registry.RegistryService;
import org.apache.dubbo.remoting.Codec;
import org.apache.dubbo.remoting.Dispatcher;
import org.apache.dubbo.remoting.Transporter;
import org.apache.dubbo.remoting.exchange.Exchanger;
import org.apache.dubbo.remoting.telnet.TelnetHandler;
import org.apache.dubbo.rpc.ExporterListener;
import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.InvokerListener;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.support.MockInvoker;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
import static org.apache.dubbo.common.constants.CommonConstants.FILE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOADBALANCE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_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.common.constants.CommonConstants.REMOVE_VALUE_PREFIX;
import static org.apache.dubbo.common.constants.CommonConstants.THREADPOOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.common.utils.UrlUtils.isServiceDiscoveryRegistryType;
import static org.apache.dubbo.config.Constants.ARCHITECTURE;
import static org.apache.dubbo.config.Constants.CONTEXTPATH_KEY;
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
import static org.apache.dubbo.config.Constants.ENVIRONMENT;
import static org.apache.dubbo.config.Constants.LAYER_KEY;
import static org.apache.dubbo.config.Constants.LISTENER_KEY;
import static org.apache.dubbo.config.Constants.NAME;
import static org.apache.dubbo.config.Constants.ORGANIZATION;
import static org.apache.dubbo.config.Constants.OWNER;
import static org.apache.dubbo.config.Constants.STATUS_KEY;
import static org.apache.dubbo.monitor.Constants.LOGSTAT_PROTOCOL;
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.registry.Constants.REGISTER_KEY;
import static org.apache.dubbo.registry.Constants.SUBSCRIBE_KEY;
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
import static org.apache.dubbo.remoting.Constants.CODEC_KEY;
import static org.apache.dubbo.remoting.Constants.DISPATCHER_KEY;
import static org.apache.dubbo.remoting.Constants.EXCHANGER_KEY;
import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY;
import static org.apache.dubbo.remoting.Constants.SERVER_KEY;
import static org.apache.dubbo.remoting.Constants.TELNET;
import static org.apache.dubbo.remoting.Constants.TRANSPORTER_KEY;
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.LOCAL_KEY;
import static org.apache.dubbo.rpc.Constants.MOCK_KEY;
import static org.apache.dubbo.rpc.Constants.PROXY_KEY;
import static org.apache.dubbo.rpc.Constants.RETURN_PREFIX;
import static org.apache.dubbo.rpc.Constants.THROW_PREFIX;
import static org.apache.dubbo.rpc.Constants.TOKEN_KEY;
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
/**
*
*/
public class BootstrapUtils {
/**
* The maximum length of a <b>parameter's value</b>
*/
private static final int MAX_LENGTH = 200;
/**
* The maximum length of a <b>path</b>
*/
private static final int MAX_PATH_LENGTH = 200;
/**
* The rule qualification for <b>name</b>
*/
private static final Pattern PATTERN_NAME = Pattern.compile("[\\-._0-9a-zA-Z]+");
/**
* The rule qualification for <b>multiply name</b>
*/
private static final Pattern PATTERN_MULTI_NAME = Pattern.compile("[,\\-._0-9a-zA-Z]+");
/**
* The rule qualification for <b>method names</b>
*/
private static final Pattern PATTERN_METHOD_NAME = Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
/**
* The rule qualification for <b>path</b>
*/
private static final Pattern PATTERN_PATH = Pattern.compile("[/\\-$._0-9a-zA-Z]+");
/**
* The pattern matches a value who has a symbol
*/
private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,\\s/\\-._0-9a-zA-Z]+");
/**
* The pattern matches a property key
*/
private static final Pattern PATTERN_KEY = Pattern.compile("[*,\\-._0-9a-zA-Z]+");
public static List<URL> loadRegistries(AbstractInterfaceConfig interfaceConfig, boolean provider) {
// check && override if necessary
List<URL> registryList = new ArrayList<URL>();
ApplicationConfig application = interfaceConfig.getApplication();
List<RegistryConfig> registries = interfaceConfig.getRegistries();
if (CollectionUtils.isNotEmpty(registries)) {
for (RegistryConfig config : registries) {
String address = config.getAddress();
if (StringUtils.isEmpty(address)) {
address = ANYHOST_VALUE;
}
if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
Map<String, String> map = new HashMap<String, String>();
AbstractConfig.appendParameters(map, application);
AbstractConfig.appendParameters(map, config);
map.put(PATH_KEY, RegistryService.class.getName());
AbstractInterfaceConfig.appendRuntimeParameters(map);
if (!map.containsKey(PROTOCOL_KEY)) {
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
}
List<URL> urls = UrlUtils.parseURLs(address, map);
for (URL url : urls) {
url = URLBuilder.from(url)
.addParameter(REGISTRY_KEY, url.getProtocol())
.setProtocol(extractRegistryType(url))
.build();
if ((provider && url.getParameter(REGISTER_KEY, true))
|| (!provider && url.getParameter(SUBSCRIBE_KEY, true))) {
registryList.add(url);
}
}
}
}
}
return registryList;
}
public static URL loadMonitor(AbstractInterfaceConfig interfaceConfig, URL registryURL) {
interfaceConfig.checkMonitor();
Map<String, String> map = new HashMap<String, String>();
map.put(INTERFACE_KEY, MonitorService.class.getName());
AbstractInterfaceConfig.appendRuntimeParameters(map);
//set ip
String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY);
if (StringUtils.isEmpty(hostToRegistry)) {
hostToRegistry = NetUtils.getLocalHost();
} else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
throw new IllegalArgumentException("Specified invalid registry ip from property:" +
DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
}
map.put(REGISTER_IP_KEY, hostToRegistry);
MonitorConfig monitor = interfaceConfig.getMonitor();
ApplicationConfig application = interfaceConfig.getApplication();
AbstractConfig.appendParameters(map, monitor);
AbstractConfig.appendParameters(map, application);
String address = monitor.getAddress();
String sysaddress = System.getProperty("dubbo.monitor.address");
if (sysaddress != null && sysaddress.length() > 0) {
address = sysaddress;
}
if (ConfigUtils.isNotEmpty(address)) {
if (!map.containsKey(PROTOCOL_KEY)) {
if (getExtensionLoader(MonitorFactory.class).hasExtension(LOGSTAT_PROTOCOL)) {
map.put(PROTOCOL_KEY, LOGSTAT_PROTOCOL);
} else {
map.put(PROTOCOL_KEY, DUBBO_PROTOCOL);
}
}
return UrlUtils.parseURL(address, map);
} else if ((REGISTRY_PROTOCOL.equals(monitor.getProtocol()) || SERVICE_REGISTRY_PROTOCOL.equals(monitor.getProtocol()))
&& registryURL != null) {
return URLBuilder.from(registryURL)
.setProtocol(DUBBO_PROTOCOL)
.addParameter(PROTOCOL_KEY, monitor.getProtocol())
.addParameterAndEncoded(REFER_KEY, StringUtils.toQueryString(map))
.build();
}
return null;
}
/**
* Legitimacy check and setup of local simulated operations. The operations can be a string with Simple operation or
* a classname whose {@link Class} implements a particular function
*
* @param interfaceClass for provider side, it is the {@link Class} of the service that will be exported; for consumer
* side, it is the {@link Class} of the remote service interface that will be referenced
*/
public static void checkMock(Class<?> interfaceClass, AbstractInterfaceConfig config) {
String mock = config.getMock();
if (ConfigUtils.isEmpty(mock)) {
return;
}
String normalizedMock = MockInvoker.normalizeMock(mock);
if (normalizedMock.startsWith(RETURN_PREFIX)) {
normalizedMock = normalizedMock.substring(RETURN_PREFIX.length()).trim();
try {
//Check whether the mock value is legal, if it is illegal, throw exception
MockInvoker.parseMockValue(normalizedMock);
} catch (Exception e) {
throw new IllegalStateException("Illegal mock return in <dubbo:service/reference ... " +
"mock=\"" + mock + "\" />");
}
} else if (normalizedMock.startsWith(THROW_PREFIX)) {
normalizedMock = normalizedMock.substring(THROW_PREFIX.length()).trim();
if (ConfigUtils.isNotEmpty(normalizedMock)) {
try {
//Check whether the mock value is legal
MockInvoker.getThrowable(normalizedMock);
} catch (Exception e) {
throw new IllegalStateException("Illegal mock throw in <dubbo:service/reference ... " +
"mock=\"" + mock + "\" />");
}
}
} else {
//Check whether the mock class is a implementation of the interfaceClass, and if it has a default constructor
MockInvoker.getMockObject(normalizedMock, interfaceClass);
}
}
public static void validateAbstractInterfaceConfig(AbstractInterfaceConfig config) {
checkName(LOCAL_KEY, config.getLocal());
checkName("stub", config.getStub());
checkMultiName("owner", config.getOwner());
checkExtension(ProxyFactory.class, PROXY_KEY, config.getProxy());
checkExtension(Cluster.class, CLUSTER_KEY, config.getCluster());
checkMultiExtension(Filter.class, FILE_KEY, config.getFilter());
checkMultiExtension(InvokerListener.class, LISTENER_KEY, config.getListener());
checkNameHasSymbol(LAYER_KEY, config.getLayer());
List<MethodConfig> methods = config.getMethods();
if (CollectionUtils.isNotEmpty(methods)) {
methods.forEach(BootstrapUtils::validateMethodConfig);
}
}
public static void validateServiceConfig(ServiceConfig config) {
checkKey(VERSION_KEY, config.getVersion());
checkKey(GROUP_KEY, config.getGroup());
checkName(TOKEN_KEY, config.getToken());
checkPathName(PATH_KEY, config.getPath());
checkMultiExtension(ExporterListener.class, "listener", config.getListener());
validateAbstractInterfaceConfig(config);
}
public static void validateReferenceConfig(ReferenceConfig config) {
checkMultiExtension(InvokerListener.class, "listener", config.getListener());
checkKey(VERSION_KEY, config.getVersion());
checkKey(GROUP_KEY, config.getGroup());
checkName(CLIENT_KEY, config.getClient());
validateAbstractInterfaceConfig(config);
}
public static void validateConfigCenterConfig(ConfigCenterConfig config) {
checkParameterName(config.getParameters());
}
public static void validateApplicationConfig(ApplicationConfig config) {
checkName(NAME, config.getName());
checkMultiName(OWNER, config.getOwner());
checkName(ORGANIZATION, config.getOrganization());
checkName(ARCHITECTURE, config.getArchitecture());
checkName(ENVIRONMENT, config.getEnvironment());
checkParameterName(config.getParameters());
}
public static void validateModuleConfig(ModuleConfig config) {
checkName(NAME, config.getName());
checkName(OWNER, config.getOwner());
checkName(ORGANIZATION, config.getOrganization());
}
public static void validateMonitorConfig(MonitorConfig config) {
checkParameterName(config.getParameters());
}
public static void validateProtocolConfig(ProtocolConfig config) {
String name = config.getName();
checkName("name", name);
checkName(HOST_KEY, config.getHost());
checkPathName("contextpath", config.getContextpath());
if (DUBBO_PROTOCOL.equals(name)) {
checkMultiExtension(Codec.class, CODEC_KEY, config.getCodec());
}
if (DUBBO_PROTOCOL.equals(name)) {
checkMultiExtension(Serialization.class, SERIALIZATION_KEY, config.getSerialization());
}
if (DUBBO_PROTOCOL.equals(name)) {
checkMultiExtension(Transporter.class, SERVER_KEY, config.getServer());
}
if (DUBBO_PROTOCOL.equals(name)) {
checkMultiExtension(Transporter.class, CLIENT_KEY, config.getClient());
}
checkMultiExtension(TelnetHandler.class, TELNET, config.getTelnet());
checkMultiExtension(StatusChecker.class, "status", config.getStatus());
checkExtension(Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(Exchanger.class, EXCHANGER_KEY, config.getExchanger());
checkExtension(Dispatcher.class, DISPATCHER_KEY, config.getDispatcher());
checkExtension(Dispatcher.class, "dispather", config.getDispather());
checkExtension(ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
}
public static void validateProviderConfig(ProviderConfig config) {
checkPathName(CONTEXTPATH_KEY, config.getContextpath());
checkExtension(ThreadPool.class, THREADPOOL_KEY, config.getThreadpool());
checkMultiExtension(TelnetHandler.class, TELNET, config.getTelnet());
checkMultiExtension(StatusChecker.class, STATUS_KEY, config.getStatus());
checkExtension(Transporter.class, TRANSPORTER_KEY, config.getTransporter());
checkExtension(Exchanger.class, EXCHANGER_KEY, config.getExchanger());
}
public static void validateRegistryConfig(RegistryConfig config) {
checkName(PROTOCOL_KEY, config.getProtocol());
checkName(USERNAME_KEY, config.getUsername());
checkLength(PASSWORD_KEY, config.getPassword());
checkPathLength(FILE_KEY, config.getFile());
checkName(TRANSPORTER_KEY, config.getTransporter());
checkName(SERVER_KEY, config.getServer());
checkName(CLIENT_KEY, config.getClient());
checkParameterName(config.getParameters());
}
public static void validateSslConfig(SslConfig config) {
}
public static void validateMethodConfig(MethodConfig config) {
checkExtension(LoadBalance.class, LOADBALANCE_KEY, config.getLoadbalance());
checkParameterName(config.getParameters());
checkMethodName("name", config.getName());
String mock = config.getMock();
if (mock.startsWith(RETURN_PREFIX) || mock.startsWith(THROW_PREFIX + " ")) {
checkLength(MOCK_KEY, mock);
} else if (mock.startsWith(FAIL_PREFIX) || mock.startsWith(FORCE_PREFIX)) {
checkNameHasSymbol(MOCK_KEY, mock);
} else {
checkName(MOCK_KEY, mock);
}
}
private static String extractRegistryType(URL url) {
return isServiceDiscoveryRegistryType(url) ? SERVICE_REGISTRY_PROTOCOL : REGISTRY_PROTOCOL;
}
private static void checkExtension(Class<?> type, String property, String value) {
checkName(property, value);
if (StringUtils.isNotEmpty(value)
&& !ExtensionLoader.getExtensionLoader(type).hasExtension(value)) {
throw new IllegalStateException("No such extension " + value + " for " + property + "/" + type.getName());
}
}
/**
* Check whether there is a <code>Extension</code> who's name (property) is <code>value</code> (special treatment is
* required)
*
* @param type The Extension type
* @param property The extension key
* @param value The Extension name
*/
private static void checkMultiExtension(Class<?> type, String property, String value) {
checkMultiName(property, value);
if (StringUtils.isNotEmpty(value)) {
String[] values = value.split("\\s*[,]+\\s*");
for (String v : values) {
if (v.startsWith(REMOVE_VALUE_PREFIX)) {
v = v.substring(1);
}
if (DEFAULT_KEY.equals(v)) {
continue;
}
if (!ExtensionLoader.getExtensionLoader(type).hasExtension(v)) {
throw new IllegalStateException("No such extension " + v + " for " + property + "/" + type.getName());
}
}
}
}
protected static void checkLength(String property, String value) {
checkProperty(property, value, MAX_LENGTH, null);
}
protected static void checkPathLength(String property, String value) {
checkProperty(property, value, MAX_PATH_LENGTH, null);
}
protected static void checkName(String property, String value) {
checkProperty(property, value, MAX_LENGTH, PATTERN_NAME);
}
protected static void checkNameHasSymbol(String property, String value) {
checkProperty(property, value, MAX_LENGTH, PATTERN_NAME_HAS_SYMBOL);
}
protected static void checkKey(String property, String value) {
checkProperty(property, value, MAX_LENGTH, PATTERN_KEY);
}
protected static void checkMultiName(String property, String value) {
checkProperty(property, value, MAX_LENGTH, PATTERN_MULTI_NAME);
}
protected static void checkPathName(String property, String value) {
checkProperty(property, value, MAX_PATH_LENGTH, PATTERN_PATH);
}
protected static void checkMethodName(String property, String value) {
checkProperty(property, value, MAX_LENGTH, PATTERN_METHOD_NAME);
}
protected static void checkParameterName(Map<String, String> parameters) {
if (CollectionUtils.isEmptyMap(parameters)) {
return;
}
for (Map.Entry<String, String> entry : parameters.entrySet()) {
checkNameHasSymbol(entry.getKey(), entry.getValue());
}
}
protected static void checkProperty(String property, String value, int maxlength, Pattern pattern) {
if (StringUtils.isEmpty(value)) {
return;
}
if (value.length() > maxlength) {
throw new IllegalStateException("Invalid " + property + "=\"" + value + "\" is longer than " + maxlength);
}
if (pattern != null) {
Matcher matcher = pattern.matcher(value);
if (!matcher.matches()) {
throw new IllegalStateException("Invalid " + property + "=\"" + value + "\" contains illegal " +
"character, only digit, letter, '-', '_' or '.' is legal.");
}
}
}
}

View File

@ -0,0 +1,594 @@
/*
* 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.bootstrap;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.bytecode.Wrapper;
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.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.config.AbstractConfig;
import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.event.ReferenceConfigDestroyedEvent;
import org.apache.dubbo.event.Event;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
import org.apache.dubbo.rpc.cluster.support.registry.ZoneAwareCluster;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.model.ServiceDescriptor;
import org.apache.dubbo.rpc.model.ServiceMetadata;
import org.apache.dubbo.rpc.model.ServiceRepository;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.apache.dubbo.rpc.service.Destroyable;
import org.apache.dubbo.rpc.service.GenericService;
import org.apache.dubbo.rpc.support.ProtocolUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.MONITOR_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROXY_CLASS_REF;
import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SEMICOLON_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.utils.NetUtils.isInvalidLocalHost;
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
import static org.apache.dubbo.registry.Constants.CONSUMER_PROTOCOL;
import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
import static org.apache.dubbo.rpc.cluster.Constants.REFER_KEY;
/**
* A simple util class for cache {@link ReferenceConfig}.
* <p>
* {@link ReferenceConfig} is a heavy Object, it's necessary to cache these object
* for the framework which create {@link ReferenceConfig} frequently.
* <p>
* You can implement and use your own {@link ReferenceConfig} cache if you need use complicate strategy.
*/
public class ReferenceConfigCache {
public static final String DEFAULT_NAME = "_DEFAULT_";
/**
* Create the key with the <b>Group</b>, <b>Interface</b> and <b>version</b> attribute of {@link ReferenceConfig}.
* <p>
* key example: <code>group1/org.apache.dubbo.foo.FooService:1.0.0</code>.
*/
public static final KeyGenerator DEFAULT_KEY_GENERATOR = referenceConfig -> {
String iName = referenceConfig.getInterface();
if (StringUtils.isBlank(iName)) {
Class<?> clazz = referenceConfig.getInterfaceClass();
iName = clazz.getName();
}
if (StringUtils.isBlank(iName)) {
throw new IllegalArgumentException("No interface info in ReferenceConfig" + referenceConfig);
}
StringBuilder ret = new StringBuilder();
if (!StringUtils.isBlank(referenceConfig.getGroup())) {
ret.append(referenceConfig.getGroup()).append("/");
}
ret.append(iName);
if (!StringUtils.isBlank(referenceConfig.getVersion())) {
ret.append(":").append(referenceConfig.getVersion());
}
return ret.toString();
};
static final ConcurrentMap<String, ReferenceConfigCache> CACHE_HOLDER = new ConcurrentHashMap<String, ReferenceConfigCache>();
private final String name;
private final KeyGenerator generator;
private final ConcurrentMap<String, ReferenceConfig<?>> referredReferences = new ConcurrentHashMap<>();
private final ConcurrentMap<Class<?>, ConcurrentMap<String, Object>> proxies = new ConcurrentHashMap<>();
private ReferenceConfigCache(String name, KeyGenerator generator) {
this.name = name;
this.generator = generator;
}
/**
* Get the cache use default name and {@link #DEFAULT_KEY_GENERATOR} to generate cache key.
* Create cache if not existed yet.
*/
public static ReferenceConfigCache getCache() {
return getCache(DEFAULT_NAME);
}
/**
* Get the cache use specified name and {@link KeyGenerator}.
* Create cache if not existed yet.
*/
public static ReferenceConfigCache getCache(String name) {
return getCache(name, DEFAULT_KEY_GENERATOR);
}
/**
* Get the cache use specified {@link KeyGenerator}.
* Create cache if not existed yet.
*/
public static ReferenceConfigCache getCache(String name, KeyGenerator keyGenerator) {
ReferenceConfigCache cache = CACHE_HOLDER.get(name);
if (cache != null) {
return cache;
}
CACHE_HOLDER.putIfAbsent(name, new ReferenceConfigCache(name, keyGenerator));
return CACHE_HOLDER.get(name);
}
@SuppressWarnings("unchecked")
public <T> T get(ReferenceConfig<T> referenceConfig) {
String key = generator.generateKey(referenceConfig);
Class<?> type = referenceConfig.getInterfaceClass();
proxies.computeIfAbsent(type, _t -> new ConcurrentHashMap());
ConcurrentMap<String, Object> proxiesOfType = proxies.get(type);
proxiesOfType.computeIfAbsent(key, _k -> {
Object proxy = ReferHelper.refer(referenceConfig);
referredReferences.put(key, referenceConfig);
return proxy;
});
return (T) proxiesOfType.get(key);
}
/**
* Fetch cache with the specified key. The key is decided by KeyGenerator passed-in. If the default KeyGenerator is
* used, then the key is in the format of <code>group/interfaceClass:version</code>
*
* @param key cache key
* @param type object class
* @param <T> object type
* @return object from the cached ReferenceConfig
* @see KeyGenerator#generateKey(ReferenceConfig)
*/
@SuppressWarnings("unchecked")
public <T> T get(String key, Class<T> type) {
Map<String, Object> proxiesOfType = proxies.get(type);
if (CollectionUtils.isEmptyMap(proxiesOfType)) {
return null;
}
return (T) proxiesOfType.get(key);
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
ReferenceConfig<?> rc = referredReferences.get(key);
if (rc == null) {
return null;
}
return (T) get(key, rc.getInterfaceClass());
}
@SuppressWarnings("unchecked")
public <T> List<T> get(Class<T> type) {
Map<String, Object> proxiesOfType = proxies.get(type);
if (CollectionUtils.isEmptyMap(proxiesOfType)) {
return Collections.emptyList();
}
List<T> proxySet = new ArrayList<>();
proxiesOfType.values().forEach(obj -> proxySet.add((T) obj));
return proxySet;
}
public void destroy(String key, Class<?> type) {
ReferenceConfig<?> rc = referredReferences.remove(key);
if (rc == null) {
return;
}
ApplicationModel.getConfigManager().removeConfig(rc);
Map<String, Object> proxiesOfType = proxies.remove(type);
proxiesOfType.forEach((_k, _v) -> {
if (key == null || _k.equals(key)) {
Destroyable proxy = (Destroyable) _v;
proxy.$destroy();
}
});
}
public void destroy(Class<?> type) {
destroy(null, type);
}
/**
* clear and destroy one {@link ReferenceConfig} in the cache.
*
* @param referenceConfig use for create key.
*/
public <T> void destroy(ReferenceConfig<T> referenceConfig) {
String key = generator.generateKey(referenceConfig);
Class<?> type = referenceConfig.getInterfaceClass();
destroy(key, type);
}
/**
* clear and destroy all {@link ReferenceConfig} in the cache.
*/
public void destroyAll() {
if (CollectionUtils.isEmptyMap(referredReferences)) {
return;
}
referredReferences.forEach((_k, referenceConfig) -> {
ApplicationModel.getConfigManager().removeConfig(referenceConfig);
});
proxies.forEach((_type, proxiesOfType) -> {
proxiesOfType.forEach((_k, v) -> {
Destroyable proxy = (Destroyable) v;
proxy.$destroy();
});
});
referredReferences.clear();
proxies.clear();
}
public ConcurrentMap<String, ReferenceConfig<?>> getReferredReferences() {
return referredReferences;
}
public ConcurrentMap<Class<?>, ConcurrentMap<String, Object>> getProxies() {
return proxies;
}
@Override
public String toString() {
return "ReferenceConfigCache(name: " + name
+ ")";
}
public interface KeyGenerator {
String generateKey(ReferenceConfig<?> referenceConfig);
}
public static class ReferHelper {
public static final Logger logger = LoggerFactory.getLogger(ReferHelper.class);
/**
* The {@link Protocol} implementation with adaptive functionality,it will be different in different scenarios.
* A particular {@link Protocol} implementation is determined by the protocol attribute in the {@link URL}.
* For example:
*
* <li>when the url is registry://224.5.6.7:1234/org.apache.dubbo.registry.RegistryService?application=dubbo-sample,
* then the protocol is <b>RegistryProtocol</b></li>
*
* <li>when the url is dubbo://224.5.6.7:1234/org.apache.dubbo.config.api.DemoService?application=dubbo-sample, then
* the protocol is <b>DubboProtocol</b></li>
* <p>
* Actuallywhen the {@link ExtensionLoader} init the {@link Protocol} instants,it will automatically wraps two
* layers, and eventually will get a <b>ProtocolFilterWrapper</b> or <b>ProtocolListenerWrapper</b>
*/
private static final Protocol REF_PROTOCOL = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
/**
* The {@link Cluster}'s implementation with adaptive functionality, and actually it will get a {@link Cluster}'s
* specific implementation who is wrapped with <b>MockClusterInvoker</b>
*/
private static final Cluster CLUSTER = ExtensionLoader.getExtensionLoader(Cluster.class).getAdaptiveExtension();
/**
* A {@link ProxyFactory} implementation that will generate a reference service's proxy,the JavassistProxyFactory is
* its default implementation
*/
private static final ProxyFactory PROXY_FACTORY = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
public static <T> T refer(ReferenceConfig<T> rc) {
checkAndUpdateSubConfigs(rc);
Class<?> interfaceClass = rc.getInterfaceClass();
String interfaceName = rc.getInterface();
ServiceMetadata serviceMetadata = rc.getServiceMetadata();
//init serivceMetadata
serviceMetadata.setVersion(rc.getVersion());
serviceMetadata.setGroup(rc.getGroup());
serviceMetadata.setDefaultGroup(rc.getGroup());
serviceMetadata.setServiceType(rc.getActualInterface());
serviceMetadata.setServiceInterfaceName(interfaceName);
// TODO, uncomment this line once service key is unified
serviceMetadata.setServiceKey(URL.buildKey(interfaceName, rc.getGroup(), rc.getVersion()));
rc.checkStubAndLocal(interfaceClass);
BootstrapUtils.checkMock(interfaceClass, rc);
Map<String, String> map = new HashMap<String, String>();
map.put(SIDE_KEY, CONSUMER_SIDE);
ReferenceConfig.appendRuntimeParameters(map);
if (!ProtocolUtils.isGeneric(rc.getGeneric())) {
String revision = Version.getVersion(interfaceClass, rc.getVersion());
if (revision != null && revision.length() > 0) {
map.put(REVISION_KEY, revision);
}
String[] methods = Wrapper.getWrapper(interfaceClass).getMethodNames();
if (methods.length == 0) {
logger.warn("No method found in service interface " + interfaceClass.getName());
map.put(METHODS_KEY, ANY_VALUE);
} else {
map.put(METHODS_KEY, StringUtils.join(new HashSet<String>(Arrays.asList(methods)), COMMA_SEPARATOR));
}
}
map.put(INTERFACE_KEY, interfaceName);
AbstractConfig.appendParameters(map, rc.getMetrics());
AbstractConfig.appendParameters(map, rc.getApplication());
AbstractConfig.appendParameters(map, rc.getModule());
// remove 'default.' prefix for configs from ConsumerConfig
// appendParameters(map, consumer, Constants.DEFAULT_KEY);
AbstractConfig.appendParameters(map, rc.getConsumer());
AbstractConfig.appendParameters(map, rc);
Map<String, Object> attributes = null;
if (CollectionUtils.isNotEmpty(rc.getMethods())) {
attributes = new HashMap<>();
for (MethodConfig methodConfig : rc.getMethods()) {
AbstractConfig.appendParameters(map, methodConfig, methodConfig.getName());
String retryKey = methodConfig.getName() + ".retry";
if (map.containsKey(retryKey)) {
String retryValue = map.remove(retryKey);
if ("false".equals(retryValue)) {
map.put(methodConfig.getName() + ".retries", "0");
}
}
ConsumerModel.AsyncMethodInfo asyncMethodInfo = AbstractConfig.convertMethodConfig2AsyncInfo(methodConfig);
if (asyncMethodInfo != null) {
// consumerModel.getMethodModel(methodConfig.getName()).addAttribute(ASYNC_KEY, asyncMethodInfo);
attributes.put(methodConfig.getName(), asyncMethodInfo);
}
}
}
String hostToRegistry = ConfigUtils.getSystemProperty(DUBBO_IP_TO_REGISTRY);
if (StringUtils.isEmpty(hostToRegistry)) {
hostToRegistry = NetUtils.getLocalHost();
} else if (isInvalidLocalHost(hostToRegistry)) {
throw new IllegalArgumentException("Specified invalid registry ip from property:" + DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
}
map.put(REGISTER_IP_KEY, hostToRegistry);
serviceMetadata.getAttachments().putAll(map);
ServiceRepository repository = ApplicationModel.getServiceRepository();
ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
repository.registerConsumer(
serviceMetadata.getServiceKey(),
attributes,
serviceDescriptor,
rc,
null,
serviceMetadata);
T proxy = createProxy(map, rc);
serviceMetadata.setTarget(proxy);
serviceMetadata.addAttribute(PROXY_CLASS_REF, proxy);
repository.lookupReferredService(serviceMetadata.getServiceKey()).setProxyObject(proxy);
// dispatch a ReferenceConfigDestroyedEvent since 2.7.4
dispatch(new ReferenceConfigDestroyedEvent(rc));
return proxy;
}
@SuppressWarnings({"unchecked", "rawtypes", "deprecation"})
private static <T> T createProxy(Map<String, String> map, ReferenceConfig<?> rc) {
Class<?> interfaceClass = rc.getInterfaceClass();
String interfaceName = rc.getInterface();
Invoker<?> invoker;
if (shouldJvmRefer(map, rc)) {
URL url = new URL(LOCAL_PROTOCOL, LOCALHOST_VALUE, 0, interfaceClass.getName()).addParameters(map);
invoker = REF_PROTOCOL.refer(interfaceClass, url);
if (logger.isInfoEnabled()) {
logger.info("Using injvm service " + interfaceClass.getName());
}
} else {
List<URL> urls = new ArrayList<URL>();
if (rc.getUrl() != null && rc.getUrl().length() > 0) { // user specified URL, could be peer-to-peer address, or register center's address.
String[] us = SEMICOLON_SPLIT_PATTERN.split(rc.getUrl());
if (us != null && us.length > 0) {
for (String u : us) {
URL url = URL.valueOf(u);
if (StringUtils.isEmpty(url.getPath())) {
url = url.setPath(interfaceName);
}
if (UrlUtils.isRegistry(url)) {
urls.add(url.addParameterAndEncoded(REFER_KEY, StringUtils.toQueryString(map)));
} else {
urls.add(ClusterUtils.mergeUrl(url, map));
}
}
}
} else { // assemble URL from register center's configuration
// if protocols not injvm checkRegistry
if (!LOCAL_PROTOCOL.equalsIgnoreCase(rc.getProtocol())) {
rc.checkRegistry();
List<URL> us = BootstrapUtils.loadRegistries(rc, false);
if (CollectionUtils.isNotEmpty(us)) {
for (URL u : us) {
URL monitorUrl = BootstrapUtils.loadMonitor(rc, u);
if (monitorUrl != null) {
map.put(MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
}
urls.add(u.addParameterAndEncoded(REFER_KEY, StringUtils.toQueryString(map)));
}
}
if (urls.isEmpty()) {
throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config <dubbo:registry address=\"...\" /> to your spring config.");
}
}
}
if (urls.size() == 1) {
invoker = REF_PROTOCOL.refer(interfaceClass, urls.get(0));
} else {
List<Invoker<?>> invokers = new ArrayList<Invoker<?>>();
URL registryURL = null;
for (URL url : urls) {
invokers.add(REF_PROTOCOL.refer(interfaceClass, url));
if (UrlUtils.isRegistry(url)) {
registryURL = url; // use last registry url
}
}
if (registryURL != null) { // registry url is available
// for multi-subscription scenario, use 'zone-aware' policy by default
URL u = registryURL.addParameterIfAbsent(CLUSTER_KEY, ZoneAwareCluster.NAME);
// The invoker wrap relation would be like: ZoneAwareClusterInvoker(StaticDirectory) -> FailoverClusterInvoker(RegistryDirectory, routing happens here) -> Invoker
invoker = CLUSTER.join(new StaticDirectory(u, invokers));
} else { // not a registry url, must be direct invoke.
invoker = CLUSTER.join(new StaticDirectory(invokers));
}
}
rc.updateUrls(urls);
}
if (rc.shouldCheck() && !invoker.isAvailable()) {
throw new IllegalStateException("Failed to check the status of the service "
+ interfaceName
+ ". No provider available for the service "
+ (rc.getGroup() == null ? "" : rc.getGroup() + "/")
+ interfaceName +
(rc.getVersion() == null ? "" : ":" + rc.getVersion())
+ " from the url "
+ invoker.getUrl()
+ " to the consumer "
+ NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
}
if (logger.isInfoEnabled()) {
logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
}
/**
* @since 2.7.0
* ServiceData Store
*/
String metadata = map.get(METADATA_KEY);
WritableMetadataService metadataService = WritableMetadataService.getExtension(metadata == null ? DEFAULT_METADATA_STORAGE_TYPE : metadata);
if (metadataService != null) {
URL consumerURL = new URL(CONSUMER_PROTOCOL, map.remove(REGISTER_IP_KEY), 0, map.get(INTERFACE_KEY), map);
metadataService.publishServiceDefinition(consumerURL);
}
// create service proxy
return (T) PROXY_FACTORY.getProxy(invoker);
}
/**
* This method should be called right after the creation of this class's instance, before any property in other config modules is used.
* Check each config modules are created properly and override their properties if necessary.
*/
public static void checkAndUpdateSubConfigs(ReferenceConfig<?> rc) {
if (StringUtils.isEmpty(rc.getInterface())) {
throw new IllegalStateException("<dubbo:reference interface=\"\" /> interface not allow null!");
}
rc.completeCompoundConfigs();
// get consumer's global configuration
rc.checkDefault();
rc.refresh();
if (rc.getGeneric() == null && rc.getConsumer() != null) {
rc.setGeneric(rc.getConsumer().getGeneric());
}
Class<?> interfaceClass = null;
if (ProtocolUtils.isGeneric(rc.getGeneric())) {
interfaceClass = GenericService.class;
} else {
try {
interfaceClass = Class.forName(rc.getInterface(), true, Thread.currentThread()
.getContextClassLoader());
} catch (ClassNotFoundException e) {
throw new IllegalStateException(e.getMessage(), e);
}
rc.checkInterfaceAndMethods(interfaceClass, rc.getMethods());
}
rc.setInterface(interfaceClass);
rc.resolveFile();
rc.checkApplication();
rc.checkMetadataReport();
rc.appendParameters();
}
/**
* Figure out should refer the service in the same JVM from configurations. The default behavior is true
* 1. if injvm is specified, then use it
* 2. then if a url is specified, then assume it's a remote call
* 3. otherwise, check scope parameter
* 4. if scope is not specified but the target service is provided in the same JVM, then prefer to make the local
* call, which is the default behavior
*/
protected static boolean shouldJvmRefer(Map<String, String> map, ReferenceConfig<?> rc) {
URL tmpUrl = new URL("temp", "localhost", 0, map);
boolean isJvmRefer;
if (rc.isInjvm() == null) {
// if a url is specified, don't do local reference
if (rc.getUrl() != null && rc.getUrl().length() > 0) {
isJvmRefer = false;
} else {
// by default, reference local service if there is
isJvmRefer = InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl);
}
} else {
isJvmRefer = rc.isInjvm();
}
return isJvmRefer;
}
/**
* Dispatch an {@link Event event}
*
* @param event an {@link Event event}
* @since 2.7.4
*/
protected static void dispatch(Event event) {
EventDispatcher.getDefaultExtension().dispatch(event);
}
}
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractConfig;
@ -25,16 +25,18 @@ import java.util.Map;
/**
* AbstractBuilder
*
* @param <C> The type of {@link AbstractConfig Config}
* @param <B> The type of {@link AbstractBuilder Builder}
* @since 2.7
*/
public abstract class AbstractBuilder<T extends AbstractConfig, B extends AbstractBuilder> {
public abstract class AbstractBuilder<C extends AbstractConfig, B extends AbstractBuilder> {
/**
* The config id
*/
protected String id;
protected String prefix;
protected B id(String id) {
public B id(String id) {
this.id = id;
return getThis();
}
@ -62,7 +64,7 @@ public abstract class AbstractBuilder<T extends AbstractConfig, B extends Abstra
return parameters;
}
protected void build(T instance) {
protected void build(C instance) {
if (!StringUtils.isEmpty(id)) {
instance.setId(id);
}
@ -70,4 +72,11 @@ public abstract class AbstractBuilder<T extends AbstractConfig, B extends Abstra
instance.setPrefix(prefix);
}
}
/**
* Build an instance of {@link AbstractConfig config}
*
* @return an instance of {@link AbstractConfig config}
*/
public abstract C build();
}

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractInterfaceConfig;
@ -125,7 +125,7 @@ public abstract class AbstractInterfaceBuilder<T extends AbstractInterfaceConfig
/**
* @param local
* @see org.apache.dubbo.config.builders.AbstractInterfaceBuilder#stub(String)
* @see AbstractInterfaceBuilder#stub(String)
* @deprecated Replace to <code>stub(String)</code>
*/
@Deprecated
@ -136,7 +136,7 @@ public abstract class AbstractInterfaceBuilder<T extends AbstractInterfaceConfig
/**
* @param local
* @see org.apache.dubbo.config.builders.AbstractInterfaceBuilder#stub(Boolean)
* @see AbstractInterfaceBuilder#stub(Boolean)
* @deprecated Replace to <code>stub(Boolean)</code>
*/
@Deprecated

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractMethodConfig;
@ -27,7 +27,7 @@ import java.util.Map;
* @since 2.7
*/
public abstract class AbstractMethodBuilder<T extends AbstractMethodConfig, B extends AbstractMethodBuilder<T, B>>
extends AbstractBuilder<T, B>{
extends AbstractBuilder<T, B> {
/**
* The timeout for remote invocation in milliseconds
*/

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractReferenceConfig;
@ -92,7 +92,7 @@ public abstract class AbstractReferenceBuilder<T extends AbstractReferenceConfig
/**
* @param injvm
* @see org.apache.dubbo.config.builders.AbstractInterfaceBuilder#scope(String)
* @see AbstractInterfaceBuilder#scope(String)
* @deprecated instead, use the parameter <b>scope</b> to judge if it's in jvm, scope=local
*/
@Deprecated

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.AbstractServiceConfig;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ApplicationConfig;
@ -33,6 +33,7 @@ import static org.apache.dubbo.config.Constants.PRODUCTION_ENVIRONMENT;
*/
public class ApplicationBuilder extends AbstractBuilder<ApplicationConfig, ApplicationBuilder> {
private String name;
private String metadata;
private String version;
private String owner;
private String organization;
@ -51,11 +52,20 @@ public class ApplicationBuilder extends AbstractBuilder<ApplicationConfig, Appli
private Map<String, String> parameters;
private String shutwait;
public static ApplicationBuilder newBuilder() {
return new ApplicationBuilder();
}
public ApplicationBuilder name(String name) {
this.name = name;
return getThis();
}
public ApplicationBuilder metadata(String metadata) {
this.metadata = metadata;
return getThis();
}
public ApplicationBuilder version(String version) {
this.version = version;
return getThis();
@ -167,6 +177,7 @@ public class ApplicationBuilder extends AbstractBuilder<ApplicationConfig, Appli
super.build(config);
config.setName(name);
config.setMetadataType(metadata);
config.setVersion(this.version);
config.setOwner(this.owner);
config.setOrganization(this.organization);

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ArgumentConfig;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ConfigCenterConfig;
@ -38,7 +38,6 @@ public class ConfigCenterBuilder extends AbstractBuilder<ConfigCenterConfig, Con
private Boolean highestPriority = true;
private Boolean check = true;
private String appName;
private String configFile = "dubbo.properties";
private String appConfigFile;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ConsumerConfig;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.MetadataReportConfig;
@ -60,6 +60,10 @@ public class MetadataReportBuilder extends AbstractBuilder<MetadataReportConfig,
*/
private Boolean syncReport;
public static MetadataReportBuilder newBuilder() {
return new MetadataReportBuilder();
}
public MetadataReportBuilder address(String address) {
this.address = address;
return getThis();

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ArgumentConfig;
import org.apache.dubbo.config.MethodConfig;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ModuleConfig;
import org.apache.dubbo.config.MonitorConfig;

View File

@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
import java.util.Map;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.MonitorConfig;
import java.util.Map;
/**
* This is a builder for build {@link MonitorConfig}.
*

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ProtocolConfig;
@ -185,6 +185,14 @@ public class ProtocolBuilder extends AbstractBuilder<ProtocolConfig, ProtocolBui
*/
private Boolean isDefault;
public static ProtocolBuilder newBuilder() {
return new ProtocolBuilder();
}
public ProtocolBuilder id(String id) {
return super.id(id);
}
public ProtocolBuilder name(String name) {
this.name = name;
return getThis();
@ -206,9 +214,9 @@ public class ProtocolBuilder extends AbstractBuilder<ProtocolConfig, ProtocolBui
}
/**
* @see org.apache.dubbo.config.builders.ProtocolBuilder#contextpath(String)
* @param path
* @return ProtocolBuilder
* @see ProtocolBuilder#contextpath(String)
*/
@Deprecated
public ProtocolBuilder path(String path) {
@ -297,9 +305,9 @@ public class ProtocolBuilder extends AbstractBuilder<ProtocolConfig, ProtocolBui
}
/**
* @see org.apache.dubbo.config.builders.ProtocolBuilder#dispatcher(String)
* @param dispather
* @return ProtocolBuilder
* @see ProtocolBuilder#dispatcher(String)
*/
@Deprecated
public ProtocolBuilder dispather(String dispather) {

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ProviderConfig;

View File

@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.ConsumerConfig;
import org.apache.dubbo.config.MethodConfig;
@ -64,6 +64,14 @@ public class ReferenceBuilder<T> extends AbstractReferenceBuilder<ReferenceConfi
*/
private String protocol;
public static ReferenceBuilder newBuilder() {
return new ReferenceBuilder();
}
public ReferenceBuilder<T> id(String id) {
return super.id(id);
}
public ReferenceBuilder<T> interfaceName(String interfaceName) {
this.interfaceName = interfaceName;
return getThis();

View File

@ -14,12 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
import java.util.Map;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.RegistryConfig;
import java.util.Map;
/**
* This is a builder for build {@link RegistryConfig}.
*
@ -134,6 +134,40 @@ public class RegistryBuilder extends AbstractBuilder<RegistryConfig, RegistryBui
*/
private String extraKeys;
/**
* the address work as config center or not
*/
private Boolean useAsConfigCenter;
/**
* the address work as remote metadata center or not
*/
private Boolean useAsMetadataCenter;
/**
* list of rpc protocols accepted by this registry, for example, "dubbo,rest"
*/
private String accepts;
/**
* Always use this registry first if set to true, useful when subscribe to multiple registries
*/
private Boolean preferred;
/**
* Affects traffic distribution among registries, useful when subscribe to multiple registries
* Take effect only when no preferred registry is specified.
*/
private Integer weight;
public static RegistryBuilder newBuilder() {
return new RegistryBuilder();
}
public RegistryBuilder id(String id) {
return super.id(id);
}
public RegistryBuilder address(String address) {
this.address = address;
return getThis();
@ -217,7 +251,7 @@ public class RegistryBuilder extends AbstractBuilder<RegistryConfig, RegistryBui
/**
* @param wait
* @see org.apache.dubbo.config.builders.ProviderBuilder#wait(Integer)
* @see ProviderBuilder#wait(Integer)
* @deprecated
*/
@Deprecated
@ -271,6 +305,31 @@ public class RegistryBuilder extends AbstractBuilder<RegistryConfig, RegistryBui
return getThis();
}
public RegistryBuilder useAsConfigCenter(Boolean useAsConfigCenter) {
this.useAsConfigCenter = useAsConfigCenter;
return getThis();
}
public RegistryBuilder useAsMetadataCenter(Boolean useAsMetadataCenter) {
this.useAsMetadataCenter = useAsMetadataCenter;
return getThis();
}
public RegistryBuilder preferred(Boolean preferred) {
this.preferred = preferred;
return getThis();
}
public RegistryBuilder accepts(String accepts) {
this.accepts = accepts;
return getThis();
}
public RegistryBuilder weight(Integer weight) {
this.weight = weight;
return getThis();
}
public RegistryConfig build() {
RegistryConfig registry = new RegistryConfig();
super.build(registry);
@ -298,6 +357,11 @@ public class RegistryBuilder extends AbstractBuilder<RegistryConfig, RegistryBui
registry.setUsername(username);
registry.setVersion(version);
registry.setWait(wait);
registry.setUseAsConfigCenter(useAsConfigCenter);
registry.setUseAsMetadataCenter(useAsMetadataCenter);
registry.setAccepts(accepts);
registry.setPreferred(preferred);
registry.setWeight(weight);
return registry;
}

View File

@ -14,15 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.builders;
import java.util.ArrayList;
import java.util.List;
package org.apache.dubbo.bootstrap.builders;
import org.apache.dubbo.config.MethodConfig;
import org.apache.dubbo.config.ProviderConfig;
import org.apache.dubbo.config.ServiceConfig;
import java.util.ArrayList;
import java.util.List;
/**
* This is a builder for build {@link ServiceConfig}.
*
@ -68,6 +68,14 @@ public class ServiceBuilder<U> extends AbstractServiceBuilder<ServiceConfig, Ser
*/
private String generic;
public static ServiceBuilder newBuilder() {
return new ServiceBuilder();
}
public ServiceBuilder id(String id) {
return super.id(id);
}
public ServiceBuilder<U> interfaceName(String interfaceName) {
this.interfaceName = interfaceName;
return getThis();

View File

@ -0,0 +1,21 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* A bunch of builder classes to facilitate programming of raw API.
* TODO, these are experimental APIs and are possible to change at any time before marked as production.
*/
package org.apache.dubbo.bootstrap.builders;

View File

@ -17,8 +17,14 @@
package org.apache.dubbo.config;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.event.DubboServiceDestroyedEvent;
import org.apache.dubbo.config.event.DubboShutdownHookRegisteredEvent;
import org.apache.dubbo.config.event.DubboShutdownHookUnregisteredEvent;
import org.apache.dubbo.event.Event;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
import org.apache.dubbo.rpc.Protocol;
@ -35,14 +41,20 @@ public class DubboShutdownHook extends Thread {
private static final Logger logger = LoggerFactory.getLogger(DubboShutdownHook.class);
private static final DubboShutdownHook DUBBO_SHUTDOWN_HOOK = new DubboShutdownHook("DubboShutdownHook");
private final ShutdownHookCallbacks callbacks = ShutdownHookCallbacks.INSTANCE;
/**
* Has it already been registered or not?
*/
private final AtomicBoolean registered = new AtomicBoolean(false);
/**
* Has it already been destroyed or not?
*/
private final AtomicBoolean destroyed= new AtomicBoolean(false);
private final AtomicBoolean destroyed = new AtomicBoolean(false);
private final EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
private DubboShutdownHook(String name) {
super(name);
@ -57,15 +69,29 @@ public class DubboShutdownHook extends Thread {
if (logger.isInfoEnabled()) {
logger.info("Run shutdown hook now.");
}
callback();
doDestroy();
}
/**
* For testing purpose
*/
void clear() {
callbacks.clear();
}
private void callback() {
callbacks.callback();
}
/**
* Register the ShutdownHook
*/
public void register() {
if (!registered.get() && registered.compareAndSet(false, true)) {
Runtime.getRuntime().addShutdownHook(getDubboShutdownHook());
DubboShutdownHook dubboShutdownHook = getDubboShutdownHook();
Runtime.getRuntime().addShutdownHook(dubboShutdownHook);
dispatch(new DubboShutdownHookRegisteredEvent(dubboShutdownHook));
}
}
@ -74,7 +100,9 @@ public class DubboShutdownHook extends Thread {
*/
public void unregister() {
if (registered.get() && registered.compareAndSet(true, false)) {
Runtime.getRuntime().removeShutdownHook(getDubboShutdownHook());
DubboShutdownHook dubboShutdownHook = getDubboShutdownHook();
Runtime.getRuntime().removeShutdownHook(dubboShutdownHook);
dispatch(new DubboShutdownHookUnregisteredEvent(dubboShutdownHook));
}
}
@ -89,6 +117,12 @@ public class DubboShutdownHook extends Thread {
AbstractRegistryFactory.destroyAll();
// destroy all the protocols
destroyProtocols();
// dispatch the DubboDestroyedEvent @since 2.7.4
dispatch(new DubboServiceDestroyedEvent(this));
}
private void dispatch(Event event) {
eventDispatcher.dispatch(event);
}
/**

View File

@ -14,22 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.consumer;
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.api.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.dubbo.event.Event;
/**
* DemoAction
* An {@link Event Dubbo event} when the Dubbo service is about to be destroyed.
*
* @see Event
* @since 2.7.4
*/
public class DemoActionByAnnotation {
public class DubboServiceDestroyedEvent extends Event {
@Autowired
private DemoService demoService;
public DemoService getDemoService() {
return demoService;
public DubboServiceDestroyedEvent(Object source) {
super(source);
}
}
}

View File

@ -0,0 +1,46 @@
/*
* 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.event;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.event.Event;
/**
* An event raised when the {@link DubboShutdownHook} {@link Runtime#addShutdownHook(Thread) registered} on
* {@link ApplicationShutdownHooks JVM ShutdownHooks}
*
* @see DubboShutdownHook
* @see ApplicationShutdownHooks
* @since 2.7.4
*/
public class DubboShutdownHookRegisteredEvent extends Event {
/**
* Constructs a prototypical Event.
*
* @param dubboShutdownHook The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public DubboShutdownHookRegisteredEvent(DubboShutdownHook dubboShutdownHook) {
super(dubboShutdownHook);
}
public DubboShutdownHook getDubboShutdownHook() {
return (DubboShutdownHook) getSource();
}
}

View File

@ -0,0 +1,45 @@
/*
* 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.event;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.event.Event;
/**
* An event raised when the {@link DubboShutdownHook} {@link Runtime#removeShutdownHook(Thread) unregistered} on
* {@link ApplicationShutdownHooks JVM ShutdownHooks}
*
* @see DubboShutdownHook
* @see ApplicationShutdownHooks
* @since 2.7.4
*/
public class DubboShutdownHookUnregisteredEvent extends Event {
/**
* Constructs a prototypical Event.
*
* @param dubboShutdownHook The object on which the Event initially occurred.
* @throws IllegalArgumentException if source is null.
*/
public DubboShutdownHookUnregisteredEvent(DubboShutdownHook dubboShutdownHook) {
super(dubboShutdownHook);
}
public DubboShutdownHook getDubboShutdownHook() {
return (DubboShutdownHook) getSource();
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.event;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.event.Event;
/**
* The {@link ReferenceConfig Dubbo service ReferenceConfig} destroyed {@link Event event}
*
* @see Reference
* @see ReferenceConfig#destroy()
* @see Event
* @since 2.7.4
*/
public class ReferenceConfigDestroyedEvent extends Event {
public ReferenceConfigDestroyedEvent(ReferenceConfig referenceConfig) {
super(referenceConfig);
}
public ReferenceConfig getReferenceConfig() {
return (ReferenceConfig) getSource();
}
}

View File

@ -14,40 +14,35 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.utils;
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.event.Event;
import org.apache.dubbo.rpc.Invoker;
import java.util.concurrent.atomic.AtomicLong;
/**
* The {@link ReferenceConfig Dubbo service ReferenceConfig} initialized {@link Event event}
*
* @see Reference
* @see ReferenceConfig#get()
* @see Event
* @since 2.7.4
*/
public class ReferenceConfigInitializedEvent extends Event {
public class MockReferenceConfig extends ReferenceConfig<String> {
static AtomicLong counter = new AtomicLong();
private final Invoker<?> invoker;
String value;
boolean destroyMethodRun = false;
public static void setCounter(long c) {
counter.set(c);
public ReferenceConfigInitializedEvent(ReferenceConfig referenceConfig, Invoker<?> invoker) {
super(referenceConfig);
this.invoker = invoker;
}
public boolean isGetMethodRun() {
return value != null;
public ReferenceConfig getReferenceConfig() {
return (ReferenceConfig) getSource();
}
public boolean isDestroyMethodRun() {
return destroyMethodRun;
}
@Override
public synchronized String get() {
if (value != null) return value;
value = "" + counter.getAndIncrement();
return value;
}
@Override
public synchronized void destroy() {
destroyMethodRun = true;
public Invoker<?> getInvoker() {
return invoker;
}
}

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.event;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.event.Event;
/**
* {@link ServiceConfig} event post-{@link ServiceConfig#export() export}
*
* @since 2.7.4
*/
public class ServiceConfigExportedEvent extends Event {
public ServiceConfigExportedEvent(ServiceConfig source) {
super(source);
}
public ServiceConfig getServiceConfig() {
return (ServiceConfig) getSource();
}
}

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.event;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.event.Event;
/**
* {@link ServiceConfig} event post-{@link ServiceConfig#unexport() unexport}
*
* @since 2.7.4
*/
public class ServiceConfigUnexportedEvent extends Event {
public ServiceConfigUnexportedEvent(ServiceConfig source) {
super(source);
}
public ServiceConfig getServiceConfig() {
return (ServiceConfig) getSource();
}
}

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.config.event.listener;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.event.DubboServiceDestroyedEvent;
import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
import org.apache.dubbo.event.Event;
import org.apache.dubbo.event.GenericEventListener;
import static java.lang.String.format;
/**
* A listener for logging the {@link Event Dubbo event}
*
* @see ServiceConfigExportedEvent
* @since 2.7.4
*/
public class LoggingEventListener extends GenericEventListener {
private static final String NAME = "Dubbo Service";
private final Logger logger = LoggerFactory.getLogger(getClass());
public void onEvent(DubboServiceDestroyedEvent event) {
if (logger.isInfoEnabled()) {
logger.info(NAME + " has been destroyed.");
}
}
private void debug(String pattern, Object... args) {
if (logger.isDebugEnabled()) {
logger.debug(format(pattern, args));
}
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.event.listener;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.event.ServiceConfigExportedEvent;
import org.apache.dubbo.event.EventListener;
import org.apache.dubbo.metadata.ServiceNameMapping;
import java.util.List;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.metadata.ServiceNameMapping.getDefaultExtension;
/**
* An {@link EventListener event listener} for mapping {@link ServiceConfig#getExportedUrls() the exported Dubbo
* service inerface} to its service name
*
* @see ServiceNameMapping
* @see ServiceConfig#getExportedUrls()
* @since 2.7.4
*/
public class ServiceNameMappingListener implements EventListener<ServiceConfigExportedEvent> {
private final ServiceNameMapping serviceNameMapping = getDefaultExtension();
@Override
public void onEvent(ServiceConfigExportedEvent event) {
ServiceConfig serviceConfig = event.getServiceConfig();
List<URL> exportedURLs = serviceConfig.getExportedUrls();
exportedURLs.forEach(url -> {
String serviceInterface = url.getServiceInterface();
String group = url.getParameter(GROUP_KEY);
String version = url.getParameter(VERSION_KEY);
String protocol = url.getProtocol();
serviceNameMapping.map(serviceInterface, group, version, protocol);
});
}
}

View File

@ -0,0 +1,137 @@
/*
* 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.metadata;
import org.apache.dubbo.bootstrap.DubboBootstrap;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.MetadataServiceExporter;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.ArrayList;
import java.util.List;
import static java.util.Collections.emptyList;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
/**
* {@link MetadataServiceExporter} implementation based on {@link ConfigManager Dubbo configurations}, the clients
* should make sure the {@link ApplicationConfig}, {@link RegistryConfig} and {@link ProtocolConfig} are ready before
* {@link #export()}.
* <p>
* Typically, do not worry about their ready status, because they are initialized before
* any {@link ServiceConfig} exports, or The Dubbo export will be failed.
* <p>
* Being aware of it's not a thread-safe implementation.
*
* @see MetadataServiceExporter
* @see ServiceConfig
* @see ConfigManager
* @since 2.7.4
*/
public class ConfigurableMetadataServiceExporter implements MetadataServiceExporter {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final MetadataService metadataService;
private volatile ServiceConfig<MetadataService> serviceConfig;
private volatile boolean exported;
private volatile List<Exporter<?>> exporters;
public ConfigurableMetadataServiceExporter(MetadataService metadataService) {
this.metadataService = metadataService;
}
@Override
public ConfigurableMetadataServiceExporter export() {
if (!isExported()) {
ServiceConfig<MetadataService> serviceConfig = new ServiceConfig<>();
serviceConfig.setApplication(getApplicationConfig());
serviceConfig.setRegistries(getRegistries());
serviceConfig.setProtocol(generateMetadataProtocol());
serviceConfig.setInterface(MetadataService.class);
serviceConfig.setRef(metadataService);
serviceConfig.setGroup(getApplicationConfig().getName());
serviceConfig.setVersion(metadataService.version());
// export
exporters = DubboBootstrap.Helper.exportSync(serviceConfig);
exported = true;
if (logger.isInfoEnabled()) {
logger.info("The MetadataService exports urls : " + serviceConfig.getExportedUrls());
}
this.serviceConfig = serviceConfig;
} else {
if (logger.isWarnEnabled()) {
logger.warn("The MetadataService has been exported : " + serviceConfig.getExportedUrls());
}
}
return this;
}
@Override
public ConfigurableMetadataServiceExporter unexport() {
if (isExported()) {
exporters.get(0).unexport();
exported = false;
}
return this;
}
@Override
public List<URL> getExportedURLs() {
return serviceConfig != null ? serviceConfig.getExportedUrls() : emptyList();
}
public boolean isExported() {
return serviceConfig != null && exported;
}
private ApplicationConfig getApplicationConfig() {
return ApplicationModel.getConfigManager().getApplication().get();
}
private List<RegistryConfig> getRegistries() {
return new ArrayList<>(ApplicationModel.getConfigManager().getRegistries());
}
private ProtocolConfig generateMetadataProtocol() {
ProtocolConfig defaultProtocol = new ProtocolConfig();
defaultProtocol.setName(DUBBO);
// defaultProtocol.setHost() ?
// auto-increment port
defaultProtocol.setPort(-1);
return defaultProtocol;
}
}

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.config.metadata;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collection;
import java.util.stream.Stream;
/**
* The {@link ServiceInstanceCustomizer} to customize the {@link ServiceInstance#getPort() port} of service instance.
*
* @since 2.7.4
*/
public class ServiceInstancePortCustomizer implements ServiceInstanceCustomizer {
@Override
public void customize(ServiceInstance serviceInstance) {
if (serviceInstance.getPort() != null) {
return;
}
Collection<ProtocolConfig> protocols = ApplicationModel.getConfigManager()
.getProtocols();
if (CollectionUtils.isEmpty(protocols)) {
throw new IllegalStateException("We should have at least one protocol configured at this point.");
}
Stream<ProtocolConfig> protocolStream = protocols.stream();
ProtocolConfig protocolConfig = protocolStream
// use rest as service instance's default protocol.
.filter(protocol -> "rest".equals(protocol.getName()))
.findFirst()
.orElseGet(() -> protocolStream.findFirst().get());
if (serviceInstance instanceof DefaultServiceInstance) {
DefaultServiceInstance instance = (DefaultServiceInstance) serviceInstance;
if (protocolConfig.getPort() != null) {
instance.setPort(protocolConfig.getPort());
}
}
}
}

View File

@ -0,0 +1,2 @@
service-mapping=org.apache.dubbo.config.event.listener.ServiceNameMappingListener
config-logging=org.apache.dubbo.config.event.listener.LoggingEventListener

View File

@ -0,0 +1 @@
port=org.apache.dubbo.config.metadata.ServiceInstancePortCustomizer

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.bootstrap;
import org.junit.jupiter.api.Test;
import java.io.IOException;
/**
* {@link DubboBootstrap} Test
*
* @since 2.7.4
*/
public class DubboBootstrapTest {
@Test
public void test() throws IOException {
}
}

View File

@ -0,0 +1,58 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.config.MetadataReportConfig;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class DubboServiceConsumerBootstrap {
public static void main(String[] args) throws Exception {
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
.application("dubbo-consumer-demo")
.protocol(builder -> builder.port(20887).name("dubbo"))
// Eureka
// .registry(builder -> builder.address("eureka://127.0.0.1:8761?registry-type=service&subscribed-services=dubbo-provider-demo"))
// Zookeeper
.registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service&subscribed-services=dubbo-provider-demo"))
.metadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181"))
// Nacos
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service&subscribed.services=dubbo-provider-demo"))
// Consul
// .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1"))
.reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start();
EchoService echoService = bootstrap.getCache().get(EchoService.class).get(0);
for (int i = 0; i < 500; i++) {
Thread.sleep(2000L);
System.out.println(echoService.echo("Hello,World"));
}
}
}

View File

@ -0,0 +1,95 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.bootstrap.rest.UserServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import java.util.Arrays;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class DubboServiceProviderBootstrap {
public static void main(String[] args) {
multipleRegistries();
}
private static void multipleRegistries() {
ProtocolConfig restProtocol = new ProtocolConfig();
restProtocol.setName("rest");
restProtocol.setId("rest");
restProtocol.setPort(-1);
RegistryConfig interfaceRegistry = new RegistryConfig();
interfaceRegistry.setId("interfaceRegistry");
interfaceRegistry.setAddress("zookeeper://127.0.0.1:2181");
RegistryConfig serviceRegistry = new RegistryConfig();
serviceRegistry.setId("serviceRegistry");
serviceRegistry.setAddress("zookeeper://127.0.0.1:2181?registry-type=service");
ServiceConfig<EchoService> echoService = new ServiceConfig<>();
echoService.setInterface(EchoService.class.getName());
echoService.setRef(new EchoServiceImpl());
// echoService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
ServiceConfig<UserService> userService = new ServiceConfig<>();
userService.setInterface(UserService.class.getName());
userService.setRef(new UserServiceImpl());
userService.setProtocol(restProtocol);
// userService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-provider-demo");
applicationConfig.setMetadataType("remote");
DubboBootstrap.getInstance()
.application(applicationConfig)
// Zookeeper in service registry type
// .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry.type=service"))
// Nacos
// .registry("zookeeper", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service"))
.registries(Arrays.asList(interfaceRegistry, serviceRegistry))
// .registry(RegistryBuilder.newBuilder().address("consul://127.0.0.1:8500?registry.type=service").build())
.protocol(builder -> builder.port(-1).name("dubbo"))
.metadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181"))
.service(echoService)
.service(userService)
.start()
.await();
}
private static void testSCCallDubbo() {
}
private static void testDubboCallSC() {
}
private static void testDubboTansormation() {
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.bootstrap.rest.UserServiceImpl;
/**
* TODO
*/
public class DubboServiceProviderMinimumBootstrap {
public static void main(String[] args) {
DubboBootstrap.getInstance()
.application("dubbo-provider-demo")
.registry(builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service"))
// .registry(builder -> builder.address("eureka://127.0.0.1:8761?registry-type=service"))
.protocol(builder -> builder.port(-1).name("dubbo"))
.service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()))
.service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()))
.start()
.await();
}
}

View File

@ -0,0 +1,31 @@
/*
* 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.bootstrap;
/**
* Echo Service
*
* @since 2.7.4
*/
public interface EchoService {
String GROUP = "DEFAULT";
String VERSION = "1.0.0";
String echo(String message);
}

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.bootstrap;
import org.apache.dubbo.rpc.RpcContext;
import static java.lang.String.format;
/**
* The implementation of {@link EchoService}
*
* @see EchoService
* @since 2.7.4
*/
public class EchoServiceImpl implements EchoService {
@Override
public String echo(String message) {
RpcContext rpcContext = RpcContext.getContext();
return format("[%s:%s] ECHO - %s", rpcContext.getLocalHost(), rpcContext.getLocalPort(), message);
}
}

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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.config.MetadataReportConfig;
import java.util.List;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class EtcdDubboServiceConsumerBootstrap {
public static void main(String[] args) throws Exception {
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
.application("dubbo-consumer-demo")
// Zookeeper
.protocol(builder -> builder.port(20887).name("dubbo"))
.registry("etcd3", builder -> builder.address("etcd3://127.0.0.1:2379?registry-type=service&subscribed-services=dubbo-provider-demo"))
.metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
// Nacos
// .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1"))
.reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start();
List<EchoService> echoServices = bootstrap.getCache().get(EchoService.class);
for (int i = 0; i < 500; i++) {
Thread.sleep(2000L);
System.out.println(echoServices.get(0).echo("Hello,World"));
}
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.bootstrap.rest.UserServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import java.util.Arrays;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class EtcdDubboServiceProviderBootstrap {
public static void main(String[] args) {
multipleRegistries();
}
private static void multipleRegistries() {
ProtocolConfig restProtocol = new ProtocolConfig();
restProtocol.setName("rest");
restProtocol.setId("rest");
restProtocol.setPort(-1);
RegistryConfig interfaceRegistry = new RegistryConfig();
interfaceRegistry.setId("interfaceRegistry");
interfaceRegistry.setAddress("etcd3://127.0.0.1:2379");
RegistryConfig serviceRegistry = new RegistryConfig();
serviceRegistry.setId("serviceRegistry");
serviceRegistry.setAddress("etcd3://127.0.0.1:2379?registry-type=service");
ServiceConfig<EchoService> echoService = new ServiceConfig<>();
echoService.setInterface(EchoService.class.getName());
echoService.setRef(new EchoServiceImpl());
// echoService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
ServiceConfig<UserService> userService = new ServiceConfig<>();
userService.setInterface(UserService.class.getName());
userService.setRef(new UserServiceImpl());
userService.setProtocol(restProtocol);
// userService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-provider-demo");
// applicationConfig.setMetadataType("remote");
DubboBootstrap.getInstance()
.application(applicationConfig)
// Zookeeper in service registry type
// .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry.type=service"))
// Nacos
// .registry("zookeeper", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service"))
.registries(Arrays.asList(interfaceRegistry, serviceRegistry))
// .registry(RegistryBuilder.newBuilder().address("consul://127.0.0.1:8500?registry.type=service").build())
.protocol(builder -> builder.port(-1).name("dubbo"))
// .metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
.service(echoService)
.service(userService)
.start()
.await();
}
private static void testSCCallDubbo() {
}
private static void testDubboCallSC() {
}
private static void testDubboTansormation() {
}
}

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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.MetadataReportConfig;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class NacosDubboServiceConsumerBootstrap {
public static void main(String[] args) throws Exception {
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-nacos-consumer-demo");
// applicationConfig.setMetadataType("remote");
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
.application(applicationConfig)
// Zookeeper
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service&subscribed.services=dubbo-nacos-provider-demo"))
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo"))
.registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=service-provider"))
.metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start();
UserService userService = bootstrap.getCache().get(UserService.class).get(0);
for (int i = 0; i < 500; i++) {
Thread.sleep(2000L);
System.out.println(userService.getUser(i * 1L));
}
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.bootstrap.rest.UserServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.MetadataReportConfig;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class NacosDubboServiceProviderBootstrap {
public static void main(String[] args) {
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-nacos-provider-demo");
// applicationConfig.setMetadataType("remote");
DubboBootstrap.getInstance()
.application(applicationConfig)
// Zookeeper in service registry type
.registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service"))
// Nacos
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service"))
// .registry(RegistryBuilder.newBuilder().address("etcd3://127.0.0.1:2379?registry.type=service").build())
.metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
.protocol("dubbo", builder -> builder.port(20885).name("dubbo"))
.protocol("rest", builder -> builder.port(9090).name("rest"))
.service(builder -> builder.id("echo").interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
.service(builder -> builder.id("user").interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
.start()
.await();
}
}

View File

@ -0,0 +1,49 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class ZookeeperDubboServiceConsumerBootstrap {
public static void main(String[] args) throws Exception {
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
.application("zookeeper-dubbo-consumer")
.registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service&subscribed-services=zookeeper-dubbo-provider"))
.reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start()
.await();
EchoService echoService = bootstrap.getCache().get(EchoService.class).get(0);
UserService userService = bootstrap.getCache().get(UserService.class).get(0);
for (int i = 0; i < 500; i++) {
Thread.sleep(2000L);
System.out.println(echoService.echo("Hello,World"));
System.out.println(userService.getUser(i * 1L));
}
}
}

View File

@ -0,0 +1,38 @@
/*
* 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.bootstrap;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.bootstrap.rest.UserServiceImpl;
/**
* TODO
*/
public class ZookeeperDubboServiceProviderBootstrap {
public static void main(String[] args) {
DubboBootstrap.getInstance()
.application("zookeeper-dubbo-provider")
.registry(builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service"))
.protocol("dubbo", builder -> builder.port(-1).name("dubbo"))
.protocol("rest", builder -> builder.port(8081).name("rest"))
.service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
.service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
.start()
.await();
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.bootstrap.compatible;
import org.apache.dubbo.bootstrap.DubboBootstrap;
import org.apache.dubbo.bootstrap.EchoService;
import org.apache.dubbo.bootstrap.rest.UserService;
import org.apache.dubbo.config.RegistryConfig;
/**
* Dubbo Provider Bootstrap
*
* @since 2.7.4
*/
public class DubboInterfaceConsumerBootstrap {
public static void main(String[] args) throws Exception {
RegistryConfig interfaceRegistry = new RegistryConfig();
interfaceRegistry.setId("interfaceRegistry");
interfaceRegistry.setAddress("zookeeper://127.0.0.1:2181");
DubboBootstrap bootstrap = DubboBootstrap.getInstance()
.application("dubbo-consumer-demo")
// Zookeeper
.registry(interfaceRegistry)
// Nacos
// .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo"))
.reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))
.start()
.await();
EchoService echoService = bootstrap.getCache().get(EchoService.class).get(0);
UserService userService = bootstrap.getCache().get(UserService.class).get(0);
for (int i = 0; i < 500; i++) {
Thread.sleep(2000L);
System.out.println(echoService.echo("Hello,World"));
System.out.println(userService.getUser(1L));
}
}
}

View File

@ -0,0 +1,77 @@
/*
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.dubbo.bootstrap.rest;
import org.codehaus.jackson.annotate.JsonProperty;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class User implements Serializable {
@NotNull
@Min(1L)
private Long id;
@JsonProperty("username")
@XmlElement(name = "username")
@NotNull
@Size(min = 6, max = 50)
private String name;
public User() {
}
public User(Long id, String name) {
this.id = id;
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User (" +
"id=" + id +
", name='" + name + '\'' +
')';
}
}

View File

@ -0,0 +1,45 @@
/*
*
* 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.bootstrap.rest;
import org.apache.dubbo.rpc.protocol.rest.support.ContentType;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("users")
@Consumes({MediaType.APPLICATION_JSON, MediaType.TEXT_XML})
@Produces({ContentType.APPLICATION_JSON_UTF_8, ContentType.TEXT_XML_UTF_8})
@Api(value = "UserService")
public interface UserService {
@GET
@Path("{id : \\d+}")
@ApiOperation(value = "getUser")
User getUser(@ApiParam(value = "id") @PathParam("id") Long id);
}

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.bootstrap.rest;
import java.util.concurrent.atomic.AtomicLong;
public class UserServiceImpl implements UserService {
private final AtomicLong idGen = new AtomicLong();
@Override
public User getUser(Long id) {
return new User(id, "username" + id);
}
}

View File

@ -0,0 +1,7 @@
###set log levels###
log4j.rootLogger=info, stdout
###output to the console###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%d{dd/MM/yy HH:mm:ss:SSS z}] %t %5p %c{2}: %m%n

View File

@ -18,10 +18,11 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config</artifactId>
<artifactId>dubbo-bootstrap</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-config-spring</artifactId>
<artifactId>dubbo-bootstrap-spring</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The spring config module of dubbo project</description>
@ -31,7 +32,12 @@
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-config-api</artifactId>
<artifactId>dubbo-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bootstrap-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
@ -57,6 +63,12 @@
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-monitor-default</artifactId>
@ -128,6 +140,5 @@
<artifactId>tomcat-embed-core</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -33,10 +33,9 @@ import java.util.HashMap;
import java.util.Map;
/**
* Since 2.7.0+, export and refer will only be executed when Spring is fully initialized, and each Config bean will get refreshed on the start of the export and refer process.
* Start from 2.7.0+, export and refer will only be executed when Spring is fully initialized, and each Config bean will get refreshed on the start of the export and refer process.
* So it's ok for this bean not to be the first Dubbo Config bean being initialized.
* <p>
* If use ConfigCenterConfig directly, you should make sure ConfigCenterConfig.init() is called before actually export/refer any Dubbo service.
*/
public class ConfigCenterBean extends ConfigCenterConfig implements ApplicationContextAware, DisposableBean, EnvironmentAware {
@ -59,12 +58,9 @@ public class ConfigCenterBean extends ConfigCenterConfig implements ApplicationC
public void setEnvironment(Environment environment) {
if (includeSpringEnv) {
// Get PropertySource mapped to 'dubbo.properties' in Spring Environment.
Map<String, String> externalProperties = getConfigurations(getConfigFile(), environment);
setExternalConfig(getConfigurations(getConfigFile(), environment));
// Get PropertySource mapped to 'application.dubbo.properties' in Spring Environment.
Map<String, String> appExternalProperties = getConfigurations(StringUtils.isNotEmpty(getAppConfigFile()) ? getAppConfigFile() : ("application." + getConfigFile()), environment);
// Refresh Dubbo Environment
org.apache.dubbo.common.config.Environment.getInstance().setExternalConfigMap(externalProperties);
org.apache.dubbo.common.config.Environment.getInstance().setAppExternalConfigMap(appExternalProperties);
setAppExternalConfig(getConfigurations(StringUtils.isNotEmpty(getAppConfigFile()) ? getAppConfigFile() : ("application." + getConfigFile()), environment));
}
}

View File

@ -0,0 +1,89 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.spring;
import org.apache.dubbo.bootstrap.ReferenceConfigCache;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.apache.dubbo.config.support.Parameter;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* ReferenceFactoryBean
*/
public class ReferenceBean<T> extends ReferenceConfig<T> implements FactoryBean, ApplicationContextAware, InitializingBean, DisposableBean {
private static final long serialVersionUID = 213195494150089726L;
private transient ApplicationContext applicationContext;
public ReferenceBean() {
super();
}
public ReferenceBean(Reference reference) {
super(reference);
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
SpringExtensionFactory.addApplicationContext(applicationContext);
}
@Override
public Object getObject() {
// FIXME, When using spring, is it possible for user to specify a different ReferenceConfigCache instance?
return ReferenceConfigCache.getCache().get(this);
}
@Override
public Class<?> getObjectType() {
return getInterfaceClass();
}
@Override
@Parameter(excluded = true)
public boolean isSingleton() {
return true;
}
@Override
@SuppressWarnings({"unchecked"})
public void afterPropertiesSet() throws Exception {
if (applicationContext != null) {
BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ConfigCenterBean.class, false, false);
}
// eager init if necessary.
if (shouldInit()) {
getObject();
}
}
@Override
public void destroy() {
// do nothing
}
}

View File

@ -0,0 +1,146 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.spring;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.spring.context.event.ServiceBeanExportedEvent;
import org.apache.dubbo.config.spring.extension.SpringExtensionFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
/**
* ServiceFactoryBean
*
* @export
*/
public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean,
ApplicationContextAware, BeanNameAware,
ApplicationEventPublisherAware {
private static final long serialVersionUID = 213195494150089726L;
private final transient Service service;
private transient ApplicationContext applicationContext;
private transient String beanName;
private ApplicationEventPublisher applicationEventPublisher;
public ServiceBean() {
super();
this.service = null;
}
public ServiceBean(Service service) {
super(service);
this.service = service;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
SpringExtensionFactory.addApplicationContext(applicationContext);
}
@Override
public void setBeanName(String name) {
this.beanName = name;
}
/**
* Gets associated {@link Service}
*
* @return associated {@link Service}
*/
public Service getService() {
return service;
}
@Override
public void afterPropertiesSet() throws Exception {
if (StringUtils.isEmpty(getPath())) {
if (StringUtils.isNotEmpty(beanName)
&& StringUtils.isNotEmpty(getInterface())
&& beanName.startsWith(getInterface())) {
setPath(beanName);
}
}
}
/**
* Get the name of {@link ServiceBean}
*
* @return {@link ServiceBean}'s name
* @since 2.6.5
*/
public String getBeanName() {
return this.beanName;
}
/**
* @since 2.6.5
*/
@Override
public void exported() {
super.exported();
// Publish ServiceBeanExportedEvent
publishExportEvent();
}
/**
* @since 2.6.5
*/
private void publishExportEvent() {
ServiceBeanExportedEvent exportEvent = new ServiceBeanExportedEvent(this);
applicationEventPublisher.publishEvent(exportEvent);
}
@Override
public void destroy() throws Exception {
// no need to call unexport() here, see
// org.apache.dubbo.config.spring.extension.SpringExtensionFactory.ShutdownHookListener
}
// merged from dubbox
@Override
protected Class getServiceClass(T ref) {
if (AopUtils.isAopProxy(ref)) {
return AopUtils.getTargetClass(ref);
}
return super.getServiceClass(ref);
}
/**
* @param applicationEventPublisher
* @since 2.6.5
*/
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
this.applicationEventPublisher = applicationEventPublisher;
}
}

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