You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/08/31 02:50:33 UTC
[dubbo] branch 3.0 updated: [3.0] add bootstrap test (#8639)
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.0 by this push:
new 3f59150 [3.0] add bootstrap test (#8639)
3f59150 is described below
commit 3f591501a68c43e2798adb51ae362d6ca55e8f3b
Author: ken.lj <ke...@gmail.com>
AuthorDate: Tue Aug 31 10:50:20 2021 +0800
[3.0] add bootstrap test (#8639)
---
dubbo-config/dubbo-config-api/pom.xml | 7 +
.../dubbo/config/bootstrap/DubboBootstrap.java | 84 ++++--------
.../dubbo/config/bootstrap/DubboBootstrapTest.java | 147 ++++++++++++++++++++-
.../metadata/ServiceInstanceMetadataUtils.java | 32 ++++-
4 files changed, 208 insertions(+), 62 deletions(-)
diff --git a/dubbo-config/dubbo-config-api/pom.xml b/dubbo-config/dubbo-config-api/pom.xml
index 665d14d..ad4220b 100644
--- a/dubbo-config/dubbo-config-api/pom.xml
+++ b/dubbo-config/dubbo-config-api/pom.xml
@@ -172,5 +172,12 @@
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.testcontainers</groupId>
+ <artifactId>testcontainers</artifactId>
+ <version>1.15.3</version>
+ <scope>test</scope>
+ </dependency>
+
</dependencies>
</project>
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
index a502ce8..19d924d 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/bootstrap/DubboBootstrap.java
@@ -68,10 +68,8 @@ import org.apache.dubbo.metadata.report.MetadataReportInstance;
import org.apache.dubbo.metadata.report.support.AbstractMetadataReportFactory;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.metadata.MetadataUtils;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
-import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -88,6 +86,7 @@ import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Condition;
@@ -113,7 +112,6 @@ import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_METADATA_PUBLISH_DELAY;
import static org.apache.dubbo.metadata.MetadataConstants.METADATA_PUBLISH_DELAY_KEY;
import static org.apache.dubbo.metadata.WritableMetadataService.getDefaultExtension;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.calInstanceRevision;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.setMetadataStorageType;
import static org.apache.dubbo.registry.support.AbstractRegistryFactory.getServiceDiscoveries;
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
@@ -128,7 +126,7 @@ import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
*
* @since 2.7.5
*/
-public class DubboBootstrap {
+public final class DubboBootstrap {
public static final String DEFAULT_REGISTRY_ID = "REGISTRY#DEFAULT";
@@ -161,43 +159,44 @@ public class DubboBootstrap {
private final ExecutorService executorService = newSingleThreadExecutor();
private final ExecutorRepository executorRepository = getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
- ;
- private final ConfigManager configManager;
+ protected ScheduledFuture<?> asyncMetadataFuture;
- private final Environment environment;
+ protected final ConfigManager configManager;
- private ReferenceConfigCache cache;
+ protected final Environment environment;
- private AtomicBoolean initialized = new AtomicBoolean(false);
+ protected ReferenceConfigCache cache;
- private AtomicBoolean started = new AtomicBoolean(false);
+ protected AtomicBoolean initialized = new AtomicBoolean(false);
- private AtomicBoolean startup = new AtomicBoolean(true);
+ protected AtomicBoolean started = new AtomicBoolean(false);
- private AtomicBoolean destroyed = new AtomicBoolean(false);
+ protected AtomicBoolean startup = new AtomicBoolean(true);
- private AtomicBoolean shutdown = new AtomicBoolean(false);
+ protected AtomicBoolean destroyed = new AtomicBoolean(false);
- private volatile boolean isCurrentlyInStart = false;
+ protected AtomicBoolean shutdown = new AtomicBoolean(false);
- private volatile ServiceInstance serviceInstance;
+ protected volatile boolean isCurrentlyInStart = false;
- private volatile MetadataService metadataService;
+ protected volatile ServiceInstance serviceInstance;
- private volatile MetadataServiceExporter metadataServiceExporter;
+ protected volatile MetadataService metadataService;
- private List<ServiceConfigBase<?>> exportedServices = new ArrayList<>();
+ protected volatile MetadataServiceExporter metadataServiceExporter;
- private final List<CompletableFuture<?>> asyncExportingFutures = new ArrayList<>();
+ protected List<ServiceConfigBase<?>> exportedServices = new ArrayList<>();
- private final List<CompletableFuture<?>> asyncReferringFutures = new ArrayList<>();
+ protected final List<CompletableFuture<?>> asyncExportingFutures = new ArrayList<>();
- private volatile boolean asyncExportFinish = true;
+ protected final List<CompletableFuture<?>> asyncReferringFutures = new ArrayList<>();
- private volatile boolean asyncReferFinish = true;
+ protected volatile boolean asyncExportFinish = true;
- private static boolean ignoreConfigState;
+ protected volatile boolean asyncReferFinish = true;
+
+ protected static boolean ignoreConfigState;
/**
* See {@link ApplicationModel} and {@link ExtensionLoader} for why DubboBootstrap is designed to be singleton.
@@ -1505,7 +1504,7 @@ public class DubboBootstrap {
}
}
- private void registerServiceInstance() {
+ protected void registerServiceInstance() {
if (this.serviceInstance != null) {
return;
}
@@ -1515,14 +1514,14 @@ public class DubboBootstrap {
ServiceInstance serviceInstance = createServiceInstance(serviceName);
boolean registered = true;
try {
- doRegisterServiceInstance(serviceInstance);
+ ServiceInstanceMetadataUtils.registerMetadataAndInstance(serviceInstance);
} catch (Exception e) {
registered = false;
logger.error("Register instance error", e);
}
if(registered){
// scheduled task for updating Metadata and ServiceInstance
- executorRepository.nextScheduledExecutor().scheduleAtFixedRate(() -> {
+ asyncMetadataFuture = executorRepository.nextScheduledExecutor().scheduleAtFixedRate(() -> {
InMemoryWritableMetadataService localMetadataService = (InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension();
localMetadataService.blockUntilUpdated();
try {
@@ -1536,36 +1535,6 @@ public class DubboBootstrap {
}
}
- private void doRegisterServiceInstance(ServiceInstance serviceInstance) {
- // register instance only when at least one service is exported.
- if (serviceInstance.getPort() > 0) {
- if (REMOTE_METADATA_STORAGE_TYPE.equals(ServiceInstanceMetadataUtils.getMetadataStorageType(serviceInstance))) {
- publishMetadataToRemote(serviceInstance);
- }
- logger.info("Start registering instance address to registry.");
- getServiceDiscoveries().forEach(serviceDiscovery ->
- {
- ServiceInstance serviceInstanceForRegistry = new DefaultServiceInstance((DefaultServiceInstance) serviceInstance);
- calInstanceRevision(serviceDiscovery, serviceInstanceForRegistry);
- if (logger.isDebugEnabled()) {
- logger.info("Start registering instance address to registry" + serviceDiscovery.getUrl() + ", instance " + serviceInstanceForRegistry);
- }
- // register metadata
- serviceDiscovery.register(serviceInstanceForRegistry);
- });
- }
- }
-
- private void publishMetadataToRemote(ServiceInstance serviceInstance) {
-// InMemoryWritableMetadataService localMetadataService = (InMemoryWritableMetadataService)WritableMetadataService.getDefaultExtension();
-// localMetadataService.blockUntilUpdated();
- if (logger.isInfoEnabled()) {
- logger.info("Start publishing metadata to remote center, this only makes sense for applications enabled remote metadata center.");
- }
- RemoteMetadataServiceImpl remoteMetadataService = MetadataUtils.getRemoteMetadataService();
- remoteMetadataService.publishMetadata(serviceInstance.getServiceName());
- }
-
private void unregisterServiceInstance() {
if (serviceInstance != null) {
getServiceDiscoveries().forEach(serviceDiscovery -> {
@@ -1595,6 +1564,9 @@ public class DubboBootstrap {
unexportMetadataService();
unexportServices();
unreferServices();
+ if (asyncMetadataFuture != null) {
+ asyncMetadataFuture.cancel(true);
+ }
}
destroyRegistries();
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
index 484c315..24915d7 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/bootstrap/DubboBootstrapTest.java
@@ -20,17 +20,29 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.config.AbstractInterfaceConfig;
import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.MetadataReportConfig;
import org.apache.dubbo.config.MonitorConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.SysProps;
-import org.apache.dubbo.config.AbstractInterfaceConfig;
import org.apache.dubbo.config.api.DemoService;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
+import org.apache.dubbo.metadata.MetadataInfo;
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.monitor.MonitorService;
import org.apache.dubbo.registry.RegistryService;
+import org.apache.dubbo.registry.client.metadata.MetadataUtils;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol;
+import org.apache.curator.test.TestingServer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
@@ -45,11 +57,18 @@ import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_MONITOR_ADDRESS;
+import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SECONDS_KEY;
+import static org.apache.dubbo.rpc.model.ApplicationModel.getApplicationConfig;
+import static org.hamcrest.CoreMatchers.anything;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.is;
/**
* {@link DubboBootstrap} Test
@@ -59,10 +78,20 @@ import static org.apache.dubbo.common.constants.CommonConstants.SHUTDOWN_WAIT_SE
public class DubboBootstrapTest {
private static File dubboProperties;
+ private static TestingServer server;
+ private static int zkServerPort = NetUtils.getAvailablePort(NetUtils.getRandomPort());
+ private static String zkServerAddress = "zookeeper://127.0.0.1:" + zkServerPort;
@BeforeAll
public static void setUp(@TempDir Path folder) {
DubboBootstrap.reset();
+ try {
+ server = new TestingServer(zkServerPort, true);
+ server.start();
+ } catch (Exception e) {
+ e.printStackTrace();
+ Assertions.fail(e.getMessage());
+ }
dubboProperties = folder.resolve(CommonConstants.DUBBO_PROPERTIES_KEY).toFile();
System.setProperty(CommonConstants.DUBBO_PROPERTIES_KEY, dubboProperties.getAbsolutePath());
}
@@ -70,11 +99,18 @@ public class DubboBootstrapTest {
@AfterAll
public static void tearDown() {
System.clearProperty(CommonConstants.DUBBO_PROPERTIES_KEY);
+ try {
+ server.stop();
+ } catch (IOException e) {
+ e.printStackTrace();
+ Assertions.fail(e.getMessage());
+ }
}
@AfterEach
public void afterEach() throws IOException {
DubboBootstrap.reset();
+ ApplicationModel.reset();
SysProps.clear();
}
@@ -209,6 +245,115 @@ public class DubboBootstrapTest {
return interfaceConfig;
}
+ @Test
+ public void testBootstrapStart() {
+ ServiceConfig<DemoService> service = new ServiceConfig<>();
+ service.setInterface(DemoService.class);
+ service.setRef(new DemoServiceImpl());
+
+ DubboBootstrap bootstrap = DubboBootstrap.getInstance();
+ bootstrap.application(new ApplicationConfig("bootstrap-test"))
+ .registry(new RegistryConfig(zkServerAddress))
+ .protocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1))
+ .service(service)
+ .start();
+
+ Assertions.assertTrue(bootstrap.isInitialized());
+ Assertions.assertTrue(bootstrap.isStarted());
+ Assertions.assertFalse(bootstrap.isShutdown());
+
+ Assertions.assertNotNull(bootstrap.serviceInstance);
+ Assertions.assertTrue(bootstrap.exportedServices.size() > 0);
+ Assertions.assertNotNull(bootstrap.asyncMetadataFuture);
+ }
+
+ @Test
+ public void testLocalMetadataServiceExporter() {
+ ServiceConfig<DemoService> service = new ServiceConfig<>();
+ service.setInterface(DemoService.class);
+ service.setRef(new DemoServiceImpl());
+
+ int availablePort = NetUtils.getAvailablePort();
+
+ ApplicationConfig applicationConfig = new ApplicationConfig("bootstrap-test");
+ applicationConfig.setMetadataServicePort(availablePort);
+ DubboBootstrap bootstrap = DubboBootstrap.getInstance();
+ bootstrap.application(applicationConfig)
+ .registry(new RegistryConfig(zkServerAddress))
+ .protocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1))
+ .service(service)
+ .start();
+
+ assertMetadataService(bootstrap, availablePort, false);
+ }
+
+ @Test
+ public void testRemoteMetadataServiceExporter() {
+ ServiceConfig<DemoService> service = new ServiceConfig<>();
+ service.setInterface(DemoService.class);
+ service.setRef(new DemoServiceImpl());
+
+ int availablePort = NetUtils.getAvailablePort();
+
+ ApplicationConfig applicationConfig = new ApplicationConfig("bootstrap-test");
+ applicationConfig.setMetadataServicePort(availablePort);
+ applicationConfig.setMetadataType(REMOTE_METADATA_STORAGE_TYPE);
+
+ RegistryConfig registryConfig = new RegistryConfig(zkServerAddress);
+ registryConfig.setUseAsMetadataCenter(false);
+ registryConfig.setUseAsConfigCenter(false);
+
+ Exception exception = null;
+ try {
+ DubboBootstrap.getInstance()
+ .application(applicationConfig)
+ .registry(registryConfig)
+ .protocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1))
+ .service(service)
+ .start();
+ } catch (Exception e) {
+ exception = e;
+ DubboBootstrap.reset();
+ }
+
+ Assertions.assertNotNull(exception);
+
+ DubboBootstrap.getInstance()
+ .application(applicationConfig)
+ .registry(registryConfig)
+ .protocol(new ProtocolConfig(CommonConstants.DUBBO_PROTOCOL, -1))
+ .service(service)
+ .metadataReport(new MetadataReportConfig(zkServerAddress))
+ .start();
+
+ assertMetadataService(DubboBootstrap.getInstance(), availablePort, true);
+
+ }
+
+ private void assertMetadataService(DubboBootstrap bootstrap, int availablePort, boolean shouldReport) {
+ Assertions.assertTrue(bootstrap.metadataServiceExporter.isExported());
+ DubboProtocol protocol = DubboProtocol.getDubboProtocol();
+ Map<String, Exporter<?>> exporters = protocol.getExporterMap();
+ Assertions.assertEquals(2, exporters.size());
+
+ ServiceConfig<MetadataService> serviceConfig = new ServiceConfig<>();
+ serviceConfig.setRegistry(new RegistryConfig("N/A"));
+ serviceConfig.setInterface(MetadataService.class);
+ serviceConfig.setGroup(getApplicationConfig().getName());
+ serviceConfig.setVersion(MetadataService.VERSION);
+ assertThat(exporters, hasEntry(is(serviceConfig.getUniqueServiceName() + ":" + availablePort), anything()));
+
+ WritableMetadataService metadataService = MetadataUtils.getLocalMetadataService();
+ MetadataInfo metadataInfo = metadataService.getDefaultMetadataInfo();
+ Assertions.assertNotNull(metadataInfo);
+ if (shouldReport) {
+ Assertions.assertTrue(metadataInfo.hasReported());
+ } else {
+ Assertions.assertFalse(metadataInfo.hasReported());
+ }
+ }
+
+
private void writeDubboProperties(String key, String value) {
OutputStream os = null;
try {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
index e4f2e90..5c0e8ea 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
@@ -32,7 +32,6 @@ import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
import com.google.gson.Gson;
@@ -53,6 +52,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_KEY;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;
import static org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.DEFAULT_REGISTER_PROVIDER_KEYS;
+import static org.apache.dubbo.registry.support.AbstractRegistryFactory.getServiceDiscoveries;
import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
/**
@@ -246,11 +246,26 @@ public class ServiceInstanceMetadataUtils {
instance.getExtendParams().remove(INSTANCE_REVISION_UPDATED_KEY);
}
- public static void refreshMetadataAndInstance(ServiceInstance serviceInstance) {
- if (REMOTE_METADATA_STORAGE_TYPE.equals(ServiceInstanceMetadataUtils.getMetadataStorageType(serviceInstance))) {
- RemoteMetadataServiceImpl remoteMetadataService = MetadataUtils.getRemoteMetadataService();
- remoteMetadataService.publishMetadata(ApplicationModel.getName());
+ public static void registerMetadataAndInstance(ServiceInstance serviceInstance) {
+ // register instance only when at least one service is exported.
+ if (serviceInstance.getPort() > 0) {
+ reportMetadataToRemote(serviceInstance);
+ LOGGER.info("Start registering instance address to registry.");
+ getServiceDiscoveries().forEach(serviceDiscovery ->
+ {
+ ServiceInstance serviceInstanceForRegistry = new DefaultServiceInstance((DefaultServiceInstance) serviceInstance);
+ calInstanceRevision(serviceDiscovery, serviceInstanceForRegistry);
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.info("Start registering instance address to registry" + serviceDiscovery.getUrl() + ", instance " + serviceInstanceForRegistry);
+ }
+ // register metadata
+ serviceDiscovery.register(serviceInstanceForRegistry);
+ });
}
+ }
+
+ public static void refreshMetadataAndInstance(ServiceInstance serviceInstance) {
+ reportMetadataToRemote(serviceInstance);
AbstractRegistryFactory.getServiceDiscoveries().forEach(serviceDiscovery -> {
ServiceInstance instance = serviceDiscovery.getLocalInstance();
@@ -277,6 +292,13 @@ public class ServiceInstanceMetadataUtils {
});
}
+ private static void reportMetadataToRemote(ServiceInstance serviceInstance) {
+ if (REMOTE_METADATA_STORAGE_TYPE.equalsIgnoreCase(getMetadataStorageType(serviceInstance))) {
+ RemoteMetadataServiceImpl remoteMetadataService = MetadataUtils.getRemoteMetadataService();
+ remoteMetadataService.publishMetadata(serviceInstance.getServiceName());
+ }
+ }
+
/**
* Set the default parameters via the specified {@link URL providerURL}
*