Skip to content

Commit b06f47a

Browse files
xraywUzimakiNarutokdavisk6velo
authored
JDK 11 HttpClient async implement for AsyncFeign. (OpenFeign#1330)
* java11 async http client for AsyncFeign * java 11 httpclient not allow some header * add unit test * add license * remove unused annotation * Merge branch 'master' of https://github.com/OpenFeign/feign into asyncfeign-java11-impl � Conflicts: � java11/src/main/java/feign/http2client/Http2Client.java * port connectionTimeout feature of Http2Client to AsyncHttpClient * fix format * Combined Sync and Async clients into a single class Co-authored-by: UzimakiNaruto <[email protected]> Co-authored-by: Kevin Davis <[email protected]> Co-authored-by: Marvin Froeder <[email protected]> Co-authored-by: Marvin Froeder <[email protected]>
1 parent 5eb9905 commit b06f47a

4 files changed

Lines changed: 1149 additions & 20 deletions

File tree

java11/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,11 @@
6969
<type>jar</type>
7070
<scope>test</scope>
7171
</dependency>
72+
<dependency>
73+
<groupId>com.google.code.gson</groupId>
74+
<artifactId>gson</artifactId>
75+
<scope>test</scope>
76+
</dependency>
7277
</dependencies>
7378

7479
<build>

java11/src/main/java/feign/http2client/Http2Client.java

Lines changed: 54 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Copyright 2012-2020 The Feign Authors
2+
* Copyright 2012-2021 The Feign Authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
55
* in compliance with the License. You may obtain a copy of the License at
@@ -13,11 +13,6 @@
1313
*/
1414
package feign.http2client;
1515

16-
import feign.Client;
17-
import feign.Request;
18-
import feign.Request.Options;
19-
import feign.Response;
20-
import feign.Util;
2116
import java.io.ByteArrayInputStream;
2217
import java.io.IOException;
2318
import java.net.URI;
@@ -32,11 +27,28 @@
3227
import java.net.http.HttpResponse;
3328
import java.net.http.HttpResponse.BodyHandlers;
3429
import java.time.Duration;
35-
import java.util.*;
30+
import java.util.Arrays;
31+
import java.util.Collection;
32+
import java.util.Collections;
33+
import java.util.HashMap;
34+
import java.util.HashSet;
35+
import java.util.List;
36+
import java.util.Map;
37+
import java.util.Optional;
38+
import java.util.OptionalLong;
39+
import java.util.Set;
40+
import java.util.TreeSet;
41+
import java.util.concurrent.CompletableFuture;
3642
import java.util.function.Function;
3743
import java.util.stream.Collectors;
44+
import feign.AsyncClient;
45+
import feign.Client;
46+
import feign.Request;
47+
import feign.Request.Options;
48+
import feign.Response;
49+
import feign.Util;
3850

39-
public class Http2Client implements Client {
51+
public class Http2Client implements Client, AsyncClient<Object> {
4052

4153
private final HttpClient client;
4254

@@ -59,9 +71,16 @@ public Http2Client(HttpClient client) {
5971

6072
@Override
6173
public Response execute(Request request, Options options) throws IOException {
62-
final HttpRequest httpRequest = newRequestBuilder(request, options).build();
63-
HttpClient clientForRequest = getOrCreateClient(options);
74+
final HttpRequest httpRequest;
75+
try {
76+
httpRequest = newRequestBuilder(request, options)
77+
.version(client.version())
78+
.build();
79+
} catch (URISyntaxException e) {
80+
throw new IOException("Invalid uri " + request.url(), e);
81+
}
6482

83+
HttpClient clientForRequest = getOrCreateClient(options);
6584
HttpResponse<byte[]> httpResponse;
6685
try {
6786
httpResponse = clientForRequest.send(httpRequest, BodyHandlers.ofByteArray());
@@ -70,17 +89,37 @@ public Response execute(Request request, Options options) throws IOException {
7089
throw new IOException("Invalid uri " + request.url(), e);
7190
}
7291

92+
return toFeignResponse(request, httpResponse);
93+
}
94+
95+
@Override
96+
public CompletableFuture<Response> execute(Request request,
97+
Options options,
98+
Optional<Object> requestContext) {
99+
HttpRequest httpRequest;
100+
try {
101+
httpRequest = newRequestBuilder(request, options).build();
102+
} catch (URISyntaxException e) {
103+
throw new IllegalArgumentException("Invalid uri " + request.url(), e);
104+
}
105+
106+
HttpClient clientForRequest = getOrCreateClient(options);
107+
CompletableFuture<HttpResponse<byte[]>> future =
108+
clientForRequest.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofByteArray());
109+
return future.thenApply(httpResponse -> toFeignResponse(request, httpResponse));
110+
}
111+
112+
protected Response toFeignResponse(Request request, HttpResponse<byte[]> httpResponse) {
73113
final OptionalLong length = httpResponse.headers().firstValueAsLong("Content-Length");
74114

75-
final Response response = Response.builder()
115+
return Response.builder()
76116
.body(new ByteArrayInputStream(httpResponse.body()),
77117
length.isPresent() ? (int) length.getAsLong() : null)
78118
.reason(httpResponse.headers().firstValue("Reason-Phrase").orElse("OK"))
79119
.request(request)
80120
.status(httpResponse.statusCode())
81121
.headers(castMapCollectType(httpResponse.headers().map()))
82122
.build();
83-
return response;
84123
}
85124

86125
private HttpClient getOrCreateClient(Options options) {
@@ -116,13 +155,8 @@ private static java.net.http.HttpClient.Builder newClientBuilder(Options options
116155
.connectTimeout(Duration.ofMillis(options.connectTimeoutMillis()));
117156
}
118157

119-
private Builder newRequestBuilder(Request request, Options options) throws IOException {
120-
URI uri;
121-
try {
122-
uri = new URI(request.url());
123-
} catch (final URISyntaxException e) {
124-
throw new IOException("Invalid uri " + request.url(), e);
125-
}
158+
private Builder newRequestBuilder(Request request, Options options) throws URISyntaxException {
159+
URI uri = new URI(request.url());
126160

127161
final BodyPublisher body;
128162
final byte[] data = request.body();
@@ -135,7 +169,7 @@ private Builder newRequestBuilder(Request request, Options options) throws IOExc
135169
final Builder requestBuilder = HttpRequest.newBuilder()
136170
.uri(uri)
137171
.timeout(Duration.ofMillis(options.readTimeoutMillis()))
138-
.version(Version.HTTP_2);
172+
.version(client.version());
139173

140174
final Map<String, Collection<String>> headers = filterRestrictedHeaders(request.headers());
141175
if (!headers.isEmpty()) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright 2012-2020 The Feign Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5+
* in compliance with the License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License
10+
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11+
* or implied. See the License for the specific language governing permissions and limitations under
12+
* the License.
13+
*/
14+
package feign.http2client.test;
15+
16+
public class CustomPojo {
17+
18+
private final String name;
19+
private final Integer number;
20+
21+
CustomPojo(String name, Integer number) {
22+
this.name = name;
23+
this.number = number;
24+
}
25+
}

0 commit comments

Comments
 (0)