remove the remoting-http (#14082)

This commit is contained in:
王聪洋 2024-05-06 14:55:41 +08:00 committed by GitHub
parent 10af737925
commit 583b57be2b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
43 changed files with 0 additions and 2770 deletions

View File

@ -76,7 +76,6 @@ dubbo-registry-nacos
dubbo-registry-zookeeper
dubbo-remoting
dubbo-remoting-api
dubbo-remoting-http
dubbo-remoting-http12
dubbo-remoting-netty
dubbo-remoting-netty4

View File

@ -133,11 +133,6 @@
<artifactId>dubbo-filter-validation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>

View File

@ -133,12 +133,6 @@
<artifactId>dubbo-filter-validation</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>

View File

@ -729,9 +729,6 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.ChannelHandler</resource>
</transformer>
@ -762,9 +759,6 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.HttpBinder</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory</resource>
</transformer>

View File

@ -343,13 +343,6 @@
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-http</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-http12</artifactId>
@ -553,7 +546,6 @@
<include>org.apache.dubbo:dubbo-registry-nacos</include>
<include>org.apache.dubbo:dubbo-registry-zookeeper</include>
<include>org.apache.dubbo:dubbo-remoting-api</include>
<include>org.apache.dubbo:dubbo-remoting-http</include>
<include>org.apache.dubbo:dubbo-remoting-http12</include>
<include>org.apache.dubbo:dubbo-remoting-netty4</include>
<include>org.apache.dubbo:dubbo-remoting-netty</include>
@ -784,9 +776,6 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.ChannelHandler</resource>
</transformer>
@ -817,9 +806,6 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.HttpBinder</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory</resource>
</transformer>

View File

@ -345,9 +345,6 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.rpc.protocol.rest.annotation.param.parse.consumer.BaseConsumerParamParser</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.factory.RestClientFactory</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.ChannelHandler</resource>
</transformer>
@ -378,9 +375,6 @@
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.exchange.Exchanger</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http.HttpBinder</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/dubbo/internal/org.apache.dubbo.remoting.http12.message.HttpMessageEncoderFactory</resource>
</transformer>

View File

@ -1,85 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<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>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>dubbo-remoting-http</artifactId>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>The http remoting module of dubbo project</description>
<properties>
<skip_maven_deploy>false</skip_maven_deploy>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>fluent-hc</artifactId>
<version>4.5.14</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,41 +0,0 @@
/*
* 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.remoting.http;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
public abstract class BaseRestClient<CLIENT> implements RestClient {
protected CLIENT client;
protected HttpClientConfig clientConfig;
public BaseRestClient(HttpClientConfig clientConfig) {
this.clientConfig = clientConfig;
client = createHttpClient(clientConfig);
}
protected abstract CLIENT createHttpClient(HttpClientConfig clientConfig);
public HttpClientConfig getClientConfig() {
return clientConfig;
}
public CLIENT getClient() {
return client;
}
}

View File

@ -1,39 +0,0 @@
/*
* 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.remoting.http;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.remoting.Constants;
/**
* HttpBinder
*/
@SPI(value = "jetty", scope = ExtensionScope.FRAMEWORK)
public interface HttpBinder {
/**
* bind the server.
*
* @param url server url.
* @return server.
*/
@Adaptive({Constants.SERVER_KEY})
HttpServer bind(URL url, HttpHandler handler);
}

View File

@ -1,34 +0,0 @@
/*
* 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.remoting.http;
import java.io.IOException;
/**
* http invocation handler.
*/
public interface HttpHandler<REQUEST, RESPONSE> {
/**
* invoke.
*
* @param request request.
* @param response response.
* @throws IOException
*/
void handle(REQUEST request, RESPONSE response) throws IOException;
}

View File

@ -1,71 +0,0 @@
/*
* 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.remoting.http;
import org.apache.dubbo.common.Resetable;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.RemotingServer;
import java.net.InetSocketAddress;
public interface HttpServer extends Resetable, RemotingServer {
/**
* 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();
}

View File

@ -1,299 +0,0 @@
/*
* 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.remoting.http;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.rpc.Invocation;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class RequestTemplate implements Serializable {
private static final long serialVersionUID = 1L;
public static final String CONTENT_ENCODING = "Content-Encoding";
private static final String CONTENT_LENGTH = "Content-Length";
public static final String ENCODING_GZIP = "gzip";
public static final String ENCODING_DEFLATE = "deflate";
private static final List<String> EMPTY_ARRAYLIST = new ArrayList<>();
private final Map<String, Collection<String>> queries = new LinkedHashMap<>();
private final Map<String, Collection<String>> headers = new LinkedHashMap<>();
private String httpMethod;
private String path;
private String address;
private Object body;
private byte[] byteBody = new byte[0];
private String protocol = "http://";
private final Invocation invocation;
private String contextPath = "";
private Class<?> bodyType;
public RequestTemplate(Invocation invocation, String httpMethod, String address) {
this(invocation, httpMethod, address, "");
}
public RequestTemplate(Invocation invocation, String httpMethod, String address, String contextPath) {
this.httpMethod = httpMethod;
this.address = address;
this.invocation = invocation;
this.contextPath = contextPath;
}
public String getURL() {
StringBuilder stringBuilder = new StringBuilder(getProtocol() + address);
stringBuilder.append(getUri());
return stringBuilder.toString();
}
public String getUri() {
StringBuilder stringBuilder = new StringBuilder(getContextPath() + path);
return stringBuilder.append(getQueryString()).toString();
}
public String getQueryString() {
if (queries.isEmpty()) {
return "";
}
StringBuilder queryBuilder = new StringBuilder("?");
for (String field : queries.keySet()) {
Collection<String> queryValues = queries.get(field);
if (queryValues == null || queryValues.isEmpty()) {
continue;
}
for (String value : queryValues) {
queryBuilder.append('&');
queryBuilder.append(field);
if (value == null) {
continue;
}
queryBuilder.append('=');
queryBuilder.append(value);
}
}
return queryBuilder.toString().replace("?&", "?");
}
public RequestTemplate path(String path) {
this.path = path;
return this;
}
public String getHttpMethod() {
return httpMethod;
}
public RequestTemplate httpMethod(String httpMethod) {
this.httpMethod = httpMethod;
return this;
}
public byte[] getSerializedBody() {
return byteBody;
}
public void serializeBody(byte[] body) {
addHeader(CONTENT_LENGTH, body.length); // must header
this.byteBody = body;
}
public boolean isBodyEmpty() {
return getUnSerializedBody() == null;
}
public RequestTemplate body(Object body, Class bodyType) {
this.body = body;
setBodyType(bodyType);
return this;
}
public Object getUnSerializedBody() {
return body;
}
public Map<String, Collection<String>> getAllHeaders() {
return headers;
}
public Collection<String> getHeaders(String name) {
return headers.get(name);
}
public String getHeader(String name) {
if (headers.containsKey(name)) {
Collection<String> headers = getHeaders(name);
if (headers.isEmpty()) {
return null;
}
String[] strings = headers.toArray(new String[0]);
return strings[0];
} else {
return null;
}
}
public Collection<String> getEncodingValues() {
if (headers.containsKey(CONTENT_ENCODING)) {
return headers.get(CONTENT_ENCODING);
}
return EMPTY_ARRAYLIST;
}
public boolean isGzipEncodedRequest() {
return getEncodingValues().contains(ENCODING_GZIP);
}
public boolean isDeflateEncodedRequest() {
return getEncodingValues().contains(ENCODING_DEFLATE);
}
public void addHeader(String key, String value) {
addValueByKey(key, value, this.headers);
}
public void addHeader(String key, Object value) {
addValueByKey(key, String.valueOf(value), this.headers);
}
public void addKeepAliveHeader(int time) {
addHeader(Constants.KEEP_ALIVE_HEADER, time);
addHeader(Constants.CONNECTION, Constants.KEEP_ALIVE);
}
public void addHeaders(String key, Collection<String> values) {
Collection<String> header = getHeaders(key);
if (header == null) {
header = new HashSet<>();
this.headers.put(key, header);
}
header.addAll(values);
}
public void addParam(String key, String value) {
addValueByKey(key, value, this.queries);
}
public void addParam(String key, Object value) {
addParam(key, String.valueOf(value));
}
public Map<String, Collection<String>> getQueries() {
return queries;
}
public Collection<String> getParam(String key) {
return getQueries().get(key);
}
public void addParams(String key, Collection<String> values) {
Collection<String> params = getParam(key);
if (params == null) {
params = new HashSet<>();
this.queries.put(key, params);
}
params.addAll(values);
}
public void addValueByKey(String key, String value, Map<String, Collection<String>> maps) {
if (value == null) {
return;
}
Collection<String> values = null;
if (!maps.containsKey(key)) {
values = new HashSet<>();
maps.put(key, values);
}
values = maps.get(key);
values.add(value);
}
public Integer getContentLength() {
if (!getAllHeaders().containsKey(CONTENT_LENGTH)) {
return null;
}
HashSet<String> strings = (HashSet<String>) getAllHeaders().get(CONTENT_LENGTH);
return Integer.parseInt(new ArrayList<>(strings).get(0));
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
addHeader("Host", address); // must header
this.address = address;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public Invocation getInvocation() {
return invocation;
}
public String getContextPath() {
if (contextPath == null || contextPath.length() == 0) {
return "";
}
if (contextPath.startsWith("/")) {
return contextPath;
} else {
return "/" + contextPath;
}
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
public Class<?> getBodyType() {
return bodyType;
}
public void setBodyType(Class<?> bodyType) {
this.bodyType = bodyType;
}
}

View File

@ -1,48 +0,0 @@
/*
* 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.remoting.http;
import org.apache.dubbo.remoting.RemotingException;
import java.util.concurrent.CompletableFuture;
public interface RestClient {
/**
* send message.
*
* @param message
* @throws RemotingException
*/
CompletableFuture<RestResult> send(RequestTemplate message);
/**
* close the channel.
*/
void close();
/**
* Graceful close the channel.
*/
void close(int timeout);
/**
* is closed.
*
* @return closed
*/
boolean isClosed();
}

View File

@ -1,42 +0,0 @@
/*
* 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.remoting.http;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* rest response facade
*/
public interface RestResult {
String getContentType();
byte[] getBody() throws IOException;
Map<String, List<String>> headers();
byte[] getErrorResponse() throws IOException;
int getResponseCode() throws IOException;
String getMessage() throws IOException;
default String appendErrorMessage(String message, String errorInfo) {
return message + "\n error info is: " + errorInfo;
}
}

View File

@ -1,60 +0,0 @@
/*
* 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.remoting.http.config;
public class HttpClientConfig {
private int readTimeout = 6 * 1000;
private int writeTimeout = 6 * 1000;
private int connectTimeout = 6 * 1000;
private int chunkLength = 8196;
private int HTTP_CLIENT_CONNECTION_MANAGER_MAX_PER_ROUTE = 20;
private int HTTP_CLIENT_CONNECTION_MANAGER_MAX_TOTAL = 20;
private int HTTPCLIENT_KEEP_ALIVE_DURATION = 30 * 1000;
private int HTTP_CLIENT_CONNECTION_MANAGER_CLOSE_WAIT_TIME_MS = 1000;
private int HTTP_CLIENT_CONNECTION_MANAGER_CLOSE_IDLE_TIME_S = 30;
public HttpClientConfig() {}
public int getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
}
public int getWriteTimeout() {
return writeTimeout;
}
public void setWriteTimeout(int writeTimeout) {
this.writeTimeout = writeTimeout;
}
public int getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
}
public int getChunkLength() {
return chunkLength;
}
}

View File

@ -1,63 +0,0 @@
/*
* 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.remoting.http.factory;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
import org.apache.dubbo.rpc.RpcException;
/**
* AbstractHttpClientFactory
*/
public abstract class AbstractHttpClientFactory implements RestClientFactory {
protected final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(getClass());
// TODO load config
protected HttpClientConfig httpClientConfig = new HttpClientConfig();
//////////////////////////////////////// implements start ///////////////////////////////////////////////
@Override
public RestClient createRestClient(URL url) throws RpcException {
beforeCreated(url);
// create a raw client
RestClient restClient = doCreateRestClient(url);
// postprocessor
afterCreated(restClient);
return restClient;
}
//////////////////////////////////////// implements end ///////////////////////////////////////////////
//////////////////////////////////////// inner methods ///////////////////////////////////////////////
protected void beforeCreated(URL url) {}
protected abstract RestClient doCreateRestClient(URL url) throws RpcException;
protected void afterCreated(RestClient client) {}
//////////////////////////////////////// inner methods ///////////////////////////////////////////////
}

View File

@ -1,35 +0,0 @@
/*
* 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.remoting.http.factory;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Adaptive;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.rpc.RpcException;
/**
* RestClientFactory. (API/SPI, Singleton, ThreadSafe)
*/
@SPI(value = Constants.OK_HTTP, scope = ExtensionScope.FRAMEWORK)
public interface RestClientFactory {
@Adaptive({Constants.CLIENT_KEY})
RestClient createRestClient(URL url) throws RpcException;
}

View File

@ -1,35 +0,0 @@
/*
* 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.remoting.http.factory.impl;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.factory.AbstractHttpClientFactory;
import org.apache.dubbo.remoting.http.restclient.HttpClientRestClient;
import org.apache.dubbo.rpc.RpcException;
@Activate(Constants.APACHE_HTTP_CLIENT)
public class ApacheHttpClientFactory extends AbstractHttpClientFactory {
@Override
protected RestClient doCreateRestClient(URL url) throws RpcException {
return new HttpClientRestClient(httpClientConfig);
}
}

View File

@ -1,35 +0,0 @@
/*
* 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.remoting.http.factory.impl;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.factory.AbstractHttpClientFactory;
import org.apache.dubbo.remoting.http.restclient.OKHttpRestClient;
import org.apache.dubbo.rpc.RpcException;
@Activate(Constants.OK_HTTP)
public class OkHttpClientFactory extends AbstractHttpClientFactory {
@Override
protected RestClient doCreateRestClient(URL url) throws RpcException {
return new OKHttpRestClient(httpClientConfig);
}
}

View File

@ -1,35 +0,0 @@
/*
* 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.remoting.http.factory.impl;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.factory.AbstractHttpClientFactory;
import org.apache.dubbo.remoting.http.restclient.URLConnectionRestClient;
import org.apache.dubbo.rpc.RpcException;
@Activate(Constants.URL_CONNECTION)
public class URLConnectionClientFactory extends AbstractHttpClientFactory {
@Override
protected RestClient doCreateRestClient(URL url) throws RpcException {
return new URLConnectionRestClient(httpClientConfig);
}
}

View File

@ -1,33 +0,0 @@
/*
* 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.remoting.http.jetty;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.http.HttpBinder;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
/**
* JettyHttpTransporter
*/
public class JettyHttpBinder implements HttpBinder {
@Override
public HttpServer bind(URL url, HttpHandler handler) {
return new JettyHttpServer(url, handler);
}
}

View File

@ -1,113 +0,0 @@
/*
* 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.remoting.http.jetty;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.servlet.DispatcherServlet;
import org.apache.dubbo.remoting.http.servlet.ServletManager;
import org.apache.dubbo.remoting.http.support.AbstractHttpServer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREADS;
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_FAILED_STOP_HTTP_SERVER;
public class JettyHttpServer extends AbstractHttpServer {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(JettyHttpServer.class);
private Server server;
private URL url;
public JettyHttpServer(URL url, final HttpHandler handler) {
super(url, handler);
this.url = url;
// set dubbo's logger
System.setProperty("org.eclipse.jetty.util.log.class", JettyLoggerAdapter.class.getName());
DispatcherServlet.addHttpHandler(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()), handler);
int threads = url.getParameter(THREADS_KEY, DEFAULT_THREADS);
QueuedThreadPool threadPool = new QueuedThreadPool();
threadPool.setDaemon(true);
threadPool.setMaxThreads(threads);
threadPool.setMinThreads(threads);
server = new Server(threadPool);
ServerConnector connector = new ServerConnector(server);
String bindIp = url.getParameter(Constants.BIND_IP_KEY, url.getHost());
if (!url.isAnyHost() && NetUtils.isValidLocalHost(bindIp)) {
connector.setHost(bindIp);
}
connector.setPort(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()));
server.addConnector(connector);
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);
// TODO Context.SESSIONS is the best option here? (In jetty 9.x, it becomes ServletContextHandler.SESSIONS)
ServletContextHandler context = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);
context.setServletHandler(servletHandler);
ServletManager.getInstance()
.addServletContext(
url.getParameter(Constants.BIND_PORT_KEY, url.getPort()), context.getServletContext());
try {
server.start();
} catch (Exception e) {
throw new IllegalStateException(
"Failed to start jetty server on " + url.getParameter(Constants.BIND_IP_KEY) + ":"
+ url.getParameter(Constants.BIND_PORT_KEY) + ", cause: " + e.getMessage(),
e);
}
}
@Override
public void close() {
super.close();
//
ServletManager.getInstance().removeServletContext(url.getParameter(Constants.BIND_PORT_KEY, url.getPort()));
if (server != null) {
try {
server.stop();
} catch (Exception e) {
logger.warn(COMMON_FAILED_STOP_HTTP_SERVER, "", "", e.getMessage(), e);
}
}
}
}

View File

@ -1,161 +0,0 @@
/*
* 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.remoting.http.jetty;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.eclipse.jetty.util.log.AbstractLogger;
import org.eclipse.jetty.util.log.Logger;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_UNEXPECTED_EXCEPTION;
/**
* logger adapter for jetty
*/
public class JettyLoggerAdapter extends AbstractLogger {
protected String name;
private final ErrorTypeAwareLogger logger;
private static boolean debugEnabled = false;
public JettyLoggerAdapter() {
this("org.apache.dubbo.remoting.http.jetty");
}
public JettyLoggerAdapter(Class<?> clazz) {
this(clazz.getName());
}
public JettyLoggerAdapter(String name) {
this.name = name;
this.logger = LoggerFactory.getErrorTypeAwareLogger(name);
}
@Override
protected Logger newLogger(String name) {
return new JettyLoggerAdapter(name);
}
@Override
public String getName() {
return this.name;
}
@Override
public void warn(String msg, Object... objects) {
if (logger.isWarnEnabled()) {
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", this.format(msg, objects));
}
}
@Override
public void warn(Throwable throwable) {
if (logger.isWarnEnabled()) {
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", throwable.getMessage(), throwable);
}
}
@Override
public void warn(String msg, Throwable throwable) {
if (logger.isWarnEnabled()) {
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", msg, throwable);
}
}
@Override
public void info(String msg, Object... objects) {
if (logger.isInfoEnabled()) {
logger.info(this.format(msg, objects));
}
}
@Override
public void info(Throwable throwable) {
if (logger.isInfoEnabled()) {
logger.info(throwable);
}
}
@Override
public void info(String msg, Throwable throwable) {
if (logger.isInfoEnabled()) {
logger.info(msg, throwable);
}
}
@Override
public boolean isDebugEnabled() {
return debugEnabled;
}
@Override
public void setDebugEnabled(boolean enabled) {
debugEnabled = enabled;
}
@Override
public void debug(String msg, Object... objects) {
if (debugEnabled && logger.isDebugEnabled()) {
logger.debug(this.format(msg, objects));
}
}
@Override
public void debug(Throwable throwable) {
if (debugEnabled && logger.isDebugEnabled()) {
logger.debug(throwable);
}
}
@Override
public void debug(String msg, Throwable throwable) {
if (debugEnabled && logger.isDebugEnabled()) {
logger.debug(msg, throwable);
}
}
@Override
public void ignore(Throwable throwable) {
if (logger.isWarnEnabled()) {
logger.warn(COMMON_UNEXPECTED_EXCEPTION, "", "", "IGNORED EXCEPTION ", throwable);
}
}
private String format(String msg, Object... args) {
msg = String.valueOf(msg); // Avoids NPE
String braces = "{}";
StringBuilder builder = new StringBuilder();
int start = 0;
for (Object arg : args) {
int bracesIndex = msg.indexOf(braces, start);
if (bracesIndex < 0) {
builder.append(msg.substring(start));
builder.append(' ');
builder.append(arg);
start = msg.length();
} else {
builder.append(msg, start, bracesIndex);
builder.append(arg);
start = bracesIndex + braces.length();
}
}
builder.append(msg.substring(start));
return builder.toString();
}
}

View File

@ -1,188 +0,0 @@
/*
* 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.remoting.http.restclient;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
import org.apache.http.client.methods.HttpOptions;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
public class HttpClientRestClient implements RestClient {
private final CloseableHttpClient closeableHttpClient;
private final HttpClientConfig httpClientConfig;
public HttpClientRestClient(HttpClientConfig clientConfig) {
closeableHttpClient = createHttpClient();
httpClientConfig = clientConfig;
}
@Override
public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {
HttpRequestBase httpRequest = null;
String httpMethod = requestTemplate.getHttpMethod();
httpRequest = createHttpUriRequest(httpMethod, requestTemplate);
if (httpRequest instanceof HttpEntityEnclosingRequest) {
((HttpEntityEnclosingRequestBase) httpRequest)
.setEntity(new ByteArrayEntity(requestTemplate.getSerializedBody()));
}
Map<String, Collection<String>> allHeaders = requestTemplate.getAllHeaders();
allHeaders.remove("Content-Length");
// header
for (String headerName : allHeaders.keySet()) {
Collection<String> headerValues = allHeaders.get(headerName);
for (String headerValue : headerValues) {
httpRequest.addHeader(headerName, headerValue);
}
}
httpRequest.setConfig(getRequestConfig(httpClientConfig));
CompletableFuture<RestResult> future = new CompletableFuture<>();
try {
CloseableHttpResponse response = closeableHttpClient.execute(httpRequest);
future.complete(new RestResult() {
@Override
public String getContentType() {
Header header = response.getFirstHeader("Content-Type");
return header == null ? null : header.getValue();
}
@Override
public byte[] getBody() throws IOException {
if (response.getEntity() == null) {
return new byte[0];
}
return IOUtils.toByteArray(response.getEntity().getContent());
}
@Override
public Map<String, List<String>> headers() {
return Arrays.stream(response.getAllHeaders())
.collect(Collectors.toMap(Header::getName, h -> Collections.singletonList(h.getValue())));
}
@Override
public byte[] getErrorResponse() throws IOException {
return getBody();
}
@Override
public int getResponseCode() {
return response.getStatusLine().getStatusCode();
}
@Override
public String getMessage() throws IOException {
return appendErrorMessage(
response.getStatusLine().getReasonPhrase(), new String(getErrorResponse()));
}
});
} catch (IOException e) {
future.completeExceptionally(e);
}
return future;
}
private RequestConfig getRequestConfig(HttpClientConfig clientConfig) {
// TODO config
return RequestConfig.custom().build();
}
@Override
public void close() {
try {
closeableHttpClient.close();
} catch (IOException e) {
}
}
@Override
public void close(int timeout) {}
@Override
public boolean isClosed() {
// TODO close judge
return true;
}
public CloseableHttpClient createHttpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
return HttpClients.custom().setConnectionManager(connectionManager).build();
}
protected HttpRequestBase createHttpUriRequest(String httpMethod, RequestTemplate requestTemplate) {
String uri = requestTemplate.getURL();
HttpRequestBase httpUriRequest = null;
if (HttpGet.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpGet(uri);
} else if (HttpHead.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpHead(uri);
} else if (HttpPost.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpPost(uri);
} else if (HttpPut.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpPut(uri);
} else if (HttpPatch.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpPatch(uri);
} else if (HttpDelete.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpDelete(uri);
} else if (HttpOptions.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpOptions(uri);
} else if (HttpTrace.METHOD_NAME.equals(httpMethod)) {
httpUriRequest = new HttpTrace(uri);
} else {
throw new IllegalArgumentException("Invalid HTTP method: " + httpMethod);
}
return httpUriRequest;
}
}

View File

@ -1,150 +0,0 @@
/*
* 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.remoting.http.restclient;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.internal.http.HttpMethod;
// TODO add version 4.0 implements ,and default version is < 4.0,for dependency conflict
public class OKHttpRestClient implements RestClient {
private final OkHttpClient okHttpClient;
private final HttpClientConfig httpClientConfig;
public OKHttpRestClient(HttpClientConfig clientConfig) {
this.okHttpClient = createHttpClient(clientConfig);
this.httpClientConfig = clientConfig;
}
@Override
public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {
Request.Builder builder = new Request.Builder();
// url
builder.url(requestTemplate.getURL());
Map<String, Collection<String>> allHeaders = requestTemplate.getAllHeaders();
boolean hasBody = false;
RequestBody requestBody = null;
// GET & HEAD body is forbidden
if (HttpMethod.permitsRequestBody(requestTemplate.getHttpMethod())) {
requestBody = RequestBody.create(null, requestTemplate.getSerializedBody());
hasBody = true;
}
// header
for (String headerName : allHeaders.keySet()) {
Collection<String> headerValues = allHeaders.get(headerName);
if (!hasBody && "Content-Length".equals(headerName)) {
continue;
}
for (String headerValue : headerValues) {
builder.addHeader(headerName, headerValue);
}
}
builder.method(requestTemplate.getHttpMethod(), requestBody);
CompletableFuture<RestResult> future = new CompletableFuture<>();
okHttpClient.newCall(builder.build()).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
future.completeExceptionally(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
future.complete(new RestResult() {
@Override
public String getContentType() {
return response.header("Content-Type");
}
@Override
public byte[] getBody() throws IOException {
ResponseBody body = response.body();
return body == null ? null : body.bytes();
}
@Override
public Map<String, List<String>> headers() {
return response.headers().toMultimap();
}
@Override
public byte[] getErrorResponse() throws IOException {
return getBody();
}
@Override
public int getResponseCode() throws IOException {
return response.code();
}
@Override
public String getMessage() throws IOException {
return appendErrorMessage(response.message(), new String(getBody()));
}
});
}
});
return future;
}
@Override
public void close() {
okHttpClient.connectionPool().evictAll();
}
@Override
public void close(int timeout) {}
@Override
public boolean isClosed() {
return okHttpClient.retryOnConnectionFailure();
}
public OkHttpClient createHttpClient(HttpClientConfig httpClientConfig) {
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(httpClientConfig.getReadTimeout(), TimeUnit.SECONDS)
.writeTimeout(httpClientConfig.getWriteTimeout(), TimeUnit.SECONDS)
.connectTimeout(httpClientConfig.getConnectTimeout(), TimeUnit.SECONDS)
.build();
return client;
}
}

View File

@ -1,170 +0,0 @@
/*
* 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.remoting.http.restclient;
import org.apache.dubbo.remoting.http.RequestTemplate;
import org.apache.dubbo.remoting.http.RestClient;
import org.apache.dubbo.remoting.http.RestResult;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.io.IOUtils;
public class URLConnectionRestClient implements RestClient {
private final HttpClientConfig clientConfig;
public URLConnectionRestClient(HttpClientConfig clientConfig) {
this.clientConfig = clientConfig;
}
@Override
public CompletableFuture<RestResult> send(RequestTemplate requestTemplate) {
CompletableFuture<RestResult> future = new CompletableFuture<>();
try {
HttpURLConnection connection = (HttpURLConnection) new URL(requestTemplate.getURL()).openConnection();
connection.setConnectTimeout(clientConfig.getConnectTimeout());
connection.setReadTimeout(clientConfig.getReadTimeout());
connection.setRequestMethod(requestTemplate.getHttpMethod());
prepareConnection(connection, requestTemplate.getHttpMethod());
// writeHeaders
for (String field : requestTemplate.getAllHeaders().keySet()) {
for (String value : requestTemplate.getHeaders(field)) {
connection.addRequestProperty(field, value);
}
}
// writeBody
boolean gzipEncodedRequest = requestTemplate.isGzipEncodedRequest();
boolean deflateEncodedRequest = requestTemplate.isDeflateEncodedRequest();
if (requestTemplate.isBodyEmpty()) {
future.complete(getRestResultFromConnection(connection));
return future;
}
Integer contentLength = requestTemplate.getContentLength();
if (contentLength != null) {
connection.setFixedLengthStreamingMode(contentLength);
} else {
connection.setChunkedStreamingMode(clientConfig.getChunkLength());
}
OutputStream out = connection.getOutputStream();
if (gzipEncodedRequest) {
out = new GZIPOutputStream(out);
} else if (deflateEncodedRequest) {
out = new DeflaterOutputStream(out);
}
try {
out.write(requestTemplate.getSerializedBody());
} finally {
try {
out.close();
} catch (IOException suppressed) {
}
}
future.complete(getRestResultFromConnection(connection));
} catch (Exception e) {
future.completeExceptionally(e);
}
return future;
}
@Override
public void close() {}
@Override
public void close(int timeout) {}
@Override
public boolean isClosed() {
return true;
}
private RestResult getRestResultFromConnection(HttpURLConnection connection) {
return new RestResult() {
@Override
public String getContentType() {
return connection.getContentType();
}
@Override
public byte[] getBody() throws IOException {
return IOUtils.toByteArray(connection.getInputStream());
}
@Override
public Map<String, List<String>> headers() {
return connection.getHeaderFields();
}
@Override
public byte[] getErrorResponse() throws IOException {
return IOUtils.toByteArray(connection.getErrorStream());
}
@Override
public int getResponseCode() throws IOException {
return connection.getResponseCode();
}
@Override
public String getMessage() throws IOException {
return appendErrorMessage(connection.getResponseMessage(), new String(getErrorResponse()));
}
};
}
private void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
connection.setDoInput(true);
if ("GET".equals(httpMethod)) {
connection.setInstanceFollowRedirects(true);
} else {
connection.setInstanceFollowRedirects(false);
}
if ("POST".equals(httpMethod)
|| "PUT".equals(httpMethod)
|| "PATCH".equals(httpMethod)
|| "DELETE".equals(httpMethod)) {
connection.setDoOutput(true);
} else {
connection.setDoOutput(false);
}
connection.setRequestMethod(httpMethod);
}
}

View File

@ -1,37 +0,0 @@
/*
* 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.remoting.http.servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* This class must be defined before something like spring's ContextLoaderListener in web.xml
*/
public class BootstrapListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletManager.getInstance()
.addServletContext(ServletManager.EXTERNAL_SERVER_PORT, servletContextEvent.getServletContext());
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
ServletManager.getInstance().removeServletContext(ServletManager.EXTERNAL_SERVER_PORT);
}
}

View File

@ -1,65 +0,0 @@
/*
* 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.remoting.http.servlet;
import org.apache.dubbo.remoting.http.HttpHandler;
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;
/**
* Service dispatcher Servlet.
*/
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 5766349180380479888L;
private static final Map<Integer, HttpHandler> HANDLERS = new ConcurrentHashMap<>();
private static DispatcherServlet INSTANCE;
public DispatcherServlet() {
DispatcherServlet.INSTANCE = this;
}
public static void addHttpHandler(int port, HttpHandler processor) {
HANDLERS.put(port, processor);
}
public static void removeHttpHandler(int port) {
HANDLERS.remove(port);
}
public static DispatcherServlet getInstance() {
return INSTANCE;
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpHandler handler = HANDLERS.get(request.getLocalPort());
if (handler == null) { // service not found.
response.sendError(HttpServletResponse.SC_NOT_FOUND, "Service not found.");
} else {
handler.handle(request, response);
}
}
}

View File

@ -1,33 +0,0 @@
/*
* 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.remoting.http.servlet;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.http.HttpBinder;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
/**
* ServletHttpTransporter
*/
public class ServletHttpBinder implements HttpBinder {
@Override
public HttpServer bind(URL url, HttpHandler handler) {
return new ServletHttpServer(url, handler);
}
}

View File

@ -1,30 +0,0 @@
/*
* 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.remoting.http.servlet;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.support.AbstractHttpServer;
public class ServletHttpServer extends AbstractHttpServer {
public ServletHttpServer(URL url, HttpHandler handler) {
super(url, handler);
DispatcherServlet.addHttpHandler(url.getParameter(Constants.BIND_PORT_KEY, 8080), handler);
}
}

View File

@ -1,50 +0,0 @@
/*
* 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.remoting.http.servlet;
import javax.servlet.ServletContext;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* TODO this may not be a pretty elegant solution,
*/
public class ServletManager {
public static final int EXTERNAL_SERVER_PORT = -1234;
private static final ServletManager INSTANCE = new ServletManager();
private final Map<Integer, ServletContext> contextMap = new ConcurrentHashMap<>();
public static ServletManager getInstance() {
return INSTANCE;
}
public void addServletContext(int port, ServletContext servletContext) {
contextMap.put(port, servletContext);
}
public void removeServletContext(int port) {
contextMap.remove(port);
}
public ServletContext getServletContext(int port) {
return contextMap.get(port);
}
}

View File

@ -1,124 +0,0 @@
/*
* 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.remoting.http.support;
import org.apache.dubbo.common.Parameters;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.ChannelHandler;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
import java.net.InetSocketAddress;
import java.util.Collection;
/**
* AbstractHttpServer
*/
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;
}
@Override
public HttpHandler getHttpHandler() {
return handler;
}
@Override
public URL getUrl() {
return url;
}
@Override
public void reset(URL url) {}
@Override
public boolean isBound() {
return true;
}
@Override
public InetSocketAddress getLocalAddress() {
return url.toInetSocketAddress();
}
@Override
public void close() {
closed = true;
}
@Override
public void close(int timeout) {
close();
}
@Override
public boolean isClosed() {
return closed;
}
/**
* Following methods are extended from RemotingServer, useless for http servers
*/
@Override
public boolean canHandleIdle() {
return false;
}
@Override
public Collection<Channel> getChannels() {
return null;
}
@Override
public Channel getChannel(InetSocketAddress remoteAddress) {
return null;
}
@Override
public void reset(Parameters parameters) {}
@Override
public ChannelHandler getChannelHandler() {
return null;
}
@Override
public void send(Object message) throws RemotingException {}
@Override
public void send(Object message, boolean sent) throws RemotingException {}
@Override
public void startClose() {}
}

View File

@ -1,30 +0,0 @@
/*
* 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.remoting.http.tomcat;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.remoting.http.HttpBinder;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
public class TomcatHttpBinder implements HttpBinder {
@Override
public HttpServer bind(URL url, HttpHandler handler) {
return new TomcatHttpServer(url, handler);
}
}

View File

@ -1,100 +0,0 @@
/*
* 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.remoting.http.tomcat;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.ErrorTypeAwareLogger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.utils.SystemPropertyConfigUtils;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.servlet.DispatcherServlet;
import org.apache.dubbo.remoting.http.servlet.ServletManager;
import org.apache.dubbo.remoting.http.support.AbstractHttpServer;
import java.io.File;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_THREADS;
import static org.apache.dubbo.common.constants.CommonConstants.SystemProperty.SYSTEM_JAVA_IO_TMPDIR;
import static org.apache.dubbo.common.constants.CommonConstants.THREADS_KEY;
import static org.apache.dubbo.common.constants.LoggerCodeConstants.COMMON_FAILED_STOP_HTTP_SERVER;
import static org.apache.dubbo.remoting.Constants.ACCEPTS_KEY;
public class TomcatHttpServer extends AbstractHttpServer {
private static final ErrorTypeAwareLogger logger = LoggerFactory.getErrorTypeAwareLogger(TomcatHttpServer.class);
private final Tomcat tomcat;
private final URL url;
public TomcatHttpServer(URL url, final HttpHandler handler) {
super(url, handler);
this.url = url;
DispatcherServlet.addHttpHandler(url.getPort(), handler);
String baseDir = new File(SystemPropertyConfigUtils.getSystemProperty(SYSTEM_JAVA_IO_TMPDIR)).getAbsolutePath();
tomcat = new Tomcat();
Connector connector = tomcat.getConnector();
connector.setPort(url.getPort());
connector.setProperty("maxThreads", String.valueOf(url.getParameter(THREADS_KEY, DEFAULT_THREADS)));
connector.setProperty("maxConnections", String.valueOf(url.getParameter(ACCEPTS_KEY, -1)));
connector.setProperty("URIEncoding", "UTF-8");
connector.setProperty("connectionTimeout", "60000");
connector.setProperty("maxKeepAliveRequests", "-1");
tomcat.setBaseDir(baseDir);
tomcat.setPort(url.getPort());
Context context = tomcat.addContext("/", baseDir);
Tomcat.addServlet(context, "dispatcher", new DispatcherServlet());
// Issue : https://github.com/apache/dubbo/issues/6418
// addServletMapping method will be removed since Tomcat 9
// context.addServletMapping("/*", "dispatcher");
context.addServletMappingDecoded("/*", "dispatcher");
ServletManager.getInstance().addServletContext(url.getPort(), context.getServletContext());
// tell tomcat to fail on startup failures.
System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
try {
tomcat.start();
} catch (LifecycleException e) {
throw new IllegalStateException("Failed to start tomcat server at " + url.getAddress(), e);
}
}
@Override
public void close() {
super.close();
ServletManager.getInstance().removeServletContext(url.getPort());
try {
tomcat.stop();
// close port by destroy()
tomcat.destroy();
} catch (Exception e) {
logger.warn(COMMON_FAILED_STOP_HTTP_SERVER, "", "", e.getMessage(), e);
}
}
}

View File

@ -1,3 +0,0 @@
servlet=org.apache.dubbo.remoting.http.servlet.ServletHttpBinder
jetty=org.apache.dubbo.remoting.http.jetty.JettyHttpBinder
tomcat=org.apache.dubbo.remoting.http.tomcat.TomcatHttpBinder

View File

@ -1,4 +0,0 @@
ok-http=org.apache.dubbo.remoting.http.factory.impl.OkHttpClientFactory
url-connection=org.apache.dubbo.remoting.http.factory.impl.URLConnectionClientFactory
apache-http-client=org.apache.dubbo.remoting.http.factory.impl.ApacheHttpClientFactory

View File

@ -1,57 +0,0 @@
/*
* 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.remoting.http.jetty;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.apache.http.client.fluent.Request;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
class JettyHttpBinderTest {
@Test
void shouldAbleHandleRequestForJettyBinder() throws Exception {
int port = NetUtils.getAvailablePort();
URL url = new ServiceConfigURL(
"http", "localhost", port, new String[] {Constants.BIND_PORT_KEY, String.valueOf(port)});
HttpServer httpServer = new JettyHttpServer(url, new HttpHandler<HttpServletRequest, HttpServletResponse>() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().write("Jetty");
}
});
String response =
Request.Get(url.toJavaURL().toURI()).execute().returnContent().asString();
assertThat(response, is("Jetty"));
httpServer.close();
}
}

View File

@ -1,127 +0,0 @@
/*
* 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.remoting.http.jetty;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.support.FailsafeErrorTypeAwareLogger;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.apache.http.client.fluent.Request;
import org.eclipse.jetty.util.log.Log;
import org.junit.jupiter.api.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class JettyLoggerAdapterTest {
@Test
void testJettyUseDubboLogger() throws Exception {
int port = NetUtils.getAvailablePort();
URL url = new ServiceConfigURL(
"http", "localhost", port, new String[] {Constants.BIND_PORT_KEY, String.valueOf(port)});
HttpServer httpServer = new JettyHttpServer(url, new HttpHandler<HttpServletRequest, HttpServletResponse>() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().write("Jetty is using Dubbo's logger");
}
});
Request.Get(url.toJavaURL().toURI()).execute().returnContent().asString();
assertThat(Log.getLog().getClass().isAssignableFrom(JettyLoggerAdapter.class), is(true));
httpServer.close();
}
@Test
void testSuccessLogger() throws Exception {
Logger successLogger = mock(Logger.class);
Class<?> clazz = Class.forName("org.apache.dubbo.remoting.http.jetty.JettyLoggerAdapter");
JettyLoggerAdapter jettyLoggerAdapter =
(JettyLoggerAdapter) clazz.getDeclaredConstructor().newInstance();
Field loggerField = clazz.getDeclaredField("logger");
loggerField.setAccessible(true);
loggerField.set(jettyLoggerAdapter, new FailsafeErrorTypeAwareLogger(successLogger));
jettyLoggerAdapter.setDebugEnabled(true);
when(successLogger.isDebugEnabled()).thenReturn(true);
when(successLogger.isWarnEnabled()).thenReturn(true);
when(successLogger.isInfoEnabled()).thenReturn(true);
jettyLoggerAdapter.warn("warn");
jettyLoggerAdapter.info("info");
jettyLoggerAdapter.debug("debug");
verify(successLogger).warn(anyString());
verify(successLogger).info(anyString());
verify(successLogger).debug(anyString());
jettyLoggerAdapter.warn(new Exception("warn"));
jettyLoggerAdapter.info(new Exception("info"));
jettyLoggerAdapter.debug(new Exception("debug"));
jettyLoggerAdapter.ignore(new Exception("ignore"));
jettyLoggerAdapter.warn("warn", new Exception("warn"));
jettyLoggerAdapter.info("info", new Exception("info"));
jettyLoggerAdapter.debug("debug", new Exception("debug"));
}
@Test
void testNewLogger() {
JettyLoggerAdapter loggerAdapter = new JettyLoggerAdapter();
org.eclipse.jetty.util.log.Logger logger =
loggerAdapter.newLogger(this.getClass().getName());
assertThat(logger.getClass().isAssignableFrom(JettyLoggerAdapter.class), is(true));
}
@Test
void testDebugEnabled() {
JettyLoggerAdapter loggerAdapter = new JettyLoggerAdapter();
loggerAdapter.setDebugEnabled(true);
assertThat(loggerAdapter.isDebugEnabled(), is(true));
}
@Test
void testLoggerFormat() throws Exception {
Class<?> clazz = Class.forName("org.apache.dubbo.remoting.http.jetty.JettyLoggerAdapter");
Object newInstance = clazz.getDeclaredConstructor().newInstance();
Method method = clazz.getDeclaredMethod("format", String.class, Object[].class);
method.setAccessible(true);
String print = (String) method.invoke(newInstance, "Hello,{}! I'am {}", new String[] {"World", "Jetty"});
assertThat(print, is("Hello,World! I'am Jetty"));
}
}

View File

@ -1,240 +0,0 @@
/*
* 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.remoting.http.rest;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.*;
import org.apache.dubbo.remoting.http.config.HttpClientConfig;
import org.apache.dubbo.remoting.http.jetty.JettyHttpServer;
import org.apache.dubbo.remoting.http.restclient.HttpClientRestClient;
import org.apache.dubbo.remoting.http.restclient.OKHttpRestClient;
import org.apache.dubbo.remoting.http.restclient.URLConnectionRestClient;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
public class RestClientTest {
@Test
public void testRestClient() throws Exception {
int port = NetUtils.getAvailablePort();
URL url = new ServiceConfigURL(
"http", "localhost", port, new String[] {Constants.BIND_PORT_KEY, String.valueOf(port)});
HttpServer httpServer = new JettyHttpServer(url, new HttpHandler<HttpServletRequest, HttpServletResponse>() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().write("Jetty");
}
});
RequestTemplate requestTemplate = new RequestTemplate(null, "POST", "localhost:" + port);
requestTemplate.addParam("p1", "value1");
requestTemplate.addParam("p2", "value2");
requestTemplate.addParams("p3", Arrays.asList("value3", "value3.1"));
requestTemplate.addHeader("test", "dubbo");
requestTemplate.addKeepAliveHeader(60);
requestTemplate.addHeaders("header", Arrays.asList("h1", "h2"));
requestTemplate.path("/test");
requestTemplate.serializeBody("test".getBytes(StandardCharsets.UTF_8));
RestClient restClient = new OKHttpRestClient(new HttpClientConfig());
CompletableFuture<RestResult> send = restClient.send(requestTemplate);
RestResult restResult = send.get();
assertThat(new String(restResult.getBody()), is("Jetty"));
restClient = new HttpClientRestClient(new HttpClientConfig());
send = restClient.send(requestTemplate);
restResult = send.get();
assertThat(new String(restResult.getBody()), is("Jetty"));
restClient = new URLConnectionRestClient(new HttpClientConfig());
send = restClient.send(requestTemplate);
restResult = send.get();
assertThat(new String(restResult.getBody()), is("Jetty"));
httpServer.close();
}
@Test
public void testError() throws Exception {
int port = NetUtils.getAvailablePort();
URL url = new ServiceConfigURL(
"http", "localhost", port, new String[] {Constants.BIND_PORT_KEY, String.valueOf(port)});
HttpServer httpServer = new JettyHttpServer(url, new HttpHandler<HttpServletRequest, HttpServletResponse>() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setStatus(500);
response.getWriter().write("server error");
response.addHeader("Content-Type", "text/html");
}
});
RequestTemplate requestTemplate = new RequestTemplate(null, null, null);
requestTemplate.httpMethod("POST");
requestTemplate.setAddress("localhost:" + port);
requestTemplate.setProtocol("http://");
requestTemplate.addHeader("test", "dubbo");
requestTemplate.path("/test");
requestTemplate.serializeBody("test".getBytes(StandardCharsets.UTF_8));
RestClient restClient = new OKHttpRestClient(new HttpClientConfig());
CompletableFuture<RestResult> send = restClient.send(requestTemplate);
String error = "Server Error\n" + " error info is: server error";
RestResult restResult = send.get();
String contentType = "text/html;charset=iso-8859-1";
Assertions.assertEquals(500, restResult.getResponseCode());
Assertions.assertEquals(error, restResult.getMessage());
Assertions.assertEquals(contentType, restResult.getContentType());
Map<String, List<String>> headers = restResult.headers();
restClient.close();
restClient = new HttpClientRestClient(new HttpClientConfig());
send = restClient.send(requestTemplate);
restResult = send.get();
Assertions.assertEquals(500, restResult.getResponseCode());
Assertions.assertEquals(error, restResult.getMessage());
Assertions.assertEquals(contentType, restResult.getContentType());
restClient.close();
restClient = new URLConnectionRestClient(new HttpClientConfig());
send = restClient.send(requestTemplate);
restResult = send.get();
Assertions.assertEquals(500, restResult.getResponseCode());
Assertions.assertEquals(error, restResult.getMessage());
Assertions.assertEquals(contentType, restResult.getContentType());
restClient.close();
httpServer.close();
}
@Test
public void testMethod() {
RequestTemplate requestTemplate = new RequestTemplate(null, null, null);
requestTemplate.body(new Object(), Object.class);
Assertions.assertEquals(requestTemplate.getBodyType(), Object.class);
requestTemplate.addHeader("Content-Length", 1);
Integer contentLength = requestTemplate.getContentLength();
Assertions.assertEquals(1, contentLength);
List<String> strings = Arrays.asList("h1", "h2");
requestTemplate.addHeaders("header", strings);
Assertions.assertArrayEquals(
strings.toArray(new String[0]),
requestTemplate.getHeaders("header").toArray(new String[0]));
strings = Arrays.asList("p1", "p2");
requestTemplate.addParams("param", strings);
Assertions.assertArrayEquals(
strings.toArray(new String[0]),
requestTemplate.getParam("param").toArray(new String[0]));
}
@Test
void testBuildURL() throws Exception {
int port = NetUtils.getAvailablePort();
URL url = new ServiceConfigURL(
"http", "localhost", port, new String[] {Constants.BIND_PORT_KEY, String.valueOf(port)});
HttpServer httpServer = new JettyHttpServer(url, new HttpHandler<HttpServletRequest, HttpServletResponse>() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
response.getWriter().write(request.getQueryString());
}
});
RequestTemplate requestTemplate = new RequestTemplate(null, "POST", "localhost:" + port);
requestTemplate.addParam("name", "李强");
requestTemplate.addParam("age", "18");
requestTemplate.path("/hello/world");
// When using the OKHttpRestClient, parameters will be encoded with UTF-8 and appended to the URL
RestClient restClient = new OKHttpRestClient(new HttpClientConfig());
CompletableFuture<RestResult> send = restClient.send(requestTemplate);
RestResult restResult = send.get();
assertThat(new String(restResult.getBody()), is("name=%E6%9D%8E%E5%BC%BA&age=18"));
// When using the HttpClientRestClient, parameters will be encoded with UTF-8 and appended to the URL
restClient = new HttpClientRestClient(new HttpClientConfig());
send = restClient.send(requestTemplate);
restResult = send.get();
assertThat(new String(restResult.getBody()), is("name=%E6%9D%8E%E5%BC%BA&age=18"));
// When using the URLConnectionRestClient, parameters won't be encoded and still appended to the URL
restClient = new URLConnectionRestClient(new HttpClientConfig());
send = restClient.send(requestTemplate);
restResult = send.get();
assertThat(new String(restResult.getBody(), StandardCharsets.UTF_8), is("name=李强&age=18"));
}
}

View File

@ -1,60 +0,0 @@
/*
* 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.remoting.http.tomcat;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.url.component.ServiceConfigURL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.remoting.Constants;
import org.apache.dubbo.remoting.http.HttpHandler;
import org.apache.dubbo.remoting.http.HttpServer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.apache.http.client.fluent.Request;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
class TomcatHttpBinderTest {
@Test
void shouldAbleHandleRequestForTomcatBinder() throws Exception {
int port = NetUtils.getAvailablePort();
URL url = new ServiceConfigURL(
"http", "localhost", port, new String[] {Constants.BIND_PORT_KEY, String.valueOf(port)});
HttpServer httpServer = new TomcatHttpBinder()
.bind(url, new HttpHandler<HttpServletRequest, HttpServletResponse>() {
@Override
public void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.getWriter().write("Tomcat");
}
});
String response =
Request.Get(url.toJavaURL().toURI()).execute().returnContent().asString();
assertThat(response, is("Tomcat"));
httpServer.close();
assertThat(NetUtils.isPortInUsed(port), is(false));
}
}

View File

@ -1,29 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ 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.
-->
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="%d{HH:mm:ss.SSS} |-%highlight{%-5p} [%t] %40.40c:%-3L -| %m%n%rEx{filters(jdk.internal.reflect,java.lang.reflect,sun.reflect,org.junit,org.mockito)}" charset="UTF-8"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>

View File

@ -29,7 +29,6 @@
<description>The remoting module of dubbo project</description>
<modules>
<module>dubbo-remoting-api</module>
<module>dubbo-remoting-http</module>
<module>dubbo-remoting-netty</module>
<module>dubbo-remoting-zookeeper-api</module>
<module>dubbo-remoting-zookeeper</module>

View File

@ -300,11 +300,6 @@
<artifactId>dubbo-remoting-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-remoting-http12</artifactId>