refactor config-center implementation

This commit is contained in:
ken.lj 2018-12-03 15:59:52 +08:00
parent 38a8fad488
commit 00b15a44c6
36 changed files with 458 additions and 263 deletions

View File

@ -21,7 +21,6 @@ import org.apache.dubbo.common.URL;
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.StringUtils;
import org.apache.dubbo.configcenter.ConfigChangeEvent;
import org.apache.dubbo.configcenter.ConfigChangeType;
import org.apache.dubbo.configcenter.ConfigurationListener;
@ -58,33 +57,25 @@ public class ConfigConditionRouter extends AbstractRouter implements Configurati
this.configuration = configuration;
this.force = false;
this.url = url;
try {
String rawRule = this.configuration.getConfig(url.getEncodedServiceKey() + Constants.ROUTERS_SUFFIX, this);
String appRawRule = this.configuration.getConfig(url.getParameter(Constants.APPLICATION_KEY) + Constants.ROUTERS_SUFFIX, this);
if (!StringUtils.isEmpty(rawRule)) {
try {
routerRule = ConditionRuleParser.parse(rawRule);
generateConditions();
} catch (Exception e) {
logger.error("Failed to parse the raw condition rule and it will not take effect, please check if the condition rule matches with the template, the raw rule is: \n" + rawRule, e);
}
}
if (!StringUtils.isEmpty(appRawRule)) {
try {
appRouterRule = ConditionRuleParser.parse(appRawRule);
generateAppConditions();
} catch (Exception e) {
logger.error("Failed to parse the raw condition rule and it will not take effect, please check if the condition rule matches with the template, the raw rule is: \n" + appRawRule, e);
}
}
} catch (Exception e) {
throw new IllegalStateException("Failed to init the condition router for service " + url.getServiceKey() + ", application " + url.getParameter(Constants.APPLICATION_KEY), e);
synchronized (this) {
String appKey = url.getParameter(Constants.APPLICATION_KEY) + Constants.ROUTERS_SUFFIX;
configuration.addListener(appKey, this);
String appRawRule = configuration.getConfig(appKey);
if (appRawRule != null) {
this.process(new ConfigChangeEvent(appKey, appRawRule));
}
String key = url.getEncodedServiceKey() + Constants.ROUTERS_SUFFIX;
configuration.addListener(key, this);
String rawRule = configuration.getConfig(key);
if (rawRule != null) {
this.process(new ConfigChangeEvent(key, rawRule));
}
}
}
@Override
public void process(ConfigChangeEvent event) {
public synchronized void process(ConfigChangeEvent event) {
if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
// Now, we can only recognize if it's a app level or service level change by try to match event key.
if (event.getKey().endsWith(this.url.getParameter(Constants.APPLICATION_KEY) + Constants.ROUTERS_SUFFIX)) {

View File

@ -27,6 +27,7 @@ import org.apache.dubbo.configcenter.ConfigChangeEvent;
import org.apache.dubbo.configcenter.ConfigChangeType;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.RpcException;
@ -56,7 +57,7 @@ public class TagRouter extends AbstractRouter implements Comparable<Router>, Con
private TagRouterRule tagRouterRule;
private String application;
private AtomicBoolean isInited = new AtomicBoolean(false);
private AtomicBoolean inited = new AtomicBoolean(false);
/**
* compatible constructor, it should never be called to create TagRouter.
@ -64,7 +65,7 @@ public class TagRouter extends AbstractRouter implements Comparable<Router>, Con
* @param url
*/
public TagRouter(URL url) {
this(ExtensionLoader.getExtensionLoader(DynamicConfiguration.class).getDefaultExtension(), url);
this(ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getDefaultExtension().getDynamicConfiguration(url), url);
}
public TagRouter(DynamicConfiguration configuration, URL url) {
@ -80,24 +81,25 @@ public class TagRouter extends AbstractRouter implements Comparable<Router>, Con
}
private void init() {
if (!isInited.compareAndSet(false, true)) {
if (!inited.compareAndSet(false, true)) {
return;
}
if (StringUtils.isEmpty(application)) {
logger.error("TagRouter must getConfig from or subscribe to a specific application, but the application in this TagRouter is not specified.");
}
try {
String rawRule = this.configuration.getConfig(application + TAGROUTERRULES_DATAID, this);
if (StringUtils.isNotEmpty(rawRule)) {
this.tagRouterRule = TagRuleParser.parse(rawRule);
synchronized (this) {
String key = application + TAGROUTERRULES_DATAID;
configuration.addListener(key, this);
String rawRule = configuration.getConfig(key);
if (rawRule != null) {
this.process(new ConfigChangeEvent(key, rawRule));
}
} catch (Exception e) {
logger.error("Failed to parse the raw tag router rule and it will not take effect, please check if the rule matches with the template, the raw rule is:\n ", e);
}
}
@Override
public void process(ConfigChangeEvent event) {
public synchronized void process(ConfigChangeEvent event) {
try {
if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
this.tagRouterRule = null;

View File

@ -19,7 +19,7 @@ package org.apache.dubbo.rpc.cluster.router.file;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.RouterFactory;
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@ -165,7 +166,7 @@ public class FileRouterEngineTest {
Map<String, List<Invoker<FileRouterEngineTest>>> methodInvokers = new HashMap<>();
methodInvokers.put("method1", invokers);
methodInvokers.put("method2", invokers);
dic.buildRouterChain(methodInvokers, ExtensionLoader.getExtensionLoader(DynamicConfiguration.class).getDefaultExtension());
dic.buildRouterChain(methodInvokers, ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getDefaultExtension().getDynamicConfiguration(null));
dic.getRouterChain().setResidentRouters(Arrays.asList(routerFactory.getRouter(url)));
}

View File

@ -20,7 +20,7 @@ import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Result;
@ -34,6 +34,7 @@ import org.apache.dubbo.rpc.cluster.filter.DemoService;
import org.apache.dubbo.rpc.cluster.loadbalance.LeastActiveLoadBalance;
import org.apache.dubbo.rpc.cluster.loadbalance.RandomLoadBalance;
import org.apache.dubbo.rpc.cluster.loadbalance.RoundRobinLoadBalance;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -458,7 +459,7 @@ public class AbstractClusterInvokerTest {
private void initDic() {
Map<String, List<Invoker<IHelloService>>> map = new HashMap<>();
map.put("sayHello", invokers);
dic.buildRouterChain(map, ExtensionLoader.getExtensionLoader(DynamicConfiguration.class).getDefaultExtension());
dic.buildRouterChain(map, ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getDefaultExtension().getDynamicConfiguration(null));
}
@Test()

View File

@ -19,7 +19,7 @@ package org.apache.dubbo.rpc.cluster.support.wrapper;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
@ -31,6 +31,7 @@ import org.apache.dubbo.rpc.cluster.LoadBalance;
import org.apache.dubbo.rpc.cluster.directory.StaticDirectory;
import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker;
import org.apache.dubbo.rpc.support.MockProtocol;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
@ -660,7 +661,7 @@ public class MockClusterInvokerTest {
Arrays.stream(methods).forEach(m -> {
methodInvokers.put(m.getName(), invokers);
});
dic.buildRouterChain(methodInvokers, ExtensionLoader.getExtensionLoader(DynamicConfiguration.class).getDefaultExtension());
dic.buildRouterChain(methodInvokers, ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getDefaultExtension().getDynamicConfiguration(null));
AbstractClusterInvoker<IHelloService> cluster = new AbstractClusterInvoker(dic) {
@Override
protected Result doInvoke(Invocation invocation, List invokers, LoadBalance loadbalance)

View File

@ -14,31 +14,15 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter;
package org.apache.dubbo.common.config;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.config.Environment;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
/**
* Utilities for manipulating configurations from different sources
*/
public class ConfigurationUtils {
/**
* If user opens DynamicConfig, the extension instance must has been created during the initialization of
* ConfigCenterConfig with the right extension type user specifies. If no DynamicConfig presents,
* NopDynamicConfiguration will be used.
*/
public static DynamicConfiguration getDynamicConfiguration() {
DynamicConfiguration dynamicConfiguration = (DynamicConfiguration) Environment.getInstance().getDynamicConfiguration();
if (dynamicConfiguration == null) {
dynamicConfiguration = getExtensionLoader(DynamicConfiguration.class).getDefaultExtension();
}
return dynamicConfiguration;
}
// FIXME
@SuppressWarnings("deprecation")
public static int getServerShutdownTimeout() {
int timeout = Constants.DEFAULT_SERVER_SHUTDOWN_TIMEOUT;
@ -63,4 +47,12 @@ public class ConfigurationUtils {
}
return timeout;
}
public static String getProperty(String property) {
return getProperty(property, null);
}
public static String getProperty(String property, String defaultValue) {
return Environment.getInstance().getConfiguration().getString(property, defaultValue);
}
}

View File

@ -24,6 +24,7 @@ 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.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import java.io.IOException;
import java.io.StringReader;
@ -94,11 +95,10 @@ public class ConfigCenterConfig extends AbstractConfig {
}
private DynamicConfiguration startDynamicConfiguration(URL url) {
DynamicConfiguration dynamicConfiguration = ExtensionLoader.getExtensionLoader(DynamicConfiguration.class).getExtension(url.getProtocol());
// TODO, maybe we need a factory to do this?
dynamicConfiguration.initWith(url);
Environment.getInstance().setDynamicConfiguration(dynamicConfiguration);
return dynamicConfiguration;
DynamicConfigurationFactory dynamicConfigurationFactory = ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getExtension(url.getProtocol());
DynamicConfiguration configuration = dynamicConfigurationFactory.getDynamicConfiguration(url);
Environment.getInstance().setDynamicConfiguration(configuration);
return configuration;
}
private URL toConfigUrl() {

View File

@ -21,13 +21,12 @@ import org.apache.dubbo.common.config.AbstractConfiguration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* Dynamic configuration template class. The concrete implementation needs to provide implementation for three methods.
*
* @see AbstractDynamicConfiguration#getTargetConfig(String, String, long)
* @see AbstractDynamicConfiguration#addConfigurationListener(TargetListener, ConfigurationListener)
* @see AbstractDynamicConfiguration#addConfigurationListener(String key, TargetListener, ConfigurationListener)
* @see AbstractDynamicConfiguration#createTargetListener(String)
*/
public abstract class AbstractDynamicConfiguration<TargetListener> extends AbstractConfiguration
@ -35,7 +34,6 @@ public abstract class AbstractDynamicConfiguration<TargetListener> extends Abstr
protected static final String DEFAULT_GROUP = "dubbo";
protected URL url;
private AtomicBoolean inited = new AtomicBoolean(false);
// One key can register multiple target listeners, but one target listener only maps to one configuration listener
protected ConcurrentMap<String, TargetListener> targetListeners =
@ -44,12 +42,9 @@ public abstract class AbstractDynamicConfiguration<TargetListener> extends Abstr
public AbstractDynamicConfiguration() {
}
@Override
public void initWith(URL url) {
if (!inited.compareAndSet(false, true)) {
return;
}
public AbstractDynamicConfiguration(URL url) {
this.url = url;
initWith(url);
}
@Override
@ -60,30 +55,18 @@ public abstract class AbstractDynamicConfiguration<TargetListener> extends Abstr
@Override
public String getConfig(String key) {
return getConfig(key, null, null);
return getConfig(key, null, 0L);
}
@Override
public String getConfig(String key, String group) {
return getConfig(key, group, null);
return getConfig(key, group, 0L);
}
@Override
public String getConfig(String key, ConfigurationListener listener) {
return getConfig(key, null, listener);
}
@Override
public String getConfig(String key, String group, ConfigurationListener listener) {
return getConfig(key, group, listener, 0L);
}
@Override
public String getConfig(String key, String group, ConfigurationListener listener, long timeout) {
public String getConfig(String key, String group, long timeout) {
try {
if (listener != null) {
this.addListener(key, listener);
}
return getTargetConfig(key, group, timeout);
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
@ -95,6 +78,9 @@ public abstract class AbstractDynamicConfiguration<TargetListener> extends Abstr
}
protected abstract void initWith(URL url);
// FIXME do wo need this?
protected abstract void recover();
/**

View File

@ -0,0 +1,41 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter;
import org.apache.dubbo.common.URL;
/**
*
*/
public abstract class AbstractDynamicConfigurationFactory implements DynamicConfigurationFactory {
private volatile DynamicConfiguration dynamicConfiguration;
@Override
public DynamicConfiguration getDynamicConfiguration(URL url) {
if (dynamicConfiguration == null) {
synchronized (this) {
if (dynamicConfiguration == null) {
dynamicConfiguration = createDynamicConfiguration(url);
}
}
}
return dynamicConfiguration;
}
protected abstract DynamicConfiguration createDynamicConfiguration(URL url);
}

View File

@ -22,7 +22,6 @@ package org.apache.dubbo.configcenter;
public interface ConfigurationListener {
/**
* FIXME should it be synchronized?
* Listener call back method. Listener gets notified by this method once there's any change happens on the config
* the listener listens on.
*

View File

@ -1,54 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter;
import org.apache.dubbo.common.config.AbstractConfiguration;
import org.apache.dubbo.common.config.Configuration;
/**
* A wrapper to fetch a config for the specific key with the different prefix in the specified order.
*/
public class ConfigurationWrapper extends AbstractConfiguration {
private String application;
private String service;
private String method;
private Configuration delegate;
public ConfigurationWrapper(String application, String service, String method, Configuration configuration) {
this.application = application;
this.service = service;
this.method = method;
this.delegate = configuration;
}
// FIXME: I think the order is wrong, service.method.key go first, then service.key, and then application.key
@Override
protected Object getInternalProperty(String key) {
Object value = delegate.getProperty(application + "." + key);
if (value == null) {
value = delegate.getProperty(service + "." + key);
}
if (value == null) {
value = delegate.getProperty(service + "." + method + "." + key);
}
if (value == null) {
value = delegate.getProperty(key);
}
return value;
}
}

View File

@ -16,32 +16,24 @@
*/
package org.apache.dubbo.configcenter;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.extension.SPI;
/**
* Dynamic configuration
*/
@SPI("nop")
public interface DynamicConfiguration extends Configuration {
/**
* Init dynamic configuration from URL
*
* @param url the url in which info for initializing dynamic configuration is contained.
*/
void initWith(URL url);
/**
* Register a configuration listener for a specified key
* The listener only works for service governance purpose, so the group would always be 'dubbo'
* The listener only works for service governance purpose, so the target group would always be the value user specifies at startup or 'dubbo' by default.
* This method will only register listener, which means it will not trigger a notification that contains the current value.
*
* @param key the key to represent a configuration
* @param listener configuration listener
*/
void addListener(String key, ConfigurationListener listener);
void removeListener(String key, ConfigurationListener listener);
/**
@ -62,34 +54,14 @@ public interface DynamicConfiguration extends Configuration {
String getConfig(String key, String group);
/**
* Get the configuration mapped to the given key, and notify the passed-in listener
*
* @param key property key
* @param listener configuration listener
* @return
*/
String getConfig(String key, ConfigurationListener listener);
/**
* Get the configuration mapped to the given key and the given group, and notify the passed-in listener
*
* @param key property key
* @param group group
* @param listener configuration listener
* @return target configuration mapped to the given key and the given group
*/
String getConfig(String key, String group, ConfigurationListener listener);
/**
* Get the configuration mapped to the given key and the given group, and notify the passed-in listener. If the
* Get the configuration mapped to the given key and the given group. If the
* configuration fails to fetch after timeout exceeds, IllegalStateException will be thrown.
*
* @param key property key
* @param group group
* @param listener configuration listener
* @param timeout timeout value for fetching the target config
* @return target configuration mapped to the given key and the given group, IllegalStateException will be thrown
* if timeout exceeds.
*/
String getConfig(String key, String group, ConfigurationListener listener, long timeout);
String getConfig(String key, String group, long timeout) throws IllegalStateException;
}

View File

@ -16,17 +16,15 @@
*/
package org.apache.dubbo.configcenter;
/**
* Config type
*/
public enum ConfigType {
/**
* For Dubbo dynamic config other than routing rules.
*/
CONFIGURATORS,
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
/**
*
*/
@SPI("nop")
public interface DynamicConfigurationFactory {
DynamicConfiguration getDynamicConfiguration(URL url);
/**
* For Dubbo routing rules
*/
ROUTERS
}

View File

@ -16,6 +16,7 @@
*/
package org.apache.dubbo.configcenter.support.nop;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.configcenter.AbstractDynamicConfiguration;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.dubbo.configcenter.DynamicConfiguration;
@ -26,6 +27,18 @@ import org.apache.dubbo.configcenter.DynamicConfiguration;
*/
public class NopDynamicConfiguration extends AbstractDynamicConfiguration {
NopDynamicConfiguration() {
}
public NopDynamicConfiguration(URL url) {
super(url);
}
@Override
protected void initWith(URL url) {
}
@Override
protected String getTargetConfig(String key, String group, long timeout) {
return null;

View File

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter.support.nop;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory;
import org.apache.dubbo.configcenter.DynamicConfiguration;
/**
*
*/
public class NopDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
@Override
protected DynamicConfiguration createDynamicConfiguration(URL url) {
return new NopDynamicConfiguration(url);
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.configcenter.mock;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.apache.dubbo.configcenter.support.nop.NopDynamicConfigurationFactory;
import org.junit.Assert;
import org.junit.Test;
/**
*
*/
public class AbstractDynamicConfigurationTest {
public DynamicConfigurationFactory configurationFactory = ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getExtension("mock");
public URL url = URL.valueOf("nop://127.0.0.1:10880/DynamicConfiguration");
@Test
public void testInit() {
DynamicConfiguration configuration1 = configurationFactory.getDynamicConfiguration(url);
DynamicConfiguration configuration2 = configurationFactory.getDynamicConfiguration(url);
Assert.assertEquals(configuration1, configuration2);
}
@Test
public void testDefaultExtension() {
DynamicConfigurationFactory factory = ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getDefaultExtension();
Assert.assertTrue(factory instanceof NopDynamicConfigurationFactory);
}
}

View File

@ -16,8 +16,49 @@
*/
package org.apache.dubbo.configcenter.mock;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.configcenter.AbstractDynamicConfiguration;
import org.apache.dubbo.configcenter.ConfigurationListener;
/**
*
*/
public class MockDynamicConfiguration {
public class MockDynamicConfiguration extends AbstractDynamicConfiguration {
MockDynamicConfiguration() {
}
MockDynamicConfiguration(URL url) {
super(url);
}
@Override
protected void initWith(URL url) {
}
@Override
protected void recover() {
}
@Override
protected String getTargetConfig(String key, String group, long timeout) {
return null;
}
@Override
protected void addConfigurationListener(String key, Object o, ConfigurationListener configurationListener) {
}
@Override
protected Object createTargetListener(String key) {
return null;
}
@Override
protected Object getInternalProperty(String key) {
return null;
}
}

View File

@ -0,0 +1,32 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter.mock;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory;
import org.apache.dubbo.configcenter.DynamicConfiguration;
/**
*
*/
public class MockDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
@Override
protected DynamicConfiguration createDynamicConfiguration(URL url) {
return new MockDynamicConfiguration(url);
}
}

View File

@ -1 +0,0 @@
mock=org.apache.dubbo.configcenter.support.mock.MockDynamicConfiguration

View File

@ -0,0 +1 @@
mock=org.apache.dubbo.configcenter.mock.MockDynamicConfigurationFactory

View File

@ -47,14 +47,15 @@ public class ApolloDynamicConfiguration extends AbstractDynamicConfiguration<Apo
private Config dubboConfig;
public ApolloDynamicConfiguration() {
ApolloDynamicConfiguration() {
}
ApolloDynamicConfiguration(URL url) {
super(url);
}
@Override
public void initWith(URL url) {
super.initWith(url);
// Instead of using Dubbo's configuration, I would suggest use the original configuration method Apollo provides.
String configEnv = url.getParameter(Constants.CONFIG_ENV_KEY);
String configAddr = url.getBackupAddress();
@ -71,7 +72,7 @@ public class ApolloDynamicConfiguration extends AbstractDynamicConfiguration<Apo
dubboConfig = ConfigService.getConfig(url.getParameter(Constants.CONFIG_GROUP_KEY, DEFAULT_GROUP));
// Decide to fail or to continue when failed to connect to remote server.
boolean check = url.getParameter(Constants.CONFIG_CHECK_KEY, false);
boolean check = url.getParameter(Constants.CONFIG_CHECK_KEY, true);
if (dubboConfig.getSourceType() != ConfigSourceType.REMOTE) {
if (check) {
throw new IllegalStateException("Failed to connect to config center, the config center is Apollo, " +
@ -142,7 +143,7 @@ public class ApolloDynamicConfiguration extends AbstractDynamicConfiguration<Apo
public void onChange(com.ctrip.framework.apollo.model.ConfigChangeEvent changeEvent) {
for (String key : changeEvent.changedKeys()) {
ConfigChange change = changeEvent.getChange(key);
if (StringUtils.isEmpty(change.getNewValue())) {
if ("".equals(change.getNewValue())) {
logger.warn("an empty rule is received for " + key + ", the current working rule is " +
change.getOldValue() + ", the empty rule will not take effect.");
return;

View File

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter.support.apollo;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory;
import org.apache.dubbo.configcenter.DynamicConfiguration;
/**
*
*/
public class ApolloDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
@Override
protected DynamicConfiguration createDynamicConfiguration(URL url) {
return new ApolloDynamicConfiguration(url);
}
}

View File

@ -16,16 +16,17 @@
*/
package org.apache.dubbo.configcenter.support.zookeeper;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.configcenter.ConfigChangeEvent;
import org.apache.dubbo.configcenter.ConfigChangeType;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCacheEvent;
import org.apache.curator.framework.recipes.cache.TreeCacheListener;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
@ -97,6 +98,7 @@ public class CacheListener implements TreeCacheListener {
/**
* This is used to convert a configuration nodePath into a key
* TODO doc
*
* @param path
* @return key (nodePath less the config root path)

View File

@ -16,16 +16,17 @@
*/
package org.apache.dubbo.configcenter.support.zookeeper;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.configcenter.AbstractDynamicConfiguration;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.ChildData;
import org.apache.curator.framework.recipes.cache.TreeCache;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -43,25 +44,29 @@ import static org.apache.dubbo.common.Constants.CONFIG_NAMESPACE_KEY;
*/
public class ZookeeperDynamicConfiguration extends AbstractDynamicConfiguration<CacheListener> {
private static final Logger logger = LoggerFactory.getLogger(ZookeeperDynamicConfiguration.class);
private Executor executor = Executors.newFixedThreadPool(1);
private Executor executor;
private CuratorFramework client;
// The final root path would be: /configRootPath/"config"
private String rootPath;
private TreeCache treeCache;
private CountDownLatch initializedLatch = new CountDownLatch(1);
private CountDownLatch initializedLatch;
private CacheListener cacheListener;
@Override
public void initWith(URL url) {
super.initWith(url);
ZookeeperDynamicConfiguration() {
}
ZookeeperDynamicConfiguration(URL url) {
super(url);
}
protected void initWith(URL url) {
rootPath = "/" + url.getParameter(CONFIG_NAMESPACE_KEY, Constants.DUBBO) + "/config";
RetryPolicy policy = new ExponentialBackoffRetry(1000, 3);
int sessionTimeout = 60 * 1000;
int connectTimeout = 10 * 1000;
int sessionTimeout = url.getParameter("config.session.timeout", 60 * 1000);
int connectTimeout = url.getParameter("config.connect.timeout", 10 * 1000);
String connectString = url.getBackupAddress();
client = newClient(connectString, sessionTimeout, connectTimeout, policy);
client.start();
@ -69,7 +74,7 @@ public class ZookeeperDynamicConfiguration extends AbstractDynamicConfiguration<
try {
boolean connected = client.blockUntilConnected(3 * connectTimeout, TimeUnit.MILLISECONDS);
if (!connected) {
if (url.getParameter(Constants.CONFIG_CHECK_KEY, false)) {
if (url.getParameter(Constants.CONFIG_CHECK_KEY, true)) {
throw new IllegalStateException("Failed to connect to config center (zookeeper): "
+ connectString + " in " + 3 * connectTimeout + "ms.");
} else {
@ -81,8 +86,9 @@ public class ZookeeperDynamicConfiguration extends AbstractDynamicConfiguration<
+ connectString + " config center, ", e);
}
initializedLatch = new CountDownLatch(1);
this.cacheListener = new CacheListener(rootPath, initializedLatch);
this.executor = Executors.newFixedThreadPool(1);
// build local cache
try {
this.buildCache();
@ -97,7 +103,7 @@ public class ZookeeperDynamicConfiguration extends AbstractDynamicConfiguration<
key = group + "." + key;
}
return (String) getInternalProperty(key);
return (String) getInternalProperty(rootPath + "/" + key.replaceFirst("\\.", "/"));
}
@Override
@ -116,7 +122,7 @@ public class ZookeeperDynamicConfiguration extends AbstractDynamicConfiguration<
*/
@Override
protected Object getInternalProperty(String key) {
ChildData childData = treeCache.getCurrentData(rootPath + "/" + key.replaceFirst("\\.", "/"));
ChildData childData = treeCache.getCurrentData(key);
if (childData != null) {
return new String(childData.getData(), StandardCharsets.UTF_8);
}

View File

@ -0,0 +1,31 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.configcenter.support.zookeeper;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.configcenter.AbstractDynamicConfigurationFactory;
import org.apache.dubbo.configcenter.DynamicConfiguration;
/**
*
*/
public class ZookeeperDynamicConfigurationFactory extends AbstractDynamicConfigurationFactory {
@Override
protected DynamicConfiguration createDynamicConfiguration(URL url) {
return new ZookeeperDynamicConfiguration(url);
}
}

View File

@ -1 +1 @@
zookeeper=org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfiguration
zookeeper=org.apache.dubbo.configcenter.support.zookeeper.ZookeeperDynamicConfigurationFactory

View File

@ -16,16 +16,18 @@
*/
package org.apache.dubbo.configcenter.support.zookeeper;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.configcenter.ConfigChangeEvent;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.configcenter.DynamicConfigurationFactory;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
@ -66,8 +68,7 @@ public class ZookeeperDynamicConfigurationTest {
configUrl = URL.valueOf("zookeeper://localhost:" + zkServerPort);
configuration = ExtensionLoader.getExtensionLoader(DynamicConfiguration.class).getExtension(configUrl.getProtocol());
configuration.initWith(configUrl);
configuration = ExtensionLoader.getExtensionLoader(DynamicConfigurationFactory.class).getExtension(configUrl.getProtocol()).getDynamicConfiguration(configUrl);
}
@AfterClass

View File

@ -16,8 +16,7 @@
*/
package org.apache.dubbo.container.log4j;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.container.Container;
import org.apache.log4j.Appender;
@ -44,10 +43,9 @@ public class Log4jContainer implements Container {
@Override
@SuppressWarnings("unchecked")
public void start() {
Configuration configuration = Environment.getInstance().getConfiguration();
String file = configuration.getString(LOG4J_FILE);
String file = ConfigurationUtils.getProperty(LOG4J_FILE);
if (file != null && file.length() > 0) {
String level = configuration.getString(LOG4J_LEVEL);
String level = ConfigurationUtils.getProperty(LOG4J_LEVEL);
if (level == null || level.length() == 0) {
level = DEFAULT_LOG4J_LEVEL;
}
@ -61,7 +59,7 @@ public class Log4jContainer implements Container {
properties.setProperty("log4j.appender.application.layout.ConversionPattern", "%d [%t] %-5p %C{6} (%F:%L) - %m%n");
PropertyConfigurator.configure(properties);
}
String subdirectory = configuration.getString(LOG4J_SUBDIRECTORY);
String subdirectory = ConfigurationUtils.getProperty(LOG4J_SUBDIRECTORY);
if (subdirectory != null && subdirectory.length() > 0) {
Enumeration<org.apache.log4j.Logger> ls = LogManager.getCurrentLoggers();
while (ls.hasMoreElements()) {

View File

@ -192,27 +192,22 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
public void subscribe(URL url) {
setConsumerUrl(url);
String rawConfig = null;
try {
rawConfig = dynamicConfiguration.getConfig(url.getEncodedServiceKey() + Constants.CONFIGURATORS_SUFFIX, this);
if (StringUtils.isNotEmpty(rawConfig)) {
this.dynamicConfigurators = configToConfiguratiors(rawConfig);
}
} catch (Exception e) {
logger.error("Failed to load or parse dynamic config (service level), the raw config is: " + rawConfig, e);
}
String rawConfigApp = null;
try {
rawConfigApp = dynamicConfiguration.getConfig(url.getParameter(Constants.APPLICATION_KEY) + Constants.CONFIGURATORS_SUFFIX, this);
if (StringUtils.isNotEmpty(rawConfigApp)) {
this.appDynamicConfigurators = configToConfiguratiors(rawConfigApp);
}
} catch (Exception e) {
logger.error("Failed to load or parse dynamic config (application level), the raw config is: " + rawConfigApp, e);
}
registry.subscribe(url, this);
synchronized (this) {
String key = url.getEncodedServiceKey() + Constants.CONFIGURATORS_SUFFIX;
dynamicConfiguration.addListener(key, this);
String rawConfig = dynamicConfiguration.getConfig(key);
if (rawConfig != null) {
this.process(new ConfigChangeEvent(key, rawConfig));
}
String appKey = url.getParameter(Constants.APPLICATION_KEY) + Constants.CONFIGURATORS_SUFFIX;
String appRawConfig = dynamicConfiguration.getConfig(appKey);
if (appRawConfig != null) {
this.process(new ConfigChangeEvent(appKey, appRawConfig));
}
}
}
@Override
@ -279,6 +274,14 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
List<Router> routers = toRouters(routerUrls);
addRouters(routers);
}
overrideDirectoryUrl();
// providers
refreshInvoker(invokerUrls);
}
private void overrideDirectoryUrl() {
// merge override parameters
this.overrideDirectoryUrl = directoryUrl;
List<Configurator> localConfigurators = this.configurators; // local reference
@ -299,8 +302,6 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
this.overrideDirectoryUrl = configurator.configure(overrideDirectoryUrl);
});
}
// providers
refreshInvoker(invokerUrls);
}
/* private List<URL> compositeDynamicConfiguration(List<URL> urls) {
@ -708,7 +709,7 @@ public class RegistryDirectory<T> extends AbstractDirectory<T> implements Notify
}
@Override
public void process(ConfigChangeEvent event) {
public synchronized void process(ConfigChangeEvent event) {
List<URL> urls = new ArrayList<>();
if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
URL url = getConsumerUrl().clearParameters().setProtocol(Constants.EMPTY_PROTOCOL);

View File

@ -18,6 +18,8 @@ package org.apache.dubbo.registry.integration;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.config.Environment;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
@ -28,7 +30,6 @@ import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.configcenter.ConfigChangeEvent;
import org.apache.dubbo.configcenter.ConfigChangeType;
import org.apache.dubbo.configcenter.ConfigurationListener;
import org.apache.dubbo.configcenter.ConfigurationUtils;
import org.apache.dubbo.configcenter.DynamicConfiguration;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.Registry;
@ -86,7 +87,7 @@ public class RegistryProtocol implements Protocol {
public RegistryProtocol() {
INSTANCE = this;
dynamicConfiguration = ConfigurationUtils.getDynamicConfiguration();
dynamicConfiguration = (DynamicConfiguration) Environment.getInstance().getDynamicConfiguration();
}
public static RegistryProtocol getRegistryProtocol() {
@ -159,7 +160,7 @@ public class RegistryProtocol implements Protocol {
final OverrideListener overrideSubscribeListener = new OverrideListener(overrideSubscribeUrl, originInvoker);
overrideListeners.put(overrideSubscribeUrl, overrideSubscribeListener);
providerUrl = overrideUrlWithConfig(providerUrl, overrideSubscribeListener);
providerUrl = overrideUrlWithConfig(providerUrl);
//export invoker
final ExporterChangeableWrapper<T> exporter = doLocalExport(originInvoker, providerUrl);
@ -174,7 +175,9 @@ public class RegistryProtocol implements Protocol {
ProviderConsumerRegTable.getProviderWrapper(originInvoker).setReg(true);
}
// Deprecated! Subscribe to override rules in 2.6.x or before.
registry.subscribe(overrideSubscribeUrl, overrideSubscribeListener);
subscribeDynamicConfiguration(overrideSubscribeUrl);
exporter.setRegisterUrl(registeredProviderUrl);
exporter.setSubscribeUrl(overrideSubscribeUrl);
@ -182,24 +185,49 @@ public class RegistryProtocol implements Protocol {
return new DestroyableExporter<>(exporter);
}
private <T> URL overrideUrlWithConfig(URL providerUrl, OverrideListener listener) {
/**
* Get existing configuration rule and override provider url before exporting.
*
* @param providerUrl
* @param <T>
* @return
*/
private <T> URL overrideUrlWithConfig(URL providerUrl) {
List<Configurator> configurators = new LinkedList<>();
String appRawConfig = dynamicConfiguration.getConfig(providerUrl.getParameter(Constants.APPLICATION_KEY) + Constants.CONFIGURATORS_SUFFIX, listener);
String appRawConfig = dynamicConfiguration.getConfig(providerUrl.getParameter(Constants.APPLICATION_KEY) + Constants.CONFIGURATORS_SUFFIX);
if (!StringUtils.isEmpty(appRawConfig)) {
List<Configurator> appDynamicConfigurators = RegistryDirectory.configToConfiguratiors(appRawConfig);
listener.setAppDynamicConfigurators(appDynamicConfigurators);
configurators.addAll(appDynamicConfigurators);
}
String rawConfig = dynamicConfiguration.getConfig(providerUrl.getEncodedServiceKey() + Constants.CONFIGURATORS_SUFFIX, listener);
String rawConfig = dynamicConfiguration.getConfig(providerUrl.getEncodedServiceKey() + Constants.CONFIGURATORS_SUFFIX);
if (!StringUtils.isEmpty(rawConfig)) {
List<Configurator> dynamicConfigurators = RegistryDirectory.configToConfiguratiors(rawConfig);
listener.setDynamicConfigurators(dynamicConfigurators);
configurators.addAll(dynamicConfigurators);
}
providerUrl = getConfigedInvokerUrl(configurators, providerUrl);
return providerUrl;
}
private void subscribeDynamicConfiguration(URL url) {
synchronized (overrideListeners.get(url)) {
OverrideListener listener = (OverrideListener) overrideListeners.get(url);
String appKey = url.getParameter(Constants.APPLICATION_KEY) + Constants.CONFIGURATORS_SUFFIX;
dynamicConfiguration.addListener(appKey, listener);
String appRawConfig = dynamicConfiguration.getConfig(appKey);
if (appRawConfig != null) {
listener.process(new ConfigChangeEvent(appKey, appRawConfig));
}
String serviceKey = url.getEncodedServiceKey() + Constants.CONFIGURATORS_SUFFIX;
dynamicConfiguration.addListener(serviceKey, listener);
String rawConfig = dynamicConfiguration.getConfig(serviceKey);
if (rawConfig != null) {
listener.process(new ConfigChangeEvent(serviceKey, rawConfig));
}
}
}
@SuppressWarnings("unchecked")
private <T> ExporterChangeableWrapper<T> doLocalExport(final Invoker<T> originInvoker, URL providerUrl) {
String key = getCacheKey(originInvoker);
@ -556,7 +584,7 @@ public class RegistryProtocol implements Protocol {
}
@Override
public void process(ConfigChangeEvent event) {
public synchronized void process(ConfigChangeEvent event) {
List<URL> urls;
if (event.getChangeType().equals(ConfigChangeType.DELETED)) {
URL originUrl = RegistryProtocol.this.getProviderUrl(originInvoker);

View File

@ -18,8 +18,8 @@ package org.apache.dubbo.rpc.protocol.dubbo;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.utils.AtomicPositiveInteger;
import org.apache.dubbo.configcenter.ConfigurationUtils;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.TimeoutException;
import org.apache.dubbo.remoting.exchange.ExchangeClient;

View File

@ -18,13 +18,13 @@ package org.apache.dubbo.rpc.protocol.dubbo;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.serialize.support.SerializableClassRegistry;
import org.apache.dubbo.common.serialize.support.SerializationOptimizer;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.configcenter.ConfigurationUtils;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.Transporter;

View File

@ -19,13 +19,14 @@ package org.apache.dubbo.rpc.protocol.dubbo;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.configcenter.ConfigurationUtils;
import org.apache.dubbo.remoting.exchange.ExchangeClient;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.ProxyFactory;
import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;

View File

@ -18,8 +18,8 @@ package org.apache.dubbo.rpc.protocol.thrift;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.configcenter.ConfigurationUtils;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.Transporter;