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 2019/01/06 11:47:20 UTC
[incubator-dubbo] 01/01: resolve conflicts
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 2.7.0-release
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git
commit 90030e77676a2a4db262094877bd7b01479f1097
Merge: e6b340d ec8a5b9
Author: ken.lj <ke...@gmail.com>
AuthorDate: Sun Jan 6 19:45:21 2019 +0800
resolve conflicts
.../src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java | 1 -
.../src/main/java/org/apache/dubbo/config/ReferenceConfig.java | 1 +
.../test/java/org/apache/dubbo/config/AbstractInterfaceConfigTest.java | 2 ++
3 files changed, 3 insertions(+), 1 deletion(-)
diff --cc dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
index d8194d3,87cf709..657f21b
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java
@@@ -1,810 -1,737 +1,809 @@@
-/*
- * 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.Version;
-import org.apache.dubbo.common.config.Environment;
-import org.apache.dubbo.common.utils.Assert;
-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.common.utils.UrlUtils;
-import org.apache.dubbo.config.support.Parameter;
-import org.apache.dubbo.metadata.integration.MetadataReportService;
-import org.apache.dubbo.monitor.MonitorFactory;
-import org.apache.dubbo.monitor.MonitorService;
-import org.apache.dubbo.registry.RegistryService;
-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.model.ApplicationModel;
-import org.apache.dubbo.rpc.support.MockInvoker;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.dubbo.common.Constants.APPLICATION_KEY;
-import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
-
-/**
- * AbstractDefaultConfig
- *
- * @export
- */
-public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
-
- private static final long serialVersionUID = -1559314110797223229L;
-
- /**
- * Local impl class name for the service interface
- */
- protected String local;
-
- /**
- * Local stub class name for the service interface
- */
- protected String stub;
-
- /**
- * Service monitor
- */
- protected MonitorConfig monitor;
-
- /**
- * Strategies for generating dynamic agents,there are two strategies can be choosed: jdk and javassist
- */
- protected String proxy;
-
- /**
- * Cluster type
- */
- protected String cluster;
-
- /**
- * The {@link Filter} when the provicer side exposed a service or the customer side references a remote service used,
- * if there are more than one, you can use commas to separate them
- */
- protected String filter;
-
- /**
- * The Listener when the provider side exposes a service or the customer side references a remote service used
- * if there are more than one, you can use commas to separate them
- */
- protected String listener;
-
- /**
- * The owner of zhe service providers
- */
- protected String owner;
-
- /**
- * Connection limits, 0 means shared connection, otherwise it defines the connections delegated to the current service
- */
- protected Integer connections;
-
- /**
- * The layer of service providers
- */
- protected String layer;
-
- /**
- * The application info
- */
- protected ApplicationConfig application;
-
- /**
- * The module info
- */
- protected ModuleConfig module;
-
- /**
- * Registry centers
- */
- protected List<RegistryConfig> registries;
-
- protected String registryIds;
-
- // connection events
- protected String onconnect;
-
- /**
- * Disconnection events
- */
- protected String ondisconnect;
- protected MetadataReportConfig metadataReportConfig;
- // callback limits
- private Integer callbacks;
- // the scope for referring/exporting a service, if it's local, it means searching in current JVM only.
- private String scope;
-
- /**
- * Check whether the registry config is exists, and then conversion it to {@link RegistryConfig}
- */
- protected void checkRegistry() {
- loadRegistriesFromBackwardConfig();
-
- convertRegistryIdsToRegistries();
-
- for (RegistryConfig registryConfig : registries) {
- registryConfig.refresh();
- if (StringUtils.isNotEmpty(registryConfig.getId())) {
- registryConfig.setPrefix(Constants.REGISTRIES_SUFFIX);
- registryConfig.refresh();
- }
- }
-
- for (RegistryConfig registryConfig : registries) {
- if (!registryConfig.isValid()) {
- throw new IllegalStateException("No registry config found or it's not a valid config! " +
- "The registry config is: " + registryConfig);
- }
- }
-
- useRegistryForConfigIfNecessary();
- }
-
- @SuppressWarnings("deprecation")
- protected void checkApplication() {
- // for backward compatibility
- if (application == null) {
- application = new ApplicationConfig();
- }
-
- application.refresh();
-
- if (!application.isValid()) {
- throw new IllegalStateException("No application config found or it's not a valid config! " +
- "Please add <dubbo:application name=\"...\" /> to your spring config.");
- }
-
- ApplicationModel.setApplication(application.getName());
-
- // backward compatibility
- String wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_KEY);
- if (wait != null && wait.trim().length() > 0) {
- System.setProperty(Constants.SHUTDOWN_WAIT_KEY, wait.trim());
- } else {
- wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY);
- if (wait != null && wait.trim().length() > 0) {
- System.setProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY, wait.trim());
- }
- }
- }
-
- protected void checkMonitor() {
- if (monitor == null) {
- monitor = new MonitorConfig();
- }
-
- monitor.refresh();
-
- if (!monitor.isValid()) {
- logger.info("There's no valid monitor config found, if you want to open monitor statistics for Dubbo, " +
- "please make sure your monitor is configured properly.");
- }
- }
-
- protected void checkMetadataReport() {
- if (metadataReportConfig == null) {
- metadataReportConfig = new MetadataReportConfig();
- }
- metadataReportConfig.refresh();
- if (!metadataReportConfig.isValid()) {
- logger.warn("There's no valid metadata config found, if you are using the simplified mode of registry url, " +
- "please make sure you have a metadata address configured properly.");
- }
- }
-
-
- /**
- *
- * Load the registry and conversion it to {@link URL}, the priority order is: system property > dubbo registry config
- *
- * @param provider whether it is the provider side
- * @return
- */
- protected List<URL> loadRegistries(boolean provider) {
- // check && override if necessary
- List<URL> registryList = new ArrayList<URL>();
- if (registries != null && !registries.isEmpty()) {
- for (RegistryConfig config : registries) {
- String address = config.getAddress();
- if (StringUtils.isEmpty(address)) {
- address = Constants.ANYHOST_VALUE;
- }
- if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
- Map<String, String> map = new HashMap<String, String>();
- appendParameters(map, application);
- appendParameters(map, config);
- map.put("path", RegistryService.class.getName());
- appendRuntimeParameters(map);
- if (!map.containsKey("protocol")) {
- map.put("protocol", "dubbo");
- }
- List<URL> urls = UrlUtils.parseURLs(address, map);
-
- for (URL url : urls) {
- url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
- url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
- if ((provider && url.getParameter(Constants.REGISTER_KEY, true))
- || (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
- registryList.add(url);
- }
- }
- }
- }
- }
- return registryList;
- }
-
- /**
- *
- * Load the monitor config from the system properties and conversation it to {@link URL}
- *
- * @param registryURL
- * @return
- */
- protected URL loadMonitor(URL registryURL) {
- checkMonitor();
- Map<String, String> map = new HashMap<String, String>();
- map.put(Constants.INTERFACE_KEY, MonitorService.class.getName());
- appendRuntimeParameters(map);
- //set ip
- String hostToRegistry = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);
- if (hostToRegistry == null || hostToRegistry.length() == 0) {
- hostToRegistry = NetUtils.getLocalHost();
- } else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
- throw new IllegalArgumentException("Specified invalid registry ip from property:" +
- Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
- }
- map.put(Constants.REGISTER_IP_KEY, hostToRegistry);
- appendParameters(map, monitor);
- 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(Constants.PROTOCOL_KEY)) {
- if (getExtensionLoader(MonitorFactory.class).hasExtension("logstat")) {
- map.put(Constants.PROTOCOL_KEY, "logstat");
- } else {
- map.put(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
- }
- }
- return UrlUtils.parseURL(address, map);
- } else if (Constants.REGISTRY_PROTOCOL.equals(monitor.getProtocol()) && registryURL != null) {
- return registryURL.setProtocol(Constants.DOBBO_PROTOCOL).addParameter(Constants.PROTOCOL_KEY, Constants.REGISTRY_PROTOCOL).addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map));
- }
- return null;
- }
-
- static void appendRuntimeParameters(Map<String, String> map) {
- map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
- map.put(Constants.SPECIFICATION_VERSION_KEY, Version.getVersion());
- map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
- if (ConfigUtils.getPid() > 0) {
- map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
- }
- }
-
- private URL loadMetadataReporterURL(boolean provider) {
- this.checkApplication();
- String address = metadataReportConfig.getAddress();
- if (address == null || address.length() == 0) {
- return null;
- }
- Map<String, String> map = new HashMap<String, String>();
- map.put(APPLICATION_KEY, application.getName());
- appendParameters(map, metadataReportConfig);
- return UrlUtils.parseURL(address, map);
- }
-
- protected MetadataReportService getMetadataReportService() {
-
- if (metadataReportConfig == null || !metadataReportConfig.isValid()) {
- return null;
- }
- return MetadataReportService.instance(() -> {
- return loadMetadataReporterURL(true);
- });
- }
-
- /**
- * Check whether the remote service interface and the methods meet with Dubbo's requirements.it mainly check, if the
- * methods configured in the configuration file are included in the interface of remote service
- *
- * @param interfaceClass the interface of remote service
- * @param methods the methods configured
- */
- protected void checkInterfaceAndMethods(Class<?> interfaceClass, List<MethodConfig> methods) {
- // interface cannot be null
- Assert.notNull(interfaceClass, new IllegalStateException("interface not allow null!"));
-
- // to verify interfaceClass is an interface
- if (!interfaceClass.isInterface()) {
- throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
- }
- // check if methods exist in the remote service interface
- if (methods != null && !methods.isEmpty()) {
- for (MethodConfig methodBean : methods) {
- methodBean.setService(interfaceClass.getName());
- methodBean.setServiceId(this.getId());
- methodBean.refresh();
- String methodName = methodBean.getName();
- if (methodName == null || methodName.length() == 0) {
- throw new IllegalStateException("<dubbo:method> name attribute is required! Please check: " +
- "<dubbo:service interface=\"" + interfaceClass.getName() + "\" ... >" +
- "<dubbo:method name=\"\" ... /></<dubbo:reference>");
- }
-
- boolean hasMethod = Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> method.getName().equals(methodName));
- if (!hasMethod) {
- throw new IllegalStateException("The interface " + interfaceClass.getName()
- + " not found method " + methodName);
- }
- }
- }
- }
-
- /**
- * 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
- */
- void checkMock(Class<?> interfaceClass) {
- if (ConfigUtils.isEmpty(mock)) {
- return;
- }
-
- String normalizedMock = MockInvoker.normalizeMock(mock);
- if (normalizedMock.startsWith(Constants.RETURN_PREFIX)) {
- normalizedMock = normalizedMock.substring(Constants.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(Constants.THROW_PREFIX)) {
- normalizedMock = normalizedMock.substring(Constants.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);
- }
- }
-
- /**
- * Legitimacy check of stub, note that: the local will deprecated, and replace with <code>stub</code>
- *
- * @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
- */
- void checkStubAndLocal(Class<?> interfaceClass) {
- if (ConfigUtils.isNotEmpty(local)) {
- Class<?> localClass = ConfigUtils.isDefault(local) ?
- ReflectUtils.forName(interfaceClass.getName() + "Local") : ReflectUtils.forName(local);
- verify(interfaceClass, localClass);
- }
- if (ConfigUtils.isNotEmpty(stub)) {
- Class<?> localClass = ConfigUtils.isDefault(stub) ?
- ReflectUtils.forName(interfaceClass.getName() + "Stub") : ReflectUtils.forName(stub);
- verify(interfaceClass, localClass);
- }
- }
-
- private void verify(Class<?> interfaceClass, Class<?> localClass) {
- if (!interfaceClass.isAssignableFrom(localClass)) {
- throw new IllegalStateException("The local implementation class " + localClass.getName() +
- " not implement interface " + interfaceClass.getName());
- }
-
- try {
- //Check if the localClass a contructor with parameter who's type is interfaceClass
- ReflectUtils.findConstructor(localClass, interfaceClass);
- } catch (NoSuchMethodException e) {
- throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() +
- "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
- }
- }
-
- private void overrideParameters(Map<String, String> map) {
- map.put(Constants.PATH_KEY, RegistryService.class.getName());
- map.put(Constants.DOBBO_PROTOCOL, Version.getProtocolVersion());
- map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
- if (ConfigUtils.getPid() > 0) {
- map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
- }
- map.putIfAbsent(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
- }
-
- private void convertRegistryIdsToRegistries() {
- if (StringUtils.isEmpty(registryIds) && (registries == null || registries.isEmpty())) {
- Set<String> configedRegistries = new HashSet<>();
- configedRegistries.addAll(getSubProperties(Environment.getInstance().getExternalConfigurationMap(),
- Constants.REGISTRIES_SUFFIX));
- configedRegistries.addAll(getSubProperties(Environment.getInstance().getAppExternalConfigurationMap(),
- Constants.REGISTRIES_SUFFIX));
-
- registryIds = String.join(",", configedRegistries);
- }
-
- if (StringUtils.isEmpty(registryIds)) {
- if (registries == null || registries.isEmpty()) {
- registries = new ArrayList<>();
- registries.add(new RegistryConfig());
- }
- } else {
- String[] arr = Constants.COMMA_SPLIT_PATTERN.split(registryIds);
- if (registries == null || registries.isEmpty()) {
- registries = new ArrayList<>();
- }
- Arrays.stream(arr).forEach(id -> {
- if (registries.stream().noneMatch(reg -> reg.getId().equals(id))) {
- RegistryConfig registryConfig = new RegistryConfig();
- registryConfig.setId(id);
- registries.add(registryConfig);
- }
- });
- if (registries.size() > arr.length) {
- throw new IllegalStateException("Too much registries found, the registries assigned to this service " +
- "are :" + registryIds + ", but got " + registries.size() + " registries!");
- }
- }
-
- }
-
- private void loadRegistriesFromBackwardConfig() {
- // for backward compatibility
- // -Ddubbo.registry.address is now deprecated.
- if (registries == null || registries.isEmpty()) {
- String address = ConfigUtils.getProperty("dubbo.registry.address");
- if (address != null && address.length() > 0) {
- registries = new ArrayList<RegistryConfig>();
- String[] as = address.split("\\s*[|]+\\s*");
- for (String a : as) {
- RegistryConfig registryConfig = new RegistryConfig();
- registryConfig.setAddress(a);
- registries.add(registryConfig);
- }
- }
- }
- }
-
- /**
- * For compatibility purpose, use registry as the default config center if the registry protocol is zookeeper and
- * there's no config center specified explicitly.
- */
- private void useRegistryForConfigIfNecessary() {
- registries.stream().filter(RegistryConfig::isZookeeperProtocol).findFirst().ifPresent(rc -> {
- // we use the loading status of DynamicConfiguration to decide whether ConfigCenter has been initiated.
- Environment.getInstance().getDynamicConfiguration().orElseGet(() -> {
- ConfigCenterConfig configCenterConfig = new ConfigCenterConfig();
- configCenterConfig.setProtocol(rc.getProtocol());
- configCenterConfig.setAddress(rc.getAddress());
- configCenterConfig.setHighestPriority(false);
- configCenterConfig.init();
- return null;
- });
- });
- }
-
- /**
- * @return local
- * @deprecated Replace to <code>getStub()</code>
- */
- @Deprecated
- public String getLocal() {
- return local;
- }
-
- /**
- * @param local
- * @deprecated Replace to <code>setStub(Boolean)</code>
- */
- @Deprecated
- public void setLocal(Boolean local) {
- if (local == null) {
- setLocal((String) null);
- } else {
- setLocal(String.valueOf(local));
- }
- }
-
- /**
- * @param local
- * @deprecated Replace to <code>setStub(String)</code>
- */
- @Deprecated
- public void setLocal(String local) {
- checkName("local", local);
- this.local = local;
- }
-
- public String getStub() {
- return stub;
- }
-
- public void setStub(Boolean stub) {
- if (stub == null) {
- setStub((String) null);
- } else {
- setStub(String.valueOf(stub));
- }
- }
-
- public void setStub(String stub) {
- checkName("stub", stub);
- this.stub = stub;
- }
-
- public String getCluster() {
- return cluster;
- }
-
- public void setCluster(String cluster) {
- checkExtension(Cluster.class, "cluster", cluster);
- this.cluster = cluster;
- }
-
- public String getProxy() {
- return proxy;
- }
-
- public void setProxy(String proxy) {
- checkExtension(ProxyFactory.class, "proxy", proxy);
- this.proxy = proxy;
- }
-
- public Integer getConnections() {
- return connections;
- }
-
- public void setConnections(Integer connections) {
- this.connections = connections;
- }
-
- @Parameter(key = Constants.REFERENCE_FILTER_KEY, append = true)
- public String getFilter() {
- return filter;
- }
-
- public void setFilter(String filter) {
- checkMultiExtension(Filter.class, "filter", filter);
- this.filter = filter;
- }
-
- @Parameter(key = Constants.INVOKER_LISTENER_KEY, append = true)
- public String getListener() {
- return listener;
- }
-
- public void setListener(String listener) {
- checkMultiExtension(InvokerListener.class, "listener", listener);
- this.listener = listener;
- }
-
- public String getLayer() {
- return layer;
- }
-
- public void setLayer(String layer) {
- checkNameHasSymbol("layer", layer);
- this.layer = layer;
- }
-
- public ApplicationConfig getApplication() {
- return application;
- }
-
- public void setApplication(ApplicationConfig application) {
- this.application = application;
- }
-
- public ModuleConfig getModule() {
- return module;
- }
-
- public void setModule(ModuleConfig module) {
- this.module = module;
- }
-
- public RegistryConfig getRegistry() {
- return registries == null || registries.isEmpty() ? null : registries.get(0);
- }
-
- public void setRegistry(RegistryConfig registry) {
- List<RegistryConfig> registries = new ArrayList<RegistryConfig>(1);
- registries.add(registry);
- this.registries = registries;
- }
-
- public List<RegistryConfig> getRegistries() {
- return registries;
- }
-
- @SuppressWarnings({"unchecked"})
- public void setRegistries(List<? extends RegistryConfig> registries) {
- this.registries = (List<RegistryConfig>) registries;
- }
-
- @Parameter(excluded = true)
- public String getRegistryIds() {
- return registryIds;
- }
-
- public void setRegistryIds(String registryIds) {
- this.registryIds = registryIds;
- }
-
- public MonitorConfig getMonitor() {
- return monitor;
- }
-
- public void setMonitor(String monitor) {
- this.monitor = new MonitorConfig(monitor);
- }
-
- public void setMonitor(MonitorConfig monitor) {
- this.monitor = monitor;
- }
-
- public String getOwner() {
- return owner;
- }
-
- public void setOwner(String owner) {
- checkMultiName("owner", owner);
- this.owner = owner;
- }
-
- public Integer getCallbacks() {
- return callbacks;
- }
-
- public void setCallbacks(Integer callbacks) {
- this.callbacks = callbacks;
- }
-
- public String getOnconnect() {
- return onconnect;
- }
-
- public void setOnconnect(String onconnect) {
- this.onconnect = onconnect;
- }
-
- public String getOndisconnect() {
- return ondisconnect;
- }
-
- public void setOndisconnect(String ondisconnect) {
- this.ondisconnect = ondisconnect;
- }
-
- public String getScope() {
- return scope;
- }
-
- public void setScope(String scope) {
- this.scope = scope;
- }
-
- public MetadataReportConfig getMetadataReportConfig() {
- return metadataReportConfig;
- }
-
- public void setMetadataReportConfig(MetadataReportConfig metadataReportConfig) {
- this.metadataReportConfig = metadataReportConfig;
- }
-
-}
+/*
+ * 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.Version;
+import org.apache.dubbo.common.config.Environment;
+import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.Assert;
+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.common.utils.UrlUtils;
+import org.apache.dubbo.config.context.ConfigManager;
+import org.apache.dubbo.config.support.Parameter;
+import org.apache.dubbo.configcenter.DynamicConfiguration;
+import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
+import org.apache.dubbo.metadata.integration.MetadataReportService;
+import org.apache.dubbo.monitor.MonitorFactory;
+import org.apache.dubbo.monitor.MonitorService;
+import org.apache.dubbo.registry.RegistryService;
+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.model.ApplicationModel;
+import org.apache.dubbo.rpc.support.MockInvoker;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.dubbo.common.Constants.APPLICATION_KEY;
+import static org.apache.dubbo.common.config.ConfigurationUtils.parseProperties;
+import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
+
+/**
+ * AbstractDefaultConfig
+ *
+ * @export
+ */
+public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
+
+ private static final long serialVersionUID = -1559314110797223229L;
+
+ /**
+ * Local impl class name for the service interface
+ */
+ protected String local;
+
+ /**
+ * Local stub class name for the service interface
+ */
+ protected String stub;
+
+ /**
+ * Service monitor
+ */
+ protected MonitorConfig monitor;
+
+ /**
+ * Strategies for generating dynamic agents,there are two strategies can be choosed: jdk and javassist
+ */
+ protected String proxy;
+
+ /**
+ * Cluster type
+ */
+ protected String cluster;
+
+ /**
+ * The {@link Filter} when the provicer side exposed a service or the customer side references a remote service used,
+ * if there are more than one, you can use commas to separate them
+ */
+ protected String filter;
+
+ /**
+ * The Listener when the provider side exposes a service or the customer side references a remote service used
+ * if there are more than one, you can use commas to separate them
+ */
+ protected String listener;
+
+ /**
+ * The owner of zhe service providers
+ */
+ protected String owner;
+
+ /**
+ * Connection limits, 0 means shared connection, otherwise it defines the connections delegated to the current service
+ */
+ protected Integer connections;
+
+ /**
+ * The layer of service providers
+ */
+ protected String layer;
+
+ /**
+ * The application info
+ */
+ protected ApplicationConfig application;
+
+ /**
+ * The module info
+ */
+ protected ModuleConfig module;
+
+ /**
+ * Registry centers
+ */
+ protected List<RegistryConfig> registries;
+
+ protected String registryIds;
+
+ // connection events
+ protected String onconnect;
+
+ /**
+ * Disconnection events
+ */
+ protected String ondisconnect;
+ protected MetadataReportConfig metadataReportConfig;
+
+ protected ConfigCenterConfig configCenter;
+
+ // callback limits
+ private Integer callbacks;
+ // the scope for referring/exporting a service, if it's local, it means searching in current JVM only.
+ private String scope;
+
+ /**
+ * Check whether the registry config is exists, and then conversion it to {@link RegistryConfig}
+ */
+ protected void checkRegistry() {
+ loadRegistriesFromBackwardConfig();
+
+ convertRegistryIdsToRegistries();
+
+ setRegistries(this.registries);
+
+ for (RegistryConfig registryConfig : registries) {
+ registryConfig.refresh();
+ if (StringUtils.isNotEmpty(registryConfig.getId())) {
+ registryConfig.setPrefix(Constants.REGISTRIES_SUFFIX);
+ registryConfig.refresh();
+ }
+ }
+
+ for (RegistryConfig registryConfig : registries) {
+ if (!registryConfig.isValid()) {
+ throw new IllegalStateException("No registry config found or it's not a valid config! " +
+ "The registry config is: " + registryConfig);
+ }
+ }
+
+ useRegistryForConfigIfNecessary();
+ }
+
+ @SuppressWarnings("deprecation")
+ protected void checkApplication() {
+ // for backward compatibility
+ createApplicationIfAbsent();
+
+ application.refresh();
+
+ if (!application.isValid()) {
+ throw new IllegalStateException("No application config found or it's not a valid config! " +
+ "Please add <dubbo:application name=\"...\" /> to your spring config.");
+ }
+
+ ApplicationModel.setApplication(application.getName());
+
+ // backward compatibility
+ String wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_KEY);
+ if (wait != null && wait.trim().length() > 0) {
+ System.setProperty(Constants.SHUTDOWN_WAIT_KEY, wait.trim());
+ } else {
+ wait = ConfigUtils.getProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY);
+ if (wait != null && wait.trim().length() > 0) {
+ System.setProperty(Constants.SHUTDOWN_WAIT_SECONDS_KEY, wait.trim());
+ }
+ }
+ }
+
+ protected void checkMonitor() {
+ createMonitorIfAbsent();
+ monitor.refresh();
+ if (!monitor.isValid()) {
+ logger.info("There's no valid monitor config found, if you want to open monitor statistics for Dubbo, " +
+ "please make sure your monitor is configured properly.");
+ }
+ }
+
+ private void createMonitorIfAbsent() {
+ if (this.monitor != null) {
+ return;
+ }
+ ConfigManager configManager = ConfigManager.getInstance();
+ setMonitor(configManager.getMonitor().orElse(new MonitorConfig()));
+ }
+
+ protected void checkMetadataReport() {
+ // TODO get from ConfigManager first, only create if absent.
+ if (metadataReportConfig == null) {
+ setMetadataReportConfig(new MetadataReportConfig());
+ }
+ metadataReportConfig.refresh();
+ if (!metadataReportConfig.isValid()) {
+ logger.warn("There's no valid metadata config found, if you are using the simplified mode of registry url, " +
+ "please make sure you have a metadata address configured properly.");
+ }
+ }
+
+
+ void checkConfigCenter() {
+ if (configCenter == null) {
+ return;
+ }
+ // give jvm properties the chance to override local configs, e.g., -Ddubbo.configcenter.highestPriority
+ configCenter.refresh();
+ prepareEnvironment();
+ }
+
+ private void prepareEnvironment() {
+ if (configCenter.isValid()) {
+ if (!configCenter.checkOrUpdateInited()) {
+ return;
+ }
+ DynamicConfiguration dynamicConfiguration = getDynamicConfiguration(configCenter.toUrl());
+ String configContent = dynamicConfiguration.getConfig(configCenter.getConfigFile(), configCenter.getGroup());
+
+ String appGroup = application != null ? application.getName() : null;
+ String appConfigContent = null;
+ if (StringUtils.isNotEmpty(appGroup)) {
+ appConfigContent = dynamicConfiguration.getConfig
+ (StringUtils.isNotEmpty(configCenter.getAppConfigFile()) ? configCenter.getAppConfigFile() : configCenter.getConfigFile(),
+ appGroup
+ );
+ }
+ try {
+ Environment.getInstance().setConfigCenterFirst(configCenter.isHighestPriority());
+ Environment.getInstance().updateExternalConfigurationMap(parseProperties(configContent));
+ Environment.getInstance().updateAppExternalConfigurationMap(parseProperties(appConfigContent));
+ } catch (IOException e) {
+ throw new IllegalStateException("Failed to parse configurations from Config Center.", e);
+ }
+ }
+ }
+
+ private DynamicConfiguration getDynamicConfiguration(URL url) {
+ DynamicConfigurationFactory factories = ExtensionLoader
+ .getExtensionLoader(DynamicConfigurationFactory.class)
+ .getExtension(url.getProtocol());
+ DynamicConfiguration configuration = factories.getDynamicConfiguration(url);
+ Environment.getInstance().setDynamicConfiguration(configuration);
+ return configuration;
+ }
+
+ /**
+ *
+ * Load the registry and conversion it to {@link URL}, the priority order is: system property > dubbo registry config
+ *
+ * @param provider whether it is the provider side
+ * @return
+ */
+ protected List<URL> loadRegistries(boolean provider) {
+ // check && override if necessary
- checkRegistry();
+ List<URL> registryList = new ArrayList<URL>();
+ if (registries != null && !registries.isEmpty()) {
+ for (RegistryConfig config : registries) {
+ String address = config.getAddress();
+ if (StringUtils.isEmpty(address)) {
+ address = Constants.ANYHOST_VALUE;
+ }
+ if (!RegistryConfig.NO_AVAILABLE.equalsIgnoreCase(address)) {
+ Map<String, String> map = new HashMap<String, String>();
+ appendParameters(map, application);
+ appendParameters(map, config);
+ map.put("path", RegistryService.class.getName());
+ appendRuntimeParameters(map);
+ if (!map.containsKey("protocol")) {
+ map.put("protocol", "dubbo");
+ }
+ List<URL> urls = UrlUtils.parseURLs(address, map);
+
+ for (URL url : urls) {
+ url = url.addParameter(Constants.REGISTRY_KEY, url.getProtocol());
+ url = url.setProtocol(Constants.REGISTRY_PROTOCOL);
+ if ((provider && url.getParameter(Constants.REGISTER_KEY, true))
+ || (!provider && url.getParameter(Constants.SUBSCRIBE_KEY, true))) {
+ registryList.add(url);
+ }
+ }
+ }
+ }
+ }
+ return registryList;
+ }
+
+ /**
+ *
+ * Load the monitor config from the system properties and conversation it to {@link URL}
+ *
+ * @param registryURL
+ * @return
+ */
+ protected URL loadMonitor(URL registryURL) {
+ checkMonitor();
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(Constants.INTERFACE_KEY, MonitorService.class.getName());
+ appendRuntimeParameters(map);
+ //set ip
+ String hostToRegistry = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY);
+ if (hostToRegistry == null || hostToRegistry.length() == 0) {
+ hostToRegistry = NetUtils.getLocalHost();
+ } else if (NetUtils.isInvalidLocalHost(hostToRegistry)) {
+ throw new IllegalArgumentException("Specified invalid registry ip from property:" +
+ Constants.DUBBO_IP_TO_REGISTRY + ", value:" + hostToRegistry);
+ }
+ map.put(Constants.REGISTER_IP_KEY, hostToRegistry);
+ appendParameters(map, monitor);
+ 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(Constants.PROTOCOL_KEY)) {
+ if (getExtensionLoader(MonitorFactory.class).hasExtension("logstat")) {
+ map.put(Constants.PROTOCOL_KEY, "logstat");
+ } else {
+ map.put(Constants.PROTOCOL_KEY, Constants.DOBBO_PROTOCOL);
+ }
+ }
+ return UrlUtils.parseURL(address, map);
+ } else if (Constants.REGISTRY_PROTOCOL.equals(monitor.getProtocol()) && registryURL != null) {
+ return registryURL.setProtocol(Constants.DOBBO_PROTOCOL).addParameter(Constants.PROTOCOL_KEY, Constants.REGISTRY_PROTOCOL).addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map));
+ }
+ return null;
+ }
+
+ static void appendRuntimeParameters(Map<String, String> map) {
+ map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion());
+ map.put(Constants.SPECIFICATION_VERSION_KEY, Version.getVersion());
+ map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis()));
+ if (ConfigUtils.getPid() > 0) {
+ map.put(Constants.PID_KEY, String.valueOf(ConfigUtils.getPid()));
+ }
+ }
+
+ private URL loadMetadataReporterURL(boolean provider) {
+ this.checkApplication();
+ String address = metadataReportConfig.getAddress();
+ if (address == null || address.length() == 0) {
+ return null;
+ }
+ Map<String, String> map = new HashMap<String, String>();
+ map.put(APPLICATION_KEY, application.getName());
+ appendParameters(map, metadataReportConfig);
+ return UrlUtils.parseURL(address, map);
+ }
+
+ protected MetadataReportService getMetadataReportService() {
+
+ if (metadataReportConfig == null || !metadataReportConfig.isValid()) {
+ return null;
+ }
+ return MetadataReportService.instance(() -> {
+ return loadMetadataReporterURL(true);
+ });
+ }
+
+ /**
+ * Check whether the remote service interface and the methods meet with Dubbo's requirements.it mainly check, if the
+ * methods configured in the configuration file are included in the interface of remote service
+ *
+ * @param interfaceClass the interface of remote service
+ * @param methods the methods configured
+ */
+ protected void checkInterfaceAndMethods(Class<?> interfaceClass, List<MethodConfig> methods) {
+ // interface cannot be null
+ Assert.notNull(interfaceClass, new IllegalStateException("interface not allow null!"));
+
+ // to verify interfaceClass is an interface
+ if (!interfaceClass.isInterface()) {
+ throw new IllegalStateException("The interface class " + interfaceClass + " is not a interface!");
+ }
+ // check if methods exist in the remote service interface
+ if (methods != null && !methods.isEmpty()) {
+ for (MethodConfig methodBean : methods) {
+ methodBean.setService(interfaceClass.getName());
+ methodBean.setServiceId(this.getId());
+ methodBean.refresh();
+ String methodName = methodBean.getName();
+ if (methodName == null || methodName.length() == 0) {
+ throw new IllegalStateException("<dubbo:method> name attribute is required! Please check: " +
+ "<dubbo:service interface=\"" + interfaceClass.getName() + "\" ... >" +
+ "<dubbo:method name=\"\" ... /></<dubbo:reference>");
+ }
+
+ boolean hasMethod = Arrays.stream(interfaceClass.getMethods()).anyMatch(method -> method.getName().equals(methodName));
+ if (!hasMethod) {
+ throw new IllegalStateException("The interface " + interfaceClass.getName()
+ + " not found method " + methodName);
+ }
+ }
+ }
+ }
+
+ /**
+ * 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
+ */
+ void checkMock(Class<?> interfaceClass) {
+ if (ConfigUtils.isEmpty(mock)) {
+ return;
+ }
+
+ String normalizedMock = MockInvoker.normalizeMock(mock);
+ if (normalizedMock.startsWith(Constants.RETURN_PREFIX)) {
+ normalizedMock = normalizedMock.substring(Constants.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(Constants.THROW_PREFIX)) {
+ normalizedMock = normalizedMock.substring(Constants.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);
+ }
+ }
+
+ /**
+ * Legitimacy check of stub, note that: the local will deprecated, and replace with <code>stub</code>
+ *
+ * @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
+ */
+ void checkStubAndLocal(Class<?> interfaceClass) {
+ if (ConfigUtils.isNotEmpty(local)) {
+ Class<?> localClass = ConfigUtils.isDefault(local) ?
+ ReflectUtils.forName(interfaceClass.getName() + "Local") : ReflectUtils.forName(local);
+ verify(interfaceClass, localClass);
+ }
+ if (ConfigUtils.isNotEmpty(stub)) {
+ Class<?> localClass = ConfigUtils.isDefault(stub) ?
+ ReflectUtils.forName(interfaceClass.getName() + "Stub") : ReflectUtils.forName(stub);
+ verify(interfaceClass, localClass);
+ }
+ }
+
+ private void verify(Class<?> interfaceClass, Class<?> localClass) {
+ if (!interfaceClass.isAssignableFrom(localClass)) {
+ throw new IllegalStateException("The local implementation class " + localClass.getName() +
+ " not implement interface " + interfaceClass.getName());
+ }
+
+ try {
+ //Check if the localClass a contructor with parameter who's type is interfaceClass
+ ReflectUtils.findConstructor(localClass, interfaceClass);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException("No such constructor \"public " + localClass.getSimpleName() +
+ "(" + interfaceClass.getName() + ")\" in local implementation class " + localClass.getName());
+ }
+ }
+
+ private void convertRegistryIdsToRegistries() {
+ if (StringUtils.isEmpty(registryIds) && (registries == null || registries.isEmpty())) {
+ Set<String> configedRegistries = new HashSet<>();
+ configedRegistries.addAll(getSubProperties(Environment.getInstance().getExternalConfigurationMap(),
+ Constants.REGISTRIES_SUFFIX));
+ configedRegistries.addAll(getSubProperties(Environment.getInstance().getAppExternalConfigurationMap(),
+ Constants.REGISTRIES_SUFFIX));
+
+ registryIds = String.join(",", configedRegistries);
+ }
+
+ if (StringUtils.isEmpty(registryIds)) {
+ if (registries == null || registries.isEmpty()) {
+ registries = ConfigManager.getInstance().getDefaultRegistries().orElse(Arrays.asList(new RegistryConfig()));
+ }
+ } else {
+ String[] arr = Constants.COMMA_SPLIT_PATTERN.split(registryIds);
+ if (registries == null || registries.isEmpty()) {
+ registries = new ArrayList<>();
+ }
+ Arrays.stream(arr).forEach(id -> {
+ if (registries.stream().noneMatch(reg -> reg.getId().equals(id))) {
+ registries.add(ConfigManager.getInstance().getRegistry(id).orElseGet(() -> {
+ RegistryConfig registryConfig = new RegistryConfig();
+ registryConfig.setId(id);
+ return registryConfig;
+ }));
+ }
+ });
+ if (registries.size() > arr.length) {
+ throw new IllegalStateException("Too much registries found, the registries assigned to this service " +
+ "are :" + registryIds + ", but got " + registries.size() + " registries!");
+ }
+ }
+
+ }
+
+ private void loadRegistriesFromBackwardConfig() {
+ // for backward compatibility
+ // -Ddubbo.registry.address is now deprecated.
+ if (registries == null || registries.isEmpty()) {
+ String address = ConfigUtils.getProperty("dubbo.registry.address");
+ if (address != null && address.length() > 0) {
+ registries = new ArrayList<RegistryConfig>();
+ String[] as = address.split("\\s*[|]+\\s*");
+ for (String a : as) {
+ RegistryConfig registryConfig = new RegistryConfig();
+ registryConfig.setAddress(a);
+ registries.add(registryConfig);
+ }
+ }
+ }
+ }
+
+ /**
+ * For compatibility purpose, use registry as the default config center if the registry protocol is zookeeper and
+ * there's no config center specified explicitly.
+ */
+ private void useRegistryForConfigIfNecessary() {
+ registries.stream().filter(RegistryConfig::isZookeeperProtocol).findFirst().ifPresent(rc -> {
+ // we use the loading status of DynamicConfiguration to decide whether ConfigCenter has been initiated.
+ Environment.getInstance().getDynamicConfiguration().orElseGet(() -> {
+ ConfigManager configManager = ConfigManager.getInstance();
+ ConfigCenterConfig cc = configManager.getConfigCenter().orElse(new ConfigCenterConfig());
+ cc.setProtocol(rc.getProtocol());
+ cc.setAddress(rc.getAddress());
+ cc.setHighestPriority(false);
+ setConfigCenter(cc);
+ prepareEnvironment();
+ return null;
+ });
+ });
+ }
+
+ /**
+ * @return local
+ * @deprecated Replace to <code>getStub()</code>
+ */
+ @Deprecated
+ public String getLocal() {
+ return local;
+ }
+
+ /**
+ * @param local
+ * @deprecated Replace to <code>setStub(Boolean)</code>
+ */
+ @Deprecated
+ public void setLocal(Boolean local) {
+ if (local == null) {
+ setLocal((String) null);
+ } else {
+ setLocal(String.valueOf(local));
+ }
+ }
+
+ /**
+ * @param local
+ * @deprecated Replace to <code>setStub(String)</code>
+ */
+ @Deprecated
+ public void setLocal(String local) {
+ checkName("local", local);
+ this.local = local;
+ }
+
+ public String getStub() {
+ return stub;
+ }
+
+ public void setStub(Boolean stub) {
+ if (stub == null) {
+ setStub((String) null);
+ } else {
+ setStub(String.valueOf(stub));
+ }
+ }
+
+ public void setStub(String stub) {
+ checkName("stub", stub);
+ this.stub = stub;
+ }
+
+ public String getCluster() {
+ return cluster;
+ }
+
+ public void setCluster(String cluster) {
+ checkExtension(Cluster.class, "cluster", cluster);
+ this.cluster = cluster;
+ }
+
+ public String getProxy() {
+ return proxy;
+ }
+
+ public void setProxy(String proxy) {
+ checkExtension(ProxyFactory.class, "proxy", proxy);
+ this.proxy = proxy;
+ }
+
+ public Integer getConnections() {
+ return connections;
+ }
+
+ public void setConnections(Integer connections) {
+ this.connections = connections;
+ }
+
+ @Parameter(key = Constants.REFERENCE_FILTER_KEY, append = true)
+ public String getFilter() {
+ return filter;
+ }
+
+ public void setFilter(String filter) {
+ checkMultiExtension(Filter.class, "filter", filter);
+ this.filter = filter;
+ }
+
+ @Parameter(key = Constants.INVOKER_LISTENER_KEY, append = true)
+ public String getListener() {
+ return listener;
+ }
+
+ public void setListener(String listener) {
+ checkMultiExtension(InvokerListener.class, "listener", listener);
+ this.listener = listener;
+ }
+
+ public String getLayer() {
+ return layer;
+ }
+
+ public void setLayer(String layer) {
+ checkNameHasSymbol("layer", layer);
+ this.layer = layer;
+ }
+
+ public ApplicationConfig getApplication() {
+ return application;
+ }
+
+ public void setApplication(ApplicationConfig application) {
+ this.application = application;
+ ConfigManager.getInstance().setApplication(this.application);
+ }
+
+ private void createApplicationIfAbsent() {
+ if (this.application != null) {
+ return;
+ }
+ ConfigManager configManager = ConfigManager.getInstance();
+ setApplication(configManager.getApplication().orElse(new ApplicationConfig()));
+ }
+
+ public ModuleConfig getModule() {
+ return module;
+ }
+
+ public void setModule(ModuleConfig module) {
+ this.module = module;
+ ConfigManager.getInstance().setModule(module);
+ }
+
+ public RegistryConfig getRegistry() {
+ return registries == null || registries.isEmpty() ? null : registries.get(0);
+ }
+
+ public void setRegistry(RegistryConfig registry) {
+ List<RegistryConfig> registries = new ArrayList<RegistryConfig>(1);
+ registries.add(registry);
+ setRegistries(registries);
+ }
+
+ public List<RegistryConfig> getRegistries() {
+ return registries;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void setRegistries(List<? extends RegistryConfig> registries) {
+ this.registries = (List<RegistryConfig>) registries;
+ ConfigManager.getInstance().addRegistries(this.registries);
+ }
+
+ @Parameter(excluded = true)
+ public String getRegistryIds() {
+ return registryIds;
+ }
+
+ public void setRegistryIds(String registryIds) {
+ this.registryIds = registryIds;
+ }
+
+ public MonitorConfig getMonitor() {
+ return monitor;
+ }
+
+ public void setMonitor(String monitor) {
+ this.monitor = new MonitorConfig(monitor);
+ }
+
+ public void setMonitor(MonitorConfig monitor) {
+ this.monitor = monitor;
+ ConfigManager.getInstance().setMonitor(monitor);
+ }
+
+ public String getOwner() {
+ return owner;
+ }
+
+ public void setOwner(String owner) {
+ checkMultiName("owner", owner);
+ this.owner = owner;
+ }
+
+ public ConfigCenterConfig getConfigCenter() {
+ return configCenter;
+ }
+
+ public void setConfigCenter(ConfigCenterConfig configCenter) {
+ this.configCenter = configCenter;
+ ConfigManager.getInstance().setConfigCenter(configCenter);
+ }
+
+ public Integer getCallbacks() {
+ return callbacks;
+ }
+
+ public void setCallbacks(Integer callbacks) {
+ this.callbacks = callbacks;
+ }
+
+ public String getOnconnect() {
+ return onconnect;
+ }
+
+ public void setOnconnect(String onconnect) {
+ this.onconnect = onconnect;
+ }
+
+ public String getOndisconnect() {
+ return ondisconnect;
+ }
+
+ public void setOndisconnect(String ondisconnect) {
+ this.ondisconnect = ondisconnect;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public MetadataReportConfig getMetadataReportConfig() {
+ return metadataReportConfig;
+ }
+
+ public void setMetadataReportConfig(MetadataReportConfig metadataReportConfig) {
+ this.metadataReportConfig = metadataReportConfig;
+ }
+
+}
diff --cc dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index ecabbab,5dcf189..a88529b
--- 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
@@@ -211,7 -208,17 +211,8 @@@ public class ReferenceConfig<T> extend
checkInterfaceAndMethods(interfaceClass, methods);
}
resolveFile();
- if (consumer != null) {
- inheritIfAbsentFromConsumer();
- }
- if (module != null) {
- inheritIfAbsentFromModule();
- }
- if (application != null) {
- inheritIfAbsentFromApplication();
- }
checkApplication();
+ checkRegistry();
checkMetadataReport();
}