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/06/24 10:10:59 UTC
[dubbo] branch 3.0 updated: Add ServiceListener for ServiceConfig
(#8134)
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 9bccd5c Add ServiceListener for ServiceConfig (#8134)
9bccd5c is described below
commit 9bccd5cfdd131e77c69cb2d45e970ffb10cf6c3c
Author: Gong Dewei <ky...@qq.com>
AuthorDate: Thu Jun 24 18:10:45 2021 +0800
Add ServiceListener for ServiceConfig (#8134)
---
.../org/apache/dubbo/config/ServiceConfig.java | 31 ++++++++++++++-
.../org/apache/dubbo/config/ServiceListener.java | 38 ++++++++++++++++++
.../dubbo/config/bootstrap/DubboBootstrap.java | 8 ++--
.../org/apache/dubbo/config/ServiceConfigTest.java | 28 +++++++++++++-
.../dubbo/config/mock/MockServiceListener.java | 45 ++++++++++++++++++++++
.../org.apache.dubbo.config.ServiceListener | 1 +
6 files changed, 144 insertions(+), 7 deletions(-)
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 2463147..8d5893b 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -142,6 +142,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
*/
private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
+ private List<ServiceListener> serviceListeners = new ArrayList<>();
+
public ServiceConfig() {
}
@@ -182,15 +184,20 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
exporters.clear();
}
unexported = true;
+ onUnexpoted();
}
public void init() {
if (this.initialized.compareAndSet(false, true)) {
if (this.bootstrap == null) {
- this.bootstrap = DubboBootstrap.getInstance();
+ this.setBootstrap(DubboBootstrap.getInstance());
this.bootstrap.initialize();
}
+ // load ServiceListeners from extension
+ ExtensionLoader<ServiceListener> extensionLoader = ExtensionLoader.getExtensionLoader(ServiceListener.class);
+ this.serviceListeners.addAll(extensionLoader.getSupportedExtensionInstances());
+
this.checkAndUpdateSubConfigs();
}
@@ -203,7 +210,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
public synchronized void export() {
if (this.shouldExport() && !this.exported) {
this.init();
- this.bootstrap.service(this);
// check bootstrap state
if (!bootstrap.isInitialized()) {
@@ -236,6 +242,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension();
serviceNameMapping.map(url);
});
+ onExported();
}
private void checkAndUpdateSubConfigs() {
@@ -748,4 +755,24 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
public void setBootstrap(DubboBootstrap bootstrap) {
this.bootstrap = bootstrap;
}
+
+ public void addServiceListener(ServiceListener listener) {
+ this.serviceListeners.add(listener);
+ }
+
+ public boolean removeServiceListener(ServiceListener listener) {
+ return this.serviceListeners.remove(listener);
+ }
+
+ protected void onExported() {
+ for (ServiceListener serviceListener : this.serviceListeners) {
+ serviceListener.exported(this);
+ }
+ }
+
+ protected void onUnexpoted() {
+ for (ServiceListener serviceListener : this.serviceListeners) {
+ serviceListener.unexported(this);
+ }
+ }
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceListener.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceListener.java
new file mode 100644
index 0000000..451356c
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceListener.java
@@ -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.config;
+
+import org.apache.dubbo.common.extension.SPI;
+
+/**
+ * Listener for service config
+ */
+@SPI
+public interface ServiceListener {
+
+ /**
+ * Callback when ServiceConfig is exported
+ * @param sc
+ */
+ void exported(ServiceConfig sc);
+
+ /**
+ * Callback when ServiceConfig is unexported
+ * @param sc
+ */
+ void unexported(ServiceConfig sc);
+}
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 85b4853..f15d25e 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
@@ -257,9 +257,9 @@ public class DubboBootstrap {
DubboShutdownHook.getDubboShutdownHook().unregister();
}
- private boolean isOnlyRegisterProvider() {
+ private boolean isRegisterConsumerInstance() {
Boolean registerConsumer = getApplication().getRegisterConsumer();
- return registerConsumer == null || !registerConsumer;
+ return Boolean.TRUE.equals(registerConsumer);
}
private String getMetadataType() {
@@ -1095,8 +1095,8 @@ public class DubboBootstrap {
// 1. export Dubbo Services
exportServices();
- // Not only provider register
- if (!isOnlyRegisterProvider() || hasExportedServices()) {
+ // If register consumer instance or has exported services
+ if (isRegisterConsumerInstance() || hasExportedServices()) {
// 2. export MetadataService
exportMetadataService();
// 3. Register the local ServiceInstance if required
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
index 3aebdd0..a4c6a62 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ServiceConfigTest.java
@@ -18,10 +18,12 @@
package org.apache.dubbo.config;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.config.api.DemoService;
import org.apache.dubbo.config.api.Greeting;
import org.apache.dubbo.config.mock.MockProtocol2;
import org.apache.dubbo.config.mock.MockRegistryFactory2;
+import org.apache.dubbo.config.mock.MockServiceListener;
import org.apache.dubbo.config.mock.TestProxyFactory;
import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.registry.Registry;
@@ -40,6 +42,7 @@ import org.mockito.Mockito;
import java.util.Collections;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
@@ -67,6 +70,8 @@ import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.Mockito.withSettings;
@@ -288,7 +293,7 @@ public class ServiceConfigTest {
@Test
public void testApplicationInUrl() {
service.export();
- Assertions.assertNotNull(service.toUrl().getApplication());
+ assertNotNull(service.toUrl().getApplication());
Assertions.assertEquals("app", service.toUrl().getApplication());
}
@@ -335,4 +340,25 @@ public class ServiceConfigTest {
assertThat(url.getParameters(), hasEntry(SIDE_KEY, PROVIDER));
Mockito.verify(protocolDelegate).export(Mockito.any(Invoker.class));
}
+
+ @Test
+ public void testServiceListener() {
+ ExtensionLoader<ServiceListener> extensionLoader = ExtensionLoader.getExtensionLoader(ServiceListener.class);
+ Set<ServiceListener> serviceListeners = extensionLoader.getSupportedExtensionInstances();
+ MockServiceListener mockServiceListener = null;
+ for (ServiceListener serviceListener : serviceListeners) {
+ if (serviceListener instanceof MockServiceListener) {
+ mockServiceListener = (MockServiceListener) serviceListener;
+ }
+ }
+ assertNotNull(mockServiceListener);
+ mockServiceListener.clearExportedServices();
+
+ service.export();
+
+ Map<String, ServiceConfig> exportedServices = mockServiceListener.getExportedServices();
+ assertEquals(1, exportedServices.size());
+ ServiceConfig serviceConfig = exportedServices.get(service.getUniqueServiceName());
+ assertSame(service, serviceConfig);
+ }
}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceListener.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceListener.java
new file mode 100644
index 0000000..5cc31b8
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceListener.java
@@ -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.config.mock;
+
+import org.apache.dubbo.config.ServiceConfig;
+import org.apache.dubbo.config.ServiceListener;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class MockServiceListener implements ServiceListener {
+
+ private Map<String, ServiceConfig> exportedServices = new ConcurrentHashMap<>();
+
+ @Override
+ public void exported(ServiceConfig sc) {
+ exportedServices.put(sc.getUniqueServiceName(), sc);
+ }
+
+ @Override
+ public void unexported(ServiceConfig sc) {
+ }
+
+ public Map<String, ServiceConfig> getExportedServices() {
+ return exportedServices;
+ }
+
+ public void clearExportedServices() {
+ exportedServices.clear();
+ }
+}
diff --git a/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener
new file mode 100644
index 0000000..d7ce28b
--- /dev/null
+++ b/dubbo-config/dubbo-config-api/src/test/resources/META-INF/services/org.apache.dubbo.config.ServiceListener
@@ -0,0 +1 @@
+mock=org.apache.dubbo.config.mock.MockServiceListener