修改HttpServer扩展点
git-svn-id: http://code.alibabatech.com/svn/dubbo/trunk@174 1a56cb94-b969-4eaa-88fa-be21384802f2
This commit is contained in:
parent
60bc67ce59
commit
4990572d21
|
|
@ -41,6 +41,6 @@
|
|||
<dependency>
|
||||
<groupId>org.mortbay.jetty</groupId>
|
||||
<artifactId>jetty</artifactId>
|
||||
</dependency>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.http;
|
||||
|
||||
import com.alibaba.dubbo.common.Adaptive;
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
|
||||
/**
|
||||
* HttpBinder
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
@Extension("jetty")
|
||||
public interface HttpBinder {
|
||||
|
||||
/**
|
||||
* bind the server.
|
||||
*
|
||||
* @param url server url.
|
||||
* @return server.
|
||||
*/
|
||||
@Adaptive({Constants.SERVER_KEY})
|
||||
HttpServer bind(URL url, HttpHandler handler);
|
||||
|
||||
}
|
||||
|
|
@ -26,8 +26,8 @@ import javax.servlet.http.HttpServletResponse;
|
|||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public interface HttpProcessor {
|
||||
|
||||
public interface HttpHandler {
|
||||
|
||||
/**
|
||||
* invoke.
|
||||
*
|
||||
|
|
@ -36,6 +36,6 @@ public interface HttpProcessor {
|
|||
* @throws IOException
|
||||
* @throws ServletException
|
||||
*/
|
||||
public abstract void invoke(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
|
||||
|
||||
void handle(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException;
|
||||
|
||||
}
|
||||
|
|
@ -15,12 +15,56 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.remoting.http;
|
||||
|
||||
public interface HttpServer {
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
int getPort();
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.Resetable;
|
||||
|
||||
public interface HttpServer extends Resetable {
|
||||
|
||||
/**
|
||||
* get http handler.
|
||||
*
|
||||
* @return http handler.
|
||||
*/
|
||||
HttpHandler getHttpHandler();
|
||||
|
||||
/**
|
||||
* get url.
|
||||
*
|
||||
* @return url
|
||||
*/
|
||||
URL getUrl();
|
||||
|
||||
/**
|
||||
* get local address.
|
||||
*
|
||||
* @return local address.
|
||||
*/
|
||||
InetSocketAddress getLocalAddress();
|
||||
|
||||
/**
|
||||
* close the channel.
|
||||
*/
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Graceful close the channel.
|
||||
*/
|
||||
void close(int timeout);
|
||||
|
||||
/**
|
||||
* is bound.
|
||||
*
|
||||
* @return bound
|
||||
*/
|
||||
boolean isBound();
|
||||
|
||||
/**
|
||||
* is closed.
|
||||
*
|
||||
* @return closed
|
||||
*/
|
||||
boolean isClosed();
|
||||
|
||||
}
|
||||
|
|
@ -1,92 +0,0 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.http;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.nio.SelectChannelConnector;
|
||||
import org.mortbay.jetty.servlet.ServletHandler;
|
||||
import org.mortbay.jetty.servlet.ServletHolder;
|
||||
import org.mortbay.thread.QueuedThreadPool;
|
||||
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.NetUtils;
|
||||
|
||||
public class JettyHttpServer implements HttpServer {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class);
|
||||
|
||||
private String host;
|
||||
|
||||
private int port;
|
||||
|
||||
private int threads;
|
||||
|
||||
private Server server;
|
||||
|
||||
public JettyHttpServer(int port, int threads) {
|
||||
this.port = port;
|
||||
this.threads = threads;
|
||||
}
|
||||
|
||||
public JettyHttpServer(String host, int port, int threads) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.threads = threads;
|
||||
}
|
||||
|
||||
public void start() {
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
threadPool.setDaemon(true);
|
||||
threadPool.setMaxThreads(threads);
|
||||
threadPool.setMinThreads(threads);
|
||||
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
if (NetUtils.isValidLocalHost(host)) {
|
||||
connector.setHost(host);
|
||||
}
|
||||
connector.setPort(port);
|
||||
|
||||
ServletHandler handler = new ServletHandler();
|
||||
ServletHolder holder = handler.addServletWithMapping(ServiceDispatcherServlet.class, "/*");
|
||||
holder.setInitOrder(1);
|
||||
|
||||
server = new Server();
|
||||
server.setThreadPool(threadPool);
|
||||
server.addConnector(connector);
|
||||
server.addHandler(handler);
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to start jetty server on " + host + ":" + port + ", cause: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
if (server != null) {
|
||||
try {
|
||||
server.stop();
|
||||
} catch (Exception e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.http.jetty;
|
||||
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
import com.alibaba.dubbo.remoting.http.HttpBinder;
|
||||
|
||||
/**
|
||||
* JettyHttpTransporter
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
@Extension("jetty")
|
||||
public class JettyHttpBinder implements HttpBinder {
|
||||
|
||||
public HttpServer bind(URL url, HttpHandler handler) {
|
||||
return new JettyHttpServer(url, handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.http.jetty;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.mortbay.jetty.Server;
|
||||
import org.mortbay.jetty.handler.AbstractHandler;
|
||||
import org.mortbay.jetty.nio.SelectChannelConnector;
|
||||
import org.mortbay.thread.QueuedThreadPool;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.common.logger.Logger;
|
||||
import com.alibaba.dubbo.common.logger.LoggerFactory;
|
||||
import com.alibaba.dubbo.common.utils.NetUtils;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.support.AbstractHttpServer;
|
||||
|
||||
public class JettyHttpServer extends AbstractHttpServer {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(JettyHttpServer.class);
|
||||
|
||||
private Server server;
|
||||
|
||||
public JettyHttpServer(URL url, final HttpHandler handler){
|
||||
super(url, handler);
|
||||
|
||||
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
|
||||
QueuedThreadPool threadPool = new QueuedThreadPool();
|
||||
threadPool.setDaemon(true);
|
||||
threadPool.setMaxThreads(threads);
|
||||
threadPool.setMinThreads(threads);
|
||||
|
||||
SelectChannelConnector connector = new SelectChannelConnector();
|
||||
if (NetUtils.isValidLocalHost(url.getHost())) {
|
||||
connector.setHost(url.getHost());
|
||||
}
|
||||
connector.setPort(url.getPort());
|
||||
|
||||
server = new Server();
|
||||
server.setThreadPool(threadPool);
|
||||
server.addConnector(connector);
|
||||
server.addHandler(new AbstractHandler() {
|
||||
public void handle(String target, HttpServletRequest request,
|
||||
HttpServletResponse response, int dispatch) throws IOException,
|
||||
ServletException {
|
||||
handler.handle(request, response);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
server.start();
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Failed to start jetty server on " + url.getAddress() + ", cause: "
|
||||
+ e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
public void close() {
|
||||
super.close();
|
||||
if (server != null) {
|
||||
try {
|
||||
server.stop();
|
||||
} catch (Exception e) {
|
||||
logger.warn(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -13,57 +13,45 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.remoting.http;
|
||||
package com.alibaba.dubbo.remoting.http.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
|
||||
/**
|
||||
* Service dispatcher Servlet.
|
||||
*
|
||||
* @author qian.lei
|
||||
*/
|
||||
public class ServiceDispatcherServlet extends HttpServlet {
|
||||
public class DispatcherServlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 5766349180380479888L;
|
||||
|
||||
private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded";
|
||||
|
||||
private static final Map<String, HttpProcessor> processors = new ConcurrentHashMap<String, HttpProcessor>();
|
||||
private static final Map<Integer, HttpHandler> handlers = new ConcurrentHashMap<Integer, HttpHandler>();
|
||||
|
||||
public static void addProcessor(int port, String uri, HttpProcessor processor) {
|
||||
processors.put(key(port, uri), processor);
|
||||
static void addHttpInvoker(int port, HttpHandler processor) {
|
||||
handlers.put(port, processor);
|
||||
}
|
||||
|
||||
public static void removeProcessor(int port, String uri) {
|
||||
processors.remove(key(port, uri));
|
||||
}
|
||||
|
||||
private static String key(int port, String uri) {
|
||||
return port + ":" + (uri.startsWith("/") ? uri : "/" + uri);
|
||||
static void removeHttpInvoker(int port) {
|
||||
handlers.remove(port);
|
||||
}
|
||||
|
||||
protected void service(HttpServletRequest request, HttpServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
String uri = request.getRequestURI();
|
||||
String contentType = request.getContentType();
|
||||
if (contentType == null || FORM_CONTENT_TYPE.equalsIgnoreCase(contentType)) {
|
||||
int i = uri.lastIndexOf('/');
|
||||
if (i >= 0) {
|
||||
uri = uri.substring(0, i);
|
||||
}
|
||||
}
|
||||
HttpProcessor processor = processors.get(key(request.getLocalPort(), uri));
|
||||
if( processor == null ) {// service not found.
|
||||
HttpHandler handler = handlers.get(request.getLocalPort());
|
||||
if( handler == null ) {// service not found.
|
||||
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Service not found.");
|
||||
} else {
|
||||
processor.invoke(request, response);
|
||||
handler.handle(request, response);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.http.servlet;
|
||||
|
||||
import com.alibaba.dubbo.common.Adaptive;
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpBinder;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
|
||||
/**
|
||||
* ServletHttpTransporter
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
@Extension("servlet")
|
||||
public class ServletHttpBinder implements HttpBinder {
|
||||
|
||||
@Adaptive()
|
||||
public HttpServer bind(URL url, HttpHandler handler) {
|
||||
return new ServletHttpServer(url, handler);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -13,24 +13,17 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.alibaba.dubbo.remoting.http;
|
||||
package com.alibaba.dubbo.remoting.http.servlet;
|
||||
|
||||
public class ServletHttpServer implements HttpServer {
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.support.AbstractHttpServer;
|
||||
|
||||
public class ServletHttpServer extends AbstractHttpServer {
|
||||
|
||||
private final int port;
|
||||
|
||||
public ServletHttpServer(int port){
|
||||
this.port = port;
|
||||
public ServletHttpServer(URL url, HttpHandler handler){
|
||||
super(url, handler);
|
||||
DispatcherServlet.addHttpInvoker(url.getPort(), handler);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.http.support;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
|
||||
/**
|
||||
* AbstractHttpServer
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public abstract class AbstractHttpServer implements HttpServer {
|
||||
|
||||
private final URL url;
|
||||
|
||||
private final HttpHandler handler;
|
||||
|
||||
private volatile boolean closed;
|
||||
|
||||
public AbstractHttpServer(URL url, HttpHandler handler){
|
||||
if (url == null) {
|
||||
throw new IllegalArgumentException("url == null");
|
||||
}
|
||||
if (handler == null) {
|
||||
throw new IllegalArgumentException("handler == null");
|
||||
}
|
||||
this.url = url;
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
public HttpHandler getHttpHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
public URL getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void reset(URL url) {
|
||||
}
|
||||
|
||||
public boolean isBound() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public InetSocketAddress getLocalAddress() {
|
||||
return url.toInetSocketAddress();
|
||||
}
|
||||
|
||||
public void close() {
|
||||
closed = true;
|
||||
}
|
||||
|
||||
public void close(int timeout) {
|
||||
close();
|
||||
}
|
||||
|
||||
public boolean isClosed() {
|
||||
return closed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
com.alibaba.dubbo.remoting.http.servlet.ServletHttpBinder
|
||||
com.alibaba.dubbo.remoting.http.jetty.JettyHttpBinder
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.remoting.exchange.support;
|
||||
|
||||
import com.alibaba.dubbo.remoting.RemotingException;
|
||||
import com.alibaba.dubbo.remoting.exchange.ResponseCallback;
|
||||
import com.alibaba.dubbo.remoting.exchange.ResponseFuture;
|
||||
|
||||
/**
|
||||
* SimpleFuture
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class SimpleFuture implements ResponseFuture {
|
||||
|
||||
private final Object value;
|
||||
|
||||
public SimpleFuture(Object value){
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Object get() throws RemotingException {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Object get(int timeoutInMillis) throws RemotingException {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setCallback(ResponseCallback callback) {
|
||||
callback.done(value);
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -42,6 +42,12 @@
|
|||
<dependency>
|
||||
<groupId>com.caucho</groupId>
|
||||
<artifactId>hessian</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<scope>provided</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -15,22 +15,25 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
import com.alibaba.dubbo.remoting.http.JettyHttpServer;
|
||||
import com.alibaba.dubbo.remoting.http.ServiceDispatcherServlet;
|
||||
import com.alibaba.dubbo.remoting.http.ServletHttpServer;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.dubbo.common.Extension;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.remoting.http.HttpBinder;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.remoting.http.HttpServer;
|
||||
import com.alibaba.dubbo.rpc.Exporter;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractProtocol;
|
||||
|
||||
/**
|
||||
* http rpc support.
|
||||
|
|
@ -42,7 +45,13 @@ public class HessianProtocol extends AbstractProtocol {
|
|||
|
||||
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
|
||||
|
||||
private ProxyFactory proxyFactory;
|
||||
private HttpBinder httpTransporter;
|
||||
|
||||
private ProxyFactory proxyFactory;
|
||||
|
||||
public void setHttpTransporter(HttpBinder httpTransporter) {
|
||||
this.httpTransporter = httpTransporter;
|
||||
}
|
||||
|
||||
public void setProxyFactory(ProxyFactory proxyFactory) {
|
||||
this.proxyFactory = proxyFactory;
|
||||
|
|
@ -50,40 +59,37 @@ public class HessianProtocol extends AbstractProtocol {
|
|||
|
||||
public int getDefaultPort() {
|
||||
return 80;
|
||||
}
|
||||
|
||||
private class HessianHandler implements HttpHandler {
|
||||
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
String uri = request.getRequestURI();
|
||||
HessianRpcExporter<?> exporter = (HessianRpcExporter<?>) exporterMap.get(uri);
|
||||
exporter.handle(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {
|
||||
URL url = invoker.getUrl();
|
||||
|
||||
final String uri = url.getPath(); // service uri also exporter cache key.
|
||||
|
||||
int threads = url.getParameter(Constants.THREADS_KEY, Constants.DEFAULT_THREADS);
|
||||
final URL url = invoker.getUrl();
|
||||
final String uri = url.getAbsolutePath(); // service uri also exporter cache key.
|
||||
|
||||
String addr = url.getHost() + ":" + url.getPort();
|
||||
HttpServer server = serverMap.get(addr);
|
||||
if (server == null) {
|
||||
String type = url.getParameter(Constants.SERVER_KEY, "jetty");
|
||||
if ("servlet".equals(type)) {
|
||||
server = new ServletHttpServer(url.getPort());
|
||||
} else if ("jetty".equals(type)) {
|
||||
// 和Dubbo协议一样,总是绑定到0.0.0.0上
|
||||
server = new JettyHttpServer(url.getPort(), threads);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported http server " + type
|
||||
+ ", only support servlet, jetty!");
|
||||
}
|
||||
server.start();
|
||||
server = httpTransporter.bind(url, new HessianHandler());
|
||||
serverMap.put(addr, server);
|
||||
}
|
||||
|
||||
HessianRpcExporter<T> exporter = new HessianRpcExporter<T>(invoker, proxyFactory) {
|
||||
public void unexport() {
|
||||
super.unexport();
|
||||
exporterMap.remove(uri);
|
||||
exporterMap.remove(uri);
|
||||
}
|
||||
};
|
||||
exporterMap.put(uri, exporter);
|
||||
ServiceDispatcherServlet.addProcessor(url.getPort(), uri, exporter);
|
||||
return exporter;
|
||||
}
|
||||
|
||||
|
|
@ -100,9 +106,9 @@ public class HessianProtocol extends AbstractProtocol {
|
|||
if (server != null) {
|
||||
try {
|
||||
if (logger.isInfoEnabled()) {
|
||||
logger.info("Close hessian server 0.0.0.0:" + server.getPort());
|
||||
logger.info("Close hessian server " + server.getUrl());
|
||||
}
|
||||
server.stop();
|
||||
server.close();
|
||||
} catch (Throwable t) {
|
||||
logger.warn(t.getMessage(), t);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import com.alibaba.dubbo.remoting.http.HttpProcessor;
|
||||
import com.alibaba.dubbo.remoting.http.HttpHandler;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.RpcContext;
|
||||
|
|
@ -33,7 +33,7 @@ import com.caucho.hessian.server.HessianSkeleton;
|
|||
*
|
||||
* @author qian.lei
|
||||
*/
|
||||
public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpProcessor {
|
||||
public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpHandler {
|
||||
|
||||
private HessianSkeleton skeleton;
|
||||
|
||||
|
|
@ -42,9 +42,9 @@ public class HessianRpcExporter<T> extends AbstractExporter<T> implements HttpPr
|
|||
skeleton = new HessianSkeleton(proxyFactory.getProxy(invoker), invoker.getInterface());
|
||||
}
|
||||
|
||||
public void invoke(HttpServletRequest request, HttpServletResponse response)
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
if (request.getMethod().equalsIgnoreCase("POST") == false) {
|
||||
if (! request.getMethod().equalsIgnoreCase("POST")) {
|
||||
response.setStatus(500);
|
||||
} else {
|
||||
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(),
|
||||
|
|
|
|||
|
|
@ -15,17 +15,18 @@
|
|||
*/
|
||||
package com.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
import com.caucho.hessian.HessianException;
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
import com.alibaba.dubbo.common.Constants;
|
||||
import com.alibaba.dubbo.common.URL;
|
||||
import com.alibaba.dubbo.rpc.Invocation;
|
||||
import com.alibaba.dubbo.rpc.Invoker;
|
||||
import com.alibaba.dubbo.rpc.ProxyFactory;
|
||||
import com.alibaba.dubbo.rpc.Result;
|
||||
import com.alibaba.dubbo.rpc.RpcException;
|
||||
import com.alibaba.dubbo.rpc.RpcResult;
|
||||
import com.alibaba.dubbo.rpc.protocol.AbstractInvoker;
|
||||
import com.caucho.hessian.HessianException;
|
||||
import com.caucho.hessian.client.HessianConnectionFactory;
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
|
||||
/**
|
||||
* hessian rpc invoker.
|
||||
|
|
@ -36,24 +37,24 @@ public class HessianRpcInvoker<T> extends AbstractInvoker<T> {
|
|||
|
||||
protected static final String HESSIAN_EXCEPTION_PREFIX = HessianException.class.getPackage().getName() + "."; //fix by tony.chenl
|
||||
|
||||
protected Invoker<T> invoker;
|
||||
protected Invoker<T> invoker;
|
||||
|
||||
protected HessianConnectionFactory hessianConnectionFactory = new HttpClientConnectionFactory();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public HessianRpcInvoker(Class<T> serviceType, URL url, ProxyFactory proxyFactory){
|
||||
super(serviceType, url);
|
||||
int timeout;
|
||||
String t = url.getParameter(Constants.TIMEOUT_KEY);
|
||||
if (t != null && t.length() > 0) {
|
||||
timeout = Integer.parseInt(t);
|
||||
} else {
|
||||
timeout = Constants.DEFAULT_TIMEOUT;
|
||||
}
|
||||
|
||||
java.net.URL httpUrl = url.setProtocol("http").toJavaURL();
|
||||
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
|
||||
HessianProxyFactory hessianProxyFactory = new HessianProxyFactory();
|
||||
String client = url.getParameter(Constants.CLIENT_KEY, Constants.DEFAULT_HTTP_CLIENT);
|
||||
if ("httpclient".equals(client)) {
|
||||
hessianProxyFactory.setConnectionFactory(hessianConnectionFactory);
|
||||
} else if (client != null && client.length() > 0 && ! Constants.DEFAULT_HTTP_CLIENT.equals(client)) {
|
||||
throw new IllegalStateException("Unsupported http protocol client=\"" + client + "\"!");
|
||||
}
|
||||
int timeout = url.getParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
|
||||
hessianProxyFactory.setConnectTimeout(timeout);
|
||||
hessianProxyFactory.setReadTimeout(timeout);
|
||||
invoker = proxyFactory.getInvoker((T)hessianProxyFactory.create(serviceType, httpUrl, Thread.currentThread().getContextClassLoader()), serviceType, url);
|
||||
invoker = proxyFactory.getInvoker((T)hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader()), serviceType, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
||||
import com.caucho.hessian.client.HessianConnection;
|
||||
|
||||
/**
|
||||
* HttpClientConnection
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class HttpClientConnection implements HessianConnection {
|
||||
|
||||
private final HttpClient httpClient;
|
||||
|
||||
private final ByteArrayOutputStream output;
|
||||
|
||||
private final HttpPost request;
|
||||
|
||||
private volatile HttpResponse response;
|
||||
|
||||
public HttpClientConnection(HttpClient httpClient, URL url) {
|
||||
this.httpClient = httpClient;
|
||||
this.output = new ByteArrayOutputStream();
|
||||
this.request = new HttpPost(url.toString());
|
||||
}
|
||||
|
||||
public void addHeader(String key, String value) {
|
||||
request.addHeader(new BasicHeader(key, value));
|
||||
}
|
||||
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return output;
|
||||
}
|
||||
|
||||
public void sendRequest() throws IOException {
|
||||
request.setEntity(new ByteArrayEntity(output.toByteArray()));
|
||||
this.response = httpClient.execute(request);
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return response == null || response.getStatusLine() == null ? 0 : response.getStatusLine().getStatusCode();
|
||||
}
|
||||
|
||||
public String getStatusMessage() {
|
||||
return response == null || response.getStatusLine() == null ? null : response.getStatusLine().getReasonPhrase();
|
||||
}
|
||||
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return response == null || response.getEntity() == null ? null : response.getEntity().getContent();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
HttpPost request = this.request;
|
||||
if (request != null) {
|
||||
request.abort();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws IOException {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright 1999-2011 Alibaba Group.
|
||||
*
|
||||
* Licensed 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 com.alibaba.dubbo.rpc.protocol.hessian;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.params.HttpConnectionParams;
|
||||
|
||||
import com.caucho.hessian.client.HessianConnection;
|
||||
import com.caucho.hessian.client.HessianConnectionFactory;
|
||||
import com.caucho.hessian.client.HessianProxyFactory;
|
||||
|
||||
/**
|
||||
* HttpClientConnectionFactory
|
||||
*
|
||||
* @author william.liangf
|
||||
*/
|
||||
public class HttpClientConnectionFactory implements HessianConnectionFactory {
|
||||
|
||||
private final HttpClient httpClient = new DefaultHttpClient();
|
||||
|
||||
public void setHessianProxyFactory(HessianProxyFactory factory) {
|
||||
HttpConnectionParams.setConnectionTimeout(httpClient.getParams(), (int) factory.getConnectTimeout());
|
||||
HttpConnectionParams.setSoTimeout(httpClient.getParams(), (int) factory.getReadTimeout());
|
||||
}
|
||||
|
||||
public HessianConnection open(URL url) throws IOException {
|
||||
return new HttpClientConnection(httpClient, url);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue