You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2018/10/30 10:16:09 UTC
[incubator-dubbo] 03/07: Merge branch 'master' into
dev-metadata-config-mergemaster
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch dev-metadata
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git
commit 9af1f1a971a776ba6c4cad6fb09d6d7caf5d4f95
Merge: e125951 36a1155
Author: ken.lj <ke...@gmail.com>
AuthorDate: Tue Oct 30 14:36:32 2018 +0800
Merge branch 'master' into dev-metadata-config-mergemaster
# Conflicts:
# dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
# dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/StaticDirectory.java
# dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
# dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/tag/TagRouterTest.java
# dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
# dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
# dubbo-dependencies-bom/pom.xml
# dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/integration/RegistryDirectory.java
.../ISSUE_TEMPLATE/dubbo-issue-report-template.md | 4 +-
.travis.yml | 5 +-
FAQ.md | 6 +-
NOTICE | 11 +-
README.md | 21 +-
dubbo-all/pom.xml | 49 +-
dubbo-bom/pom.xml | 5 +
.../rpc/cluster/directory/AbstractDirectory.java | 1 +
.../cluster/loadbalance/AbstractLoadBalance.java | 6 +-
.../loadbalance/LeastActiveLoadBalance.java | 31 +-
.../rpc/cluster/loadbalance/RandomLoadBalance.java | 8 +-
.../cluster/loadbalance/RoundRobinLoadBalance.java | 164 ++-
.../cluster/router/condition/ConditionRouter.java | 9 +-
.../cluster/router/mock/MockInvokersSelector.java | 4 +-
.../cluster/support/AbstractClusterInvoker.java | 12 +-
.../dubbo/rpc/cluster/support/ClusterUtils.java | 14 +-
.../org/apache/dubbo/rpc/cluster/StickyTest.java | 4 +-
.../loadbalance/LeastActiveBalanceTest.java | 28 +-
.../cluster/loadbalance/LoadBalanceBaseTest.java | 131 ++-
.../cluster/loadbalance/RandomLoadBalanceTest.java | 32 +-
.../loadbalance/RoundRobinLoadBalanceTest.java | 133 ++-
.../support/AbstractClusterInvokerTest.java | 18 +-
.../java/org/apache/dubbo/common/Constants.java | 2 +
.../src/main/java/org/apache/dubbo/common/URL.java | 116 +-
.../common/beanutil/JavaBeanSerializeUtil.java | 18 +-
.../dubbo/common/bytecode/ClassGenerator.java | 722 ++++++------
.../org/apache/dubbo/common/bytecode/Mixin.java | 41 +-
.../org/apache/dubbo/common/bytecode/Proxy.java | 62 +-
.../org/apache/dubbo/common/bytecode/Wrapper.java | 90 +-
.../dubbo/common/compiler/support/JdkCompiler.java | 6 +-
.../dubbo/common/extension/ExtensionLoader.java | 72 +-
.../java/org/apache/dubbo/common/io/Bytes.java | 123 +-
.../org/apache/dubbo/common/io/StreamUtils.java | 29 +-
.../common/io/UnsafeByteArrayInputStream.java | 21 +-
.../common/io/UnsafeByteArrayOutputStream.java | 15 +-
.../apache/dubbo/common/io/UnsafeStringReader.java | 21 +-
.../apache/dubbo/common/io/UnsafeStringWriter.java | 14 +-
.../dubbo/common/json/GenericJSONConverter.java | 108 +-
.../org/apache/dubbo/common/json/J2oVisitor.java | 77 +-
.../java/org/apache/dubbo/common/json/JSON.java | 28 +-
.../org/apache/dubbo/common/json/JSONArray.java | 8 +-
.../org/apache/dubbo/common/json/JSONObject.java | 11 +-
.../org/apache/dubbo/common/json/JSONReader.java | 6 +-
.../org/apache/dubbo/common/json/JSONWriter.java | 15 +-
.../java/org/apache/dubbo/common/json/Yylex.java | 30 +-
.../dubbo/common/logger/jdk/JdkLoggerAdapter.java | 36 +-
.../common/logger/log4j/Log4jLoggerAdapter.java | 36 +-
.../common/status/support/LoadStatusChecker.java | 5 +
.../common/store/support/SimpleDataStore.java | 4 +-
.../dubbo/common/utils/AtomicPositiveInteger.java | 8 +-
.../org/apache/dubbo/common/utils/ClassHelper.java | 16 +-
.../apache/dubbo/common/utils/CollectionUtils.java | 4 +-
.../dubbo/common/utils/CompatibleTypeUtils.java | 13 +-
.../org/apache/dubbo/common/utils/ConfigUtils.java | 5 +-
.../org/apache/dubbo/common/utils/IOUtils.java | 15 +-
.../java/org/apache/dubbo/common/utils/Log.java | 44 +-
.../org/apache/dubbo/common/utils/LogUtil.java | 23 +-
.../org/apache/dubbo/common/utils/NetUtils.java | 9 +-
.../org/apache/dubbo/common/utils/PojoUtils.java | 6 +-
.../apache/dubbo/common/utils/ReflectUtils.java | 258 +++--
.../java/org/apache/dubbo/common/utils/Stack.java | 20 +-
.../org/apache/dubbo/common/utils/StringUtils.java | 75 +-
.../org/apache/dubbo/common/utils/UrlUtils.java | 12 +-
.../common/compiler/support/JavaCodeTest.java | 6 +-
.../compiler/support/JavassistCompilerTest.java | 4 +-
.../common/compiler/support/JdkCompilerTest.java | 4 +-
.../org/apache/dubbo/common/model/AnimalEnum.java | 21 -
.../model/BizExceptionNoDefaultConstructor.java | 26 -
.../dubbo/common/model/media/MediaContent.java | 78 --
.../common/utils/CompatibleTypeUtilsTest.java | 9 +
.../apache/dubbo/common/utils/PojoUtilsTest.java | 30 +
.../apache/dubbo/common/utils/UrlUtilsTest.java | 18 +-
.../main/java/com/alibaba/dubbo/common/URL.java | 12 +-
.../org/apache/dubbo/config/MethodConfigTest.java | 27 +-
.../apache/dubbo/generic/GenericServiceTest.java | 2 +-
.../org/apache/dubbo/config/AbstractConfig.java | 58 +-
.../org/apache/dubbo/config/ReferenceConfig.java | 73 +-
.../org/apache/dubbo/config/RegistryConfig.java | 3 +-
.../org/apache/dubbo/config/ServiceConfig.java | 8 +-
.../dubbo/config/model/ApplicationModel.java | 94 --
.../dubbo/config/model/ConsumerMethodModel.java | 86 --
.../dubbo/config/utils/ReferenceConfigCache.java | 4 +-
.../apache/dubbo/config/AbstractConfigTest.java | 4 +-
.../apache/dubbo/config/GenericServiceTest.java | 10 +-
.../org/apache/dubbo/config/MethodConfigTest.java | 12 +-
.../org/apache/dubbo/config/cache/CacheTest.java | 4 +-
.../apache/dubbo/config/spring/ReferenceBean.java | 20 +-
.../apache/dubbo/config/spring/ServiceBean.java | 35 +-
.../DubboConfigBindingBeanPostProcessor.java | 2 +-
.../ReferenceAnnotationBeanPostProcessor.java | 107 +-
.../spring/extension/SpringExtensionFactory.java | 4 +
.../spring/initializer/DubboContextListener.java | 72 ++
.../spring/status/DataSourceStatusChecker.java | 12 +-
.../config/spring/status/SpringStatusChecker.java | 12 +-
.../src/main/resources/META-INF/compat/dubbo.xsd | 4 +-
.../src/main/resources/META-INF/dubbo.xsd | 2 +-
.../src/main/resources/META-INF/web-fragment.xml | 6 +-
.../org/apache/dubbo/config/spring/ConfigTest.java | 6 +-
.../ReferenceAnnotationBeanPostProcessorTest.java | 84 +-
.../DubboApplicationContextInitializerTest.java | 15 +-
.../spring/status/DataSourceStatusCheckerTest.java | 11 +-
.../spring/status/SpringStatusCheckerTest.java | 13 +-
.../dubbo/config/spring/annotation-consumer.xml | 2 +-
.../dubbo/config/spring/delay-fixed-time.xml | 2 +-
.../dubbo/config/spring/delay-on-initialized.xml | 2 +-
.../config/spring/override-multi-protocol.xml | 5 +-
.../apache/dubbo/config/spring/provider-multi.xml | 3 +-
dubbo-dependencies-bom/pom.xml | 15 +-
dubbo-distribution/pom.xml | 7 +-
.../org/apache/dubbo/cache/filter/CacheFilter.java | 26 +-
.../apache/dubbo/cache/filter/CacheFilterTest.java | 4 +-
.../validation/support/jvalidation/JValidator.java | 23 +-
.../java/org/apache/dubbo/metrics/MetricName.java | 66 +-
.../org/apache/dubbo/monitor/dubbo/Statistics.java | 51 +-
.../apache/dubbo/qos/command/CommandContext.java | 3 +-
.../java/org/apache/dubbo/qos/command/impl/Ls.java | 6 +-
.../org/apache/dubbo/qos/command/impl/Offline.java | 8 +-
.../org/apache/dubbo/qos/command/impl/Online.java | 8 +-
.../org/apache/dubbo/qos/command/impl/LsTest.java | 6 +-
.../apache/dubbo/qos/command/impl/OfflineTest.java | 4 +-
.../apache/dubbo/qos/command/impl/OnlineTest.java | 4 +-
.../registry/integration/RegistryDirectory.java | 6 +-
.../dubbo/registry/support/AbstractRegistry.java | 4 +-
.../registry/support/AbstractRegistryFactory.java | 6 +-
.../support/AbstractRegistryFactoryTest.java | 17 +-
.../registry/support/AbstractRegistryTest.java | 64 +-
.../apache/dubbo/registry/dubbo/DubboRegistry.java | 3 +-
.../apache/dubbo/registry/redis/RedisRegistry.java | 24 +-
.../registry/zookeeper/ZookeeperRegistry.java | 4 +-
.../apache/dubbo/remoting/exchange/Request.java | 4 +-
.../remoting/exchange/codec/ExchangeCodec.java | 40 +-
.../support/header/HeaderExchangeChannel.java | 20 +-
.../support/header/HeaderExchangeHandler.java | 10 +-
.../support/header/HeaderExchangeServer.java | 3 +-
.../dubbo/remoting/transport/AbstractClient.java | 23 +-
.../dubbo/remoting/transport/CodecSupport.java | 6 +
.../transport/dispatcher/ChannelEventRunnable.java | 1 +
.../dubbo/remoting/codec/ExchangeCodecTest.java | 18 +
.../transport/codec/DeprecatedExchangeCodec.java | 18 +-
.../remoting/transport/grizzly/GrizzlyChannel.java | 20 +-
.../remoting/transport/grizzly/GrizzlyClient.java | 5 +-
.../dubbo/remoting/transport/mina/MinaChannel.java | 20 +-
.../dubbo/remoting/transport/mina/MinaClient.java | 9 +-
.../remoting/transport/mina/MinaCodecAdapter.java | 4 +-
.../transport/mina/MinaClientToServerTest.java | 2 +-
.../remoting/transport/netty/NettyChannel.java | 20 +-
.../remoting/transport/netty/NettyClient.java | 5 +-
.../transport/netty/ClientReconnectTest.java | 2 +-
.../transport/netty/NettyClientToServerTest.java | 2 +-
.../remoting/transport/netty4/NettyChannel.java | 20 +-
.../remoting/transport/netty4/NettyClient.java | 9 +-
.../transport/netty4/NettyClientToServerTest.java | 2 +-
.../java/org/apache/dubbo/rpc/AsyncRpcResult.java | 5 +-
.../main/java/org/apache/dubbo/rpc/RpcContext.java | 25 +
.../org/apache/dubbo/rpc/ServiceClassHolder.java | 45 -
.../java/org/apache/dubbo/rpc/StaticContext.java | 75 --
.../org/apache/dubbo/rpc/filter/EchoFilter.java | 3 +-
.../apache/dubbo/rpc/model/ApplicationModel.java | 75 ++
.../dubbo/rpc/model/ConsumerMethodModel.java | 160 +++
.../org/apache/dubbo/rpc}/model/ConsumerModel.java | 38 +-
.../dubbo/rpc}/model/ProviderMethodModel.java | 2 +-
.../org/apache/dubbo/rpc}/model/ProviderModel.java | 19 +-
.../dubbo/rpc/protocol/AbstractExporter.java | 9 +-
.../apache/dubbo/rpc/protocol/AbstractInvoker.java | 12 +-
.../apache/dubbo/rpc/support/DelegateExporter.java | 47 -
.../org/apache/dubbo/rpc/support/RpcUtils.java | 8 +-
.../org/apache/dubbo/rpc/StaticContextTest.java | 64 --
.../rpc/protocol/dubbo/DecodeableRpcResult.java | 6 +-
.../dubbo/rpc/protocol/dubbo/DubboCodec.java | 41 +-
.../dubbo/rpc/protocol/dubbo/DubboInvoker.java | 3 +-
.../dubbo/rpc/protocol/dubbo/DubboProtocol.java | 6 +-
.../protocol/dubbo/LazyConnectExchangeClient.java | 17 +-
.../rpc/protocol/dubbo/filter/FutureFilter.java | 48 +-
.../rpc/protocol/dubbo/DubboProtocolTest.java | 24 +-
.../rpc/protocol/dubbo/ExplicitCallbackTest.java | 5 +-
.../rpc/protocol/dubbo/ImplicitCallBackTest.java | 75 +-
.../dubbo/telnet/ChangeTelnetHandlerTest.java | 2 +-
.../dubbo/telnet/InvokerTelnetHandlerTest.java | 12 +-
.../dubbo/telnet/ListTelnetHandlerTest.java | 8 +-
.../dubbo/telnet/PortTelnetHandlerTest.java | 12 +-
.../dubbo/rpc/protocol/redis/RedisProtocol.java | 24 +-
.../dubbo/rpc/protocol/rest/RestProtocol.java | 6 +-
.../dubbo/rpc/protocol/rest/RestProtocolTest.java | 50 +-
.../dubbo/rpc/protol/rest/RestProtocolTest.java | 23 +-
.../dubbo/rpc/protocol/thrift/ThriftProtocol.java | 3 +-
.../io/RandomAccessByteArrayOutputStream.java | 15 +-
.../webservice/WebserviceProtocolTest.java | 4 +-
.../dubbo-serialization-api/pom.xml | 2 +-
.../dubbo-serialization-fastjson/pom.xml | 2 +-
.../serialize/fastjson/FastJsonObjectInput.java | 5 +-
.../common/serialize/fastjson/model/Image.java | 104 --
.../common/serialize/fastjson/model/Person.java | 38 -
.../src/test/resources/log4j.xml | 32 -
.../dubbo-serialization-fst/pom.xml | 2 +-
.../common/serialize/fst/model/AnimalEnum.java | 21 -
.../common/serialize/fst/model/FullAddress.java | 199 ----
.../src/test/resources/log4j.xml | 32 -
.../dubbo-serialization-hessian2/pom.xml | 2 +-
.../org/apache/dubbo/common/model/AnimalEnum.java | 21 -
.../apache/dubbo/common/model/BizException.java | 29 -
.../model/BizExceptionNoDefaultConstructor.java | 26 -
.../java/org/apache/dubbo/common/model/Person.java | 95 --
.../dubbo/common/model/SerializablePerson.java | 97 --
.../org/apache/dubbo/common/model/media/Image.java | 120 --
.../org/apache/dubbo/common/model/media/Media.java | 205 ----
.../dubbo/common/model/media/MediaContent.java | 78 --
.../dubbo/common/model/person/BigPerson.java | 151 ---
.../dubbo/common/model/person/FullAddress.java | 202 ----
.../dubbo/common/model/person/PersonInfo.java | 206 ----
.../apache/dubbo/common/model/person/Phone.java | 139 ---
.../src/test/resources/log4j.xml | 32 -
.../dubbo/common/serialize/dubbo/SimpleDO.fc | 2 -
.../dubbo-serialization-jdk/pom.xml | 2 +-
.../serialize/java/CompactedObjectInputStream.java | 3 +-
.../common/serialize/java/JavaObjectInput.java | 15 +-
.../java/org/apache/dubbo/common/model/Person.java | 95 --
.../dubbo/common/model/SerializablePerson.java | 97 --
.../org/apache/dubbo/common/model/media/Image.java | 120 --
.../dubbo/common/model/person/BigPerson.java | 151 ---
.../dubbo/common/model/person/PersonInfo.java | 206 ----
.../dubbo/common/model/person/PersonStatus.java | 22 -
.../apache/dubbo/common/model/person/Phone.java | 139 ---
.../AbstractSerializationPersionFailTest.java | 137 ---
.../AbstractSerializationPersionOkTest.java | 93 --
.../serialization/AbstractSerializationTest.java | 1210 -------------------
.../src/test/resources/log4j.xml | 32 -
.../dubbo/common/serialize/dubbo/SimpleDO.fc | 2 -
.../dubbo-serialization-kryo/pom.xml | 2 +-
.../org/apache/dubbo/common/model/AnimalEnum.java | 21 -
.../apache/dubbo/common/model/BizException.java | 29 -
.../model/BizExceptionNoDefaultConstructor.java | 26 -
.../org/apache/dubbo/common/model/media/Media.java | 205 ----
.../dubbo/common/model/media/MediaContent.java | 78 --
.../dubbo/common/model/person/FullAddress.java | 202 ----
.../dubbo/common/model/person/PersonStatus.java | 22 -
.../AbstractSerializationPersionFailTest.java | 137 ---
.../AbstractSerializationPersionOkTest.java | 93 --
.../serialization/AbstractSerializationTest.java | 1215 --------------------
.../src/test/resources/log4j.xml | 32 -
.../pom.xml | 28 +-
.../protostuff/ProtostuffObjectInput.java | 134 +++
.../protostuff/ProtostuffObjectOutput.java | 128 +++
.../protostuff/ProtostuffSerialization.java | 110 +-
.../dubbo/common/serialize/protostuff/Wrapper.java | 62 +-
.../protostuff/delegate/TimeDelegate.java | 54 +
.../serialize/protostuff/utils/WrapperUtils.java | 92 ++
...org.apache.dubbo.common.serialize.Serialization | 1 +
.../dubbo-serialization-test/pom.xml | 73 ++
.../base/AbstractSerializationPersonFailTest.java} | 25 +-
.../base/AbstractSerializationPersonOkTest.java} | 41 +-
.../serialize/base}/AbstractSerializationTest.java | 50 +-
.../fastjson/FastJsonObjectInputTest.java | 2 +-
.../fastjson/FastJsonObjectOutputTest.java | 6 +-
.../fastjson/FastJsonSerializationTest.java | 3 -
.../dubbo/common/serialize/fst/FstFactoryTest.java | 0
.../common/serialize/fst/FstObjectInputTest.java | 5 +-
.../common/serialize/fst/FstObjectOutputTest.java | 6 +-
.../common/serialize/fst/FstSerializationTest.java | 0
.../serialize/hessian2/Hessian2PersonOkTest.java} | 17 +-
.../hessian2}/Hessian2SerializationTest.java | 7 +-
.../jdk}/CompactedJavaSerializationTest.java | 5 +-
.../serialize/jdk}/JavaSerializationTest.java | 5 +-
.../common/serialize/jdk/JdkPersonOkTest.java} | 12 +-
.../jdk}/NativeJavaSerializationTest.java | 5 +-
.../common/serialize/kryo/KryoPersonOkTest.java} | 11 +-
.../serialize/kryo}/KyroSerializationTest.java | 4 +-
.../serialize/kryo}/ReflectionUtilsTest.java | 3 +-
.../dubbo/common/serialize}/model/AnimalEnum.java | 2 +-
.../common/serialize}/model/BizException.java | 2 +-
.../model/BizExceptionNoDefaultConstructor.java | 2 +-
.../dubbo/common/serialize}/model/Person.java | 2 +-
.../serialize}/model/SerializablePerson.java | 2 +-
.../dubbo/common/serialize}/model/media/Image.java | 2 +-
.../dubbo/common/serialize}/model/media/Media.java | 2 +-
.../serialize}/model/media/MediaContent.java | 2 +-
.../common/serialize}/model/person/BigPerson.java | 2 +-
.../serialize}/model/person/FullAddress.java | 2 +-
.../common/serialize}/model/person/PersonInfo.java | 2 +-
.../serialize}/model/person/PersonStatus.java | 2 +-
.../common/serialize}/model/person/Phone.java | 2 +-
.../protostuff/ProtostuffSerializationTest.java | 21 +-
.../support/SerializableClassRegistryTest.java | 13 +-
.../src/test/resources/log4j.xml | 58 +-
.../SimpleDO.fc | 0
dubbo-serialization/pom.xml | 4 +-
pom.xml | 8 +-
286 files changed, 4269 insertions(+), 8503 deletions(-)
diff --cc dubbo-all/pom.xml
index f4ce3e9,8e8fa66..e7ac32e
--- a/dubbo-all/pom.xml
+++ b/dubbo-all/pom.xml
@@@ -452,10 -438,8 +459,11 @@@
<include>org.apache.dubbo:dubbo-serialization-fst</include>
<include>org.apache.dubbo:dubbo-serialization-kryo</include>
<include>org.apache.dubbo:dubbo-serialization-jdk</include>
+ <include>org.apache.dubbo:dubbo-serialization-protostuff</include>
<include>org.apache.dubbo:dubbo-bootstrap</include>
+ <include>org.apache.dubbo:dubbo-governance-api</include>
+ <include>org.apache.dubbo:dubbo-governance-apollo</include>
+ <include>org.apache.dubbo:dubbo-governance-zookeeper</include>
</includes>
</artifactSet>
<transformers>
diff --cc dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
index 1f51999,0cea0b8..e77ac49
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/directory/AbstractDirectory.java
@@@ -50,16 -54,17 +50,17 @@@ public abstract class AbstractDirectory
this(url, null);
}
- public AbstractDirectory(URL url, List<Router> routers) {
- this(url, url, routers);
+ public AbstractDirectory(URL url, RouterChain<T> routerChain) {
+ this(url, url, routerChain);
}
- public AbstractDirectory(URL url, URL consumerUrl, List<Router> routers) {
- if (url == null) {
+ public AbstractDirectory(URL url, URL consumerUrl, RouterChain<T> routerChain) {
+ if (url == null)
throw new IllegalArgumentException("url == null");
+ }
this.url = url;
this.consumerUrl = consumerUrl;
- setRouters(routers);
+ setRouterChain(routerChain);
}
@Override
diff --cc dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
index 66f9ccb,35ce7e5..a479136
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/router/mock/MockInvokersSelector.java
@@@ -1,109 -1,100 +1,109 @@@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.rpc.cluster.router;
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.cluster.Router;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A specific Router designed to realize mock feature.
- * If a request is configured to use mock, then this router guarantees that only the invokers with protocol MOCK appear in final the invoker list, all other invokers will be excluded.
- *
- */
-public class MockInvokersSelector implements Router {
-
- @Override
- public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers,
- URL url, final Invocation invocation) throws RpcException {
- if (invocation.getAttachments() == null) {
- return getNormalInvokers(invokers);
- } else {
- String value = invocation.getAttachments().get(Constants.INVOCATION_NEED_MOCK);
- if (value == null) {
- return getNormalInvokers(invokers);
- } else if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
- return getMockedInvokers(invokers);
- }
- }
- return invokers;
- }
-
- private <T> List<Invoker<T>> getMockedInvokers(final List<Invoker<T>> invokers) {
- if (!hasMockProviders(invokers)) {
- return null;
- }
- List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(1);
- for (Invoker<T> invoker : invokers) {
- if (invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
- sInvokers.add(invoker);
- }
- }
- return sInvokers;
- }
-
- private <T> List<Invoker<T>> getNormalInvokers(final List<Invoker<T>> invokers) {
- if (!hasMockProviders(invokers)) {
- return invokers;
- } else {
- List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(invokers.size());
- for (Invoker<T> invoker : invokers) {
- if (!invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
- sInvokers.add(invoker);
- }
- }
- return sInvokers;
- }
- }
-
- private <T> boolean hasMockProviders(final List<Invoker<T>> invokers) {
- boolean hasMockProvider = false;
- for (Invoker<T> invoker : invokers) {
- if (invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
- hasMockProvider = true;
- break;
- }
- }
- return hasMockProvider;
- }
-
- @Override
- public URL getUrl() {
- return null;
- }
-
- @Override
- public int compareTo(Router o) {
- return 1;
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.rpc.cluster.router.mock;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.cluster.Router;
+import org.apache.dubbo.rpc.cluster.router.AbstractRouter;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A specific Router designed to realize mock feature.
+ * If a request is configured to use mock, then this router guarantees that only the invokers with protocol MOCK appear in final the invoker list, all other invokers will be excluded.
+ *
+ */
+public class MockInvokersSelector extends AbstractRouter {
+
+ public static final String NAME = "MOCK_ROUTER";
+
+ @Override
+ public <T> List<Invoker<T>> route(final List<Invoker<T>> invokers,
+ URL url, final Invocation invocation) throws RpcException {
+ if (invocation.getAttachments() == null) {
+ return getNormalInvokers(invokers);
+ } else {
+ String value = invocation.getAttachments().get(Constants.INVOCATION_NEED_MOCK);
- if (value == null)
++ if (value == null) {
+ return getNormalInvokers(invokers);
- else if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
++ } else if (Boolean.TRUE.toString().equalsIgnoreCase(value)) {
+ return getMockedInvokers(invokers);
+ }
+ }
+ return invokers;
+ }
+
+ private <T> List<Invoker<T>> getMockedInvokers(final List<Invoker<T>> invokers) {
+ if (!hasMockProviders(invokers)) {
+ return null;
+ }
+ List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(1);
+ for (Invoker<T> invoker : invokers) {
+ if (invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
+ sInvokers.add(invoker);
+ }
+ }
+ return sInvokers;
+ }
+
+ private <T> List<Invoker<T>> getNormalInvokers(final List<Invoker<T>> invokers) {
+ if (!hasMockProviders(invokers)) {
+ return invokers;
+ } else {
+ List<Invoker<T>> sInvokers = new ArrayList<Invoker<T>>(invokers.size());
+ for (Invoker<T> invoker : invokers) {
+ if (!invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
+ sInvokers.add(invoker);
+ }
+ }
+ return sInvokers;
+ }
+ }
+
+ private <T> boolean hasMockProviders(final List<Invoker<T>> invokers) {
+ boolean hasMockProvider = false;
+ for (Invoker<T> invoker : invokers) {
+ if (invoker.getUrl().getProtocol().equals(Constants.MOCK_PROTOCOL)) {
+ hasMockProvider = true;
+ break;
+ }
+ }
+ return hasMockProvider;
+ }
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ /**
+ * Always stay on the top of the list
+ *
+ * @param o
+ * @return
+ */
+ @Override
+ public int compareTo(Router o) {
+ return 1;
+ }
+
+}
diff --cc dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
index be98ae4,fdaa3b1..ff74233
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractConfig.java
@@@ -1,579 -1,534 +1,627 @@@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.dubbo.config;
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-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.ReflectUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.config.support.Parameter;
-import org.apache.dubbo.rpc.model.ConsumerMethodModel;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Utility methods and public methods for parsing configuration
- *
- * @export
- */
-public abstract class AbstractConfig implements Serializable {
-
- protected static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
- private static final long serialVersionUID = 4267533505537413570L;
- private static final int MAX_LENGTH = 200;
-
- private static final int MAX_PATH_LENGTH = 200;
-
- private static final Pattern PATTERN_NAME = Pattern.compile("[\\-._0-9a-zA-Z]+");
-
- private static final Pattern PATTERN_MULTI_NAME = Pattern.compile("[,\\-._0-9a-zA-Z]+");
-
- private static final Pattern PATTERN_METHOD_NAME = Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
-
- private static final Pattern PATTERN_PATH = Pattern.compile("[/\\-$._0-9a-zA-Z]+");
-
- private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,/\\-._0-9a-zA-Z]+");
-
- private static final Pattern PATTERN_KEY = Pattern.compile("[*,\\-._0-9a-zA-Z]+");
- private static final Map<String, String> legacyProperties = new HashMap<String, String>();
- private static final String[] SUFFIXES = new String[]{"Config", "Bean"};
-
- static {
- legacyProperties.put("dubbo.protocol.name", "dubbo.service.protocol");
- legacyProperties.put("dubbo.protocol.host", "dubbo.service.server.host");
- legacyProperties.put("dubbo.protocol.port", "dubbo.service.server.port");
- legacyProperties.put("dubbo.protocol.threads", "dubbo.service.max.thread.pool.size");
- legacyProperties.put("dubbo.consumer.timeout", "dubbo.service.invoke.timeout");
- legacyProperties.put("dubbo.consumer.retries", "dubbo.service.max.retry.providers");
- legacyProperties.put("dubbo.consumer.check", "dubbo.service.allow.no.provider");
- legacyProperties.put("dubbo.service.url", "dubbo.service.address");
-
- // this is only for compatibility
- Runtime.getRuntime().addShutdownHook(DubboShutdownHook.getDubboShutdownHook());
- }
-
- protected String id;
-
- private static String convertLegacyValue(String key, String value) {
- if (value != null && value.length() > 0) {
- if ("dubbo.service.max.retry.providers".equals(key)) {
- return String.valueOf(Integer.parseInt(value) - 1);
- } else if ("dubbo.service.allow.no.provider".equals(key)) {
- return String.valueOf(!Boolean.parseBoolean(value));
- }
- }
- return value;
- }
-
- protected static void appendProperties(AbstractConfig config) {
- if (config == null) {
- return;
- }
- String prefix = "dubbo." + getTagName(config.getClass()) + ".";
- Method[] methods = config.getClass().getMethods();
- for (Method method : methods) {
- try {
- String name = method.getName();
- if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(method.getModifiers())
- && method.getParameterTypes().length == 1 && isPrimitive(method.getParameterTypes()[0])) {
- String property = StringUtils.camelToSplitName(name.substring(3, 4).toLowerCase() + name.substring(4), ".");
-
- String value = null;
- if (config.getId() != null && config.getId().length() > 0) {
- String pn = prefix + config.getId() + "." + property;
- value = System.getProperty(pn);
- if (!StringUtils.isBlank(value)) {
- logger.info("Use System Property " + pn + " to config dubbo");
- }
- }
- if (value == null || value.length() == 0) {
- String pn = prefix + property;
- value = System.getProperty(pn);
- if (!StringUtils.isBlank(value)) {
- logger.info("Use System Property " + pn + " to config dubbo");
- }
- }
- if (value == null || value.length() == 0) {
- Method getter;
- try {
- getter = config.getClass().getMethod("get" + name.substring(3));
- } catch (NoSuchMethodException e) {
- try {
- getter = config.getClass().getMethod("is" + name.substring(3));
- } catch (NoSuchMethodException e2) {
- getter = null;
- }
- }
- if (getter != null) {
- if (getter.invoke(config) == null) {
- if (config.getId() != null && config.getId().length() > 0) {
- value = ConfigUtils.getProperty(prefix + config.getId() + "." + property);
- }
- if (value == null || value.length() == 0) {
- value = ConfigUtils.getProperty(prefix + property);
- }
- if (value == null || value.length() == 0) {
- String legacyKey = legacyProperties.get(prefix + property);
- if (legacyKey != null && legacyKey.length() > 0) {
- value = convertLegacyValue(legacyKey, ConfigUtils.getProperty(legacyKey));
- }
- }
-
- }
- }
- }
- if (value != null && value.length() > 0) {
- method.invoke(config, convertPrimitive(method.getParameterTypes()[0], value));
- }
- }
- } catch (Exception e) {
- logger.error(e.getMessage(), e);
- }
- }
- }
-
- private static String getTagName(Class<?> cls) {
- String tag = cls.getSimpleName();
- for (String suffix : SUFFIXES) {
- if (tag.endsWith(suffix)) {
- tag = tag.substring(0, tag.length() - suffix.length());
- break;
- }
- }
- tag = tag.toLowerCase();
- return tag;
- }
-
- protected static void appendParameters(Map<String, String> parameters, Object config) {
- appendParameters(parameters, config, null);
- }
-
- @SuppressWarnings("unchecked")
- protected static void appendParameters(Map<String, String> parameters, Object config, String prefix) {
- if (config == null) {
- return;
- }
- Method[] methods = config.getClass().getMethods();
- for (Method method : methods) {
- try {
- String name = method.getName();
- if ((name.startsWith("get") || name.startsWith("is"))
- && !"getClass".equals(name)
- && Modifier.isPublic(method.getModifiers())
- && method.getParameterTypes().length == 0
- && isPrimitive(method.getReturnType())) {
- Parameter parameter = method.getAnnotation(Parameter.class);
- if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
- continue;
- }
- int i = name.startsWith("get") ? 3 : 2;
- String prop = StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + name.substring(i + 1), ".");
- String key;
- if (parameter != null && parameter.key().length() > 0) {
- key = parameter.key();
- } else {
- key = prop;
- }
- Object value = method.invoke(config);
- String str = String.valueOf(value).trim();
- if (value != null && str.length() > 0) {
- if (parameter != null && parameter.escaped()) {
- str = URL.encode(str);
- }
- if (parameter != null && parameter.append()) {
- String pre = parameters.get(Constants.DEFAULT_KEY + "." + key);
- if (pre != null && pre.length() > 0) {
- str = pre + "," + str;
- }
- pre = parameters.get(key);
- if (pre != null && pre.length() > 0) {
- str = pre + "," + str;
- }
- }
- if (prefix != null && prefix.length() > 0) {
- key = prefix + "." + key;
- }
- parameters.put(key, str);
- } else if (parameter != null && parameter.required()) {
- throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
- }
- } else if ("getParameters".equals(name)
- && Modifier.isPublic(method.getModifiers())
- && method.getParameterTypes().length == 0
- && method.getReturnType() == Map.class) {
- Map<String, String> map = (Map<String, String>) method.invoke(config, new Object[0]);
- if (map != null && map.size() > 0) {
- String pre = (prefix != null && prefix.length() > 0 ? prefix + "." : "");
- for (Map.Entry<String, String> entry : map.entrySet()) {
- parameters.put(pre + entry.getKey().replace('-', '.'), entry.getValue());
- }
- }
- }
- } catch (Exception e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
- }
- }
-
- protected static void appendAttributes(Map<String, Object> parameters, Object config) {
- appendAttributes(parameters, config, null);
- }
-
- protected static void appendAttributes(Map<String, Object> parameters, Object config, String prefix) {
- if (config == null) {
- return;
- }
- Method[] methods = config.getClass().getMethods();
- for (Method method : methods) {
- try {
- Parameter parameter = method.getAnnotation(Parameter.class);
- if (parameter == null || !parameter.attribute()) {
- continue;
- }
- String name = method.getName();
- if ((name.startsWith("get") || name.startsWith("is"))
- && !"getClass".equals(name)
- && Modifier.isPublic(method.getModifiers())
- && method.getParameterTypes().length == 0
- && isPrimitive(method.getReturnType())) {
- String key;
- if (parameter.key().length() > 0) {
- key = parameter.key();
- } else {
- int i = name.startsWith("get") ? 3 : 2;
- key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1);
- }
- Object value = method.invoke(config);
- if (value != null) {
- if (prefix != null && prefix.length() > 0) {
- key = prefix + "." + key;
- }
- parameters.put(key, value);
- }
- }
- } catch (Exception e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
- }
- }
-
- protected static ConsumerMethodModel.AsyncMethodInfo convertMethodConfig2AyncInfo(MethodConfig methodConfig) {
- if (methodConfig == null || (methodConfig.getOninvoke() == null && methodConfig.getOnreturn() == null && methodConfig.getOnthrow() == null)) {
- return null;
- }
-
- //check config conflict
- if (Boolean.FALSE.equals(methodConfig.isReturn()) && (methodConfig.getOnreturn() != null || methodConfig.getOnthrow() != null)) {
- throw new IllegalStateException("method config error : return attribute must be set true when onreturn or onthrow has been set.");
- }
-
- ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = new ConsumerMethodModel.AsyncMethodInfo();
-
- asyncMethodInfo.setOninvokeInstance(methodConfig.getOninvoke());
- asyncMethodInfo.setOnreturnInstance(methodConfig.getOnreturn());
- asyncMethodInfo.setOnthrowInstance(methodConfig.getOnthrow());
-
- try {
- String oninvokeMethod = methodConfig.getOninvokeMethod();
- if (StringUtils.isNotEmpty(oninvokeMethod)) {
- asyncMethodInfo.setOninvokeMethod(getMethodByName(methodConfig.getOninvoke().getClass(), oninvokeMethod));
- }
-
- String onreturnMethod = methodConfig.getOnreturnMethod();
- if (StringUtils.isNotEmpty(onreturnMethod)) {
- asyncMethodInfo.setOnreturnMethod(getMethodByName(methodConfig.getOnreturn().getClass(), onreturnMethod));
- }
-
- String onthrowMethod = methodConfig.getOnthrowMethod();
- if (StringUtils.isNotEmpty(onthrowMethod)) {
- asyncMethodInfo.setOnthrowMethod(getMethodByName(methodConfig.getOnthrow().getClass(), onthrowMethod));
- }
- } catch (Exception e) {
- throw new IllegalStateException(e.getMessage(), e);
- }
-
- return asyncMethodInfo;
- }
-
- private static Method getMethodByName(Class<?> clazz, String methodName) {
- try {
- return ReflectUtils.findMethodByMethodName(clazz, methodName);
- } catch (Exception e) {
- throw new IllegalStateException(e);
- }
- }
-
- private static boolean isPrimitive(Class<?> type) {
- return type.isPrimitive()
- || type == String.class
- || type == Character.class
- || type == Boolean.class
- || type == Byte.class
- || type == Short.class
- || type == Integer.class
- || type == Long.class
- || type == Float.class
- || type == Double.class
- || type == Object.class;
- }
-
- private static Object convertPrimitive(Class<?> type, String value) {
- if (type == char.class || type == Character.class) {
- return value.length() > 0 ? value.charAt(0) : '\0';
- } else if (type == boolean.class || type == Boolean.class) {
- return Boolean.valueOf(value);
- } else if (type == byte.class || type == Byte.class) {
- return Byte.valueOf(value);
- } else if (type == short.class || type == Short.class) {
- return Short.valueOf(value);
- } else if (type == int.class || type == Integer.class) {
- return Integer.valueOf(value);
- } else if (type == long.class || type == Long.class) {
- return Long.valueOf(value);
- } else if (type == float.class || type == Float.class) {
- return Float.valueOf(value);
- } else if (type == double.class || type == Double.class) {
- return Double.valueOf(value);
- }
- return value;
- }
-
- protected static void checkExtension(Class<?> type, String property, String value) {
- checkName(property, value);
- if (value != null && value.length() > 0
- && !ExtensionLoader.getExtensionLoader(type).hasExtension(value)) {
- throw new IllegalStateException("No such extension " + value + " for " + property + "/" + type.getName());
- }
- }
-
- protected static void checkMultiExtension(Class<?> type, String property, String value) {
- checkMultiName(property, value);
- if (value != null && value.length() > 0) {
- String[] values = value.split("\\s*[,]+\\s*");
- for (String v : values) {
- if (v.startsWith(Constants.REMOVE_VALUE_PREFIX)) {
- v = v.substring(1);
- }
- if (Constants.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 (parameters == null || parameters.size() == 0) {
- 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 (value == null || value.length() == 0) {
- 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.");
- }
- }
- }
-
- @Parameter(excluded = true)
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- protected void appendAnnotation(Class<?> annotationClass, Object annotation) {
- Method[] methods = annotationClass.getMethods();
- for (Method method : methods) {
- if (method.getDeclaringClass() != Object.class
- && method.getReturnType() != void.class
- && method.getParameterTypes().length == 0
- && Modifier.isPublic(method.getModifiers())
- && !Modifier.isStatic(method.getModifiers())) {
- try {
- String property = method.getName();
- if ("interfaceClass".equals(property) || "interfaceName".equals(property)) {
- property = "interface";
- }
- String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
- Object value = method.invoke(annotation);
- if (value != null && !value.equals(method.getDefaultValue())) {
- Class<?> parameterType = ReflectUtils.getBoxedClass(method.getReturnType());
- if ("filter".equals(property) || "listener".equals(property)) {
- parameterType = String.class;
- value = StringUtils.join((String[]) value, ",");
- } else if ("parameters".equals(property)) {
- parameterType = Map.class;
- value = CollectionUtils.toStringMap((String[]) value);
- }
- try {
- Method setterMethod = getClass().getMethod(setter, parameterType);
- setterMethod.invoke(this, value);
- } catch (NoSuchMethodException e) {
- // ignore
- }
- }
- } catch (Throwable e) {
- logger.error(e.getMessage(), e);
- }
- }
- }
- }
-
- @Override
- public String toString() {
- try {
- StringBuilder buf = new StringBuilder();
- buf.append("<dubbo:");
- buf.append(getTagName(getClass()));
- Method[] methods = getClass().getMethods();
- for (Method method : methods) {
- try {
- String name = method.getName();
- if ((name.startsWith("get") || name.startsWith("is"))
- && !"getClass".equals(name) && !"get".equals(name) && !"is".equals(name)
- && Modifier.isPublic(method.getModifiers())
- && method.getParameterTypes().length == 0
- && isPrimitive(method.getReturnType())) {
- int i = name.startsWith("get") ? 3 : 2;
- String key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1);
- Object value = method.invoke(this);
- if (value != null) {
- buf.append(" ");
- buf.append(key);
- buf.append("=\"");
- buf.append(value);
- buf.append("\"");
- }
- }
- } catch (Exception e) {
- logger.warn(e.getMessage(), e);
- }
- }
- buf.append(" />");
- return buf.toString();
- } catch (Throwable t) {
- logger.warn(t.getMessage(), t);
- return super.toString();
- }
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.dubbo.config;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.CompositeConfiguration;
+import org.apache.dubbo.common.config.Configuration;
+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.ReflectUtils;
+import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.config.context.Environment;
+import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.config.utils.ConfigConverter;
++import org.apache.dubbo.rpc.model.ConsumerMethodModel;
+
+import javax.annotation.PostConstruct;
+import java.io.Serializable;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Utility methods and public methods for parsing configuration
+ *
+ * @export
+ */
+public abstract class AbstractConfig implements Serializable {
+
+ protected static final Logger logger = LoggerFactory.getLogger(AbstractConfig.class);
+ private static final long serialVersionUID = 4267533505537413570L;
+ private static final int MAX_LENGTH = 200;
+
+ private static final int MAX_PATH_LENGTH = 200;
+
+ private static final Pattern PATTERN_NAME = Pattern.compile("[\\-._0-9a-zA-Z]+");
+
+ private static final Pattern PATTERN_MULTI_NAME = Pattern.compile("[,\\-._0-9a-zA-Z]+");
+
+ private static final Pattern PATTERN_METHOD_NAME = Pattern.compile("[a-zA-Z][0-9a-zA-Z]*");
+
+ private static final Pattern PATTERN_PATH = Pattern.compile("[/\\-$._0-9a-zA-Z]+");
+
+ private static final Pattern PATTERN_NAME_HAS_SYMBOL = Pattern.compile("[:*,/\\-._0-9a-zA-Z]+");
+
+ private static final Pattern PATTERN_KEY = Pattern.compile("[*,\\-._0-9a-zA-Z]+");
+ private static final Map<String, String> legacyProperties = new HashMap<String, String>();
+ private static final String[] SUFFIXES = new String[]{"Config", "Bean"};
+
+ private boolean init;
+ private volatile Map<String, String> metaData;
+
+ static {
+ legacyProperties.put("dubbo.protocol.name", "dubbo.service.protocol");
+ legacyProperties.put("dubbo.protocol.host", "dubbo.service.server.host");
+ legacyProperties.put("dubbo.protocol.port", "dubbo.service.server.port");
+ legacyProperties.put("dubbo.protocol.threads", "dubbo.service.max.thread.pool.size");
+ legacyProperties.put("dubbo.consumer.timeout", "dubbo.service.invoke.timeout");
+ legacyProperties.put("dubbo.consumer.retries", "dubbo.service.max.retry.providers");
+ legacyProperties.put("dubbo.consumer.check", "dubbo.service.allow.no.provider");
+ legacyProperties.put("dubbo.service.url", "dubbo.service.address");
+ }
+
+ protected String id;
+
+ private static String convertLegacyValue(String key, String value) {
+ if (value != null && value.length() > 0) {
+ if ("dubbo.service.max.retry.providers".equals(key)) {
+ return String.valueOf(Integer.parseInt(value) - 1);
+ } else if ("dubbo.service.allow.no.provider".equals(key)) {
+ return String.valueOf(!Boolean.parseBoolean(value));
+ }
+ }
+ return value;
+ }
+
+ private static String getTagName(Class<?> cls) {
+ String tag = cls.getSimpleName();
+ for (String suffix : SUFFIXES) {
+ if (tag.endsWith(suffix)) {
+ tag = tag.substring(0, tag.length() - suffix.length());
+ break;
+ }
+ }
+ tag = tag.toLowerCase();
+ return tag;
+ }
+
+ protected static void appendParameters(Map<String, String> parameters, Object config) {
+ appendParameters(parameters, config, null);
+ }
+
+ @SuppressWarnings("unchecked")
+ protected static void appendParameters(Map<String, String> parameters, Object config, String prefix) {
+ if (config == null) {
+ return;
+ }
+ Method[] methods = config.getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ String name = method.getName();
+ if ((name.startsWith("get") || name.startsWith("is"))
+ && !"getClass".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && isPrimitive(method.getReturnType())) {
+ Parameter parameter = method.getAnnotation(Parameter.class);
+ if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
+ continue;
+ }
+ int i = name.startsWith("get") ? 3 : 2;
+ String prop = StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + name.substring(i + 1), ".");
+ String key;
+ if (parameter != null && parameter.key().length() > 0) {
+ key = parameter.key();
+ } else {
+ key = prop;
+ }
+ Object value = method.invoke(config);
+ String str = String.valueOf(value).trim();
+ if (value != null && str.length() > 0) {
+ if (parameter != null && parameter.escaped()) {
+ str = URL.encode(str);
+ }
+ if (parameter != null && parameter.append()) {
+ String pre = parameters.get(Constants.DEFAULT_KEY + "." + key);
+ if (pre != null && pre.length() > 0) {
+ str = pre + "," + str;
+ }
+ pre = parameters.get(key);
+ if (pre != null && pre.length() > 0) {
+ str = pre + "," + str;
+ }
+ }
+ if (prefix != null && prefix.length() > 0) {
+ key = prefix + "." + key;
+ }
+ parameters.put(key, str);
+ } else if (parameter != null && parameter.required()) {
+ throw new IllegalStateException(config.getClass().getSimpleName() + "." + key + " == null");
+ }
+ } else if ("getParameters".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && method.getReturnType() == Map.class) {
+ Map<String, String> map = (Map<String, String>) method.invoke(config, new Object[0]);
+ if (map != null && map.size() > 0) {
+ String pre = (prefix != null && prefix.length() > 0 ? prefix + "." : "");
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ parameters.put(pre + entry.getKey().replace('-', '.'), entry.getValue());
+ }
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ }
+
- protected static void appendAttributes(Map<Object, Object> parameters, Object config) {
++ protected static void appendAttributes(Map<String, Object> parameters, Object config) {
+ appendAttributes(parameters, config, null);
+ }
+
- protected static void appendAttributes(Map<Object, Object> parameters, Object config, String prefix) {
++ protected static void appendAttributes(Map<String, Object> parameters, Object config, String prefix) {
+ if (config == null) {
+ return;
+ }
+ Method[] methods = config.getClass().getMethods();
+ for (Method method : methods) {
+ try {
++ Parameter parameter = method.getAnnotation(Parameter.class);
++ if (parameter == null || !parameter.attribute()) {
++ continue;
++ }
+ String name = method.getName();
+ if ((name.startsWith("get") || name.startsWith("is"))
+ && !"getClass".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && isPrimitive(method.getReturnType())) {
- Parameter parameter = method.getAnnotation(Parameter.class);
- if (parameter == null || !parameter.attribute())
- continue;
+ String key;
+ if (parameter.key().length() > 0) {
+ key = parameter.key();
+ } else {
+ int i = name.startsWith("get") ? 3 : 2;
+ key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1);
+ }
+ Object value = method.invoke(config);
+ if (value != null) {
+ if (prefix != null && prefix.length() > 0) {
+ key = prefix + "." + key;
+ }
+ parameters.put(key, value);
+ }
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ }
+
++ protected static ConsumerMethodModel.AsyncMethodInfo convertMethodConfig2AyncInfo(MethodConfig methodConfig) {
++ if (methodConfig == null || (methodConfig.getOninvoke() == null && methodConfig.getOnreturn() == null && methodConfig.getOnthrow() == null)) {
++ return null;
++ }
++
++ //check config conflict
++ if (Boolean.FALSE.equals(methodConfig.isReturn()) && (methodConfig.getOnreturn() != null || methodConfig.getOnthrow() != null)) {
++ throw new IllegalStateException("method config error : return attribute must be set true when onreturn or onthrow has been set.");
++ }
++
++ ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = new ConsumerMethodModel.AsyncMethodInfo();
++
++ asyncMethodInfo.setOninvokeInstance(methodConfig.getOninvoke());
++ asyncMethodInfo.setOnreturnInstance(methodConfig.getOnreturn());
++ asyncMethodInfo.setOnthrowInstance(methodConfig.getOnthrow());
++
++ try {
++ String oninvokeMethod = methodConfig.getOninvokeMethod();
++ if (StringUtils.isNotEmpty(oninvokeMethod)) {
++ asyncMethodInfo.setOninvokeMethod(getMethodByName(methodConfig.getOninvoke().getClass(), oninvokeMethod));
++ }
++
++ String onreturnMethod = methodConfig.getOnreturnMethod();
++ if (StringUtils.isNotEmpty(onreturnMethod)) {
++ asyncMethodInfo.setOnreturnMethod(getMethodByName(methodConfig.getOnreturn().getClass(), onreturnMethod));
++ }
++
++ String onthrowMethod = methodConfig.getOnthrowMethod();
++ if (StringUtils.isNotEmpty(onthrowMethod)) {
++ asyncMethodInfo.setOnthrowMethod(getMethodByName(methodConfig.getOnthrow().getClass(), onthrowMethod));
++ }
++ } catch (Exception e) {
++ throw new IllegalStateException(e.getMessage(), e);
++ }
++
++ return asyncMethodInfo;
++ }
++
++ private static Method getMethodByName(Class<?> clazz, String methodName) {
++ try {
++ return ReflectUtils.findMethodByMethodName(clazz, methodName);
++ } catch (Exception e) {
++ throw new IllegalStateException(e);
++ }
++ }
++
+ private static boolean isPrimitive(Class<?> type) {
+ return type.isPrimitive()
+ || type == String.class
+ || type == Character.class
+ || type == Boolean.class
+ || type == Byte.class
+ || type == Short.class
+ || type == Integer.class
+ || type == Long.class
+ || type == Float.class
+ || type == Double.class
+ || type == Object.class;
+ }
+
+ private static Object convertPrimitive(Class<?> type, String value) {
+ if (type == char.class || type == Character.class) {
+ return value.length() > 0 ? value.charAt(0) : '\0';
+ } else if (type == boolean.class || type == Boolean.class) {
+ return Boolean.valueOf(value);
+ } else if (type == byte.class || type == Byte.class) {
+ return Byte.valueOf(value);
+ } else if (type == short.class || type == Short.class) {
+ return Short.valueOf(value);
+ } else if (type == int.class || type == Integer.class) {
+ return Integer.valueOf(value);
+ } else if (type == long.class || type == Long.class) {
+ return Long.valueOf(value);
+ } else if (type == float.class || type == Float.class) {
+ return Float.valueOf(value);
+ } else if (type == double.class || type == Double.class) {
+ return Double.valueOf(value);
+ }
+ return value;
+ }
+
+ protected static void checkExtension(Class<?> type, String property, String value) {
+ checkName(property, value);
+ if (value != null && value.length() > 0
+ && !ExtensionLoader.getExtensionLoader(type).hasExtension(value)) {
+ throw new IllegalStateException("No such extension " + value + " for " + property + "/" + type.getName());
+ }
+ }
+
+ protected static void checkMultiExtension(Class<?> type, String property, String value) {
+ checkMultiName(property, value);
+ if (value != null && value.length() > 0) {
+ String[] values = value.split("\\s*[,]+\\s*");
+ for (String v : values) {
+ if (v.startsWith(Constants.REMOVE_VALUE_PREFIX)) {
+ v = v.substring(1);
+ }
+ if (Constants.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 (parameters == null || parameters.size() == 0) {
+ 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 (value == null || value.length() == 0) {
+ 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.");
+ }
+ }
+ }
+
+ @Parameter(excluded = true)
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ protected void appendAnnotation(Class<?> annotationClass, Object annotation) {
+ Method[] methods = annotationClass.getMethods();
+ for (Method method : methods) {
+ if (method.getDeclaringClass() != Object.class
+ && method.getReturnType() != void.class
+ && method.getParameterTypes().length == 0
+ && Modifier.isPublic(method.getModifiers())
+ && !Modifier.isStatic(method.getModifiers())) {
+ try {
+ String property = method.getName();
+ if ("interfaceClass".equals(property) || "interfaceName".equals(property)) {
+ property = "interface";
+ }
+ String setter = "set" + property.substring(0, 1).toUpperCase() + property.substring(1);
+ Object value = method.invoke(annotation);
+ if (value != null && !value.equals(method.getDefaultValue())) {
+ Class<?> parameterType = ReflectUtils.getBoxedClass(method.getReturnType());
+ if ("filter".equals(property) || "listener".equals(property)) {
+ parameterType = String.class;
+ value = StringUtils.join((String[]) value, ",");
+ } else if ("parameters".equals(property)) {
+ parameterType = Map.class;
+ value = CollectionUtils.toStringMap((String[]) value);
+ }
+ try {
+ Method setterMethod = getClass().getMethod(setter, parameterType);
+ setterMethod.invoke(this, value);
+ } catch (NoSuchMethodException e) {
+ // ignore
+ }
+ }
+ } catch (Throwable e) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Should be called after Config was fully initialized.
+ *
+ * @return
+ */
+ public Map<String, String> getMetaData() {
+ metaData = new HashMap<>();
+ Method[] methods = this.getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ String name = method.getName();
+ if ((name.startsWith("get") || name.startsWith("is"))
+ && !name.equals("get")
+ && !"getClass".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && isPrimitive(method.getReturnType())) {
+ int i = name.startsWith("get") ? 3 : 2;
+ String prop = StringUtils.camelToSplitName(name.substring(i, i + 1).toLowerCase() + name.substring(i + 1), ".");
+ String key;
+ Parameter parameter = method.getAnnotation(Parameter.class);
+ if (parameter != null && parameter.key().length() > 0) {
+ key = parameter.key();
+ } else {
+ key = prop;
+ }
+ if (method.getReturnType() == Object.class || parameter != null && parameter.excluded()) {
+ metaData.put(key, null);
+ continue;
+ }
+ Object value = method.invoke(this);
+ String str = String.valueOf(value).trim();
+ if (value != null && str.length() > 0) {
+ if (parameter != null && parameter.escaped()) {
+ str = URL.encode(str);
+ }
+ if (parameter != null && parameter.append()) {
+ String pre = String.valueOf(metaData.get(Constants.DEFAULT_KEY + "." + key));
+ if (pre != null && pre.length() > 0) {
+ str = pre + "," + str;
+ }
+ pre = String.valueOf(metaData.get(key));
+ if (pre != null && pre.length() > 0) {
+ str = pre + "," + str;
+ }
+ }
+ /* if (prefix != null && prefix.length() > 0) {
+ key = prefix + "." + key;
+ }*/
+ metaData.put(key, str);
+ } else {
+ metaData.put(key, null);
+ }
+ // TODO check required somewhere else.
+ /*else if (parameter != null && parameter.required()) {
+ throw new IllegalStateException(this.getClass().getSimpleName() + "." + key + " == null");
+ }*/
+ } else if ("getParameters".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && method.getReturnType() == Map.class) {
+ Map<String, String> map = (Map<String, String>) method.invoke(this, new Object[0]);
+ if (map != null && map.size() > 0) {
+// String pre = (prefix != null && prefix.length() > 0 ? prefix + "." : "");
+ for (Map.Entry<String, String> entry : map.entrySet()) {
+ metaData.put(entry.getKey().replace('-', '.'), entry.getValue());
+ }
+ }
+ }
+ } catch (Exception e) {
+ System.out.println(this.getClass().getName());
+ System.out.println(method.getName());
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+ return metaData;
+ }
+
+ public String getPrefix() {
+ return Constants.DUBBO + "." + getTagName(this.getClass());
+ }
+
+ /**
+ * TODO
+ * Currently, only support overriding of properties explicitly defined in Config class, doesn't support overriding of customized parameters stored in 'parameters'.
+ */
+ @PostConstruct
+ public void refresh() {
+ if (init) {
+ return;
+ }
+ init = true;
+
+ try {
+ Configuration configuration = ConfigConverter.toConfiguration(this);
+ CompositeConfiguration compositeConfiguration = Environment.getInstance().getStartupCompositeConf(getPrefix(), getId());
+ int index = 1;
+ if (Environment.getInstance().isConfigCenterFirst()) {
+ index = 2;
+ }
+ compositeConfiguration.addConfiguration(index, configuration);
+ // loop methods, get override value and set the new value back to method
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods) {
+ if (isSetter(method)) {
+ try {
+ String value = compositeConfiguration.getString(extractPropertyName(method));
+ if (value != null) {
+ method.invoke(this, convertPrimitive(method.getParameterTypes()[0], value));
+ }
+ } catch (NoSuchMethodException e) {
+ logger.warn("Failed to override the property " + method.getName() + " in " + this.getClass().getSimpleName() + ", please make sure every property has a getter/setter pair.");
+ }
+ }
+ }
+ } catch (Exception e) {
+ logger.error("Failed to override ", e);
+ }
+ }
+
+ private static boolean isSetter(Method method) {
+ if (method.getName().startsWith("set")
+ && !"set".equals(method.getName())
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterCount() == 1
+ && isPrimitive(method.getParameterTypes()[0])) {
+ return true;
+ }
+ return false;
+ }
+
+ public String extractPropertyName(Method setter) throws Exception {
+ String propertyName = setter.getName().substring("set".length());
+ Method getter = null;
+ try {
+ getter = getClass().getMethod("get" + propertyName);
+ } catch (NoSuchMethodException e) {
+ getter = getClass().getMethod("is" + propertyName);
+ }
+ Parameter parameter = getter.getAnnotation(Parameter.class);
+ if (parameter != null && StringUtils.isNotEmpty(parameter.key())) {
+ propertyName = parameter.key();
+ } else {
+ propertyName = propertyName.toLowerCase();
+ }
+ return propertyName;
+ }
+
+ @Override
+ public String toString() {
+ try {
+ StringBuilder buf = new StringBuilder();
+ buf.append("<dubbo:");
+ buf.append(getTagName(getClass()));
+ Method[] methods = getClass().getMethods();
+ for (Method method : methods) {
+ try {
+ String name = method.getName();
+ if ((name.startsWith("get") || name.startsWith("is"))
+ && !"getClass".equals(name) && !"get".equals(name) && !"is".equals(name)
+ && Modifier.isPublic(method.getModifiers())
+ && method.getParameterTypes().length == 0
+ && isPrimitive(method.getReturnType())) {
+ int i = name.startsWith("get") ? 3 : 2;
+ String key = name.substring(i, i + 1).toLowerCase() + name.substring(i + 1);
+ Object value = method.invoke(this);
+ if (value != null) {
+ buf.append(" ");
+ buf.append(key);
+ buf.append("=\"");
+ buf.append(value);
+ buf.append("\"");
+ }
+ }
+ } catch (Exception e) {
+ logger.warn(e.getMessage(), e);
+ }
+ }
+ buf.append(" />");
+ return buf.toString();
+ } catch (Throwable t) {
+ logger.warn(t.getMessage(), t);
+ return super.toString();
+ }
+ }
+
+ /**
+ * FIXME check @Parameter(required=true) and any conditions that need to match.
+ */
+ public boolean isValid() {
+ return true;
+ }
+
+}
diff --cc dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 927fe51,61ed531..5587340
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@@ -24,21 -24,18 +24,19 @@@ import org.apache.dubbo.common.config.A
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
- import org.apache.dubbo.common.utils.ReflectUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
- import org.apache.dubbo.config.model.ApplicationModel;
- import org.apache.dubbo.config.model.ConsumerModel;
import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.metadata.integration.MetadataReportService;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
- import org.apache.dubbo.rpc.StaticContext;
import org.apache.dubbo.rpc.cluster.Cluster;
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
-import org.apache.dubbo.rpc.cluster.support.AvailableCluster;
import org.apache.dubbo.rpc.cluster.support.ClusterUtils;
+import org.apache.dubbo.rpc.cluster.support.RegistryAwareCluster;
+ import org.apache.dubbo.rpc.model.ApplicationModel;
+ import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.apache.dubbo.rpc.service.GenericService;
import org.apache.dubbo.rpc.support.ProtocolUtils;
diff --cc dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 608b52d,e2d3969..82cf3b3
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@@ -27,10 -27,7 +27,8 @@@ import org.apache.dubbo.common.utils.Na
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
- import org.apache.dubbo.config.model.ApplicationModel;
- import org.apache.dubbo.config.model.ProviderModel;
import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.metadata.integration.MetadataReportService;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
diff --cc dubbo-dependencies-bom/pom.xml
index 1c4cbc5,c95f748..242caab
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@@ -98,11 -98,7 +98,12 @@@
<kryo_version>4.0.1</kryo_version>
<kryo_serializers_version>0.42</kryo_serializers_version>
<fst_version>2.48-jdk-6</fst_version>
+ <apollo_client_version>1.1.1</apollo_client_version>
+ <archaius_version>0.7.6</archaius_version>
+ <snakeyaml_version>1.20</snakeyaml_version>
+ <commons_configuration_version>1.8</commons_configuration_version>
+ <commons_lang3_version>3.8.1</commons_lang3_version>
+ <protostuff_version>1.5.9</protostuff_version>
<rs_api_version>2.0</rs_api_version>
<resteasy_version>3.0.19.Final</resteasy_version>