Skip to content

Commit

Permalink
migrate http protocol (#4781)
Browse files Browse the repository at this point in the history
http to http-invoker
jsonrpc to http
  • Loading branch information
lexburner authored and chickenlj committed Aug 20, 2019
1 parent 594e4e1 commit 06f7190
Show file tree
Hide file tree
Showing 20 changed files with 705 additions and 705 deletions.
8 changes: 4 additions & 4 deletions dubbo-all/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-jsonrpc</artifactId>
<artifactId>dubbo-rpc-http</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
Expand All @@ -165,7 +165,7 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-http</artifactId>
<artifactId>dubbo-rpc-http-invoker</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
Expand Down Expand Up @@ -581,10 +581,10 @@
<include>org.apache.dubbo:dubbo-rpc-api</include>
<include>org.apache.dubbo:dubbo-rpc-dubbo</include>
<include>org.apache.dubbo:dubbo-rpc-injvm</include>
<include>org.apache.dubbo:dubbo-rpc-jsonrpc</include>
<include>org.apache.dubbo:dubbo-rpc-http</include>
<include>org.apache.dubbo:dubbo-rpc-rmi</include>
<include>org.apache.dubbo:dubbo-rpc-hessian</include>
<include>org.apache.dubbo:dubbo-rpc-http</include>
<include>org.apache.dubbo:dubbo-rpc-http-invoker</include>
<include>org.apache.dubbo:dubbo-rpc-webservice</include>
<include>org.apache.dubbo:dubbo-rpc-thrift</include>
<include>org.apache.dubbo:dubbo-rpc-memcached</include>
Expand Down
4 changes: 2 additions & 2 deletions dubbo-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-jsonrpc</artifactId>
<artifactId>dubbo-rpc-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
Expand All @@ -189,7 +189,7 @@
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-http</artifactId>
<artifactId>dubbo-rpc-http-invoker</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,20 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>dubbo-rpc</artifactId>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc</artifactId>
<version>${revision}</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>dubbo-rpc-jsonrpc</artifactId>

<description>The JSON-RPC module of dubbo project</description>

<artifactId>dubbo-rpc-http-invoker</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The http rpc module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>

<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
Expand All @@ -48,14 +44,14 @@
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>com.github.briandilley.jsonrpc4j</groupId>
<artifactId>jsonrpc4j</artifactId>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>javax.portlet</groupId>
<artifactId>portlet-api</artifactId>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-serialization-jdk</artifactId>
<version>${project.parent.version}</version>
<scope>test</scope>
</dependency>
</dependencies>


</project>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import org.aopalliance.intercept.MethodInvocation;

@Deprecated
public class HttpRemoteInvocation extends org.apache.dubbo.rpc.protocol.http.HttpRemoteInvocation {
public class HttpRemoteInvocation extends org.apache.dubbo.rpc.protocol.httpinvoker.HttpRemoteInvocation {
private static final long serialVersionUID = 1L;

public HttpRemoteInvocation(MethodInvocation methodInvocation) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
/*
* 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.httpinvoker;

import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.common.Version;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.HttpBinder;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
import org.apache.dubbo.rpc.RpcContext;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
import org.apache.dubbo.rpc.service.GenericService;
import org.apache.dubbo.rpc.support.ProtocolUtils;

import org.aopalliance.intercept.MethodInvocation;
import org.springframework.remoting.RemoteAccessException;
import org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;
import org.springframework.remoting.support.RemoteInvocation;
import org.springframework.remoting.support.RemoteInvocationFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
import static org.apache.dubbo.remoting.Constants.DUBBO_VERSION_KEY;
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;

/**
* HttpInvokerProtocol
*/
public class HttpInvokerProtocol extends AbstractProxyProtocol {

public static final int DEFAULT_PORT = 80;

private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();

private final Map<String, HttpInvokerServiceExporter> skeletonMap = new ConcurrentHashMap<String, HttpInvokerServiceExporter>();

private HttpBinder httpBinder;

public HttpInvokerProtocol() {
super(RemoteAccessException.class);
}

public void setHttpBinder(HttpBinder httpBinder) {
this.httpBinder = httpBinder;
}

@Override
public int getDefaultPort() {
return DEFAULT_PORT;
}

@Override
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
String addr = getAddr(url);
HttpServer server = serverMap.get(addr);
if (server == null) {
server = httpBinder.bind(url, new InternalHandler());
serverMap.put(addr, server);
}
final String path = url.getAbsolutePath();
skeletonMap.put(path, createExporter(impl, type));

final String genericPath = path + "/" + GENERIC_KEY;

skeletonMap.put(genericPath, createExporter(impl, GenericService.class));
return new Runnable() {
@Override
public void run() {
skeletonMap.remove(path);
skeletonMap.remove(genericPath);
}
};
}

private <T> HttpInvokerServiceExporter createExporter(T impl, Class<?> type) {
final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter();
httpServiceExporter.setServiceInterface(type);
httpServiceExporter.setService(impl);
try {
httpServiceExporter.afterPropertiesSet();
} catch (Exception e) {
throw new RpcException(e.getMessage(), e);
}
return httpServiceExporter;
}

@Override
@SuppressWarnings("unchecked")
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
final String generic = url.getParameter(GENERIC_KEY);
final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);

final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean();
httpProxyFactoryBean.setRemoteInvocationFactory(new RemoteInvocationFactory() {
@Override
public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
RemoteInvocation invocation;
/*
package was renamed to 'org.apache.dubbo' in v2.7.0, so only provider versions after v2.7.0 can
recognize org.apache.xxx.HttpRemoteInvocation'.
*/
if (Version.isRelease270OrHigher(url.getParameter(RELEASE_KEY))) {
invocation = new HttpRemoteInvocation(methodInvocation);
} else {
/*
The customized 'com.alibaba.dubbo.rpc.protocol.http.HttpRemoteInvocation' was firstly introduced
in v2.6.3. The main purpose is to support transformation of attachments in HttpInvokerProtocol, see
https://github.com/apache/dubbo/pull/1827. To guarantee interoperability with lower
versions, we need to check if the provider is v2.6.3 or higher before sending customized
HttpRemoteInvocation.
*/
if (Version.isRelease263OrHigher(url.getParameter(DUBBO_VERSION_KEY))) {
invocation = new com.alibaba.dubbo.rpc.protocol.http.HttpRemoteInvocation(methodInvocation);
} else {
invocation = new RemoteInvocation(methodInvocation);
}
}
if (isGeneric) {
invocation.addAttribute(GENERIC_KEY, generic);
}
return invocation;
}
});

String key = url.toIdentityString();
if (isGeneric) {
key = key + "/" + GENERIC_KEY;
}

httpProxyFactoryBean.setServiceUrl(key.replace("http-invoker","http"));
httpProxyFactoryBean.setServiceInterface(serviceType);
String client = url.getParameter(Constants.CLIENT_KEY);
if (StringUtils.isEmpty(client) || "simple".equals(client)) {
SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor = new SimpleHttpInvokerRequestExecutor() {
@Override
protected void prepareConnection(HttpURLConnection con,
int contentLength) throws IOException {
super.prepareConnection(con, contentLength);
con.setReadTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT));
con.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));
}
};
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
} else if ("commons".equals(client)) {
HttpComponentsHttpInvokerRequestExecutor httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor();
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT));
httpInvokerRequestExecutor.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
} else {
throw new IllegalStateException("Unsupported http protocol client " + client + ", only supported: simple, commons");
}
httpProxyFactoryBean.afterPropertiesSet();
return (T) httpProxyFactoryBean.getObject();
}

@Override
protected int getErrorCode(Throwable e) {
if (e instanceof RemoteAccessException) {
e = e.getCause();
}
if (e != null) {
Class<?> cls = e.getClass();
if (SocketTimeoutException.class.equals(cls)) {
return RpcException.TIMEOUT_EXCEPTION;
} else if (IOException.class.isAssignableFrom(cls)) {
return RpcException.NETWORK_EXCEPTION;
} else if (ClassNotFoundException.class.isAssignableFrom(cls)) {
return RpcException.SERIALIZATION_EXCEPTION;
}
}
return super.getErrorCode(e);
}

private class InternalHandler implements HttpHandler {

@Override
public void handle(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
String uri = request.getRequestURI();
HttpInvokerServiceExporter skeleton = skeletonMap.get(uri);
if (!"POST".equalsIgnoreCase(request.getMethod())) {
response.setStatus(500);
} else {
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
try {
skeleton.handleRequest(request, response);
} catch (Throwable e) {
throw new ServletException(e);
}
}
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/

package org.apache.dubbo.rpc.protocol.http;
package org.apache.dubbo.rpc.protocol.httpinvoker;

import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.RpcContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
http-invoker=org.apache.dubbo.rpc.protocol.httpinvoker.HttpInvokerProtocol
Loading

0 comments on commit 06f7190

Please sign in to comment.