-
Notifications
You must be signed in to change notification settings - Fork 0
/
AbstractVertxHttpClient.java
133 lines (118 loc) · 5.12 KB
/
AbstractVertxHttpClient.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package com.chavaillaz.client.common.vertx;
import static com.chavaillaz.client.common.utility.Utils.getCookieHeader;
import java.io.InputStream;
import java.util.concurrent.CompletableFuture;
import com.chavaillaz.client.common.AbstractHttpClient;
import com.chavaillaz.client.common.security.Authentication;
import com.fasterxml.jackson.databind.JavaType;
import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpMethod;
import io.vertx.ext.web.client.HttpRequest;
import io.vertx.ext.web.client.HttpResponse;
import io.vertx.ext.web.client.WebClient;
/**
* Abstract class implementing common parts for Vert.x HTTP.
*/
public abstract class AbstractVertxHttpClient extends AbstractHttpClient implements AutoCloseable {
protected final WebClient client;
/**
* Creates a new abstract client based on Vert.x HTTP client.
*
* @param client The web client to use
* @param baseUrl The base URL of endpoints
* @param authentication The authentication information
*/
protected AbstractVertxHttpClient(WebClient client, String baseUrl, Authentication authentication) {
super(baseUrl, authentication);
this.client = client;
}
/**
* Creates a request based on the given URL and replaces the parameters in it by the given ones.
*
* @param method The HTTP method for the request to build
* @param url The URL with possible parameters in it (using braces)
* @param parameters The parameters value to replace in the URL (in the right order)
* @return The request having the URL and authentication set
*/
protected HttpRequest<Buffer> requestBuilder(HttpMethod method, String url, Object... parameters) {
var request = client.requestAbs(method, url(url, parameters).toString())
.putHeader(HEADER_CONTENT_TYPE, HEADER_CONTENT_JSON);
getAuthentication().fillHeaders(request::putHeader);
getCookieHeader(getAuthentication()).ifPresent(value -> request.putHeader(HEADER_COOKIE, value));
return request;
}
/**
* Creates a body buffer containing the given object serialized as JSON.
*
* @param object The object to serialize
* @return The corresponding buffer for the request
*/
protected Buffer body(Object object) {
return Buffer.buffer(serialize(object));
}
/**
* Handles the request sent and returns a domain object.
*
* @param future The future response
* @param returnType The domain object type class
* @param <T> The domain object type
* @return A {@link CompletableFuture} with the deserialized domain object
*/
protected <T> CompletableFuture<T> handleAsync(Future<HttpResponse<Buffer>> future, Class<T> returnType) {
return handleAsync(future, objectMapper.constructType(returnType));
}
/**
* Handles the request sent and returns a domain object.
*
* @param future The future response
* @param returnType The domain object type class
* @param <T> The domain object type
* @return A {@link CompletableFuture} with the deserialized domain object
*/
protected <T> CompletableFuture<T> handleAsync(Future<HttpResponse<Buffer>> future, JavaType returnType) {
return handleAsyncBase(future)
.thenApply(HttpResponse::bodyAsString)
.thenApply(body -> deserialize(body, returnType));
}
/**
* Handles the request sent and returns an input stream.
*
* @param future The future response
* @return A {@link CompletableFuture} with the input stream
*/
protected CompletableFuture<InputStream> handleAsync(Future<HttpResponse<Buffer>> future) {
return handleAsyncBase(future)
.thenApply(HttpResponse::body)
.thenApply(VertxInputStream::new);
}
/**
* Handles the request sent and returns the corresponding response buffer.
*
* @param future The future response
* @return A {@link CompletableFuture} with the response buffer
*/
protected CompletableFuture<HttpResponse<Buffer>> handleAsyncBase(Future<HttpResponse<Buffer>> future) {
CompletableFuture<HttpResponse<Buffer>> completableFuture = new CompletableFuture<>();
future.onSuccess(response -> handleResponse(response, completableFuture))
.onFailure(completableFuture::completeExceptionally);
return completableFuture;
}
/**
* Handles the response by transmitting its state to the given {@link CompletableFuture}.
*
* @param response The HTTP response
* @param completableFuture The completable future to update
*/
protected void handleResponse(HttpResponse<Buffer> response, CompletableFuture<HttpResponse<Buffer>> completableFuture) {
if (response.statusCode() >= 400) {
completableFuture.completeExceptionally(responseException(response.statusCode(), response.bodyAsString()));
} else {
completableFuture.complete(response);
}
}
@Override
public void close() throws Exception {
client.close();
}
}