Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate http protocol #4781

Merged
merged 3 commits into from Aug 20, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next Next commit
migrate http protocol
  • Loading branch information
xujingfeng committed Aug 9, 2019
commit 57857e030f40d4edc4662ac6c9b4c55cff9f20db
8 changes: 4 additions & 4 deletions dubbo-all/pom.xml
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
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
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>
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
@@ -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);
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);
}
}
}

}

}
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
@@ -0,0 +1 @@
http-invoker=org.apache.dubbo.rpc.protocol.httpinvoker.HttpInvokerProtocol