Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

JDK 11 HttpClient async implement for AsyncFeign. #1330

Merged
merged 23 commits into from
Oct 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
74c963e
java11 async http client for AsyncFeign
Dec 19, 2020
5a77d5e
java 11 httpclient not allow some header
Dec 19, 2020
35fdd83
add unit test
Dec 19, 2020
1e01e62
add license
Dec 19, 2020
8360402
remove unused annotation
Dec 22, 2020
84fc737
Merge branch 'master' into asyncfeign-java11-impl
kdavisk6 Dec 22, 2020
5e8e0f9
Merge branch 'master' of https://github.com/OpenFeign/feign into asyn…
Dec 25, 2020
933c337
Merge remote-tracking branch 'origin/master' into asyncfeign-java11-impl
Dec 25, 2020
661f195
port connectionTimeout feature of Http2Client to AsyncHttpClient
Dec 25, 2020
1799068
Merge branch 'master' into asyncfeign-java11-impl
kdavisk6 Dec 29, 2020
a134eee
Merge branch 'master' into asyncfeign-java11-impl
kdavisk6 Dec 29, 2020
e5e712a
Merge branch 'master' into asyncfeign-java11-impl
xrayw Dec 30, 2020
0ef4c87
fix format
Dec 30, 2020
9c1f508
Merge branch 'master' into asyncfeign-java11-impl
xrayw Jan 12, 2021
95d3224
Merge branch 'master' into asyncfeign-java11-impl
xrayw Mar 14, 2021
d616369
Merge branch 'master' into asyncfeign-java11-impl
velo May 16, 2021
0ab763a
Merge branch 'master' into asyncfeign-java11-impl
velo May 16, 2021
7411b7f
Merge branch 'master' into asyncfeign-java11-impl
xrayw Jun 19, 2021
d715117
Merge branch 'master' into asyncfeign-java11-impl
velo Jul 19, 2021
7d66dd9
Combined Sync and Async clients into a single class
velo Jul 23, 2021
cf1dc64
Merge branch 'master' into asyncfeign-java11-impl
xrayw Jul 23, 2021
ba6f56a
Merge branch 'master' into asyncfeign-java11-impl
xrayw Sep 10, 2021
6109dc1
Merge branch 'master' into asyncfeign-java11-impl
velo Oct 17, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions java11/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
<type>jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
74 changes: 54 additions & 20 deletions java11/src/main/java/feign/http2client/Http2Client.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2012-2020 The Feign Authors
* Copyright 2012-2021 The Feign Authors
*
* Licensed 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
Expand All @@ -13,11 +13,6 @@
*/
package feign.http2client;

import feign.Client;
import feign.Request;
import feign.Request.Options;
import feign.Response;
import feign.Util;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
Expand All @@ -32,11 +27,28 @@
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.time.Duration;
import java.util.*;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalLong;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;
import feign.AsyncClient;
import feign.Client;
import feign.Request;
import feign.Request.Options;
import feign.Response;
import feign.Util;

public class Http2Client implements Client {
public class Http2Client implements Client, AsyncClient<Object> {

private final HttpClient client;

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

@Override
public Response execute(Request request, Options options) throws IOException {
final HttpRequest httpRequest = newRequestBuilder(request, options).build();
HttpClient clientForRequest = getOrCreateClient(options);
final HttpRequest httpRequest;
try {
httpRequest = newRequestBuilder(request, options)
.version(client.version())
.build();
} catch (URISyntaxException e) {
throw new IOException("Invalid uri " + request.url(), e);
}

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

return toFeignResponse(request, httpResponse);
}

@Override
public CompletableFuture<Response> execute(Request request,
Options options,
Optional<Object> requestContext) {
HttpRequest httpRequest;
try {
httpRequest = newRequestBuilder(request, options).build();
} catch (URISyntaxException e) {
throw new IllegalArgumentException("Invalid uri " + request.url(), e);
}

HttpClient clientForRequest = getOrCreateClient(options);
CompletableFuture<HttpResponse<byte[]>> future =
clientForRequest.sendAsync(httpRequest, HttpResponse.BodyHandlers.ofByteArray());
return future.thenApply(httpResponse -> toFeignResponse(request, httpResponse));
}

protected Response toFeignResponse(Request request, HttpResponse<byte[]> httpResponse) {
final OptionalLong length = httpResponse.headers().firstValueAsLong("Content-Length");

final Response response = Response.builder()
return Response.builder()
.body(new ByteArrayInputStream(httpResponse.body()),
length.isPresent() ? (int) length.getAsLong() : null)
.reason(httpResponse.headers().firstValue("Reason-Phrase").orElse("OK"))
.request(request)
.status(httpResponse.statusCode())
.headers(castMapCollectType(httpResponse.headers().map()))
.build();
return response;
}

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

private Builder newRequestBuilder(Request request, Options options) throws IOException {
URI uri;
try {
uri = new URI(request.url());
} catch (final URISyntaxException e) {
throw new IOException("Invalid uri " + request.url(), e);
}
private Builder newRequestBuilder(Request request, Options options) throws URISyntaxException {
URI uri = new URI(request.url());

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

final Map<String, Collection<String>> headers = filterRestrictedHeaders(request.headers());
if (!headers.isEmpty()) {
Expand Down
25 changes: 25 additions & 0 deletions java11/src/test/java/feign/http2client/test/CustomPojo.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Copyright 2012-2020 The Feign Authors
*
* Licensed 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 feign.http2client.test;

public class CustomPojo {

private final String name;
private final Integer number;

CustomPojo(String name, Integer number) {
this.name = name;
this.number = number;
}
}
Loading