You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by al...@apache.org on 2021/08/27 02:14:21 UTC
[dubbo] branch 3.0 updated: Verify local reference for the creation
of a local invoker process (#8592)
This is an automated email from the ASF dual-hosted git repository.
albumenj 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 7537786 Verify local reference for the creation of a local invoker process (#8592)
7537786 is described below
commit 7537786b8e7d70cb7700d3297b852f0a101c30a4
Author: huazhongming <cr...@gmail.com>
AuthorDate: Fri Aug 27 10:13:45 2021 +0800
Verify local reference for the creation of a local invoker process (#8592)
* verify create local invoker
* fix
* fix
* fix injvm protocol
---
.../filter/DefaultFilterChainBuilderTest.java | 66 +++++++++
.../dubbo/rpc/cluster/filter/DemoServiceImpl.java | 29 +---
.../apache/dubbo/rpc/cluster/filter/LogFilter.java | 36 ++---
.../dubbo/internal/org.apache.dubbo.rpc.Filter | 1 +
.../org/apache/dubbo/config/ReferenceConfig.java | 2 +-
.../apache/dubbo/config/ReferenceConfigTest.java | 162 +++++++++++++++++++--
.../dubbo/rpc/listener/ListenerInvokerWrapper.java | 7 +
.../dubbo/rpc/protocol/AbstractProtocol.java | 8 +-
.../dubbo/rpc/protocol/CountInvokerListener.java} | 31 ++--
.../rpc/protocol/ProtocolListenerWrapperTest.java | 81 +++++++++++
.../internal/org.apache.dubbo.rpc.InvokerListener | 1 +
.../dubbo/rpc/protocol/injvm/InjvmExporter.java | 2 +-
.../dubbo/rpc/protocol/injvm/InjvmInvoker.java | 2 +-
.../rpc/protocol/injvm/InjvmProtocolTest.java | 19 +--
14 files changed, 359 insertions(+), 88 deletions(-)
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java
new file mode 100644
index 0000000..655f6d9
--- /dev/null
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DefaultFilterChainBuilderTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.rpc.cluster.filter;
+
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.protocol.AbstractInvoker;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.REFERENCE_FILTER_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
+
+public class DefaultFilterChainBuilderTest {
+
+ @Test
+ public void testBuildInvokerChainForLocalReference() {
+ DefaultFilterChainBuilder defaultFilterChainBuilder = new DefaultFilterChainBuilder();
+
+ // verify that no filter is built by default
+ URL urlWithoutFilter = URL.valueOf("injvm://127.0.0.1/DemoService")
+ .addParameter(INTERFACE_KEY, DemoService.class.getName());
+ AbstractInvoker<DemoService> invokerWithoutFilter = new AbstractInvoker<DemoService>(DemoService.class, urlWithoutFilter) {
+ @Override
+ protected Result doInvoke(Invocation invocation) throws Throwable {
+ return null;
+ }
+ };
+
+ Invoker<?> invokerAfterBuild = defaultFilterChainBuilder.buildInvokerChain(invokerWithoutFilter, REFERENCE_FILTER_KEY, CONSUMER);
+ Assertions.assertTrue(invokerAfterBuild instanceof AbstractInvoker);
+
+ // verify that if LogFilter is configured, LogFilter should exist in the filter chain
+ URL urlWithFilter = URL.valueOf("injvm://127.0.0.1/DemoService")
+ .addParameter(INTERFACE_KEY, DemoService.class.getName())
+ .addParameter(REFERENCE_FILTER_KEY, "log");
+ AbstractInvoker<DemoService> invokerWithFilter = new AbstractInvoker<DemoService>(DemoService.class, urlWithFilter) {
+ @Override
+ protected Result doInvoke(Invocation invocation) throws Throwable {
+ return null;
+ }
+ };
+ invokerAfterBuild = defaultFilterChainBuilder.buildInvokerChain(invokerWithFilter, REFERENCE_FILTER_KEY, CONSUMER);
+ Assertions.assertTrue(invokerAfterBuild instanceof FilterChainBuilder.FilterChainNode);
+ Assertions.assertTrue(((FilterChainBuilder.FilterChainNode<?, ?, ?>) invokerAfterBuild).filter instanceof LogFilter);
+
+ }
+}
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DemoServiceImpl.java
similarity index 56%
copy from dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
copy to dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DemoServiceImpl.java
index cd362a3..9ccdd1b 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/DemoServiceImpl.java
@@ -14,33 +14,18 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.rpc.protocol.injvm;
+package org.apache.dubbo.rpc.cluster.filter;
-import org.apache.dubbo.rpc.Exporter;
-import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.protocol.AbstractExporter;
-import java.util.Map;
+public class DemoServiceImpl implements DemoService{
-/**
- * InjvmExporter
- */
-class InjvmExporter<T> extends AbstractExporter<T> {
-
- private final String key;
-
- private final Map<String, Exporter<?>> exporterMap;
-
- InjvmExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {
- super(invoker);
- this.key = key;
- this.exporterMap = exporterMap;
- exporterMap.put(key, this);
+ @Override
+ public String sayHello(String name) {
+ return name;
}
@Override
- public void afterUnExport() {
- exporterMap.remove(key);
+ public int plus(int a, int b) {
+ return 0;
}
-
}
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/LogFilter.java
similarity index 53%
copy from dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
copy to dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/LogFilter.java
index cd362a3..d34c1b7 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/filter/LogFilter.java
@@ -14,33 +14,33 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.rpc.protocol.injvm;
+package org.apache.dubbo.rpc.cluster.filter;
-import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.protocol.AbstractExporter;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.RpcException;
-import java.util.Map;
+import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
-/**
- * InjvmExporter
- */
-class InjvmExporter<T> extends AbstractExporter<T> {
-
- private final String key;
- private final Map<String, Exporter<?>> exporterMap;
+@Activate(group = CONSUMER, value = "log")
+public class LogFilter implements Filter, Filter.Listener {
- InjvmExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {
- super(invoker);
- this.key = key;
- this.exporterMap = exporterMap;
- exporterMap.put(key, this);
+ @Override
+ public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
+ return invoker.invoke(invocation);
}
@Override
- public void afterUnExport() {
- exporterMap.remove(key);
+ public void onResponse(Result appResponse, Invoker<?> invoker, Invocation invocation) {
+
}
+ @Override
+ public void onError(Throwable t, Invoker<?> invoker, Invocation invocation) {
+
+ }
}
diff --git a/dubbo-cluster/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter b/dubbo-cluster/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
new file mode 100644
index 0000000..44e3921
--- /dev/null
+++ b/dubbo-cluster/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Filter
@@ -0,0 +1 @@
+log=org.apache.dubbo.rpc.cluster.filter.LogFilter
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 41266c0..04511e2 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -570,7 +570,7 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
boolean isJvmRefer;
if (isInjvm() == null) {
// if an url is specified, don't do local reference
- if (url != null && url.length() > 0) {
+ if (StringUtils.isNotEmpty(url)) {
isJvmRefer = false;
} else {
// by default, reference local service if there is
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
index 71e5878..45841ad 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/ReferenceConfigTest.java
@@ -16,10 +16,12 @@
*/
package org.apache.dubbo.config;
+import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.common.config.CompositeConfiguration;
import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.config.Environment;
+import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.utils.ConfigUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;
@@ -33,11 +35,16 @@ import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
+import org.apache.dubbo.rpc.Exporter;
+import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.curator.test.TestingServer;
import org.apache.dubbo.rpc.model.ConsumerModel;
import org.apache.dubbo.rpc.model.ServiceMetadata;
import org.apache.dubbo.rpc.model.ServiceRepository;
+import org.apache.dubbo.rpc.protocol.injvm.InjvmInvoker;
+import org.apache.dubbo.rpc.protocol.injvm.InjvmProtocol;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -60,6 +67,8 @@ import java.util.stream.Collectors;
import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.BROADCAST_CLUSTER;
+import static org.apache.dubbo.common.constants.CommonConstants.CLUSTER_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
@@ -84,8 +93,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.REFER_BACKGROUND
import static org.apache.dubbo.common.constants.CommonConstants.REFER_ASYNC_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
-
-
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_KEY;
import static org.apache.dubbo.common.constants.QosConstants.QOS_ENABLE;
import static org.apache.dubbo.common.constants.QosConstants.QOS_HOST;
import static org.apache.dubbo.common.constants.QosConstants.QOS_PORT;
@@ -97,6 +105,9 @@ import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
import static org.apache.dubbo.rpc.Constants.SCOPE_REMOTE;
import static org.apache.dubbo.rpc.Constants.LOCAL_PROTOCOL;
import static org.apache.dubbo.rpc.Constants.DEFAULT_STUB_EVENT;
+import static org.apache.dubbo.rpc.Constants.LOCAL_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_KEY;
+import static org.apache.dubbo.rpc.Constants.SCOPE_LOCAL;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -412,6 +423,132 @@ public class ReferenceConfigTest {
}
@Test
+ public void testShouldJvmRefer() {
+
+ Map<String, String> parameters = new HashMap<>();
+
+ ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
+
+ // verify that if injvm is configured as true, local references should be made
+ referenceConfig.setInjvm(true);
+ Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
+
+ // verify that if injvm is configured as false, local references should not be made
+ referenceConfig.setInjvm(false);
+ Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
+
+ // verify that if url is configured, local reference should not be made
+ referenceConfig.setInjvm(null);
+ referenceConfig.setUrl("dubbo://127.0.0.1:20880/DemoService");
+ parameters.put(INTERFACE_KEY, DemoService.class.getName());
+ Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
+ parameters.clear();
+
+ // verify that if scope is configured as local, local references should be made
+ referenceConfig.setInjvm(null);
+ referenceConfig.setUrl(null);
+ parameters.put(SCOPE_KEY, SCOPE_LOCAL);
+ Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
+ parameters.clear();
+
+ // verify that if url protocol is configured as injvm, local references should be made
+ referenceConfig.setInjvm(null);
+ referenceConfig.setUrl(null);
+ parameters.put(LOCAL_PROTOCOL, "true");
+ Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
+ parameters.clear();
+
+ // verify that if generic is configured as true, local references should not be made
+ referenceConfig.setInjvm(null);
+ referenceConfig.setUrl(null);
+ parameters.put(GENERIC_KEY, "true");
+ Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
+ parameters.clear();
+
+ // verify that if the service has been exposed, and the cluster is not configured with broadcast, local reference should be made
+ referenceConfig.setInjvm(null);
+ referenceConfig.setUrl(null);
+ ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ DemoService service = new DemoServiceImpl();
+ URL url = URL.valueOf("dubbo://127.0.0.1/DemoService")
+ .addParameter(INTERFACE_KEY, DemoService.class.getName());
+ parameters.put(INTERFACE_KEY, DemoService.class.getName());
+ Exporter<?> exporter = InjvmProtocol.getInjvmProtocol().export(proxy.getInvoker(service, DemoService.class, url));
+ InjvmProtocol.getInjvmProtocol().getExporterMap().put(DemoService.class.getName(), exporter);
+ Assertions.assertTrue(referenceConfig.shouldJvmRefer(parameters));
+
+ // verify that if the service has been exposed, and the cluster is configured with broadcast, local reference should not be made
+ parameters.put(CLUSTER_KEY, BROADCAST_CLUSTER);
+ Assertions.assertFalse(referenceConfig.shouldJvmRefer(parameters));
+ parameters.clear();
+ InjvmProtocol.getInjvmProtocol().destroy();
+ }
+
+ @Test
+ public void testCreateInvokerForLocalRefer() {
+
+ ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<>();
+ referenceConfig.setScope(LOCAL_KEY);
+
+ DubboBootstrap.getInstance()
+ .application("application1")
+ .initialize();
+ referenceConfig.setBootstrap(DubboBootstrap.getInstance());
+
+ ApplicationConfig applicationConfig = new ApplicationConfig();
+ applicationConfig.setName("application1");
+ Map<String, String> parameters = new HashMap<>();
+ parameters.put("key1", "value1");
+ parameters.put("key2", "value2");
+ applicationConfig.setParameters(parameters);
+
+ ConfigManager configManager = mock(ConfigManager.class);
+ Environment environment = mock(Environment.class);
+ CompositeConfiguration compositeConfiguration = mock(CompositeConfiguration.class);
+ Configuration dynamicGlobalConfiguration = mock(Configuration.class);
+ ServiceRepository serviceRepository = mock(ServiceRepository.class);
+ ConsumerModel consumerModel = mock(ConsumerModel.class);
+
+ when(configManager.getApplicationOrElseThrow()).thenReturn(applicationConfig);
+
+ MockedStatic<ApplicationModel> applicationModelMockedStatic = Mockito.mockStatic(ApplicationModel.class);
+ applicationModelMockedStatic.when(ApplicationModel::getConfigManager).thenReturn(configManager);
+ applicationModelMockedStatic.when(ApplicationModel::getEnvironment).thenReturn(environment);
+ applicationModelMockedStatic.when(ApplicationModel::getServiceRepository).thenReturn(serviceRepository);
+ when(environment.getConfiguration()).thenReturn(compositeConfiguration);
+ when(environment.getDynamicGlobalConfiguration()).thenReturn(dynamicGlobalConfiguration);
+ when(compositeConfiguration.convert(Boolean.class, ENABLE_CONFIGURATION_LISTEN, true))
+ .thenReturn(true);
+
+ MockedStatic<MetadataReportInstance> metadataReportInstanceMockedStatic =
+ Mockito.mockStatic(MetadataReportInstance.class);
+
+ MetadataReport metadataReport = mock(MetadataReport.class);
+ metadataReportInstanceMockedStatic.when(() -> MetadataReportInstance.getMetadataReport("default"))
+ .thenReturn(metadataReport);
+
+
+ when(serviceRepository.lookupReferredService("org.apache.dubbo.config.api.DemoService"))
+ .thenReturn(consumerModel);
+
+ referenceConfig.refreshed.set(true);
+ referenceConfig.setInterface(DemoService.class);
+ referenceConfig.getInterfaceClass();
+ referenceConfig.setCheck(false);
+
+ referenceConfig.init();
+ Assertions.assertTrue(referenceConfig.getInvoker() instanceof ListenerInvokerWrapper);
+ Assertions.assertTrue(((ListenerInvokerWrapper<?>) referenceConfig.getInvoker()).getInvoker() instanceof InjvmInvoker);
+ URL url = ((ListenerInvokerWrapper<?>) referenceConfig.getInvoker()).getInvoker().getUrl();
+ Assertions.assertEquals("application1", url.getParameter("application"));
+ Assertions.assertEquals("value1", url.getParameter("key1"));
+ Assertions.assertEquals("value2", url.getParameter("key2"));
+
+ applicationModelMockedStatic.closeOnDemand();
+ metadataReportInstanceMockedStatic.closeOnDemand();
+ }
+
+ @Test
@Disabled("Disabled due to Github Actions environment")
public void testInjvm() throws Exception {
ApplicationConfig application = new ApplicationConfig();
@@ -426,13 +563,13 @@ public class ReferenceConfigTest {
protocol.setName("dubbo");
ServiceConfig<DemoService> demoService;
- demoService = new ServiceConfig<DemoService>();
+ demoService = new ServiceConfig<>();
demoService.setInterface(DemoService.class);
demoService.setRef(new DemoServiceImpl());
demoService.setRegistry(registry);
demoService.setProtocol(protocol);
- ReferenceConfig<DemoService> rc = new ReferenceConfig<DemoService>();
+ ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
rc.setRegistry(registry);
rc.setInterface(DemoService.class.getName());
rc.setScope(SCOPE_REMOTE);
@@ -466,7 +603,7 @@ public class ReferenceConfigTest {
RegistryConfig registry = new RegistryConfig();
registry.setAddress(registryUrl);
ProtocolConfig protocol = new ProtocolConfig();
- protocol.setName("mockprotocol");
+ protocol.setName("injvm");
ReferenceConfig<DemoService> rc = new ReferenceConfig<>();
rc.setRegistry(registry);
@@ -483,23 +620,22 @@ public class ReferenceConfigTest {
Assertions.assertFalse(success);
Assertions.assertNull(demoService);
- ServiceConfig<DemoService> sc = new ServiceConfig<>();
- sc.setInterface(DemoService.class);
- sc.setRef(new DemoServiceImpl());
- sc.setRegistry(registry);
- sc.setProtocol(protocol);
-
try {
System.setProperty("java.net.preferIPv4Stack", "true");
- sc.export();
+ ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ DemoService service = new DemoServiceImpl();
+ URL url = URL.valueOf("dubbo://127.0.0.1/DemoService")
+ .addParameter(INTERFACE_KEY, DemoService.class.getName());
+ InjvmProtocol.getInjvmProtocol().export(proxy.getInvoker(service, DemoService.class, url));
demoService = rc.get();
success = true;
} catch (Exception e) {
// ignore
} finally {
rc.destroy();
- sc.unexport();
+ InjvmProtocol.getInjvmProtocol().destroy();
System.clearProperty("java.net.preferIPv4Stack");
+
}
Assertions.assertTrue(success);
Assertions.assertNotNull(demoService);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java
index a0fea10..14254c7 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/listener/ListenerInvokerWrapper.java
@@ -102,4 +102,11 @@ public class ListenerInvokerWrapper<T> implements Invoker<T> {
}
}
+ public Invoker<T> getInvoker() {
+ return invoker;
+ }
+
+ public List<InvokerListener> getListeners() {
+ return listeners;
+ }
}
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
index 26db25b..64bc064 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
@@ -43,15 +43,15 @@ public abstract class AbstractProtocol implements Protocol {
protected final Logger logger = LoggerFactory.getLogger(getClass());
- protected final Map<String, Exporter<?>> exporterMap = new ConcurrentHashMap<String, Exporter<?>>();
+ protected final Map<String, Exporter<?>> exporterMap = new ConcurrentHashMap<>();
/**
* <host:port, ProtocolServer>
*/
protected final Map<String, ProtocolServer> serverMap = new ConcurrentHashMap<>();
- //TODO SoftReference
- protected final Set<Invoker<?>> invokers = new ConcurrentHashSet<Invoker<?>>();
+ // TODO SoftReference
+ protected final Set<Invoker<?>> invokers = new ConcurrentHashSet<>();
protected static String serviceKey(URL url) {
int port = url.getParameter(Constants.BIND_PORT_KEY, url.getPort());
@@ -82,7 +82,7 @@ public abstract class AbstractProtocol implements Protocol {
}
}
}
- for (String key : new ArrayList<String>(exporterMap.keySet())) {
+ for (String key : new ArrayList<>(exporterMap.keySet())) {
Exporter<?> exporter = exporterMap.remove(key);
if (exporter != null) {
try {
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/protocol/CountInvokerListener.java
similarity index 59%
copy from dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
copy to dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/protocol/CountInvokerListener.java
index cd362a3..4883380 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/protocol/CountInvokerListener.java
@@ -14,33 +14,30 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.rpc.protocol.injvm;
+package org.apache.dubbo.rpc.protocol;
-import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
-import org.apache.dubbo.rpc.protocol.AbstractExporter;
+import org.apache.dubbo.rpc.InvokerListener;
+import org.apache.dubbo.rpc.RpcException;
-import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
-/**
- * InjvmExporter
- */
-class InjvmExporter<T> extends AbstractExporter<T> {
- private final String key;
+public class CountInvokerListener implements InvokerListener {
- private final Map<String, Exporter<?>> exporterMap;
+ private final static AtomicInteger counter = new AtomicInteger(0);
- InjvmExporter(Invoker<T> invoker, String key, Map<String, Exporter<?>> exporterMap) {
- super(invoker);
- this.key = key;
- this.exporterMap = exporterMap;
- exporterMap.put(key, this);
+ @Override
+ public void referred(Invoker<?> invoker) throws RpcException {
+ counter.incrementAndGet();
}
@Override
- public void afterUnExport() {
- exporterMap.remove(key);
+ public void destroyed(Invoker<?> invoker) {
+
}
+ public static int getCounter() {
+ return counter.get();
+ }
}
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapperTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapperTest.java
new file mode 100644
index 0000000..5f0bbe4
--- /dev/null
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/protocol/ProtocolListenerWrapperTest.java
@@ -0,0 +1,81 @@
+/*
+ * 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.rpc.protocol;
+
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.listener.ListenerInvokerWrapper;
+import org.apache.dubbo.rpc.proxy.DemoService;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.INVOKER_LISTENER_KEY;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ProtocolListenerWrapperTest {
+
+
+ @Test
+ public void testLoadingListenerForLocalReference() {
+ // verify that no listener is loaded by default
+ URL urlWithoutListener = URL.valueOf("injvm://127.0.0.1/DemoService")
+ .addParameter(INTERFACE_KEY, DemoService.class.getName());
+ AbstractInvoker<DemoService> invokerWithoutListener = new AbstractInvoker<DemoService>(DemoService.class, urlWithoutListener) {
+ @Override
+ protected Result doInvoke(Invocation invocation) throws Throwable {
+ return null;
+ }
+ };
+
+ Protocol protocolWithoutListener = mock(Protocol.class);
+ when(protocolWithoutListener.refer(DemoService.class, urlWithoutListener)).thenReturn(invokerWithoutListener);
+
+ ProtocolListenerWrapper protocolListenerWrapperWithoutListener = new ProtocolListenerWrapper(protocolWithoutListener);
+
+ Invoker<?> invoker = protocolListenerWrapperWithoutListener.refer(DemoService.class, urlWithoutListener);
+ Assertions.assertTrue(invoker instanceof ListenerInvokerWrapper);
+ Assertions.assertEquals(0, ((ListenerInvokerWrapper<?>) invoker).getListeners().size());
+
+ // verify that if the invoker.listener is configured, then load the specified listener
+ URL urlWithListener = URL.valueOf("injvm://127.0.0.1/DemoService")
+ .addParameter(INTERFACE_KEY, DemoService.class.getName())
+ .addParameter(INVOKER_LISTENER_KEY, "count");
+ AbstractInvoker<DemoService> invokerWithListener = new AbstractInvoker<DemoService>(DemoService.class, urlWithListener) {
+ @Override
+ protected Result doInvoke(Invocation invocation) throws Throwable {
+ return null;
+ }
+ };
+
+ Protocol protocol = mock(Protocol.class);
+ when(protocol.refer(DemoService.class, urlWithListener)).thenReturn(invokerWithListener);
+
+ ProtocolListenerWrapper protocolListenerWrapper = new ProtocolListenerWrapper(protocol);
+
+ invoker = protocolListenerWrapper.refer(DemoService.class, urlWithListener);
+ Assertions.assertTrue(invoker instanceof ListenerInvokerWrapper);
+ Assertions.assertEquals(1, CountInvokerListener.getCounter());
+ }
+
+
+}
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener b/dubbo-rpc/dubbo-rpc-api/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener
new file mode 100644
index 0000000..e7baaec
--- /dev/null
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.InvokerListener
@@ -0,0 +1 @@
+count=org.apache.dubbo.rpc.protocol.CountInvokerListener
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
index cd362a3..bc38844 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmExporter.java
@@ -25,7 +25,7 @@ import java.util.Map;
/**
* InjvmExporter
*/
-class InjvmExporter<T> extends AbstractExporter<T> {
+public class InjvmExporter<T> extends AbstractExporter<T> {
private final String key;
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
index 04afe85..5aaaed2 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmInvoker.java
@@ -42,7 +42,7 @@ import static org.apache.dubbo.rpc.Constants.ASYNC_KEY;
/**
* InjvmInvoker
*/
-class InjvmInvoker<T> extends AbstractInvoker<T> {
+public class InjvmInvoker<T> extends AbstractInvoker<T> {
private final String key;
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
index 2228aed..a35e0b3 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/test/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocolTest.java
@@ -51,13 +51,10 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
public class InjvmProtocolTest {
- static {
- InjvmProtocol injvm = InjvmProtocol.getInjvmProtocol();
- }
- private Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
- private ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
- private List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
+ private final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
+ private final ProxyFactory proxy = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
+ private final List<Exporter<?>> exporters = new ArrayList<>();
@AfterEach
public void after() throws Exception {
@@ -78,7 +75,7 @@ public class InjvmProtocolTest {
assertEquals(service.getSize(new String[]{"", "", ""}), 3);
service.invoke("injvm://127.0.0.1/TestService", "invoke");
- InjvmInvoker injvmInvoker = new InjvmInvoker(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService"), null, new HashMap<String, Exporter<?>>());
+ InjvmInvoker<?> injvmInvoker = new InjvmInvoker<>(DemoService.class, URL.valueOf("injvm://127.0.0.1/TestService"), null, new HashMap<>());
assertFalse(injvmInvoker.isAvailable());
}
@@ -98,7 +95,7 @@ public class InjvmProtocolTest {
public void testIsInjvmRefer() throws Exception {
DemoService service = new DemoServiceImpl();
URL url = URL.valueOf("injvm://127.0.0.1/TestService")
- .addParameter(INTERFACE_KEY, DemoService.class.getName());
+ .addParameter(INTERFACE_KEY, DemoService.class.getName());
Exporter<?> exporter = protocol.export(proxy.getInvoker(service, DemoService.class, url));
exporters.add(exporter);
@@ -106,7 +103,7 @@ public class InjvmProtocolTest {
assertTrue(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
url = url.addParameter(GROUP_KEY, "*")
- .addParameter(VERSION_KEY, "*");
+ .addParameter(VERSION_KEY, "*");
assertTrue(InjvmProtocol.getInjvmProtocol().isInjvmRefer(url));
url = URL.valueOf("fake://127.0.0.1/TestService").addParameter(SCOPE_KEY, SCOPE_LOCAL);
@@ -129,8 +126,8 @@ public class InjvmProtocolTest {
public void testLocalProtocolAsync() throws Exception {
DemoService service = new DemoServiceImpl();
URL url = URL.valueOf("injvm://127.0.0.1/TestService")
- .addParameter(ASYNC_KEY, true)
- .addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer");
+ .addParameter(ASYNC_KEY, true)
+ .addParameter(INTERFACE_KEY, DemoService.class.getName()).addParameter("application", "consumer");
Invoker<?> invoker = proxy.getInvoker(service, DemoService.class, url);
assertTrue(invoker.isAvailable());
Exporter<?> exporter = protocol.export(invoker);