Merge remote-tracking branch 'origin/cloud-native' into cloud-native

This commit is contained in:
ken.lj 2019-09-06 21:32:42 +08:00
commit 0dad8290ea
62 changed files with 2241 additions and 183 deletions

View File

@ -274,6 +274,16 @@
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -449,6 +459,16 @@
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -498,6 +518,16 @@
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
<exclusions>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-core</artifactId>
</exclusion>
<exclusion>
<groupId>io.grpc</groupId>
<artifactId>grpc-netty</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
@ -652,8 +682,15 @@
</includes>
</artifactSet>
<transformers>
<!-- dubbo-common beginning -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.compiler.Compiler
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
@ -661,18 +698,37 @@
META-INF/dubbo/internal/org.apache.dubbo.common.extension.ExtensionFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.infra.InfraAdapter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>
META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
</resource>
</transformer>
<!-- dubbo-common end -->
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.serialize.Serialization
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.status.StatusChecker
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.threadpool.ThreadPool
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.Dispatcher</resource>
</transformer>
@ -754,22 +810,10 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.cache.CacheFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.store.DataStore
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.logger.LoggerAdapter
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.qos.command.BaseCommand
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory
</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.metadata.report.MetadataReportFactory
</resource>

View File

@ -85,6 +85,13 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-metadata-report-redis</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-configcenter-zookeeper</artifactId>

View File

@ -27,6 +27,7 @@ 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.common.utils.UrlUtils;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ConfigCenterConfig;
import org.apache.dubbo.config.ConsumerConfig;
@ -602,6 +603,11 @@ public class DubboBootstrap extends GenericEventListener implements Lifecycle {
*/
@Override
public DubboBootstrap start() {
if (!shouldStart()) {
return this;
}
if (!isInitialized()) {
initialize();
}
@ -632,6 +638,22 @@ public class DubboBootstrap extends GenericEventListener implements Lifecycle {
return this;
}
/**
* Should Start current bootstrap
*
* @return If there is not any service discovery registry in the {@link ConfigManager#getRegistries()}, it will not
* start current bootstrap
*/
private boolean shouldStart() {
return configManager.getRegistries()
.stream()
.map(RegistryConfig::getAddress)
.map(URL::valueOf)
.filter(UrlUtils::isServiceDiscoveryRegistryType)
.count() > 0;
}
private boolean hasExportedServices() {
return !metadataService.getExportedURLs().isEmpty();
}

View File

@ -34,7 +34,7 @@ public class EtcdDubboServiceConsumerBootstrap {
.application("dubbo-consumer-demo")
// Zookeeper
.protocol(builder -> builder.port(20887).name("dubbo"))
.registry("etcd3", builder -> builder.address("etcd3://127.0.0.1:2379?registry.type=service&subscribed.services=dubbo-provider-demo"))
.registry("etcd3", builder -> builder.address("etcd3://127.0.0.1:2379?registry-type=service&subscribed-services=dubbo-provider-demo"))
.metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
// Nacos
// .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1"))

View File

@ -49,7 +49,7 @@ public class EtcdDubboServiceProviderBootstrap {
RegistryConfig serviceRegistry = new RegistryConfig();
serviceRegistry.setId("serviceRegistry");
serviceRegistry.setAddress("etcd3://127.0.0.1:2379?registry.type=service");
serviceRegistry.setAddress("etcd3://127.0.0.1:2379?registry-type=service");
ServiceConfig<EchoService> echoService = new ServiceConfig<>();
echoService.setInterface(EchoService.class.getName());
@ -63,7 +63,7 @@ public class EtcdDubboServiceProviderBootstrap {
// userService.setRegistries(Arrays.asList(interfaceRegistry, serviceRegistry));
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-provider-demo");
applicationConfig.setMetadataType("remote");
// applicationConfig.setMetadataType("remote");
new DubboBootstrap()
.application(applicationConfig)
// Zookeeper in service registry type
@ -73,7 +73,7 @@ public class EtcdDubboServiceProviderBootstrap {
.registries(Arrays.asList(interfaceRegistry, serviceRegistry))
// .registry(RegistryBuilder.newBuilder().address("consul://127.0.0.1:8500?registry.type=service").build())
.protocol(builder -> builder.port(-1).name("dubbo"))
.metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
// .metadataReport(new MetadataReportConfig("etcd://127.0.0.1:2379"))
.service(echoService)
.service(userService)
.start()

View File

@ -35,6 +35,9 @@ public class NacosDubboServiceConsumerBootstrap {
// applicationConfig.setMetadataType("remote");
new DubboBootstrap()
.application(applicationConfig)
// Zookeeper
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry.type=service&subscribed.services=dubbo-nacos-provider-demo"))
// .registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=dubbo-nacos-provider-demo"))
.registry("nacos", builder -> builder.address("nacos://127.0.0.1:8848?registry-type=service&subscribed-services=service-provider"))
.metadataReport(new MetadataReportConfig("nacos://127.0.0.1:8848"))
.reference("user", builder -> builder.interfaceClass(UserService.class).protocol("rest"))

View File

@ -29,7 +29,7 @@ public class ZookeeperDubboServiceProviderBootstrap {
.application("zookeeper-dubbo-provider")
.registry(builder -> builder.address("zookeeper://127.0.0.1:2181?registry-type=service"))
.protocol("dubbo", builder -> builder.port(-1).name("dubbo"))
.protocol("rest", builder -> builder.port(8082).name("rest"))
.protocol("rest", builder -> builder.port(8081).name("rest"))
.service("echo", builder -> builder.interfaceClass(EchoService.class).ref(new EchoServiceImpl()).protocolIds("dubbo"))
.service("user", builder -> builder.interfaceClass(UserService.class).ref(new UserServiceImpl()).protocolIds("rest"))
.start()

View File

@ -189,11 +189,11 @@ public abstract class AbstractDynamicConfiguration implements DynamicConfigurati
}
protected static int getThreadPoolSize(URL url) {
return url.getParameter(THREAD_POOL_SIZE_PARAM_NAME, DEFAULT_THREAD_POOL_SIZE);
return getParameter(url, THREAD_POOL_SIZE_PARAM_NAME, DEFAULT_THREAD_POOL_SIZE);
}
protected static long getThreadPoolKeepAliveTime(URL url) {
return url.getParameter(THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME, DEFAULT_THREAD_POOL_KEEP_ALIVE_TIME);
return getParameter(url, THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME, DEFAULT_THREAD_POOL_KEEP_ALIVE_TIME);
}
protected static String getParameter(URL url, String name, String defaultValue) {
@ -202,4 +202,18 @@ public abstract class AbstractDynamicConfiguration implements DynamicConfigurati
}
return defaultValue;
}
protected static int getParameter(URL url, String name, int defaultValue) {
if (url != null) {
return url.getParameter(name, defaultValue);
}
return defaultValue;
}
protected static long getParameter(URL url, String name, long defaultValue) {
if (url != null) {
return url.getParameter(name, defaultValue);
}
return defaultValue;
}
}

View File

@ -24,14 +24,17 @@ import java.util.concurrent.ConcurrentHashMap;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
/**
* Abstract {@link DynamicConfigurationFactory} implementation with cache ability
*
* @see DynamicConfigurationFactory
* @since 2.7.4
*/
public abstract class AbstractDynamicConfigurationFactory implements DynamicConfigurationFactory {
private volatile Map<String, DynamicConfiguration> dynamicConfigurations = new ConcurrentHashMap<>();
@Override
public DynamicConfiguration getDynamicConfiguration(URL url) {
public final DynamicConfiguration getDynamicConfiguration(URL url) {
String key = url == null ? DEFAULT_KEY : url.getAddress();
return dynamicConfigurations.computeIfAbsent(key, k -> createDynamicConfiguration(url));
}

View File

@ -39,7 +39,7 @@ public class ConfigChangedEvent extends EventObject {
}
public ConfigChangedEvent(String key, String group, String content, ConfigChangeType changeType) {
super(key + "=" + content);
super(key + "," + group);
this.key = key;
this.group = group;
this.content = content;
@ -62,22 +62,6 @@ public class ConfigChangedEvent extends EventObject {
return changeType;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ConfigChangedEvent)) return false;
ConfigChangedEvent that = (ConfigChangedEvent) o;
return Objects.equals(getKey(), that.getKey()) &&
Objects.equals(group, that.group) &&
Objects.equals(getContent(), that.getContent()) &&
getChangeType() == that.getChangeType();
}
@Override
public int hashCode() {
return Objects.hash(getKey(), group, getContent(), getChangeType());
}
@Override
public String toString() {
return "ConfigChangedEvent{" +
@ -87,4 +71,20 @@ public class ConfigChangedEvent extends EventObject {
", changeType=" + changeType +
"} " + super.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ConfigChangedEvent)) return false;
ConfigChangedEvent that = (ConfigChangedEvent) o;
return Objects.equals(getKey(), that.getKey()) &&
Objects.equals(getGroup(), that.getGroup()) &&
Objects.equals(getContent(), that.getContent()) &&
getChangeType() == that.getChangeType();
}
@Override
public int hashCode() {
return Objects.hash(getKey(), getGroup(), getContent(), getChangeType());
}
}

View File

@ -582,13 +582,13 @@ public class FileSystemDynamicConfiguration extends AbstractDynamicConfiguration
}
protected static File initDirectory(URL url) {
String directoryPath = url.getParameter(CONFIG_CENTER_DIR_PARAM_NAME, url.getPath());
String directoryPath = getParameter(url, CONFIG_CENTER_DIR_PARAM_NAME, url == null ? null : url.getPath());
File rootDirectory = null;
if (!StringUtils.isBlank(directoryPath)) {
rootDirectory = new File("/" + directoryPath);
}
if (!rootDirectory.exists()) { // If the directory does not exist
if (directoryPath == null || !rootDirectory.exists()) { // If the directory does not exist
rootDirectory = new File(DEFAULT_CONFIG_CENTER_DIR_PATH);
}

View File

@ -35,7 +35,7 @@ public class ShutdownHookCallbacks {
private final List<ShutdownHookCallback> callbacks = new LinkedList<>();
public ShutdownHookCallbacks() {
ShutdownHookCallbacks() {
loadCallbacks();
}

View File

@ -27,6 +27,7 @@ import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import static java.util.Collections.emptyMap;
import static org.apache.dubbo.common.constants.CommonConstants.ANY_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.CLASSIFIER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
@ -50,9 +51,11 @@ import static org.apache.dubbo.common.constants.RegistryConstants.EMPTY_PROTOCOL
import static org.apache.dubbo.common.constants.RegistryConstants.OVERRIDE_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDERS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTERS_CATEGORY;
import static org.apache.dubbo.common.constants.RegistryConstants.ROUTE_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
public class UrlUtils {
@ -490,6 +493,31 @@ public class UrlUtils {
return REGISTRY_PROTOCOL.equals(url.getProtocol()) || SERVICE_REGISTRY_PROTOCOL.equalsIgnoreCase(url.getProtocol());
}
/**
* The specified {@link URL} is service discovery registry type or not
*
* @param url the {@link URL} connects to the registry
* @return If it is, return <code>true</code>, or <code>false</code>
* @since 2.7.4
*/
public static boolean isServiceDiscoveryRegistryType(URL url) {
return isServiceDiscoveryRegistryType(url == null ? emptyMap() : url.getParameters());
}
/**
* The specified parameters of {@link URL} is service discovery registry type or not
*
* @param parameters the parameters of {@link URL} that connects to the registry
* @return If it is, return <code>true</code>, or <code>false</code>
* @since 2.7.4
*/
public static boolean isServiceDiscoveryRegistryType(Map<String, String> parameters) {
if (parameters == null || parameters.isEmpty()) {
return false;
}
return SERVICE_REGISTRY_TYPE.equals(parameters.get(REGISTRY_TYPE_KEY));
}
/**
* Check if the given value matches the given pattern. The pattern supports wildcard "*".
*
@ -507,7 +535,7 @@ public class UrlUtils {
/**
* @param serviceKey, {group}/{interfaceName}:{version}
* @return [group, interfaceName, version]
* @return [group, interfaceName, version]
*/
public static String[] parseServiceKey(String serviceKey) {
String[] arr = new String[3];

View File

@ -29,7 +29,7 @@ import java.util.Map;
*/
class InmemoryConfigurationTest {
private static InmemoryConfiguration memConfig;
private InmemoryConfiguration memConfig;
private static final String MOCK_KEY = "mockKey";
private static final String MOCK_VALUE = "mockValue";
private static final String MOCK_ONE_KEY = "one";
@ -59,7 +59,6 @@ class InmemoryConfigurationTest {
Assertions.assertEquals(MOCK_VALUE, memConfig.getInternalProperty(MOCK_KEY));
Assertions.assertEquals(MOCK_VALUE, memConfig.getString(MOCK_KEY, MOCK_VALUE));
Assertions.assertEquals(MOCK_VALUE, memConfig.getProperty(MOCK_KEY, MOCK_VALUE));
}
/**
@ -84,11 +83,27 @@ class InmemoryConfigurationTest {
}
@Test
public void testGetInt() {
memConfig.addProperty("a", "1");
Assertions.assertEquals(1, memConfig.getInt("a"));
Assertions.assertEquals(Integer.valueOf(1), memConfig.getInteger("a", 2));
Assertions.assertEquals(2, memConfig.getInt("b", 2));
}
@Test
public void getBoolean() {
memConfig.addProperty("a", Boolean.TRUE.toString());
Assertions.assertTrue(memConfig.getBoolean("a"));
Assertions.assertFalse(memConfig.getBoolean("b", false));
Assertions.assertTrue(memConfig.getBoolean("b", Boolean.TRUE));
}
/**
* Clean.
*/
@AfterEach
public void clean(){
public void clean() {
}

View File

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

View File

@ -0,0 +1,167 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.config.configcenter;
import org.apache.dubbo.common.URL;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.DEFAULT_THREAD_POOL_KEEP_ALIVE_TIME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.DEFAULT_THREAD_POOL_PREFIX;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.DEFAULT_THREAD_POOL_SIZE;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.PARAM_NAME_PREFIX;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.THREAD_POOL_PREFIX_PARAM_NAME;
import static org.apache.dubbo.common.config.configcenter.AbstractDynamicConfiguration.THREAD_POOL_SIZE_PARAM_NAME;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* {@link AbstractDynamicConfiguration} Test
*
* @since 2.7.4
*/
public class AbstractDynamicConfigurationTest {
private AbstractDynamicConfiguration configuration;
@BeforeEach
public void init() {
configuration = new AbstractDynamicConfiguration() {
@Override
protected String doGetConfig(String key, String group) throws Exception {
return null;
}
@Override
protected void doClose() throws Exception {
}
};
}
@Test
public void testConstants() {
assertEquals("dubbo.config-center.", PARAM_NAME_PREFIX);
assertEquals("dubbo.config-center.workers", DEFAULT_THREAD_POOL_PREFIX);
assertEquals("dubbo.config-center.thread-pool.prefix", THREAD_POOL_PREFIX_PARAM_NAME);
assertEquals("dubbo.config-center.thread-pool.size", THREAD_POOL_SIZE_PARAM_NAME);
assertEquals("dubbo.config-center.thread-pool.keep-alive-time", THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME);
assertEquals(1, DEFAULT_THREAD_POOL_SIZE);
assertEquals(60 * 1000, DEFAULT_THREAD_POOL_KEEP_ALIVE_TIME);
}
@Test
public void testConstructor() {
URL url = URL.valueOf("default://")
.addParameter(THREAD_POOL_PREFIX_PARAM_NAME, "test")
.addParameter(THREAD_POOL_SIZE_PARAM_NAME, 10)
.addParameter(THREAD_POOL_KEEP_ALIVE_TIME_PARAM_NAME, 100);
AbstractDynamicConfiguration configuration = new AbstractDynamicConfiguration(url) {
@Override
protected String doGetConfig(String key, String group) throws Exception {
return null;
}
@Override
protected void doClose() throws Exception {
}
};
ThreadPoolExecutor threadPoolExecutor = configuration.getWorkersThreadPool();
ThreadFactory threadFactory = threadPoolExecutor.getThreadFactory();
Thread thread = threadFactory.newThread(() -> {
});
assertEquals(10, threadPoolExecutor.getCorePoolSize());
assertEquals(10, threadPoolExecutor.getMaximumPoolSize());
assertEquals(100, threadPoolExecutor.getKeepAliveTime(TimeUnit.MILLISECONDS));
assertEquals("test-thread-1", thread.getName());
}
@Test
public void testPublishConfig() {
assertThrows(UnsupportedOperationException.class, () -> configuration.publishConfig(null, null), "No support");
assertThrows(UnsupportedOperationException.class, () -> configuration.publishConfig(null, null, null), "No support");
}
@Test
public void testRemoveConfig() {
assertThrows(UnsupportedOperationException.class, () -> configuration.removeConfig(null), "No support");
assertThrows(UnsupportedOperationException.class, () -> configuration.removeConfig(null, null), "No support");
}
@Test
public void testGetConfigGroups() {
assertThrows(UnsupportedOperationException.class, () -> configuration.getConfigGroups(), "No support");
}
@Test
public void testGetConfigKeys() {
assertThrows(UnsupportedOperationException.class, () -> configuration.getConfigKeys(null), "No support");
}
@Test
public void testGetConfigs() {
assertThrows(UnsupportedOperationException.class, () -> configuration.getConfigs(null), "No support");
assertThrows(UnsupportedOperationException.class, () -> configuration.getConfigs(null, 1000), "No support");
}
@Test
public void testGetConfig() {
assertNull(configuration.getConfig(null, null));
assertNull(configuration.getConfig(null, null, 200));
}
@Test
public void testGetInternalProperty() {
assertNull(configuration.getInternalProperty(null));
}
@Test
public void testGetProperties() {
assertNull(configuration.getProperties(null, null));
assertNull(configuration.getProperties(null, null, 100L));
}
@Test
public void testAddListener() {
configuration.addListener(null, null);
configuration.addListener(null, null, null);
}
@Test
public void testRemoveListener() {
configuration.removeListener(null, null);
configuration.removeListener(null, null, null);
}
@Test
public void testClose() throws Exception {
configuration.close();
}
}

View File

@ -0,0 +1,38 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.config.configcenter;
import org.junit.jupiter.api.Test;
import static org.apache.dubbo.common.config.configcenter.ConfigChangeType.ADDED;
import static org.apache.dubbo.common.config.configcenter.ConfigChangeType.DELETED;
import static org.apache.dubbo.common.config.configcenter.ConfigChangeType.MODIFIED;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
/**
* {@link ConfigChangeType} Test
*
* @see ConfigChangeType
* @since 2.7.4
*/
public class ConfigChangeTypeTest {
@Test
public void testMembers() {
assertArrayEquals(new ConfigChangeType[]{ADDED, MODIFIED, DELETED}, ConfigChangeType.values());
}
}

View File

@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.config.configcenter;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
/**
* {@link ConfigChangedEvent} Test
*
* @since 2.7.4
*/
public class ConfigChangedEventTest {
private static final String key = "k";
private static final String group = "g";
private static final String content = "c";
@Test
public void testGetter() {
ConfigChangedEvent event = new ConfigChangedEvent(key, group, content);
assertEquals(key, event.getKey());
assertEquals(group, event.getGroup());
assertEquals(content, event.getContent());
assertEquals(ConfigChangeType.MODIFIED, event.getChangeType());
assertEquals("k,g", event.getSource());
event = new ConfigChangedEvent(key, group, content, ConfigChangeType.ADDED);
assertEquals(key, event.getKey());
assertEquals(group, event.getGroup());
assertEquals(content, event.getContent());
assertEquals(ConfigChangeType.ADDED, event.getChangeType());
assertEquals("k,g", event.getSource());
}
@Test
public void testEqualsAndHashCode() {
for (ConfigChangeType type : ConfigChangeType.values()) {
assertEquals(new ConfigChangedEvent(key, group, content, type), new ConfigChangedEvent(key, group, content, type));
assertEquals(new ConfigChangedEvent(key, group, content, type).hashCode(), new ConfigChangedEvent(key, group, content, type).hashCode());
assertEquals(new ConfigChangedEvent(key, group, content, type).toString(), new ConfigChangedEvent(key, group, content, type).toString());
}
}
@Test
public void testToString() {
ConfigChangedEvent event = new ConfigChangedEvent(key, group, content);
assertNotNull(event.toString());
}
}

View File

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.config.configcenter.file;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.DynamicConfigurationFactory;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link FileSystemDynamicConfigurationFactory} Test
*
* @since 2.7.4
*/
public class FileSystemDynamicConfigurationFactoryTest {
@Test
public void testGetFactory() {
DynamicConfigurationFactory factory = DynamicConfigurationFactory.getDynamicConfigurationFactory("not-exists");
assertEquals(factory, DynamicConfigurationFactory.getDynamicConfigurationFactory("file"));
assertEquals(factory.getDynamicConfiguration(URL.valueOf("dummy")), factory.getDynamicConfiguration(URL.valueOf("dummy")));
assertEquals(FileSystemDynamicConfiguration.class, factory.getDynamicConfiguration(URL.valueOf("dummy")).getClass());
}
}

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.common.config.configcenter.file;
import org.apache.dubbo.common.URL;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -49,12 +50,18 @@ public class FileSystemDynamicConfigurationTest {
@BeforeEach
public void init() {
String classPath = getClassPath();
URL url = valueOf("dubbo://127.0.0.1:20880").addParameter(CONFIG_CENTER_DIR_PARAM_NAME, classPath + File.separator + "config-center");
File rootDirectory = new File(getClassPath(), "config-center");
rootDirectory.mkdirs();
URL url = valueOf("dubbo://127.0.0.1:20880").addParameter(CONFIG_CENTER_DIR_PARAM_NAME, rootDirectory.getAbsolutePath());
configuration = new FileSystemDynamicConfiguration(url);
deleteQuietly(configuration.getRootDirectory());
}
@AfterEach
public void destroy() throws Exception {
configuration.close();
}
private String getClassPath() {
return getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
}

View File

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.extension;
import org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt;
import org.apache.dubbo.common.utils.IOUtils;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link AdaptiveClassCodeGenerator} Test
*
* @since 2.7.4
*/
public class AdaptiveClassCodeGeneratorTest {
@Test
public void testGenerate() throws IOException {
AdaptiveClassCodeGenerator generator = new AdaptiveClassCodeGenerator(HasAdaptiveExt.class, "adaptive");
String value = generator.generate();
URL url = getClass().getResource("/org/apache/dubbo/common/extension/adaptive/HasAdaptiveExt$Adaptive");
try (InputStream inputStream = url.openStream()) {
String content = IOUtils.read(new InputStreamReader(inputStream, "UTF-8"));
assertEquals(content, value);
}
}
}

View File

@ -53,11 +53,13 @@ import org.apache.dubbo.common.extension.injection.impl.InjectExtImpl;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.hamcrest.CoreMatchers.allOf;
import static org.hamcrest.CoreMatchers.anyOf;
import static org.hamcrest.CoreMatchers.instanceOf;
@ -73,7 +75,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getExtensionLoader_Null() throws Exception {
try {
ExtensionLoader.getExtensionLoader(null);
getExtensionLoader(null);
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected.getMessage(),
@ -84,7 +86,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getExtensionLoader_NotInterface() throws Exception {
try {
ExtensionLoader.getExtensionLoader(ExtensionLoaderTest.class);
getExtensionLoader(ExtensionLoaderTest.class);
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected.getMessage(),
@ -95,7 +97,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getExtensionLoader_NotSpiAnnotation() throws Exception {
try {
ExtensionLoader.getExtensionLoader(NoSpiExt.class);
getExtensionLoader(NoSpiExt.class);
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected.getMessage(),
@ -107,34 +109,34 @@ public class ExtensionLoaderTest {
@Test
public void test_getDefaultExtension() throws Exception {
SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getDefaultExtension();
SimpleExt ext = getExtensionLoader(SimpleExt.class).getDefaultExtension();
assertThat(ext, instanceOf(SimpleExtImpl1.class));
String name = ExtensionLoader.getExtensionLoader(SimpleExt.class).getDefaultExtensionName();
String name = getExtensionLoader(SimpleExt.class).getDefaultExtensionName();
assertEquals("impl1", name);
}
@Test
public void test_getDefaultExtension_NULL() throws Exception {
Ext2 ext = ExtensionLoader.getExtensionLoader(Ext2.class).getDefaultExtension();
Ext2 ext = getExtensionLoader(Ext2.class).getDefaultExtension();
assertNull(ext);
String name = ExtensionLoader.getExtensionLoader(Ext2.class).getDefaultExtensionName();
String name = getExtensionLoader(Ext2.class).getDefaultExtensionName();
assertNull(name);
}
@Test
public void test_getExtension() throws Exception {
assertTrue(ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension("impl1") instanceof SimpleExtImpl1);
assertTrue(ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension("impl2") instanceof SimpleExtImpl2);
assertTrue(getExtensionLoader(SimpleExt.class).getExtension("impl1") instanceof SimpleExtImpl1);
assertTrue(getExtensionLoader(SimpleExt.class).getExtension("impl2") instanceof SimpleExtImpl2);
}
@Test
public void test_getExtension_WithWrapper() throws Exception {
WrappedExt impl1 = ExtensionLoader.getExtensionLoader(WrappedExt.class).getExtension("impl1");
WrappedExt impl1 = getExtensionLoader(WrappedExt.class).getExtension("impl1");
assertThat(impl1, anyOf(instanceOf(Ext5Wrapper1.class), instanceOf(Ext5Wrapper2.class)));
WrappedExt impl2 = ExtensionLoader.getExtensionLoader(WrappedExt.class).getExtension("impl2");
WrappedExt impl2 = getExtensionLoader(WrappedExt.class).getExtension("impl2");
assertThat(impl2, anyOf(instanceOf(Ext5Wrapper1.class), instanceOf(Ext5Wrapper2.class)));
@ -150,7 +152,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getExtension_ExceptionNoExtension() throws Exception {
try {
ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension("XXX");
getExtensionLoader(SimpleExt.class).getExtension("XXX");
fail();
} catch (IllegalStateException expected) {
assertThat(expected.getMessage(), containsString("No such extension org.apache.dubbo.common.extension.ext1.SimpleExt by name XXX"));
@ -160,7 +162,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getExtension_ExceptionNoExtension_WrapperNotAffactName() throws Exception {
try {
ExtensionLoader.getExtensionLoader(WrappedExt.class).getExtension("XXX");
getExtensionLoader(WrappedExt.class).getExtension("XXX");
fail();
} catch (IllegalStateException expected) {
assertThat(expected.getMessage(), containsString("No such extension org.apache.dubbo.common.extension.ext6_wrap.WrappedExt by name XXX"));
@ -170,7 +172,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getExtension_ExceptionNullArg() throws Exception {
try {
ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension(null);
getExtensionLoader(SimpleExt.class).getExtension(null);
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected.getMessage(), containsString("Extension name == null"));
@ -179,12 +181,12 @@ public class ExtensionLoaderTest {
@Test
public void test_hasExtension() throws Exception {
assertTrue(ExtensionLoader.getExtensionLoader(SimpleExt.class).hasExtension("impl1"));
assertFalse(ExtensionLoader.getExtensionLoader(SimpleExt.class).hasExtension("impl1,impl2"));
assertFalse(ExtensionLoader.getExtensionLoader(SimpleExt.class).hasExtension("xxx"));
assertTrue(getExtensionLoader(SimpleExt.class).hasExtension("impl1"));
assertFalse(getExtensionLoader(SimpleExt.class).hasExtension("impl1,impl2"));
assertFalse(getExtensionLoader(SimpleExt.class).hasExtension("xxx"));
try {
ExtensionLoader.getExtensionLoader(SimpleExt.class).hasExtension(null);
getExtensionLoader(SimpleExt.class).hasExtension(null);
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected.getMessage(), containsString("Extension name == null"));
@ -193,14 +195,14 @@ public class ExtensionLoaderTest {
@Test
public void test_hasExtension_wrapperIsNotExt() throws Exception {
assertTrue(ExtensionLoader.getExtensionLoader(WrappedExt.class).hasExtension("impl1"));
assertFalse(ExtensionLoader.getExtensionLoader(WrappedExt.class).hasExtension("impl1,impl2"));
assertFalse(ExtensionLoader.getExtensionLoader(WrappedExt.class).hasExtension("xxx"));
assertTrue(getExtensionLoader(WrappedExt.class).hasExtension("impl1"));
assertFalse(getExtensionLoader(WrappedExt.class).hasExtension("impl1,impl2"));
assertFalse(getExtensionLoader(WrappedExt.class).hasExtension("xxx"));
assertFalse(ExtensionLoader.getExtensionLoader(WrappedExt.class).hasExtension("wrapper1"));
assertFalse(getExtensionLoader(WrappedExt.class).hasExtension("wrapper1"));
try {
ExtensionLoader.getExtensionLoader(WrappedExt.class).hasExtension(null);
getExtensionLoader(WrappedExt.class).hasExtension(null);
fail();
} catch (IllegalArgumentException expected) {
assertThat(expected.getMessage(), containsString("Extension name == null"));
@ -209,7 +211,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getSupportedExtensions() throws Exception {
Set<String> exts = ExtensionLoader.getExtensionLoader(SimpleExt.class).getSupportedExtensions();
Set<String> exts = getExtensionLoader(SimpleExt.class).getSupportedExtensions();
Set<String> expected = new HashSet<String>();
expected.add("impl1");
@ -221,7 +223,7 @@ public class ExtensionLoaderTest {
@Test
public void test_getSupportedExtensions_wrapperIsNotExt() throws Exception {
Set<String> exts = ExtensionLoader.getExtensionLoader(WrappedExt.class).getSupportedExtensions();
Set<String> exts = getExtensionLoader(WrappedExt.class).getSupportedExtensions();
Set<String> expected = new HashSet<String>();
expected.add("impl1");
@ -233,35 +235,35 @@ public class ExtensionLoaderTest {
@Test
public void test_AddExtension() throws Exception {
try {
ExtensionLoader.getExtensionLoader(AddExt1.class).getExtension("Manual1");
getExtensionLoader(AddExt1.class).getExtension("Manual1");
fail();
} catch (IllegalStateException expected) {
assertThat(expected.getMessage(), containsString("No such extension org.apache.dubbo.common.extension.ext8_add.AddExt1 by name Manual"));
}
ExtensionLoader.getExtensionLoader(AddExt1.class).addExtension("Manual1", AddExt1_ManualAdd1.class);
AddExt1 ext = ExtensionLoader.getExtensionLoader(AddExt1.class).getExtension("Manual1");
getExtensionLoader(AddExt1.class).addExtension("Manual1", AddExt1_ManualAdd1.class);
AddExt1 ext = getExtensionLoader(AddExt1.class).getExtension("Manual1");
assertThat(ext, instanceOf(AddExt1_ManualAdd1.class));
assertEquals("Manual1", ExtensionLoader.getExtensionLoader(AddExt1.class).getExtensionName(AddExt1_ManualAdd1.class));
assertEquals("Manual1", getExtensionLoader(AddExt1.class).getExtensionName(AddExt1_ManualAdd1.class));
}
@Test
public void test_AddExtension_NoExtend() throws Exception {
// ExtensionLoader.getExtensionLoader(Ext9Empty.class).getSupportedExtensions();
ExtensionLoader.getExtensionLoader(Ext9Empty.class).addExtension("ext9", Ext9EmptyImpl.class);
Ext9Empty ext = ExtensionLoader.getExtensionLoader(Ext9Empty.class).getExtension("ext9");
getExtensionLoader(Ext9Empty.class).addExtension("ext9", Ext9EmptyImpl.class);
Ext9Empty ext = getExtensionLoader(Ext9Empty.class).getExtension("ext9");
assertThat(ext, instanceOf(Ext9Empty.class));
assertEquals("ext9", ExtensionLoader.getExtensionLoader(Ext9Empty.class).getExtensionName(Ext9EmptyImpl.class));
assertEquals("ext9", getExtensionLoader(Ext9Empty.class).getExtensionName(Ext9EmptyImpl.class));
}
@Test
public void test_AddExtension_ExceptionWhenExistedExtension() throws Exception {
SimpleExt ext = ExtensionLoader.getExtensionLoader(SimpleExt.class).getExtension("impl1");
SimpleExt ext = getExtensionLoader(SimpleExt.class).getExtension("impl1");
try {
ExtensionLoader.getExtensionLoader(AddExt1.class).addExtension("impl1", AddExt1_ManualAdd1.class);
getExtensionLoader(AddExt1.class).addExtension("impl1", AddExt1_ManualAdd1.class);
fail();
} catch (IllegalStateException expected) {
assertThat(expected.getMessage(), containsString("Extension name impl1 already exists (Extension interface org.apache.dubbo.common.extension.ext8_add.AddExt1)!"));
@ -270,7 +272,7 @@ public class ExtensionLoaderTest {
@Test
public void test_AddExtension_Adaptive() throws Exception {
ExtensionLoader<AddExt2> loader = ExtensionLoader.getExtensionLoader(AddExt2.class);
ExtensionLoader<AddExt2> loader = getExtensionLoader(AddExt2.class);
loader.addExtension(null, AddExt2_ManualAdaptive.class);
AddExt2 adaptive = loader.getAdaptiveExtension();
@ -279,7 +281,7 @@ public class ExtensionLoaderTest {
@Test
public void test_AddExtension_Adaptive_ExceptionWhenExistedAdaptive() throws Exception {
ExtensionLoader<AddExt1> loader = ExtensionLoader.getExtensionLoader(AddExt1.class);
ExtensionLoader<AddExt1> loader = getExtensionLoader(AddExt1.class);
loader.getAdaptiveExtension();
@ -294,30 +296,30 @@ public class ExtensionLoaderTest {
@Test
public void test_replaceExtension() throws Exception {
try {
ExtensionLoader.getExtensionLoader(AddExt1.class).getExtension("Manual2");
getExtensionLoader(AddExt1.class).getExtension("Manual2");
fail();
} catch (IllegalStateException expected) {
assertThat(expected.getMessage(), containsString("No such extension org.apache.dubbo.common.extension.ext8_add.AddExt1 by name Manual"));
}
{
AddExt1 ext = ExtensionLoader.getExtensionLoader(AddExt1.class).getExtension("impl1");
AddExt1 ext = getExtensionLoader(AddExt1.class).getExtension("impl1");
assertThat(ext, instanceOf(AddExt1Impl1.class));
assertEquals("impl1", ExtensionLoader.getExtensionLoader(AddExt1.class).getExtensionName(AddExt1Impl1.class));
assertEquals("impl1", getExtensionLoader(AddExt1.class).getExtensionName(AddExt1Impl1.class));
}
{
ExtensionLoader.getExtensionLoader(AddExt1.class).replaceExtension("impl1", AddExt1_ManualAdd2.class);
AddExt1 ext = ExtensionLoader.getExtensionLoader(AddExt1.class).getExtension("impl1");
getExtensionLoader(AddExt1.class).replaceExtension("impl1", AddExt1_ManualAdd2.class);
AddExt1 ext = getExtensionLoader(AddExt1.class).getExtension("impl1");
assertThat(ext, instanceOf(AddExt1_ManualAdd2.class));
assertEquals("impl1", ExtensionLoader.getExtensionLoader(AddExt1.class).getExtensionName(AddExt1_ManualAdd2.class));
assertEquals("impl1", getExtensionLoader(AddExt1.class).getExtensionName(AddExt1_ManualAdd2.class));
}
}
@Test
public void test_replaceExtension_Adaptive() throws Exception {
ExtensionLoader<AddExt3> loader = ExtensionLoader.getExtensionLoader(AddExt3.class);
ExtensionLoader<AddExt3> loader = getExtensionLoader(AddExt3.class);
AddExt3 adaptive = loader.getAdaptiveExtension();
assertFalse(adaptive instanceof AddExt3_ManualAdaptive);
@ -330,10 +332,10 @@ public class ExtensionLoaderTest {
@Test
public void test_replaceExtension_ExceptionWhenNotExistedExtension() throws Exception {
AddExt1 ext = ExtensionLoader.getExtensionLoader(AddExt1.class).getExtension("impl1");
AddExt1 ext = getExtensionLoader(AddExt1.class).getExtension("impl1");
try {
ExtensionLoader.getExtensionLoader(AddExt1.class).replaceExtension("NotExistedExtension", AddExt1_ManualAdd1.class);
getExtensionLoader(AddExt1.class).replaceExtension("NotExistedExtension", AddExt1_ManualAdd1.class);
fail();
} catch (IllegalStateException expected) {
assertThat(expected.getMessage(), containsString("Extension name NotExistedExtension doesn't exist (Extension interface org.apache.dubbo.common.extension.ext8_add.AddExt1)"));
@ -342,7 +344,7 @@ public class ExtensionLoaderTest {
@Test
public void test_replaceExtension_Adaptive_ExceptionWhenNotExistedExtension() throws Exception {
ExtensionLoader<AddExt4> loader = ExtensionLoader.getExtensionLoader(AddExt4.class);
ExtensionLoader<AddExt4> loader = getExtensionLoader(AddExt4.class);
try {
loader.replaceExtension(null, AddExt4_ManualAdaptive.class);
@ -354,7 +356,7 @@ public class ExtensionLoaderTest {
@Test
public void test_InitError() throws Exception {
ExtensionLoader<InitErrorExt> loader = ExtensionLoader.getExtensionLoader(InitErrorExt.class);
ExtensionLoader<InitErrorExt> loader = getExtensionLoader(InitErrorExt.class);
loader.getExtension("ok");
@ -371,21 +373,21 @@ public class ExtensionLoaderTest {
public void testLoadActivateExtension() throws Exception {
// test default
URL url = URL.valueOf("test://localhost/test");
List<ActivateExt1> list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "default_group");
Assertions.assertEquals(1, list.size());
Assertions.assertSame(list.get(0).getClass(), ActivateExt1Impl1.class);
// test group
url = url.addParameter(GROUP_KEY, "group1");
list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "group1");
Assertions.assertEquals(1, list.size());
Assertions.assertSame(list.get(0).getClass(), GroupActivateExtImpl.class);
// test old @Activate group
url = url.addParameter(GROUP_KEY, "old_group");
list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "old_group");
Assertions.assertEquals(2, list.size());
Assertions.assertTrue(list.get(0).getClass() == OldActivateExt1Impl2.class
@ -395,7 +397,7 @@ public class ExtensionLoaderTest {
url = url.removeParameter(GROUP_KEY);
url = url.addParameter(GROUP_KEY, "value");
url = url.addParameter("value", "value");
list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "value");
Assertions.assertEquals(1, list.size());
Assertions.assertSame(list.get(0).getClass(), ValueActivateExtImpl.class);
@ -403,7 +405,7 @@ public class ExtensionLoaderTest {
// test order
url = URL.valueOf("test://localhost/test");
url = url.addParameter(GROUP_KEY, "order");
list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, new String[]{}, "order");
Assertions.assertEquals(2, list.size());
Assertions.assertSame(list.get(0).getClass(), OrderActivateExtImpl1.class);
@ -414,14 +416,14 @@ public class ExtensionLoaderTest {
public void testLoadDefaultActivateExtension() throws Exception {
// test default
URL url = URL.valueOf("test://localhost/test?ext=order1,default");
List<ActivateExt1> list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
List<ActivateExt1> list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, "ext", "default_group");
Assertions.assertEquals(2, list.size());
Assertions.assertSame(list.get(0).getClass(), OrderActivateExtImpl1.class);
Assertions.assertSame(list.get(1).getClass(), ActivateExt1Impl1.class);
url = URL.valueOf("test://localhost/test?ext=default,order1");
list = ExtensionLoader.getExtensionLoader(ActivateExt1.class)
list = getExtensionLoader(ActivateExt1.class)
.getActivateExtension(url, "ext", "default_group");
Assertions.assertEquals(2, list.size());
Assertions.assertSame(list.get(0).getClass(), ActivateExt1Impl1.class);
@ -431,7 +433,7 @@ public class ExtensionLoaderTest {
@Test
public void testInjectExtension() {
// test default
InjectExt injectExt = ExtensionLoader.getExtensionLoader(InjectExt.class).getExtension("injection");
InjectExt injectExt = getExtensionLoader(InjectExt.class).getExtension("injection");
InjectExtImpl injectExtImpl = (InjectExtImpl) injectExt;
Assertions.assertNotNull(injectExtImpl.getSimpleExt());
Assertions.assertNull(injectExtImpl.getSimpleExt1());
@ -440,13 +442,28 @@ public class ExtensionLoaderTest {
@Test
void testMultiNames() {
Ext10MultiNames ext10MultiNames = ExtensionLoader.getExtensionLoader(Ext10MultiNames.class).getExtension("impl");
Ext10MultiNames ext10MultiNames = getExtensionLoader(Ext10MultiNames.class).getExtension("impl");
Assertions.assertNotNull(ext10MultiNames);
ext10MultiNames = ExtensionLoader.getExtensionLoader(Ext10MultiNames.class).getExtension("implMultiName");
ext10MultiNames = getExtensionLoader(Ext10MultiNames.class).getExtension("implMultiName");
Assertions.assertNotNull(ext10MultiNames);
Assertions.assertThrows(
IllegalStateException.class,
() -> ExtensionLoader.getExtensionLoader(Ext10MultiNames.class).getExtension("impl,implMultiName")
() -> getExtensionLoader(Ext10MultiNames.class).getExtension("impl,implMultiName")
);
}
@Test
public void testGetOrDefaultExtension() {
ExtensionLoader<InjectExt> loader = getExtensionLoader(InjectExt.class);
InjectExt injectExt = loader.getOrDefaultExtension("non-exists");
assertEquals(InjectExtImpl.class, injectExt.getClass());
assertEquals(InjectExtImpl.class, loader.getOrDefaultExtension("injection").getClass());
}
@Test
public void testGetSupported() {
ExtensionLoader<InjectExt> loader = getExtensionLoader(InjectExt.class);
assertEquals(1, loader.getSupportedExtensions().size());
assertEquals(Collections.singleton("injection"), loader.getSupportedExtensions());
}
}

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.function;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.apache.dubbo.common.function.ThrowableAction.execute;
/**
* {@link ThrowableAction} Test
*
* @since 2.7.4
*/
public class ThrowableActionTest {
@Test
public void testExecute() {
Assertions.assertThrows(RuntimeException.class, () -> execute(() -> {
throw new Exception("Test");
}), "Test");
}
}

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.function;
import org.junit.jupiter.api.Test;
import static org.apache.dubbo.common.function.ThrowableConsumer.execute;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* {@link ThrowableConsumer} Test
*
* @since 2.7.4
*/
public class ThrowableConsumerTest {
@Test
public void testExecute() {
assertThrows(RuntimeException.class, () -> execute("Hello,World", m -> {
throw new Exception(m);
}), "Hello,World");
}
}

View File

@ -0,0 +1,37 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.function;
import org.junit.jupiter.api.Test;
import static org.apache.dubbo.common.function.ThrowableConsumer.execute;
import static org.junit.jupiter.api.Assertions.assertThrows;
/**
* {@link ThrowableFunction} Test
*
* @since 2.7.4
*/
public class ThrowableFunctionTest {
@Test
public void testExecute() {
assertThrows(RuntimeException.class, () -> execute("Hello,World", m -> {
throw new Exception(m);
}), "Hello,World");
}
}

View File

@ -0,0 +1,36 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.lang;
/**
* Default {@link ShutdownHookCallback}
*
* @since 2.7.4
*/
public class DefaultShutdownHookCallback implements ShutdownHookCallback {
private boolean executed = false;
@Override
public void callback() throws Throwable {
executed = true;
}
public boolean isExecuted() {
return executed;
}
}

View File

@ -41,7 +41,7 @@ public class PrioritizedTest {
@Test
public void testGetPriority() {
assertEquals(Prioritized.MIN_PRIORITY, new Prioritized() {
assertEquals(Prioritized.NORMAL_PRIORITY, new Prioritized() {
}.getPriority());
}

View File

@ -16,10 +16,42 @@
*/
package org.apache.dubbo.common.lang;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* {@link ShutdownHookCallbacks}
*
* @since 2.7.4
*/
public class ShutdownHookCallbacksTest {
private ShutdownHookCallbacks callbacks;
@BeforeEach
public void init() {
callbacks = new ShutdownHookCallbacks();
}
@Test
public void testSingleton() {
assertNotNull(callbacks);
}
@Test
public void testCallback() {
callbacks.callback();
DefaultShutdownHookCallback callback = (DefaultShutdownHookCallback) callbacks.getCallbacks().iterator().next();
assertTrue(callback.isExecuted());
}
@AfterEach
public void destroy() {
callbacks.clear();
assertTrue(callbacks.getCallbacks().isEmpty());
}
}

View File

@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
import org.apache.dubbo.common.lang.Prioritized;
/**
* Default {@link CharSequence}
*
* @since 2.7.4
*/
public class DefaultCharSequence implements CharSequence, Prioritized {
@Override
public int length() {
return 0;
}
@Override
public char charAt(int index) {
return 0;
}
@Override
public CharSequence subSequence(int start, int end) {
return null;
}
public int getPriority() {
return MAX_PRIORITY;
}
}

View File

@ -0,0 +1,40 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.common.utils;
import org.junit.jupiter.api.Test;
import java.util.List;
import static org.apache.dubbo.common.utils.DubboServiceLoader.loadServices;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link DubboServiceLoader} Test
*
* @since 2.7.4
*/
public class DubboServiceLoaderTest {
@Test
public void testLoad() {
List<CharSequence> charSequences = loadServices(CharSequence.class);
assertEquals(DefaultCharSequence.class, charSequences.get(0).getClass());
assertEquals(String.class, charSequences.get(1).getClass());
assertEquals(StringBuilder.class, charSequences.get(2).getClass());
}
}

View File

@ -0,0 +1,3 @@
java.lang.String
java.lang.StringBuilder
org.apache.dubbo.common.utils.DefaultCharSequence

View File

@ -0,0 +1 @@
org.apache.dubbo.common.lang.DefaultShutdownHookCallback

View File

@ -0,0 +1,12 @@
package org.apache.dubbo.common.extension.adaptive;
import org.apache.dubbo.common.extension.ExtensionLoader;
public class HasAdaptiveExt$Adaptive implements org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt {
public java.lang.String echo(org.apache.dubbo.common.URL arg0, java.lang.String arg1) {
if (arg0 == null) throw new IllegalArgumentException("url == null");
org.apache.dubbo.common.URL url = arg0;
String extName = url.getParameter("has.adaptive.ext", "adaptive");
if(extName == null) throw new IllegalStateException("Failed to get extension (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt) name from url (" + url.toString() + ") use keys([has.adaptive.ext])");
org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt extension = (org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt)ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.extension.adaptive.HasAdaptiveExt.class).getExtension(extName);
return extension.echo(arg0, arg1);
}
}

View File

@ -59,10 +59,9 @@ import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SE
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_TYPE_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_PROTOCOL;
import static org.apache.dubbo.common.constants.RegistryConstants.SERVICE_REGISTRY_TYPE;
import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoader;
import static org.apache.dubbo.common.utils.UrlUtils.isServiceDiscoveryRegistryType;
import static org.apache.dubbo.config.Constants.DUBBO_IP_TO_REGISTRY;
import static org.apache.dubbo.config.Constants.LAYER_KEY;
import static org.apache.dubbo.config.Constants.LISTENER_KEY;
@ -308,9 +307,7 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig {
}
private String extractRegistryType(URL url) {
boolean isServiceRegistry = url.getParameter(REGISTRY_TYPE_KEY) != null
&& SERVICE_REGISTRY_TYPE.equals(url.getParameter(REGISTRY_TYPE_KEY));
return isServiceRegistry ? SERVICE_REGISTRY_PROTOCOL : REGISTRY_PROTOCOL;
return isServiceDiscoveryRegistryType(url) ? SERVICE_REGISTRY_PROTOCOL : REGISTRY_PROTOCOL;
}
/**

View File

@ -31,8 +31,7 @@ public class ServiceInstancePortCustomizer implements ServiceInstanceCustomizer
@Override
public void customize(ServiceInstance serviceInstance) {
if (serviceInstance.getPort() != null
|| serviceInstance.getPort().intValue() < 1) {
if (serviceInstance.getPort() != null) {
return;
}

View File

@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.event.EventListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link DubboServiceDestroyedEvent} Test
*
* @since 2.7.4
*/
public class DubboServiceDestroyedEventTest implements EventListener<DubboServiceDestroyedEvent> {
private DubboServiceDestroyedEvent event;
private EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
private DubboShutdownHook dubboShutdownHook;
@BeforeEach
public void init() {
eventDispatcher.removeAllEventListeners();
eventDispatcher.addEventListener(this);
dubboShutdownHook = DubboShutdownHook.getDubboShutdownHook();
}
@Test
public void testOnEvent() {
dubboShutdownHook.doDestroy();
assertEquals(dubboShutdownHook, event.getSource());
}
@Override
public void onEvent(DubboServiceDestroyedEvent event) {
this.event = event;
}
}

View File

@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.event.EventListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link DubboShutdownHookRegisteredEvent} Test
*
* @since 2.7.4
*/
public class DubboShutdownHookRegisteredEventTest implements EventListener<DubboShutdownHookRegisteredEvent> {
private DubboShutdownHookRegisteredEvent event;
private EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
private DubboShutdownHook dubboShutdownHook;
@BeforeEach
public void init() {
eventDispatcher.removeAllEventListeners();
eventDispatcher.addEventListener(this);
dubboShutdownHook = DubboShutdownHook.getDubboShutdownHook();
}
@Test
public void testOnEvent() {
dubboShutdownHook.register();
assertEquals(dubboShutdownHook, event.getSource());
assertEquals(dubboShutdownHook, event.getDubboShutdownHook());
}
@Override
public void onEvent(DubboShutdownHookRegisteredEvent event) {
this.event = event;
}
}

View File

@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.DubboShutdownHook;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.event.EventListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link DubboShutdownHookUnregisteredEvent} Test
*
* @since 2.7.4
*/
public class DubboShutdownHookUnregisteredEventTest implements EventListener<DubboShutdownHookUnregisteredEvent> {
private DubboShutdownHookUnregisteredEvent event;
private EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
private DubboShutdownHook dubboShutdownHook;
@BeforeEach
public void init() {
eventDispatcher.removeAllEventListeners();
eventDispatcher.addEventListener(this);
dubboShutdownHook = DubboShutdownHook.getDubboShutdownHook();
}
@Test
public void testOnEvent() {
dubboShutdownHook.register();
dubboShutdownHook.unregister();
assertEquals(dubboShutdownHook, event.getSource());
assertEquals(dubboShutdownHook, event.getDubboShutdownHook());
}
@Override
public void onEvent(DubboShutdownHookUnregisteredEvent event) {
this.event = event;
}
}

View File

@ -0,0 +1,65 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.event.EventListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.util.ReflectionUtils.findField;
import static org.springframework.util.ReflectionUtils.setField;
/**
* {@link ReferenceConfigDestroyedEvent} Test
*
* @since 2.7.4
*/
public class ReferenceConfigDestroyedEventTest implements EventListener<ReferenceConfigDestroyedEvent> {
private ReferenceConfigDestroyedEvent event;
private EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
private ReferenceConfig referenceConfig;
@BeforeEach
public void init() throws Exception {
eventDispatcher.removeAllEventListeners();
eventDispatcher.addEventListener(this);
referenceConfig = new ReferenceConfig();
Field field = findField(referenceConfig.getClass(), "ref");
field.setAccessible(true);
setField(field, referenceConfig, new Object());
}
@Test
public void testOnEvent() {
referenceConfig.destroy();
assertEquals(referenceConfig, event.getSource());
}
@Override
public void onEvent(ReferenceConfigDestroyedEvent event) {
this.event = event;
}
}

View File

@ -0,0 +1,59 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.event;
import org.apache.dubbo.config.ReferenceConfig;
import org.apache.dubbo.event.EventDispatcher;
import org.apache.dubbo.event.EventListener;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link ReferenceConfigInitializedEvent} Test
*
* @since 2.7.4
*/
public class ReferenceConfigInitializedEventTest implements EventListener<ReferenceConfigInitializedEvent> {
private ReferenceConfigInitializedEvent event;
private EventDispatcher eventDispatcher = EventDispatcher.getDefaultExtension();
private ReferenceConfig referenceConfig;
@BeforeEach
public void init() throws Exception {
eventDispatcher.removeAllEventListeners();
eventDispatcher.addEventListener(this);
referenceConfig = new ReferenceConfig();
}
@Test
public void testOnEvent() {
eventDispatcher.dispatch(new ReferenceConfigInitializedEvent(referenceConfig, null));
assertEquals(referenceConfig, event.getSource());
assertEquals(referenceConfig, event.getReferenceConfig());
}
@Override
public void onEvent(ReferenceConfigInitializedEvent event) {
this.event = event;
}
}

View File

@ -81,7 +81,7 @@ public class ConfigurableMetadataServiceExporterTest {
assertEquals(MetadataService.class.getName(), url.getServiceInterface());
assertEquals("test", url.getParameter(GROUP_KEY));
assertEquals(MetadataService.VERSION, url.getParameter(VERSION_KEY));
assertEquals("mockprotocol", url.getProtocol());
assertEquals("dubbo", url.getProtocol());
exporter.unexport();
}

View File

@ -0,0 +1,60 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.metadata;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.context.ConfigManager;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link ServiceInstancePortCustomizer} Test
*
* @since 2.7.4
*/
public class ServiceInstancePortCustomizerTest {
private ServiceInstancePortCustomizer customizer;
private DefaultServiceInstance serviceInstance;
@BeforeEach
public void init() {
customizer = new ServiceInstancePortCustomizer();
serviceInstance = new DefaultServiceInstance();
ConfigManager.getInstance()
.addProtocol(new ProtocolConfig("rest", 9090));
}
@Test
public void testCustomizeWithoutSet() {
serviceInstance.setPort(8080);
customizer.customize(serviceInstance);
assertEquals(8080, serviceInstance.getPort());
}
@Test
public void testCustomize() {
customizer.customize(serviceInstance);
assertEquals(9090, serviceInstance.getPort());
}
}

View File

@ -16,7 +16,8 @@
*/
package org.apache.dubbo.config.spring.context.annotation;
import org.springframework.context.Lifecycle;
import org.apache.dubbo.common.context.Lifecycle;
import org.springframework.context.annotation.Import;
import java.lang.annotation.Documented;

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.spring.context.annotation;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* {@link EnableDubboLifecycle} Test
*
* @since 2.7.4
*/
@EnableDubboLifecycle
public class EnableDubboLifecycleTest {
private AnnotationConfigApplicationContext context;
static boolean initialized = false;
static boolean started = false;
@BeforeEach
public void init() {
context = new AnnotationConfigApplicationContext(EnableDubboLifecycleTest.class);
}
@AfterEach
public void destroy() {
context.close();
}
@Test
public void test() {
assertTrue(initialized);
assertTrue(started);
}
}

View File

@ -0,0 +1,58 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.dubbo.config.spring.context.annotation;
import org.apache.dubbo.common.context.Lifecycle;
/**
* {@link Lifecycle}
*/
public class MyLifecycle implements Lifecycle {
@Override
public Lifecycle initialize() throws IllegalStateException {
EnableDubboLifecycleTest.initialized = true;
return this;
}
@Override
public boolean isInitialized() {
return true;
}
@Override
public Lifecycle start() throws IllegalStateException {
initialize();
EnableDubboLifecycleTest.started = true;
return this;
}
@Override
public boolean isStarted() {
return true;
}
@Override
public Lifecycle stop() throws IllegalStateException {
return this;
}
@Override
public void destroy() throws IllegalStateException {
}
}

View File

@ -0,0 +1 @@
org.apache.dubbo.config.spring.context.annotation.MyLifecycle

View File

@ -159,7 +159,7 @@
<mortbay_jetty_version>6.1.26</mortbay_jetty_version>
<portlet_version>2.0</portlet_version>
<maven_flatten_version>1.1.0</maven_flatten_version>
<revision>2.7.4-SNAPSHOT</revision>
<revision>2.7.5-cloudnative-SNAPSHOT</revision>
</properties>
<dependencyManagement>

View File

@ -32,7 +32,7 @@
<packaging>pom</packaging>
<properties>
<revision>2.7.4-SNAPSHOT</revision>
<revision>2.7.5-cloudnative-SNAPSHOT</revision>
<maven_flatten_version>1.1.0</maven_flatten_version>
</properties>

View File

@ -17,6 +17,8 @@
package org.apache.dubbo.metadata.store;
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.StringUtils;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.WritableMetadataService;
@ -25,11 +27,14 @@ import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
import com.google.gson.Gson;
import java.util.Collection;
import java.util.Comparator;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentNavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@ -46,19 +51,42 @@ import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
*
* @see MetadataService
* @see WritableMetadataService
* @since 2.7.4
* @since 2.7.5
*/
public class InMemoryWritableMetadataService extends BaseWritableMetadataService implements WritableMetadataService {
public class InMemoryWritableMetadataService implements WritableMetadataService {
final Logger logger = LoggerFactory.getLogger(getClass());
private final Lock lock = new ReentrantLock();
// =================================== Registration =================================== //
/**
* All exported {@link URL urls} {@link Map} whose key is the return value of {@link URL#getServiceKey()} method
* and value is the {@link SortedSet sorted set} of the {@link URL URLs}
*/
ConcurrentNavigableMap<String, SortedSet<URL>> exportedServiceURLs = new ConcurrentSkipListMap<>();
// ==================================================================================== //
// =================================== Subscription =================================== //
/**
* The subscribed {@link URL urls} {@link Map} of {@link MetadataService},
* whose key is the return value of {@link URL#getServiceKey()} method and value is
* the {@link SortedSet sorted set} of the {@link URL URLs}
*/
ConcurrentNavigableMap<String, SortedSet<URL>> subscribedServiceURLs = new ConcurrentSkipListMap<>();
ConcurrentNavigableMap<String, String> serviceDefinitions = new ConcurrentSkipListMap<>();
@Override
public SortedSet<String> getSubscribedURLs() {
return super.getSubscribedURLs();
return getAllUnmodifiableServiceURLs(subscribedServiceURLs);
}
SortedSet<String> getAllUnmodifiableServiceURLs(Map<String, SortedSet<URL>> serviceURLs) {
return MetadataService.toSortedStrings(serviceURLs.values().stream().flatMap(Collection::stream));
}
@Override
@ -129,8 +157,14 @@ public class InMemoryWritableMetadataService extends BaseWritableMetadataService
boolean removeURL(Map<String, SortedSet<URL>> serviceURLs, URL url) {
return executeMutually(() -> {
SortedSet<URL> urls = serviceURLs.getOrDefault(url.getServiceKey(), emptySortedSet());
return urls.remove(url);
String key = url.getServiceKey();
SortedSet<URL> urls = serviceURLs.getOrDefault(key, emptySortedSet());
boolean r = urls.remove(url);
// if it is empty
if (urls.isEmpty()) {
serviceURLs.remove(key);
}
return r;
});
}
@ -155,8 +189,8 @@ public class InMemoryWritableMetadataService extends BaseWritableMetadataService
return success;
}
private static SortedSet<String> getServiceURLs(Map<String, SortedSet<URL>> exportedServiceURLs, String serviceKey,
String protocol) {
private SortedSet<String> getServiceURLs(Map<String, SortedSet<URL>> exportedServiceURLs, String serviceKey,
String protocol) {
SortedSet<URL> serviceURLs = exportedServiceURLs.get(serviceKey);
@ -167,7 +201,7 @@ public class InMemoryWritableMetadataService extends BaseWritableMetadataService
return MetadataService.toSortedStrings(serviceURLs.stream().filter(url -> isAcceptableProtocol(protocol, url)));
}
private static boolean isAcceptableProtocol(String protocol, URL url) {
private boolean isAcceptableProtocol(String protocol, URL url) {
return protocol == null
|| protocol.equals(url.getParameter(PROTOCOL_KEY))
|| protocol.equals(url.getProtocol());

View File

@ -19,6 +19,7 @@ package org.apache.dubbo.metadata.store;
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.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
@ -54,13 +55,15 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
*
* @since 2.7.5
*/
public class RemoteWritableMetadataService extends BaseWritableMetadataService implements WritableMetadataService {
public class RemoteWritableMetadataService implements WritableMetadataService {
protected final Logger logger = LoggerFactory.getLogger(getClass());
private volatile String exportedRevision;
private volatile String subscribedRevision;
private InMemoryWritableMetadataService writableMetadataService;
public RemoteWritableMetadataService() {
public RemoteWritableMetadataService(InMemoryWritableMetadataService writableMetadataService) {
this.writableMetadataService = writableMetadataService;
}
public MetadataReport getMetadataReport() {
@ -93,13 +96,15 @@ public class RemoteWritableMetadataService extends BaseWritableMetadataService i
public void publishProvider(URL providerUrl) throws RpcException {
//first add into the list
// remove the individul param
providerUrl = providerUrl.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY, Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
providerUrl = providerUrl.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY,
Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
try {
String interfaceName = providerUrl.getParameter(INTERFACE_KEY);
if (StringUtils.isNotEmpty(interfaceName)) {
Class interfaceClass = Class.forName(interfaceName);
FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, providerUrl.getParameters());
FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass,
providerUrl.getParameters());
getMetadataReport().storeProviderMetadata(new MetadataIdentifier(providerUrl.getServiceInterface(),
providerUrl.getParameter(VERSION_KEY), providerUrl.getParameter(GROUP_KEY),
PROVIDER_SIDE, providerUrl.getParameter(APPLICATION_KEY)), fullServiceDefinition);
@ -114,7 +119,8 @@ public class RemoteWritableMetadataService extends BaseWritableMetadataService i
@Deprecated
public void publishConsumer(URL consumerURL) throws RpcException {
consumerURL = consumerURL.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY, Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
consumerURL = consumerURL.removeParameters(PID_KEY, TIMESTAMP_KEY, Constants.BIND_IP_KEY,
Constants.BIND_PORT_KEY, TIMESTAMP_KEY);
getMetadataReport().storeConsumerMetadata(new MetadataIdentifier(consumerURL.getServiceInterface(),
consumerURL.getParameter(VERSION_KEY), consumerURL.getParameter(GROUP_KEY), CONSUMER_SIDE,
consumerURL.getParameter(APPLICATION_KEY)), consumerURL.getParameters());
@ -153,12 +159,14 @@ public class RemoteWritableMetadataService extends BaseWritableMetadataService i
result = false;
}
}
if (!StringUtils.isEmpty(subscribedRevision) && !subscribedRevision.equals(this.subscribedRevision)) {
if (!StringUtils.isEmpty(subscribedRevision) && !subscribedRevision.equals(this.subscribedRevision)
&& CollectionUtils.isNotEmpty(writableMetadataService.getSubscribedURLs())) {
this.subscribedRevision = subscribedRevision;
SubscriberMetadataIdentifier metadataIdentifier = new SubscriberMetadataIdentifier();
metadataIdentifier.setApplication(serviceName());
metadataIdentifier.setRevision(subscribedRevision);
boolean executeResult = throwableAction(getMetadataReport()::saveSubscribedData, metadataIdentifier, super.getSubscribedURLs());
boolean executeResult = throwableAction(getMetadataReport()::saveSubscribedData, metadataIdentifier,
writableMetadataService.getSubscribedURLs());
if (!executeResult) {
result = false;
}
@ -168,7 +176,7 @@ public class RemoteWritableMetadataService extends BaseWritableMetadataService i
private boolean saveServiceMetadata() {
boolean result = true;
for (SortedSet<URL> urls : exportedServiceURLs.values()) {
for (SortedSet<URL> urls : writableMetadataService.exportedServiceURLs.values()) {
Iterator<URL> iterator = urls.iterator();
while (iterator.hasNext()) {
URL url = iterator.next();
@ -200,7 +208,8 @@ public class RemoteWritableMetadataService extends BaseWritableMetadataService i
return null;
}
boolean throwableAction(BiConsumer<ServiceMetadataIdentifier, URL> consumer, ServiceMetadataIdentifier metadataIdentifier, URL url) {
boolean throwableAction(BiConsumer<ServiceMetadataIdentifier, URL> consumer,
ServiceMetadataIdentifier metadataIdentifier, URL url) {
try {
consumer.accept(metadataIdentifier, url);
} catch (Exception e) {
@ -210,7 +219,8 @@ public class RemoteWritableMetadataService extends BaseWritableMetadataService i
return true;
}
boolean throwableAction(BiConsumer<SubscriberMetadataIdentifier, Set<String>> consumer, SubscriberMetadataIdentifier metadataIdentifier, Set<String> urls) {
boolean throwableAction(BiConsumer<SubscriberMetadataIdentifier, Set<String>> consumer,
SubscriberMetadataIdentifier metadataIdentifier, Set<String> urls) {
try {
consumer.accept(metadataIdentifier, urls);
} catch (Exception e) {

View File

@ -1,6 +1,7 @@
package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.InmemoryConfiguration;
import org.apache.dubbo.metadata.WritableMetadataService;
import java.util.SortedSet;
@ -12,12 +13,12 @@ import java.util.function.BiFunction;
* @since 2.7.5
*/
public class RemoteWritableMetadataServiceDelegate implements WritableMetadataService {
private WritableMetadataService defaultWritableMetadataService;
private RemoteWritableMetadataService remoteWritableMetadataService;
InMemoryWritableMetadataService defaultWritableMetadataService;
RemoteWritableMetadataService remoteWritableMetadataService;
public RemoteWritableMetadataServiceDelegate() {
defaultWritableMetadataService = WritableMetadataService.getDefaultExtension();
remoteWritableMetadataService = new RemoteWritableMetadataService();
defaultWritableMetadataService = (InMemoryWritableMetadataService) WritableMetadataService.getExtension("local");
remoteWritableMetadataService = new RemoteWritableMetadataService(defaultWritableMetadataService);
}
private WritableMetadataService getDefaultWritableMetadataService() {
@ -79,9 +80,6 @@ public class RemoteWritableMetadataServiceDelegate implements WritableMetadataSe
}
private boolean doFunction(BiFunction<WritableMetadataService, URL, Boolean> func, URL url) {
boolean result = true;
result &= func.apply(defaultWritableMetadataService, url);
result &= func.apply(remoteWritableMetadataService, url);
return result;
return func.apply(defaultWritableMetadataService, url) && func.apply(remoteWritableMetadataService, url);
}
}

View File

@ -0,0 +1,79 @@
package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
/**
* 2019-08-29
*/
public class InMemoryWritableMetadataServiceTest {
String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService2", version = "0.9.9", group = null;
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/?interface=" + interfaceName + "&version="
+ version + "&application=vicpubprovder&side=provider");
@BeforeEach
public void before() {
}
@Test
public void testPublishServiceDefinition() {
InMemoryWritableMetadataService inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
inMemoryWritableMetadataService.publishServiceDefinition(url);
String v = inMemoryWritableMetadataService.getServiceDefinition(interfaceName, version, group);
Assertions.assertNotNull(v);
}
@Test
public void testExportURL() {
InMemoryWritableMetadataService inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test567Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.exportURL(url);
Assertions.assertTrue(inMemoryWritableMetadataService.exportedServiceURLs.size() == 1);
Assertions.assertEquals(inMemoryWritableMetadataService.exportedServiceURLs.get(url.getServiceKey()).first(), url);
}
@Test
public void testSubscribeURL() {
InMemoryWritableMetadataService inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test678Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.subscribeURL(url);
Assertions.assertTrue(inMemoryWritableMetadataService.subscribedServiceURLs.size() == 1);
Assertions.assertEquals(inMemoryWritableMetadataService.subscribedServiceURLs.get(url.getServiceKey()).first(), url);
}
@Test
public void testUnExportURL() {
InMemoryWritableMetadataService inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test567Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.exportURL(url);
Assertions.assertTrue(inMemoryWritableMetadataService.exportedServiceURLs.size() == 1);
Assertions.assertEquals(inMemoryWritableMetadataService.exportedServiceURLs.get(url.getServiceKey()).first(), url);
inMemoryWritableMetadataService.unexportURL(url);
Assertions.assertTrue(inMemoryWritableMetadataService.exportedServiceURLs.size() == 0);
}
@Test
public void testUnSubscribeURL() {
InMemoryWritableMetadataService inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test678Service?version=1.0.44&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.subscribeURL(url);
Assertions.assertTrue(inMemoryWritableMetadataService.subscribedServiceURLs.size() == 1);
Assertions.assertEquals(inMemoryWritableMetadataService.subscribedServiceURLs.get(url.getServiceKey()).first(), url);
inMemoryWritableMetadataService.unsubscribeURL(url);
Assertions.assertTrue(inMemoryWritableMetadataService.subscribedServiceURLs.size() == 0);
}
}

View File

@ -21,7 +21,11 @@ import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.metadata.test.JTestMetadataReport4Test;
import org.apache.dubbo.rpc.model.ApplicationModel;
import com.google.gson.Gson;
import org.junit.jupiter.api.Assertions;
@ -38,24 +42,17 @@ import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_
public class RemoteWritableMeatadataServiceTest {
URL url = URL.valueOf("JTest://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vic");
RemoteWritableMetadataService metadataReportService1;
InMemoryWritableMetadataService inMemoryWritableMetadataService;
@BeforeEach
public void before() {
metadataReportService1 = (RemoteWritableMetadataService) WritableMetadataService.getExtension(REMOTE_METADATA_STORAGE_TYPE);
inMemoryWritableMetadataService = new InMemoryWritableMetadataService();
metadataReportService1 = new RemoteWritableMetadataService(inMemoryWritableMetadataService);
MetadataReportInstance.init(url);
}
@Test
public void testInstance() {
RemoteWritableMetadataService metadataReportService2 = (RemoteWritableMetadataService) WritableMetadataService.getExtension(REMOTE_METADATA_STORAGE_TYPE);
Assertions.assertSame(metadataReportService1, metadataReportService2);
}
@Test
public void testPublishProviderNoInterfaceName() {
URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vicpubprovder&side=provider");
metadataReportService1.publishProvider(publishUrl);
@ -93,7 +90,7 @@ public class RemoteWritableMeatadataServiceTest {
String value = jTestMetadataReport4Test.store.get(JTestMetadataReport4Test.getProviderKey(publishUrl));
FullServiceDefinition fullServiceDefinition = toServiceDefinition(value);
Map<String,String> map = fullServiceDefinition.getParameters();
Map<String, String> map = fullServiceDefinition.getParameters();
Assertions.assertEquals(map.get("application"), "vicpubp");
Assertions.assertEquals(map.get("version"), "1.0.3");
Assertions.assertEquals(map.get("interface"), "org.apache.dubbo.metadata.store.InterfaceNameTestService");
@ -119,6 +116,75 @@ public class RemoteWritableMeatadataServiceTest {
}
@Test
public void testPublishServiceDefinition() {
URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestService?version=1.0.0&application=vicpubprovder&side=provider");
metadataReportService1.publishServiceDefinition(publishUrl);
Assertions.assertTrue(metadataReportService1.getMetadataReport() instanceof JTestMetadataReport4Test);
JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.getMetadataReport();
Assertions.assertTrue(!jTestMetadataReport4Test.store.containsKey(JTestMetadataReport4Test.getProviderKey(publishUrl)));
}
@Test
public void testUnexportURL() {
}
@Test
public void testRefreshMetadataService() throws InterruptedException {
URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadataService?version=1.0.8&application=vicpubprovder&side=provider");
URL publishUrl2 = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata2Service?version=1.0.5&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.exportURL(publishUrl);
inMemoryWritableMetadataService.exportURL(publishUrl2);
String exportedRevision = "9999";
JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.getMetadataReport();
int origSize = jTestMetadataReport4Test.store.size();
Assertions.assertTrue(metadataReportService1.refreshMetadata(exportedRevision, "1109"));
Thread.sleep(200);
int size = jTestMetadataReport4Test.store.size();
Assertions.assertTrue(size - origSize == 2);
Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl.toFullString());
Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl2, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl2.toFullString());
}
@Test
public void testRefreshMetadataSubscription() throws InterruptedException {
URL subscriberUrl1 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata00Service?version=1.0.8&application=vicpubprovder&side=provider");
URL subscriberUrl2 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata09Service?version=1.0.5&application=vicpubprovder&side=provider");
inMemoryWritableMetadataService.subscribeURL(subscriberUrl1);
inMemoryWritableMetadataService.subscribeURL(subscriberUrl2);
String exportedRevision = "9999";
String subscriberRevision = "2099";
String applicationName = "wriableMetadataService";
JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) metadataReportService1.getMetadataReport();
int origSize = jTestMetadataReport4Test.store.size();
ApplicationModel.setApplication(applicationName);
Assertions.assertTrue(metadataReportService1.refreshMetadata(exportedRevision, subscriberRevision));
Thread.sleep(200);
int size = jTestMetadataReport4Test.store.size();
Assertions.assertTrue(size - origSize == 1);
String r = jTestMetadataReport4Test.store.get(getSubscriberMetadataIdentifier(
subscriberRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
Assertions.assertNotNull(r);
}
private ServiceMetadataIdentifier getServiceMetadataIdentifier(URL publishUrl, String exportedRevision) {
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(publishUrl);
serviceMetadataIdentifier.setRevision(exportedRevision);
serviceMetadataIdentifier.setProtocol(publishUrl.getProtocol());
return serviceMetadataIdentifier;
}
private SubscriberMetadataIdentifier getSubscriberMetadataIdentifier(String subscriberRevision) {
SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier();
subscriberMetadataIdentifier.setRevision(subscriberRevision);
subscriberMetadataIdentifier.setApplication(ApplicationModel.getApplication());
return subscriberMetadataIdentifier;
}
private FullServiceDefinition toServiceDefinition(String urlQuery) {
Gson gson = new Gson();
return gson.fromJson(urlQuery, FullServiceDefinition.class);

View File

@ -0,0 +1,182 @@
package org.apache.dubbo.metadata.store;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.metadata.test.JTestMetadataReport4Test;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.SortedSet;
/**
* 2019-08-27
*/
public class RemoteWritableMetadataServiceDelegateTest {
static URL metadataURL = URL.valueOf("JTest://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Tes33tService?version=1.0.0&application=vic");
RemoteWritableMetadataServiceDelegate metadataReportService;
String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService80", version = "0.6.9", group = null;
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/?interface=" + interfaceName + "&version="
+ version + "&application=vicpubprovder&side=provider");
@BeforeAll
public static void beforeAll() {
MetadataReportInstance.init(metadataURL);
}
@BeforeEach
public void before() {
metadataReportService = new RemoteWritableMetadataServiceDelegate();
}
@Test
public void testInstance() {
WritableMetadataService metadataReportService1 = WritableMetadataService.getExtension("remote");
WritableMetadataService metadataReportService2 = WritableMetadataService.getExtension("remote");
Assertions.assertSame(metadataReportService1, metadataReportService2);
Assertions.assertTrue(metadataReportService1 instanceof RemoteWritableMetadataServiceDelegate);
}
@Test
public void testPublishServiceDefinition() throws InterruptedException {
String interfaceName = "org.apache.dubbo.metadata.store.InterfaceNameTestService2", version = "0.9.9", group = null;
URL tmpUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/?interface=" + interfaceName + "&version="
+ version + "&application=vicpubprovder&side=provider");
metadataReportService.publishServiceDefinition(tmpUrl);
Thread.sleep(150);
String v = metadataReportService.getServiceDefinition(interfaceName, version, group);
Assertions.assertNotNull(v);
}
@Test
public void testExportURL() throws InterruptedException {
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test567Service?version=1.0.44&application=vicpubprovder&side=provider");
metadataReportService.exportURL(url);
Thread.sleep(100);
Assertions.assertTrue(getInMemoryWriableMetadataService().exportedServiceURLs.size() == 1);
Assertions.assertEquals(getInMemoryWriableMetadataService().exportedServiceURLs.get(url.getServiceKey()).first(), url);
}
@Test
public void testSubscribeURL() throws InterruptedException {
URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test0678Service?version=1.3.144&application=vicpubprovder&side=provider");
int origSize = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
metadataReportService.subscribeURL(url);
Thread.sleep(100);
int size = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
Assertions.assertTrue(size - origSize == 1);
Assertions.assertEquals(getInMemoryWriableMetadataService().subscribedServiceURLs.get(url.getServiceKey()).first(), url);
}
@Test
public void testUnExportURL() throws InterruptedException {
URL url = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test0567Service?version=1.2.44&application=vicpubprovder&side=provider");
int origSize = getInMemoryWriableMetadataService().exportedServiceURLs.size();
metadataReportService.exportURL(url);
Thread.sleep(100);
int size = getInMemoryWriableMetadataService().exportedServiceURLs.size();
Assertions.assertTrue(size - origSize == 1);
Assertions.assertEquals(getInMemoryWriableMetadataService().exportedServiceURLs.get(url.getServiceKey()).first(), url);
metadataReportService.unexportURL(url);
int unexportSize = getInMemoryWriableMetadataService().exportedServiceURLs.size();
Assertions.assertTrue(size - unexportSize == 1);
}
@Test
public void testUnSubscribeURL() throws InterruptedException {
URL url = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.Test0678Service?version=1.5.477&application=vicpubprovder&side=provider");
int origSize = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
metadataReportService.subscribeURL(url);
Thread.sleep(100);
int size = getInMemoryWriableMetadataService().subscribedServiceURLs.size();
Assertions.assertTrue(size - origSize == 1);
Assertions.assertEquals(getInMemoryWriableMetadataService().subscribedServiceURLs.get(url.getServiceKey()).first(), url);
metadataReportService.unsubscribeURL(url);
Thread.sleep(100);
Assertions.assertTrue(getInMemoryWriableMetadataService().subscribedServiceURLs.size() == 0);
}
@Test
public void testRefreshMetadataService() throws InterruptedException {
URL publishUrl = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadataService?version=1.6.8&application=vicpubprovder&side=provider");
URL publishUrl2 = URL.valueOf("dubbo://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata2Service?version=1.6.5&application=vicpubprovder&side=provider");
metadataReportService.exportURL(publishUrl);
metadataReportService.exportURL(publishUrl2);
String exportedRevision = "9999";
JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) MetadataReportInstance.getMetadataReport(true);
int origSize = jTestMetadataReport4Test.store.size();
int num = countNum();
Assertions.assertTrue(metadataReportService.refreshMetadata(exportedRevision, "1109"));
Thread.sleep(200);
int size = jTestMetadataReport4Test.store.size();
Assertions.assertTrue(size - origSize == num);
Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl.toFullString());
Assertions.assertEquals(jTestMetadataReport4Test.store.get(getServiceMetadataIdentifier(publishUrl2, exportedRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY)), publishUrl2.toFullString());
}
@Test
public void testRefreshMetadataSubscription() throws InterruptedException {
URL subscriberUrl1 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata00Service?version=2.0.8&application=vicpubprovder&side=provider");
URL subscriberUrl2 = URL.valueOf("subscriber://" + NetUtils.getLocalAddress().getHostName() + ":4444/org.apache.dubbo.TestRefreshMetadata09Service?version=2.0.5&application=vicpubprovder&side=provider");
metadataReportService.subscribeURL(subscriberUrl1);
metadataReportService.subscribeURL(subscriberUrl2);
String exportedRevision = "9999";
String subscriberRevision = "2099";
String applicationName = "wriableMetadataService";
JTestMetadataReport4Test jTestMetadataReport4Test = (JTestMetadataReport4Test) MetadataReportInstance.getMetadataReport(true);
int origSize = jTestMetadataReport4Test.store.size();
ApplicationModel.setApplication(applicationName);
Assertions.assertTrue(metadataReportService.refreshMetadata(exportedRevision, subscriberRevision));
Thread.sleep(200);
int size = jTestMetadataReport4Test.store.size();
Assertions.assertTrue(size - origSize == 1);
String r = jTestMetadataReport4Test.store.get(getSubscriberMetadataIdentifier(
subscriberRevision).getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
Assertions.assertNotNull(r);
}
private ServiceMetadataIdentifier getServiceMetadataIdentifier(URL publishUrl, String exportedRevision) {
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(publishUrl);
serviceMetadataIdentifier.setRevision(exportedRevision);
serviceMetadataIdentifier.setProtocol(publishUrl.getProtocol());
return serviceMetadataIdentifier;
}
private SubscriberMetadataIdentifier getSubscriberMetadataIdentifier(String subscriberRevision) {
SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier();
subscriberMetadataIdentifier.setRevision(subscriberRevision);
subscriberMetadataIdentifier.setApplication(ApplicationModel.getApplication());
return subscriberMetadataIdentifier;
}
private InMemoryWritableMetadataService getInMemoryWriableMetadataService() {
return (InMemoryWritableMetadataService) metadataReportService.defaultWritableMetadataService;
}
private int countNum() {
int num = 0;
for (SortedSet<URL> tmp : getInMemoryWriableMetadataService().exportedServiceURLs.values()) {
num += tmp.size();
}
if (!getInMemoryWriableMetadataService().subscribedServiceURLs.values().isEmpty()) {
num++;
}
return num;
}
}

View File

@ -25,6 +25,7 @@ import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.metadata.report.support.AbstractMetadataReport;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@ -43,7 +44,7 @@ public class JTestMetadataReport4Test extends AbstractMetadataReport {
super(url);
}
public Map<String, String> store = new ConcurrentHashMap<>();
public volatile Map<String, String> store = new ConcurrentHashMap<>();
private static String getProtocol(URL url) {
@ -64,22 +65,22 @@ public class JTestMetadataReport4Test extends AbstractMetadataReport {
@Override
protected void doSaveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
store.put(metadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), url.toFullString());
}
@Override
protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier) {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
store.remove(metadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
}
@Override
protected List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier) {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
return Arrays.asList(store.getOrDefault(metadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), ""));
}
@Override
protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urls) {
store.put(subscriberMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), urls);
}
@Override
@ -97,6 +98,6 @@ public class JTestMetadataReport4Test extends AbstractMetadataReport {
@Override
public String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier) {
return null;
return store.get(consumerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
}
}

View File

@ -122,12 +122,12 @@ public class EtcdMetadataReport extends AbstractMetadataReport {
@Override
protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
return etcdClient.getKVValue(getNodeKey(subscriberMetadataIdentifier));
}
@Override
public String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier) {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
public String getServiceDefinition(MetadataIdentifier metadataIdentifier) {
return etcdClient.getKVValue(getNodeKey(metadataIdentifier));
}
private void storeMetadata(MetadataIdentifier identifier, String v) {

View File

@ -22,6 +22,8 @@ import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import com.google.gson.Gson;
import io.etcd.jetcd.ByteSequence;
@ -37,10 +39,12 @@ import org.junit.jupiter.api.Test;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
@ -74,11 +78,13 @@ public class EtcdMetadataReportTest {
}
@Test
@Disabled("Disabled because https://github.com/apache/dubbo/issues/4185")
public void testStoreProvider() throws Exception {
String version = "1.0.0";
String group = null;
String application = "etcd-metdata-report-test";
String r = etcdMetadataReport.getServiceDefinition(new MetadataIdentifier(TEST_SERVICE, version, group, "provider", application));
Assertions.assertNull(r);
MetadataIdentifier providerIdentifier =
storeProvider(etcdMetadataReport, TEST_SERVICE, version, group, application);
@ -90,6 +96,9 @@ public class EtcdMetadataReportTest {
Gson gson = new Gson();
FullServiceDefinition fullServiceDefinition = gson.fromJson(fileContent, FullServiceDefinition.class);
Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "etcdTest");
r = etcdMetadataReport.getServiceDefinition(new MetadataIdentifier(TEST_SERVICE, version, group, "provider", application));
Assertions.assertNotNull(r);
}
@Test
@ -106,6 +115,113 @@ public class EtcdMetadataReportTest {
Assertions.assertEquals(fileContent, "{\"paramConsumerTest\":\"etcdConsumer\"}");
}
@Test
public void testDoSaveMetadata() throws ExecutionException, InterruptedException {
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(TEST_SERVICE, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
group, "provider", revision, protocol);
etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, URL.encode(url.toFullString()));
}
@Test
public void testDoRemoveMetadata() throws ExecutionException, InterruptedException {
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(TEST_SERVICE, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
group, "provider", revision, protocol);
etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
Assertions.assertNotNull(fileContent);
etcdMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
response = etcdClientForTest.getKVClient().get(ByteSequence.from(
etcdMetadataReport.getNodeKey(serviceMetadataIdentifier), StandardCharsets.UTF_8));
Assertions.assertTrue(response.get().getKvs().isEmpty());
}
@Test
public void testDoGetExportedURLs() throws ExecutionException, InterruptedException {
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(TEST_SERVICE, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(TEST_SERVICE, version,
group, "provider", revision, protocol);
etcdMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
List<String> r = etcdMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
Assertions.assertTrue(r.size() == 1);
String fileContent = r.get(0);
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, url.toFullString());
}
@Test
public void testDoSaveSubscriberData() throws ExecutionException, InterruptedException {
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(TEST_SERVICE, version, group, application);
SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
Gson gson = new Gson();
String r = gson.toJson(Arrays.asList(url));
etcdMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
etcdMetadataReport.getNodeKey(subscriberMetadataIdentifier), StandardCharsets.UTF_8));
String fileContent = response.get().getKvs().get(0).getValue().toString(StandardCharsets.UTF_8);
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, r);
}
@Test
public void testDoGetSubscribedURLs() throws ExecutionException, InterruptedException {
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(TEST_SERVICE, version, group, application);
SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
Gson gson = new Gson();
String r = gson.toJson(Arrays.asList(url));
etcdMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
CompletableFuture<GetResponse> response = etcdClientForTest.getKVClient().get(ByteSequence.from(
etcdMetadataReport.getNodeKey(subscriberMetadataIdentifier), StandardCharsets.UTF_8));
String fileContent = etcdMetadataReport.doGetSubscribedURLs(subscriberMetadataIdentifier);
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, r);
}
private MetadataIdentifier storeProvider(EtcdMetadataReport etcdMetadataReport, String interfaceName, String version,
String group, String application)
throws ClassNotFoundException, InterruptedException {
@ -124,6 +240,13 @@ public class EtcdMetadataReportTest {
return providerMetadataIdentifier;
}
private URL generateURL(String interfaceName, String version, String group, String application) {
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
"?paramTest=etcdTest&version=" + version + "&application="
+ application + (group == null ? "" : "&group=" + group));
return url;
}
private MetadataIdentifier storeConsumer(EtcdMetadataReport etcdMetadataReport, String interfaceName,
String version, String group, String application) throws InterruptedException {

View File

@ -22,6 +22,8 @@ import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
import org.apache.dubbo.remoting.zookeeper.curator.CuratorZookeeperTransporter;
import com.google.gson.Gson;
@ -31,8 +33,11 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
@ -120,6 +125,112 @@ public class ZookeeperMetadataReportTest {
Assertions.assertEquals(fileContent, "{\"paramConsumerTest\":\"zkCm\"}");
}
@Test
public void testDoSaveMetadata() throws ExecutionException, InterruptedException {
String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
group, "provider", revision, protocol);
zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, URL.encode(url.toFullString()));
}
@Test
public void testDoRemoveMetadata() throws ExecutionException, InterruptedException {
String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
group, "provider", revision, protocol);
zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
Assertions.assertNotNull(fileContent);
zookeeperMetadataReport.doRemoveMetadata(serviceMetadataIdentifier);
fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(serviceMetadataIdentifier));
Assertions.assertNull(fileContent);
}
@Test
public void testDoGetExportedURLs() throws ExecutionException, InterruptedException {
String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
ServiceMetadataIdentifier serviceMetadataIdentifier = new ServiceMetadataIdentifier(interfaceName, version,
group, "provider", revision, protocol);
zookeeperMetadataReport.doSaveMetadata(serviceMetadataIdentifier, url);
List<String> r = zookeeperMetadataReport.doGetExportedURLs(serviceMetadataIdentifier);
Assertions.assertTrue(r.size() == 1);
String fileContent = r.get(0);
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, url.toFullString());
}
@Test
public void testDoSaveSubscriberData() throws ExecutionException, InterruptedException {
String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
Gson gson = new Gson();
String r = gson.toJson(Arrays.asList(url));
zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, r);
}
@Test
public void testDoGetSubscribedURLs() throws ExecutionException, InterruptedException {
String interfaceName = "org.apache.dubbo.metadata.store.zookeeper.ZookeeperMetadataReport4TstService";
String version = "1.0.0";
String group = null;
String application = "etc-metadata-report-consumer-test";
String revision = "90980";
String protocol = "xxx";
URL url = generateURL(interfaceName, version, group, application);
SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
Gson gson = new Gson();
String r = gson.toJson(Arrays.asList(url));
zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
Assertions.assertNotNull(fileContent);
Assertions.assertEquals(fileContent, r);
}
private MetadataIdentifier storePrivider(ZookeeperMetadataReport zookeeperMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException, InterruptedException {
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?paramTest=zkTest&version=" + version + "&application="
@ -156,4 +267,11 @@ public class ZookeeperMetadataReportTest {
}
return value;
}
private URL generateURL(String interfaceName, String version, String group, String application) {
URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":8989/" + interfaceName +
"?paramTest=etcdTest&version=" + version + "&application="
+ application + (group == null ? "" : "&group=" + group));
return url;
}
}

View File

@ -25,12 +25,12 @@ public class RemoteMetadataServiceProxy implements MetadataService {
protected final Logger logger = LoggerFactory.getLogger(getClass());
private String serviceName;
// FIXME this is provider revison. it also need consumer revison.
private String revision;
public RemoteMetadataServiceProxy(ServiceInstance serviceInstance) {
this.serviceName = serviceInstance.getServiceName();
// this is ServiceInstance of registry(Provider)
this.revision = serviceInstance.getMetadata()
.getOrDefault(ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME, "");
}
@ -40,7 +40,6 @@ public class RemoteMetadataServiceProxy implements MetadataService {
return serviceName;
}
// TODO, protocol should be used
@Override
public SortedSet<String> getExportedURLs(String serviceInterface, String group, String version, String protocol) {
return toSortedStrings(getMetadataReport().getExportedURLs(
@ -60,8 +59,18 @@ public class RemoteMetadataServiceProxy implements MetadataService {
@Override
public String getServiceDefinition(String serviceKey) {
String[] services = UrlUtils.parseServiceKey(serviceKey);
return getMetadataReport().getServiceDefinition(new MetadataIdentifier(services[1],
services[0], services[2], PROVIDER_SIDE, serviceName));
String serviceInterface = services[0];
// if version or group is not exist
String version = null;
if (services.length > 1) {
version = services[1];
}
String group = null;
if (services.length > 2) {
group = services[2];
}
return getMetadataReport().getServiceDefinition(new MetadataIdentifier(serviceInterface,
version, group, PROVIDER_SIDE, serviceName));
}
MetadataReport getMetadataReport() {

View File

@ -63,9 +63,9 @@ public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<Ser
private final ConcurrentMap<URL, ConcurrentMap<NotifyListener, ChildListener>> etcdListeners = new ConcurrentHashMap<>();
private EtcdClient etcdClient;
private EventDispatcher dispatcher;
private ServiceInstance serviceInstance;
EtcdClient etcdClient;
EventDispatcher dispatcher;
ServiceInstance serviceInstance;
@Override
public void onEvent(ServiceInstancesChangedEvent event) {
@ -99,7 +99,9 @@ public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<Ser
@Override
public void destroy() {
if (etcdClient != null && etcdClient.isConnected()) {
etcdClient.close();
}
}
@Override
@ -131,7 +133,7 @@ public class EtcdServiceDiscovery implements ServiceDiscovery, EventListener<Ser
public void update(ServiceInstance serviceInstance) throws RuntimeException {
try {
String path = toPath(serviceInstance);
etcdClient.put(path, new Gson().toJson(serviceInstance));
etcdClient.putEphemeral(path, new Gson().toJson(serviceInstance));
services.add(serviceInstance.getServiceName());
} catch (Throwable e) {
throw new RpcException("Failed to register " + serviceInstance + " to etcd " + etcdClient.getUrl()

View File

@ -0,0 +1,108 @@
package org.apache.dubbo.registry.etcd;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstance;
import com.google.gson.Gson;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import static java.lang.String.valueOf;
/**
* 2019-08-30
* <p>
* There is no embedded server. so it works depend on etcd local server.
*/
@Disabled
public class EtcdServiceDiscoveryTest {
static EtcdServiceDiscovery etcdServiceDiscovery;
@BeforeAll
public static void setUp() throws Exception {
URL url = URL.valueOf("etcd3://127.0.0.1:2379/org.apache.dubbo.registry.RegistryService");
etcdServiceDiscovery = new EtcdServiceDiscovery();
Assertions.assertNull(etcdServiceDiscovery.etcdClient);
etcdServiceDiscovery.initialize(url);
}
@AfterAll
public static void destroy() throws Exception {
// etcdServiceDiscovery.destroy();
}
@Test
public void testLifecycle() throws Exception {
URL url = URL.valueOf("etcd3://127.0.0.1:2233/org.apache.dubbo.registry.RegistryService");
EtcdServiceDiscovery etcdServiceDiscoveryTmp = new EtcdServiceDiscovery();
Assertions.assertNull(etcdServiceDiscoveryTmp.etcdClient);
etcdServiceDiscoveryTmp.initialize(url);
Assertions.assertNotNull(etcdServiceDiscoveryTmp.etcdClient);
Assertions.assertTrue(etcdServiceDiscoveryTmp.etcdClient.isConnected());
etcdServiceDiscoveryTmp.destroy();
Assertions.assertFalse(etcdServiceDiscoveryTmp.etcdClient.isConnected());
}
@Test
public void testRegistry() throws Exception {
ServiceInstance serviceInstance = new DefaultServiceInstance(valueOf(System.nanoTime()), "EtcdTestService", "127.0.0.1", 8080);
Assertions.assertNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
etcdServiceDiscovery.register(serviceInstance);
Assertions.assertNotNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
}
@Test
public void testUnRegistry() throws Exception {
ServiceInstance serviceInstance = new DefaultServiceInstance(valueOf(System.nanoTime()), "EtcdTest2Service", "127.0.0.1", 8080);
Assertions.assertNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
etcdServiceDiscovery.register(serviceInstance);
Assertions.assertNotNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
etcdServiceDiscovery.unregister(serviceInstance);
Assertions.assertNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
}
@Test
public void testUpdate() throws Exception {
DefaultServiceInstance serviceInstance = new DefaultServiceInstance(valueOf(System.nanoTime()), "EtcdTest34Service", "127.0.0.1", 8080);
Assertions.assertNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
etcdServiceDiscovery.register(serviceInstance);
Assertions.assertNotNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
Assertions.assertEquals(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)),
new Gson().toJson(serviceInstance));
serviceInstance.setPort(9999);
etcdServiceDiscovery.update(serviceInstance);
Assertions.assertNotNull(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)));
Assertions.assertEquals(etcdServiceDiscovery.etcdClient.getKVValue(etcdServiceDiscovery.toPath(serviceInstance)),
new Gson().toJson(serviceInstance));
}
@Test
public void testGetInstances() throws Exception {
String serviceName = "EtcdTest77Service";
Assertions.assertTrue(etcdServiceDiscovery.getInstances(serviceName).isEmpty());
etcdServiceDiscovery.register(new DefaultServiceInstance(valueOf(System.nanoTime()), serviceName, "127.0.0.1", 8080));
etcdServiceDiscovery.register(new DefaultServiceInstance(valueOf(System.nanoTime()), serviceName, "127.0.0.1", 9809));
Assertions.assertFalse(etcdServiceDiscovery.getInstances(serviceName).isEmpty());
List<String> r = convertToIpPort(etcdServiceDiscovery.getInstances(serviceName));
Assertions.assertTrue(r.contains("127.0.0.1:8080"));
Assertions.assertTrue(r.contains("127.0.0.1:9809"));
}
private List<String> convertToIpPort(List<ServiceInstance> serviceInstances) {
List<String> result = new ArrayList<>();
for (ServiceInstance serviceInstance : serviceInstances) {
result.add(serviceInstance.getHost() + ":" + serviceInstance.getPort());
}
return result;
}
}

View File

@ -125,7 +125,7 @@
<arguments />
<checkstyle.skip>true</checkstyle.skip>
<rat.skip>true</rat.skip>
<revision>2.7.4-SNAPSHOT</revision>
<revision>2.7.5-cloudnative-SNAPSHOT</revision>
</properties>
<modules>