diff --git a/dubbo-admin/pom.xml b/dubbo-admin/pom.xml index 9ce508ee5b..0aad790b9f 100644 --- a/dubbo-admin/pom.xml +++ b/dubbo-admin/pom.xml @@ -112,7 +112,7 @@ javax.servlet - servlet-api + javax.servlet-api provided diff --git a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java index 00306d4bcd..85ac39bcab 100644 --- a/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java +++ b/dubbo-config/dubbo-config-spring/src/main/java/com/alibaba/dubbo/config/spring/ServiceBean.java @@ -16,9 +16,17 @@ */ package com.alibaba.dubbo.config.spring; -import com.alibaba.dubbo.config.*; +import com.alibaba.dubbo.config.ApplicationConfig; +import com.alibaba.dubbo.config.ModuleConfig; +import com.alibaba.dubbo.config.MonitorConfig; +import com.alibaba.dubbo.config.ProtocolConfig; +import com.alibaba.dubbo.config.ProviderConfig; +import com.alibaba.dubbo.config.RegistryConfig; +import com.alibaba.dubbo.config.ServiceConfig; import com.alibaba.dubbo.config.annotation.Service; import com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory; + +import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; @@ -258,4 +266,11 @@ public class ServiceBean extends ServiceConfig implements InitializingBean unexport(); } + // merged from dubbox + protected Class getServiceClass(T ref) { + if (AopUtils.isAopProxy(ref)) { + return AopUtils.getTargetClass(ref); + } + return super.getServiceClass(ref); + } } \ No newline at end of file diff --git a/dubbo-container/dubbo-container-api/pom.xml b/dubbo-container/dubbo-container-api/pom.xml index 89dcf84236..f5364a9636 100644 --- a/dubbo-container/dubbo-container-api/pom.xml +++ b/dubbo-container/dubbo-container-api/pom.xml @@ -38,6 +38,16 @@ limitations under the License. org.mortbay.jetty jetty + + + org.mortbay.jetty + servlet-api + + + + + javax.servlet + javax.servlet-api diff --git a/dubbo-demo/dubbo-demo-consumer/pom.xml b/dubbo-demo/dubbo-demo-consumer/pom.xml index a3de795035..ed346112f0 100644 --- a/dubbo-demo/dubbo-demo-consumer/pom.xml +++ b/dubbo-demo/dubbo-demo-consumer/pom.xml @@ -60,6 +60,20 @@ limitations under the License. org.slf4j slf4j-api + + javax.servlet + javax.servlet-api + + + org.mortbay.jetty + jetty + + + org.mortbay.jetty + servlet-api + + + org.apache.commons commons-lang3 diff --git a/dubbo-maven/pom.xml b/dubbo-maven/pom.xml index 4bb81f430e..1e3edddc1a 100644 --- a/dubbo-maven/pom.xml +++ b/dubbo-maven/pom.xml @@ -158,7 +158,7 @@ limitations under the License. javax.servlet - servlet-api + javax.servlet-api 2.5 provided diff --git a/dubbo-remoting/dubbo-remoting-http/pom.xml b/dubbo-remoting/dubbo-remoting-http/pom.xml index f06660d5f0..d0a685c4d2 100644 --- a/dubbo-remoting/dubbo-remoting-http/pom.xml +++ b/dubbo-remoting/dubbo-remoting-http/pom.xml @@ -38,6 +38,12 @@ org.mortbay.jetty jetty + + + org.mortbay.jetty + servlet-api + + org.apache.tomcat.embed diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java index 83f4d826b1..ed137f15ca 100644 --- a/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/jetty/JettyHttpServer.java @@ -25,6 +25,7 @@ import com.alibaba.dubbo.remoting.http.HttpHandler; import com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet; import com.alibaba.dubbo.remoting.http.servlet.ServletManager; import com.alibaba.dubbo.remoting.http.support.AbstractHttpServer; + import org.mortbay.jetty.Server; import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.servlet.Context; @@ -39,16 +40,17 @@ public class JettyHttpServer extends AbstractHttpServer { private static final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class); private Server server; - + private URL url; public JettyHttpServer(URL url, final HttpHandler handler) { super(url, handler); this.url = url; // TODO we should leave this setting to slf4j + // we must disable the debug logging for production use Log.setLog(new StdErrLog()); Log.getLog().setDebugEnabled(false); - + DispatcherServlet.addHttpHandler(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()), handler); int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS); @@ -72,13 +74,13 @@ public class JettyHttpServer extends AbstractHttpServer { ServletHandler servletHandler = new ServletHandler(); ServletHolder servletHolder = servletHandler.addServletWithMapping(DispatcherServlet.class, "/*"); servletHolder.setInitOrder(2); - + // dubbo's original impl can't support the use of ServletContext - // server.addHandler(servletHandler); +// server.addHandler(servletHandler); // TODO Context.SESSIONS is the best option here? Context context = new Context(server, "/", Context.SESSIONS); context.setServletHandler(servletHandler); - ServletManager.getInstance().addServletContext(url.getPort(), context.getServletContext()); + ServletManager.getInstance().addServletContext(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()), context.getServletContext()); try { server.start(); @@ -90,7 +92,10 @@ public class JettyHttpServer extends AbstractHttpServer { public void close() { super.close(); - ServletManager.getInstance().removeServletContext(url.getPort()); + + // + ServletManager.getInstance().removeServletContext(url.getParameter(Constants.BIND_PORT_KEY, url.getPort())); + if (server != null) { try { server.stop(); diff --git a/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletManager.java b/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletManager.java index 8e9744d3aa..ffa1091a7e 100644 --- a/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletManager.java +++ b/dubbo-remoting/dubbo-remoting-http/src/main/java/com/alibaba/dubbo/remoting/http/servlet/ServletManager.java @@ -21,9 +21,7 @@ import java.util.concurrent.ConcurrentHashMap; /** * TODO this may not be a pretty elegant solution, - * and we may need to make change to the whole remoting-http architecture in the future * - * @author lishen */ public class ServletManager { diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java index 5fc527067e..b2993b44bd 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java @@ -68,13 +68,6 @@ public class RpcContext { private InetSocketAddress localAddress; private InetSocketAddress remoteAddress; - - // now we don't use the 'values' map to hold these objects - // we want these objects to be as generic as possible - private Object request; - - private Object response; - @Deprecated private List> invokers; @Deprecated @@ -82,35 +75,14 @@ public class RpcContext { @Deprecated private Invocation invocation; + // now we don't use the 'values' map to hold these objects + // we want these objects to be as generic as possible + private Object request; + private Object response; + protected RpcContext() { } - /** - * Get the request object of the underlying RPC protocol, e.g. HttServletRequest - * - * @return null if the underlying protocol doesn't provide support for getting request - */ - public Object getRequest() { - return request; - } - - public void setRequest(Object request) { - this.request = request; - } - - /** - * Get the response object of the underlying RPC protocol, e.g. HttServletResponse - * - * @return null if the underlying protocol doesn't provide support for getting response - */ - public Object getResponse() { - return response; - } - - public void setResponse(Object response) { - this.response = response; - } - /** * get context. * @@ -129,6 +101,53 @@ public class RpcContext { LOCAL.remove(); } + /** + * Get the request object of the underlying RPC protocol, e.g. HttpServletRequest + * + * @return null if the underlying protocol doesn't provide support for getting request + */ + public Object getRequest() { + return request; + } + + /** + * Get the request object of the underlying RPC protocol, e.g. HttpServletRequest + * + * @return null if the underlying protocol doesn't provide support for getting request or the request is not of the specified type + */ + @SuppressWarnings("unchecked") + public T getRequest(Class clazz) { + return (request != null && clazz.isAssignableFrom(request.getClass())) ? (T) request : null; + } + + + public void setRequest(Object request) { + this.request = request; + } + + /** + * Get the response object of the underlying RPC protocol, e.g. HttpServletResponse + * + * @return null if the underlying protocol doesn't provide support for getting response + */ + public Object getResponse() { + return response; + } + + /** + * Get the response object of the underlying RPC protocol, e.g. HttpServletResponse + * + * @return null if the underlying protocol doesn't provide support for getting response or the response is not of the specified type + */ + @SuppressWarnings("unchecked") + public T getResponse(Class clazz) { + return (response != null && clazz.isAssignableFrom(response.getClass())) ? (T) response : null; + } + + public void setResponse(Object response) { + this.response = response; + } + /** * is provider side. * diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ServiceClassHolder.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ServiceClassHolder.java index e6f9ec1516..0dfc54cbff 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ServiceClassHolder.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/ServiceClassHolder.java @@ -1,7 +1,7 @@ package com.alibaba.dubbo.rpc; /** - * TODO this is just a workround for rest protocol, and now we just ensure it works in the most common dubbo usages + * TODO this is just a workaround for rest protocol, and now we just ensure it works in the most common dubbo usages * * @author lishen */ diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java index 9a4a775da0..ad53baf287 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/com/alibaba/dubbo/rpc/filter/ContextFilter.java @@ -50,9 +50,20 @@ public class ContextFilter implements Filter { RpcContext.getContext() .setInvoker(invoker) .setInvocation(invocation) - .setAttachments(attachments) +// .setAttachments(attachments) // merged from dubbox .setLocalAddress(invoker.getUrl().getHost(), invoker.getUrl().getPort()); + + // mreged from dubbox + // we may already added some attachments into RpcContext before this filter (e.g. in rest protocol) + if (attachments != null) { + if (RpcContext.getContext().getAttachments() != null) { + RpcContext.getContext().getAttachments().putAll(attachments); + } else { + RpcContext.getContext().setAttachments(attachments); + } + } + if (invocation instanceof RpcInvocation) { ((RpcInvocation) invocation).setInvoker(invoker); } diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml index 1faf0e5a3b..bad6293214 100644 --- a/dubbo-rpc/dubbo-rpc-rest/pom.xml +++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml @@ -60,7 +60,7 @@ org.jboss.resteasy - resteasy-netty + resteasy-netty4 diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/NettyServer.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/NettyServer.java index 9b3ed76389..243d8e2737 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/NettyServer.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/NettyServer.java @@ -17,13 +17,17 @@ package com.alibaba.dubbo.rpc.protocol.rest; import com.alibaba.dubbo.common.Constants; import com.alibaba.dubbo.common.URL; + +import io.netty.channel.ChannelOption; import org.jboss.resteasy.plugins.server.netty.NettyJaxrsServer; import org.jboss.resteasy.spi.ResteasyDeployment; +import java.util.HashMap; +import java.util.Map; + /** * Netty server can't support @Context injection of servlet objects since it's not a servlet container * - * @author lishen */ public class NettyServer extends BaseRestServer { @@ -31,7 +35,9 @@ public class NettyServer extends BaseRestServer { protected void doStart(URL url) { server.setPort(url.getPort()); - server.setKeepAlive(url.getParameter(Constants.KEEP_ALIVE_KEY, true)); + Map channelOption = new HashMap(); + channelOption.put(ChannelOption.SO_KEEPALIVE, url.getParameter(Constants.KEEP_ALIVE_KEY, Constants.DEFAULT_KEEP_ALIVE)); + server.setChildChannelOptions(channelOption); server.setExecutorThreadCount(url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS)); server.setIoWorkerCount(url.getParameter(Constants.IO_THREADS_KEY, Constants.DEFAULT_IO_THREADS)); server.start(); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java index 918f28f91a..a4237f9e0d 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/com/alibaba/dubbo/rpc/protocol/rest/RestProtocol.java @@ -22,18 +22,19 @@ import com.alibaba.dubbo.remoting.http.HttpBinder; import com.alibaba.dubbo.remoting.http.servlet.BootstrapListener; import com.alibaba.dubbo.remoting.http.servlet.ServletManager; import com.alibaba.dubbo.rpc.RpcException; -import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol; import com.alibaba.dubbo.rpc.ServiceClassHolder; +import com.alibaba.dubbo.rpc.protocol.AbstractProxyProtocol; + import org.apache.http.HeaderElement; import org.apache.http.HeaderElementIterator; import org.apache.http.HttpResponse; -import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.SocketConfig; import org.apache.http.conn.ConnectionKeepAliveStrategy; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.PoolingClientConnectionManager; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeaderElementIterator; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.jboss.resteasy.client.jaxrs.ResteasyClient; @@ -53,7 +54,6 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; /** - * @author lishen */ public class RestProtocol extends AbstractProxyProtocol { @@ -81,7 +81,7 @@ public class RestProtocol extends AbstractProxyProtocol { } protected Runnable doExport(T impl, Class type, URL url) throws RpcException { - String addr = url.getIp() + ":" + url.getPort(); + String addr = getAddr(url); Class implClass = ServiceClassHolder.getInstance().popServiceClass(); RestServer server = servers.get(addr); if (server == null) { @@ -131,40 +131,41 @@ public class RestProtocol extends AbstractProxyProtocol { } // TODO more configs to add - - PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); // 20 is the default maxTotal of current PoolingClientConnectionManager connectionManager.setMaxTotal(url.getParameter(Constants.CONNECTIONS_KEY, 20)); connectionManager.setDefaultMaxPerRoute(url.getParameter(Constants.CONNECTIONS_KEY, 20)); connectionMonitor.addConnectionManager(connectionManager); + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT)) + .setSocketTimeout(url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT)) + .build(); -// BasicHttpContext localContext = new BasicHttpContext(); + SocketConfig socketConfig = SocketConfig.custom() + .setSoKeepAlive(true) + .setTcpNoDelay(true) + .build(); - DefaultHttpClient httpClient = new DefaultHttpClient(connectionManager); - - httpClient.setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { - public long getKeepAliveDuration(HttpResponse response, HttpContext context) { - HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE)); - while (it.hasNext()) { - HeaderElement he = it.nextElement(); - String param = he.getName(); - String value = he.getValue(); - if (value != null && param.equalsIgnoreCase("timeout")) { - return Long.parseLong(value) * 1000; + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setKeepAliveStrategy(new ConnectionKeepAliveStrategy() { + public long getKeepAliveDuration(HttpResponse response, HttpContext context) { + HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE)); + while (it.hasNext()) { + HeaderElement he = it.nextElement(); + String param = he.getName(); + String value = he.getValue(); + if (value != null && param.equalsIgnoreCase("timeout")) { + return Long.parseLong(value) * 1000; + } + } + // TODO constant + return 30 * 1000; } - } - // TODO constant - return 30 * 1000; - } - }); - - HttpParams params = httpClient.getParams(); - // TODO currently no xml config for Constants.CONNECT_TIMEOUT_KEY so we directly reuse Constants.TIMEOUT_KEY for now - HttpConnectionParams.setConnectionTimeout(params, url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT)); - HttpConnectionParams.setSoTimeout(params, url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT)); - HttpConnectionParams.setTcpNoDelay(params, true); - HttpConnectionParams.setSoKeepalive(params, true); + }) + .setDefaultRequestConfig(requestConfig) + .setDefaultSocketConfig(socketConfig) + .build(); ApacheHttpClient4Engine engine = new ApacheHttpClient4Engine(httpClient/*, localContext*/); @@ -231,9 +232,9 @@ public class RestProtocol extends AbstractProxyProtocol { protected class ConnectionMonitor extends Thread { private volatile boolean shutdown; - private final List connectionManagers = Collections.synchronizedList(new LinkedList()); + private final List connectionManagers = Collections.synchronizedList(new LinkedList()); - public void addConnectionManager(ClientConnectionManager connectionManager) { + public void addConnectionManager(PoolingHttpClientConnectionManager connectionManager) { connectionManagers.add(connectionManager); } @@ -242,7 +243,7 @@ public class RestProtocol extends AbstractProxyProtocol { while (!shutdown) { synchronized (this) { wait(1000); - for (ClientConnectionManager connectionManager : connectionManagers) { + for (PoolingHttpClientConnectionManager connectionManager : connectionManagers) { connectionManager.closeExpiredConnections(); // TODO constant connectionManager.closeIdleConnections(30, TimeUnit.SECONDS); diff --git a/dubbo-simple/dubbo-monitor-simple/pom.xml b/dubbo-simple/dubbo-monitor-simple/pom.xml index a4e1844fcc..1b5d38b115 100644 --- a/dubbo-simple/dubbo-monitor-simple/pom.xml +++ b/dubbo-simple/dubbo-monitor-simple/pom.xml @@ -105,7 +105,7 @@ limitations under the License. javax.servlet - servlet-api + javax.servlet-api org.mortbay.jetty diff --git a/dubbo/pom.xml b/dubbo/pom.xml index ef0c769ecd..2bc9b1229a 100644 --- a/dubbo/pom.xml +++ b/dubbo/pom.xml @@ -100,6 +100,14 @@ limitations under the License. org.apache.httpcomponents httpclient + + org.apache.tomcat.embed + tomcat-embed-core + + + org.apache.tomcat.embed + tomcat-embed-logging-juli + @@ -202,7 +210,7 @@ limitations under the License. org.jboss.resteasy - resteasy-netty + resteasy-netty4 org.jboss.resteasy @@ -398,6 +406,7 @@ limitations under the License. com.alibaba:dubbo-rpc-thrift com.alibaba:dubbo-rpc-memcached com.alibaba:dubbo-rpc-redis + com.alibaba:dubbo-rpc-rest com.alibaba:dubbo-filter-validation com.alibaba:dubbo-filter-cache com.alibaba:dubbo-cluster diff --git a/pom.xml b/pom.xml index 3a632adec5..be20004995 100644 --- a/pom.xml +++ b/pom.xml @@ -102,7 +102,7 @@ limitations under the License. 0.8.0 1.0.13 4.0.38 - 2.5 + 3.1.0 6.1.26 1.1.0.Final 5.4.1.Final @@ -113,11 +113,11 @@ limitations under the License. 2.2 3.1.6 1.7 - 2.24.0 - 0.26 - 1.55 + 4.0.1 + 0.42 + 2.48-jdk-6 2.0 - 3.0.7.Final + 3.1.4.Final 8.0.11 1.7.25 @@ -261,7 +261,7 @@ limitations under the License. javax.servlet - servlet-api + javax.servlet-api ${servlet_version} @@ -310,7 +310,7 @@ limitations under the License. ${velocity_version} - com.esotericsoftware.kryo + com.esotericsoftware kryo ${kryo_version} @@ -341,7 +341,7 @@ limitations under the License. org.jboss.resteasy - resteasy-netty + resteasy-netty4 ${resteasy_version}