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 fb0f13e39c18..f568700beae2 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 @@ -283,7 +283,7 @@ private void init() { checkStubAndMock(interfaceClass); Map map = new HashMap(); resolveAsyncInterface(interfaceClass, map); - Map attributes = new HashMap(); + map.put(Constants.SIDE_KEY, Constants.CONSUMER_SIDE); map.put(Constants.DUBBO_VERSION_KEY, Version.getProtocolVersion()); map.put(Constants.TIMESTAMP_KEY, String.valueOf(System.currentTimeMillis())); @@ -311,6 +311,7 @@ private void init() { appendParameters(map, this); String prefix = StringUtils.getServiceKey(map); if (methods != null && !methods.isEmpty()) { + Map attributes = new HashMap(); for (MethodConfig method : methods) { appendParameters(map, method, method.getName()); String retryKey = method.getName() + ".retry"; @@ -323,6 +324,8 @@ private void init() { appendAttributes(attributes, method, prefix + "." + method.getName()); checkAndConvertImplicitConfig(method, map, attributes); } + //attributes are stored by system context. + StaticContext.getSystemContext().putAll(attributes); } String hostToRegistry = ConfigUtils.getSystemProperty(Constants.DUBBO_IP_TO_REGISTRY); @@ -333,8 +336,6 @@ private void init() { } map.put(Constants.REGISTER_IP_KEY, hostToRegistry); - //attributes are stored by system context. - StaticContext.getSystemContext().putAll(attributes); ref = createProxy(map); ConsumerModel consumerModel = new ConsumerModel(getUniqueServiceName(), ref, interfaceClass.getMethods()); ApplicationModel.initConsumerModel(getUniqueServiceName(), consumerModel); 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 29d5d11eddc3..e2d3969e08b0 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 @@ -32,7 +32,6 @@ import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Protocol; import org.apache.dubbo.rpc.ProxyFactory; -import org.apache.dubbo.rpc.ServiceClassHolder; import org.apache.dubbo.rpc.cluster.ConfiguratorFactory; import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.model.ProviderModel; @@ -532,7 +531,6 @@ private void exportLocal(URL url) { .setProtocol(Constants.LOCAL_PROTOCOL) .setHost(LOCALHOST) .setPort(0); - ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref)); Exporter exporter = protocol.export( proxyFactory.getInvoker(ref, (Class) interfaceClass, local)); exporters.add(exporter); diff --git a/dubbo-demo/dubbo-demo-consumer/src/main/resources/META-INF/spring/dubbo-demo-consumer.xml b/dubbo-demo/dubbo-demo-consumer/src/main/resources/META-INF/spring/dubbo-demo-consumer.xml index a56a10ee7ea0..b4c1197477de 100644 --- a/dubbo-demo/dubbo-demo-consumer/src/main/resources/META-INF/spring/dubbo-demo-consumer.xml +++ b/dubbo-demo/dubbo-demo-consumer/src/main/resources/META-INF/spring/dubbo-demo-consumer.xml @@ -32,4 +32,4 @@ local regular interface --> - \ No newline at end of file + diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ServiceClassHolder.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ServiceClassHolder.java deleted file mode 100644 index bbbf755f1f77..000000000000 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ServiceClassHolder.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.dubbo.rpc; - -/** - * TODO this is just a workaround for rest protocol, and now we just ensure it works in the most common dubbo usages - * - */ -public class ServiceClassHolder { - - private static final ServiceClassHolder INSTANCE = new ServiceClassHolder(); - - private final ThreadLocal holder = new ThreadLocal(); - - public static ServiceClassHolder getInstance() { - return INSTANCE; - } - - private ServiceClassHolder() { - } - - public Class popServiceClass() { - Class clazz = holder.get(); - holder.remove(); - return clazz; - } - - public void pushServiceClass(Class clazz) { - holder.set(clazz); - } -} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java index 98d32c10e514..456930e54078 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ApplicationModel.java @@ -18,78 +18,50 @@ import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; -import org.apache.dubbo.common.utils.ConcurrentHashSet; -import org.apache.dubbo.rpc.Invoker; import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import static java.util.stream.Collectors.toSet; - // adjust project structure in order to fully utilize the methods introduced here. public class ApplicationModel { - protected static final Logger logger = LoggerFactory.getLogger(ApplicationModel.class); + protected static final Logger LOGGER = LoggerFactory.getLogger(ApplicationModel.class); /** * full qualified class name -> provided service */ - private static final ConcurrentMap> providedServices = new ConcurrentHashMap<>(); + private static final ConcurrentMap providedServices = new ConcurrentHashMap<>(); /** * full qualified class name -> subscribe service */ - private static final ConcurrentMap> consumedServices = new ConcurrentHashMap<>(); - - private static final ConcurrentMap> providedServicesInvoker = new ConcurrentHashMap<>(); + private static final ConcurrentMap consumedServices = new ConcurrentHashMap<>(); public static Collection allConsumerModels() { - return consumedServices.values().stream().flatMap(Collection::stream).collect(toSet()); + return consumedServices.values(); } public static Collection allProviderModels() { - return providedServices.values().stream().flatMap(Collection::stream).collect(toSet()); + return providedServices.values(); } - public static Collection getProviderModel(String serviceName) { + public static ProviderModel getProviderModel(String serviceName) { return providedServices.get(serviceName); } - public static Collection getConsumerModel(String serviceName) { + public static ConsumerModel getConsumerModel(String serviceName) { return consumedServices.get(serviceName); } public static void initConsumerModel(String serviceName, ConsumerModel consumerModel) { - Set consumerModels = consumedServices.computeIfAbsent(serviceName, k -> new HashSet<>()); - if (!consumerModels.add(consumerModel)) { - logger.warn("Already register the same consumer:" + serviceName); + if (consumedServices.putIfAbsent(serviceName, consumerModel) != null) { + LOGGER.warn("Already register the same consumer:" + serviceName); } } public static void initProviderModel(String serviceName, ProviderModel providerModel) { - Set providerModels = providedServices.computeIfAbsent(serviceName, k -> new HashSet<>()); - if (!providerModels.add(providerModel)) { - logger.warn("already register the provider service: " + serviceName); + if (providedServices.putIfAbsent(serviceName, providerModel) != null) { + LOGGER.warn("Already register the same:" + serviceName); } } - - public static void addProviderInvoker(String serviceName,Invoker invoker){ - Set invokers = providedServicesInvoker.get(serviceName); - if (invokers == null){ - providedServicesInvoker.putIfAbsent(serviceName,new ConcurrentHashSet()); - invokers = providedServicesInvoker.get(serviceName); - } - invokers.add(invoker); - } - - public Set getProviderInvoker(String serviceName){ - Set invokers = providedServicesInvoker.get(serviceName); - if (invokers == null){ - return Collections.emptySet(); - } - return invokers; - } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ProviderModel.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ProviderModel.java index b91d0cba0d03..179d300b5e08 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ProviderModel.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/model/ProviderModel.java @@ -46,6 +46,10 @@ public String getServiceName() { return serviceName; } + public Class getServiceInterfaceClass() { + return serviceInterfaceClass; + } + public Object getServiceInstance() { return serviceInstance; } diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/ServiceHolderTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/ServiceHolderTest.java deleted file mode 100644 index 9a9a42f27153..000000000000 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/ServiceHolderTest.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.dubbo.rpc; - -import org.junit.Assert; -import org.junit.Test; - -public class ServiceHolderTest { - - @Test - public void testHolderClass() { - - ServiceClassHolder holder = ServiceClassHolder.getInstance(); - - holder.pushServiceClass(ServiceHolderTest.class); - - Assert.assertEquals(ServiceHolderTest.class, holder.popServiceClass()); - - } -} diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java index 2268b71ac90a..6c24ca575ec7 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java @@ -23,7 +23,7 @@ import org.apache.dubbo.remoting.http.servlet.BootstrapListener; import org.apache.dubbo.remoting.http.servlet.ServletManager; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.ServiceClassHolder; +import org.apache.dubbo.rpc.model.ApplicationModel; import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol; import org.apache.http.HeaderElement; @@ -90,7 +90,7 @@ public int getDefaultPort() { @Override protected Runnable doExport(T impl, Class type, URL url) throws RpcException { String addr = getAddr(url); - Class implClass = ServiceClassHolder.getInstance().popServiceClass(); + Class implClass = ApplicationModel.getProviderModel(url.getServiceKey()).getServiceInterfaceClass(); RestServer server = servers.get(addr); if (server == null) { server = serverFactory.createServer(url.getParameter(Constants.SERVER_KEY, DEFAULT_SERVER)); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java index a698d0c3e258..215bc410c1c3 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protocol/rest/RestProtocolTest.java @@ -27,7 +27,8 @@ import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.ServiceClassHolder; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.ProviderModel; import org.hamcrest.CoreMatchers; import org.junit.After; import org.junit.Test; @@ -48,11 +49,12 @@ public void tearDown() { @Test public void testExport() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); - + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); RpcContext.getContext().setAttachment("timeout", "200"); - Exporter exporter = protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, exportUrl)); + Exporter exporter = protocol.export(proxy.getInvoker(server, IDemoService.class, exportUrl)); IDemoService demoService = this.proxy.getProxy(protocol.refer(IDemoService.class, exportUrl)); @@ -64,7 +66,9 @@ public void testExport() { @Test public void testNettyServer() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); URL nettyUrl = exportUrl.addParameter(Constants.SERVER_KEY, "netty"); Exporter exporter = protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, nettyUrl)); @@ -79,19 +83,23 @@ public void testNettyServer() { @Test(expected = RpcException.class) public void testServletWithoutWebConfig() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); URL servletUrl = exportUrl.addParameter(Constants.SERVER_KEY, "servlet"); - protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, servletUrl)); + protocol.export(proxy.getInvoker(server, IDemoService.class, servletUrl)); } @Test(expected = RpcException.class) public void testErrorHandler() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); URL nettyUrl = exportUrl.addParameter(Constants.SERVER_KEY, "netty"); - Exporter exporter = protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, nettyUrl)); + Exporter exporter = protocol.export(proxy.getInvoker(server, IDemoService.class, nettyUrl)); IDemoService demoService = this.proxy.getProxy(protocol.refer(IDemoService.class, nettyUrl)); @@ -100,10 +108,12 @@ public void testErrorHandler() { @Test public void testInvoke() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); - Exporter exporter = protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, exportUrl)); + Exporter exporter = protocol.export(proxy.getInvoker(server, IDemoService.class, exportUrl)); RpcInvocation rpcInvocation = new RpcInvocation("hello", new Class[]{Integer.class, Integer.class}, new Integer[]{2, 3}); @@ -113,11 +123,13 @@ public void testInvoke() { @Test public void testFilter() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); URL nettyUrl = exportUrl.addParameter(Constants.SERVER_KEY, "netty") .addParameter(Constants.EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.support.LoggingFilter"); - Exporter exporter = protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, nettyUrl)); + Exporter exporter = protocol.export(proxy.getInvoker(server, IDemoService.class, nettyUrl)); IDemoService demoService = this.proxy.getProxy(protocol.refer(IDemoService.class, nettyUrl)); @@ -130,12 +142,14 @@ public void testFilter() { @Test public void testRpcContextFilter() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); // use RpcContextFilter URL nettyUrl = exportUrl.addParameter(Constants.SERVER_KEY, "netty") .addParameter(Constants.EXTENSION_KEY, "org.apache.dubbo.rpc.protocol.rest.RpcContextFilter"); - Exporter exporter = protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, nettyUrl)); + Exporter exporter = protocol.export(proxy.getInvoker(server, IDemoService.class, nettyUrl)); IDemoService demoService = this.proxy.getProxy(protocol.refer(IDemoService.class, nettyUrl)); @@ -151,10 +165,12 @@ public void testRpcContextFilter() { @Test(expected = RuntimeException.class) public void testRegFail() { - ServiceClassHolder.getInstance().pushServiceClass(DemoService.class); + IDemoService server = new DemoService(); + ProviderModel providerModel = new ProviderModel(exportUrl.getServiceKey(), server, IDemoService.class); + ApplicationModel.initProviderModel(exportUrl.getServiceKey(), providerModel); URL nettyUrl = exportUrl.addParameter(Constants.EXTENSION_KEY, "com.not.existing.Filter"); - protocol.export(proxy.getInvoker(new DemoService(), IDemoService.class, nettyUrl)); + protocol.export(proxy.getInvoker(server, IDemoService.class, nettyUrl)); } @Test diff --git a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protol/rest/RestProtocolTest.java b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protol/rest/RestProtocolTest.java index bd2d66a5c41a..ab0da76a890d 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protol/rest/RestProtocolTest.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/test/java/org/apache/dubbo/rpc/protol/rest/RestProtocolTest.java @@ -16,10 +16,15 @@ */ package org.apache.dubbo.rpc.protol.rest; +import junit.framework.Assert; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; -import org.apache.dubbo.rpc.*; -import junit.framework.Assert; +import org.apache.dubbo.rpc.Exporter; +import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Protocol; +import org.apache.dubbo.rpc.ProxyFactory; +import org.apache.dubbo.rpc.model.ApplicationModel; +import org.apache.dubbo.rpc.model.ProviderModel; import org.junit.Test; /** @@ -32,12 +37,14 @@ public class RestProtocolTest { @Test public void testRestProtocol() { - ServiceClassHolder.getInstance().pushServiceClass(RestServiceImpl.class); - RestServiceImpl server = new RestServiceImpl(); - Assert.assertFalse(server.isCalled()); URL url = URL.valueOf("rest://127.0.0.1:5342/rest/say1?version=1.0.0"); + RestServiceImpl server = new RestServiceImpl(); + ProviderModel providerModel = new ProviderModel(url.getServiceKey(), server, RestService.class); + ApplicationModel.initProviderModel(url.getServiceKey(), providerModel); + Exporter exporter = protocol.export(proxyFactory.getInvoker(server, RestService.class, url)); - Invoker invoker = protocol.refer(RestService.class, url); + Invoker invoker = protocol.refer(RestService.class, url); Assert.assertFalse(server.isCalled()); + RestService client = proxyFactory.getProxy(invoker); String result = client.sayHello("haha"); Assert.assertTrue(server.isCalled()); @@ -48,10 +55,12 @@ public void testRestProtocol() { @Test public void testRestProtocolWithContextPath() { - ServiceClassHolder.getInstance().pushServiceClass(RestServiceImpl.class); RestServiceImpl server = new RestServiceImpl(); Assert.assertFalse(server.isCalled()); URL url = URL.valueOf("rest://127.0.0.1:5341/a/b/c?version=1.0.0"); + ProviderModel providerModel = new ProviderModel(url.getServiceKey(), server, RestService.class); + ApplicationModel.initProviderModel(url.getServiceKey(), providerModel); + Exporter exporter = protocol.export(proxyFactory.getInvoker(server, RestService.class, url)); url = URL.valueOf("rest://127.0.0.1:5341/a/b/c/?version=1.0.0");