Skip to content

Commit 06f7190

Browse files
lexburnerchickenlj
authored andcommitted
migrate http protocol (apache#4781)
http to http-invoker jsonrpc to http
1 parent 594e4e1 commit 06f7190

File tree

20 files changed

+705
-705
lines changed

20 files changed

+705
-705
lines changed

dubbo-all/pom.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
</dependency>
145145
<dependency>
146146
<groupId>org.apache.dubbo</groupId>
147-
<artifactId>dubbo-rpc-jsonrpc</artifactId>
147+
<artifactId>dubbo-rpc-http</artifactId>
148148
<version>${project.version}</version>
149149
<scope>compile</scope>
150150
<optional>true</optional>
@@ -165,7 +165,7 @@
165165
</dependency>
166166
<dependency>
167167
<groupId>org.apache.dubbo</groupId>
168-
<artifactId>dubbo-rpc-http</artifactId>
168+
<artifactId>dubbo-rpc-http-invoker</artifactId>
169169
<version>${project.version}</version>
170170
<scope>compile</scope>
171171
<optional>true</optional>
@@ -581,10 +581,10 @@
581581
<include>org.apache.dubbo:dubbo-rpc-api</include>
582582
<include>org.apache.dubbo:dubbo-rpc-dubbo</include>
583583
<include>org.apache.dubbo:dubbo-rpc-injvm</include>
584-
<include>org.apache.dubbo:dubbo-rpc-jsonrpc</include>
584+
<include>org.apache.dubbo:dubbo-rpc-http</include>
585585
<include>org.apache.dubbo:dubbo-rpc-rmi</include>
586586
<include>org.apache.dubbo:dubbo-rpc-hessian</include>
587-
<include>org.apache.dubbo:dubbo-rpc-http</include>
587+
<include>org.apache.dubbo:dubbo-rpc-http-invoker</include>
588588
<include>org.apache.dubbo:dubbo-rpc-webservice</include>
589589
<include>org.apache.dubbo:dubbo-rpc-thrift</include>
590590
<include>org.apache.dubbo:dubbo-rpc-memcached</include>

dubbo-bom/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@
174174
</dependency>
175175
<dependency>
176176
<groupId>org.apache.dubbo</groupId>
177-
<artifactId>dubbo-rpc-jsonrpc</artifactId>
177+
<artifactId>dubbo-rpc-http</artifactId>
178178
<version>${project.version}</version>
179179
</dependency>
180180
<dependency>
@@ -189,7 +189,7 @@
189189
</dependency>
190190
<dependency>
191191
<groupId>org.apache.dubbo</groupId>
192-
<artifactId>dubbo-rpc-http</artifactId>
192+
<artifactId>dubbo-rpc-http-invoker</artifactId>
193193
<version>${project.version}</version>
194194
</dependency>
195195
<dependency>

dubbo-rpc/dubbo-rpc-jsonrpc/pom.xml dubbo-rpc/dubbo-rpc-http-invoker/pom.xml

+13-17
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,20 @@
1414
See the License for the specific language governing permissions and
1515
limitations under the License.
1616
-->
17-
<project xmlns="http://maven.apache.org/POM/4.0.0"
18-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
19-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
17+
<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">
18+
<modelVersion>4.0.0</modelVersion>
2019
<parent>
21-
<artifactId>dubbo-rpc</artifactId>
2220
<groupId>org.apache.dubbo</groupId>
21+
<artifactId>dubbo-rpc</artifactId>
2322
<version>${revision}</version>
2423
</parent>
25-
<modelVersion>4.0.0</modelVersion>
26-
27-
<artifactId>dubbo-rpc-jsonrpc</artifactId>
28-
29-
<description>The JSON-RPC module of dubbo project</description>
30-
24+
<artifactId>dubbo-rpc-http-invoker</artifactId>
25+
<packaging>jar</packaging>
26+
<name>${project.artifactId}</name>
27+
<description>The http rpc module of dubbo project</description>
3128
<properties>
3229
<skip_maven_deploy>false</skip_maven_deploy>
3330
</properties>
34-
3531
<dependencies>
3632
<dependency>
3733
<groupId>org.apache.dubbo</groupId>
@@ -48,14 +44,14 @@
4844
<artifactId>spring-context</artifactId>
4945
</dependency>
5046
<dependency>
51-
<groupId>com.github.briandilley.jsonrpc4j</groupId>
52-
<artifactId>jsonrpc4j</artifactId>
47+
<groupId>org.springframework</groupId>
48+
<artifactId>spring-web</artifactId>
5349
</dependency>
5450
<dependency>
55-
<groupId>javax.portlet</groupId>
56-
<artifactId>portlet-api</artifactId>
51+
<groupId>org.apache.dubbo</groupId>
52+
<artifactId>dubbo-serialization-jdk</artifactId>
53+
<version>${project.parent.version}</version>
54+
<scope>test</scope>
5755
</dependency>
5856
</dependencies>
59-
60-
6157
</project>

dubbo-rpc/dubbo-rpc-http/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/com/alibaba/dubbo/rpc/protocol/http/HttpRemoteInvocation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import org.aopalliance.intercept.MethodInvocation;
2020

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

2525
public HttpRemoteInvocation(MethodInvocation methodInvocation) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.dubbo.rpc.protocol.httpinvoker;
18+
19+
import org.apache.dubbo.common.URL;
20+
import org.apache.dubbo.common.utils.StringUtils;
21+
import org.apache.dubbo.common.Version;
22+
import org.apache.dubbo.remoting.Constants;
23+
import org.apache.dubbo.remoting.http.HttpBinder;
24+
import org.apache.dubbo.remoting.http.HttpHandler;
25+
import org.apache.dubbo.remoting.http.HttpServer;
26+
import org.apache.dubbo.rpc.RpcContext;
27+
import org.apache.dubbo.rpc.RpcException;
28+
import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
29+
import org.apache.dubbo.rpc.service.GenericService;
30+
import org.apache.dubbo.rpc.support.ProtocolUtils;
31+
32+
import org.aopalliance.intercept.MethodInvocation;
33+
import org.springframework.remoting.RemoteAccessException;
34+
import org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor;
35+
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
36+
import org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter;
37+
import org.springframework.remoting.httpinvoker.SimpleHttpInvokerRequestExecutor;
38+
import org.springframework.remoting.support.RemoteInvocation;
39+
import org.springframework.remoting.support.RemoteInvocationFactory;
40+
41+
import javax.servlet.ServletException;
42+
import javax.servlet.http.HttpServletRequest;
43+
import javax.servlet.http.HttpServletResponse;
44+
import java.io.IOException;
45+
import java.net.HttpURLConnection;
46+
import java.net.SocketTimeoutException;
47+
import java.util.Map;
48+
import java.util.concurrent.ConcurrentHashMap;
49+
50+
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT;
51+
import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY;
52+
import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
53+
import static org.apache.dubbo.remoting.Constants.DUBBO_VERSION_KEY;
54+
import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
55+
56+
/**
57+
* HttpInvokerProtocol
58+
*/
59+
public class HttpInvokerProtocol extends AbstractProxyProtocol {
60+
61+
public static final int DEFAULT_PORT = 80;
62+
63+
private final Map<String, HttpServer> serverMap = new ConcurrentHashMap<String, HttpServer>();
64+
65+
private final Map<String, HttpInvokerServiceExporter> skeletonMap = new ConcurrentHashMap<String, HttpInvokerServiceExporter>();
66+
67+
private HttpBinder httpBinder;
68+
69+
public HttpInvokerProtocol() {
70+
super(RemoteAccessException.class);
71+
}
72+
73+
public void setHttpBinder(HttpBinder httpBinder) {
74+
this.httpBinder = httpBinder;
75+
}
76+
77+
@Override
78+
public int getDefaultPort() {
79+
return DEFAULT_PORT;
80+
}
81+
82+
@Override
83+
protected <T> Runnable doExport(final T impl, Class<T> type, URL url) throws RpcException {
84+
String addr = getAddr(url);
85+
HttpServer server = serverMap.get(addr);
86+
if (server == null) {
87+
server = httpBinder.bind(url, new InternalHandler());
88+
serverMap.put(addr, server);
89+
}
90+
final String path = url.getAbsolutePath();
91+
skeletonMap.put(path, createExporter(impl, type));
92+
93+
final String genericPath = path + "/" + GENERIC_KEY;
94+
95+
skeletonMap.put(genericPath, createExporter(impl, GenericService.class));
96+
return new Runnable() {
97+
@Override
98+
public void run() {
99+
skeletonMap.remove(path);
100+
skeletonMap.remove(genericPath);
101+
}
102+
};
103+
}
104+
105+
private <T> HttpInvokerServiceExporter createExporter(T impl, Class<?> type) {
106+
final HttpInvokerServiceExporter httpServiceExporter = new HttpInvokerServiceExporter();
107+
httpServiceExporter.setServiceInterface(type);
108+
httpServiceExporter.setService(impl);
109+
try {
110+
httpServiceExporter.afterPropertiesSet();
111+
} catch (Exception e) {
112+
throw new RpcException(e.getMessage(), e);
113+
}
114+
return httpServiceExporter;
115+
}
116+
117+
@Override
118+
@SuppressWarnings("unchecked")
119+
protected <T> T doRefer(final Class<T> serviceType, final URL url) throws RpcException {
120+
final String generic = url.getParameter(GENERIC_KEY);
121+
final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);
122+
123+
final HttpInvokerProxyFactoryBean httpProxyFactoryBean = new HttpInvokerProxyFactoryBean();
124+
httpProxyFactoryBean.setRemoteInvocationFactory(new RemoteInvocationFactory() {
125+
@Override
126+
public RemoteInvocation createRemoteInvocation(MethodInvocation methodInvocation) {
127+
RemoteInvocation invocation;
128+
/*
129+
package was renamed to 'org.apache.dubbo' in v2.7.0, so only provider versions after v2.7.0 can
130+
recognize org.apache.xxx.HttpRemoteInvocation'.
131+
*/
132+
if (Version.isRelease270OrHigher(url.getParameter(RELEASE_KEY))) {
133+
invocation = new HttpRemoteInvocation(methodInvocation);
134+
} else {
135+
/*
136+
The customized 'com.alibaba.dubbo.rpc.protocol.http.HttpRemoteInvocation' was firstly introduced
137+
in v2.6.3. The main purpose is to support transformation of attachments in HttpInvokerProtocol, see
138+
https://github.com/apache/dubbo/pull/1827. To guarantee interoperability with lower
139+
versions, we need to check if the provider is v2.6.3 or higher before sending customized
140+
HttpRemoteInvocation.
141+
*/
142+
if (Version.isRelease263OrHigher(url.getParameter(DUBBO_VERSION_KEY))) {
143+
invocation = new com.alibaba.dubbo.rpc.protocol.http.HttpRemoteInvocation(methodInvocation);
144+
} else {
145+
invocation = new RemoteInvocation(methodInvocation);
146+
}
147+
}
148+
if (isGeneric) {
149+
invocation.addAttribute(GENERIC_KEY, generic);
150+
}
151+
return invocation;
152+
}
153+
});
154+
155+
String key = url.toIdentityString();
156+
if (isGeneric) {
157+
key = key + "/" + GENERIC_KEY;
158+
}
159+
160+
httpProxyFactoryBean.setServiceUrl(key.replace("http-invoker","http"));
161+
httpProxyFactoryBean.setServiceInterface(serviceType);
162+
String client = url.getParameter(Constants.CLIENT_KEY);
163+
if (StringUtils.isEmpty(client) || "simple".equals(client)) {
164+
SimpleHttpInvokerRequestExecutor httpInvokerRequestExecutor = new SimpleHttpInvokerRequestExecutor() {
165+
@Override
166+
protected void prepareConnection(HttpURLConnection con,
167+
int contentLength) throws IOException {
168+
super.prepareConnection(con, contentLength);
169+
con.setReadTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT));
170+
con.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));
171+
}
172+
};
173+
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
174+
} else if ("commons".equals(client)) {
175+
HttpComponentsHttpInvokerRequestExecutor httpInvokerRequestExecutor = new HttpComponentsHttpInvokerRequestExecutor();
176+
httpInvokerRequestExecutor.setReadTimeout(url.getParameter(TIMEOUT_KEY, DEFAULT_TIMEOUT));
177+
httpInvokerRequestExecutor.setConnectTimeout(url.getParameter(Constants.CONNECT_TIMEOUT_KEY, Constants.DEFAULT_CONNECT_TIMEOUT));
178+
httpProxyFactoryBean.setHttpInvokerRequestExecutor(httpInvokerRequestExecutor);
179+
} else {
180+
throw new IllegalStateException("Unsupported http protocol client " + client + ", only supported: simple, commons");
181+
}
182+
httpProxyFactoryBean.afterPropertiesSet();
183+
return (T) httpProxyFactoryBean.getObject();
184+
}
185+
186+
@Override
187+
protected int getErrorCode(Throwable e) {
188+
if (e instanceof RemoteAccessException) {
189+
e = e.getCause();
190+
}
191+
if (e != null) {
192+
Class<?> cls = e.getClass();
193+
if (SocketTimeoutException.class.equals(cls)) {
194+
return RpcException.TIMEOUT_EXCEPTION;
195+
} else if (IOException.class.isAssignableFrom(cls)) {
196+
return RpcException.NETWORK_EXCEPTION;
197+
} else if (ClassNotFoundException.class.isAssignableFrom(cls)) {
198+
return RpcException.SERIALIZATION_EXCEPTION;
199+
}
200+
}
201+
return super.getErrorCode(e);
202+
}
203+
204+
private class InternalHandler implements HttpHandler {
205+
206+
@Override
207+
public void handle(HttpServletRequest request, HttpServletResponse response)
208+
throws IOException, ServletException {
209+
String uri = request.getRequestURI();
210+
HttpInvokerServiceExporter skeleton = skeletonMap.get(uri);
211+
if (!"POST".equalsIgnoreCase(request.getMethod())) {
212+
response.setStatus(500);
213+
} else {
214+
RpcContext.getContext().setRemoteAddress(request.getRemoteAddr(), request.getRemotePort());
215+
try {
216+
skeleton.handleRequest(request, response);
217+
} catch (Throwable e) {
218+
throw new ServletException(e);
219+
}
220+
}
221+
}
222+
223+
}
224+
225+
}

dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpRemoteInvocation.java dubbo-rpc/dubbo-rpc-http-invoker/src/main/java/org/apache/dubbo/rpc/protocol/httpinvoker/HttpRemoteInvocation.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
package org.apache.dubbo.rpc.protocol.http;
18+
package org.apache.dubbo.rpc.protocol.httpinvoker;
1919

2020
import org.apache.dubbo.common.utils.StringUtils;
2121
import org.apache.dubbo.rpc.RpcContext;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
http-invoker=org.apache.dubbo.rpc.protocol.httpinvoker.HttpInvokerProtocol

0 commit comments

Comments
 (0)