import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.lang.Nullable;
import org.springframework.util.ResourceUtils;
+import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClient.RequestHeadersSpec;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
+import reactor.netty.resources.ConnectionProvider;
import reactor.netty.tcp.TcpClient;
/**
private final String baseUrl;
private static final AtomicInteger sequenceNumber = new AtomicInteger();
private final WebClientConfig clientConfig;
+ static KeyStore clientTrustStore = null;
public AsyncRestClient(String baseUrl) {
this(baseUrl,
}
private Mono<ResponseEntity<String>> retrieve(Object traceTag, RequestHeadersSpec<?> request) {
+ final Class<String> clazz = String.class;
return request.retrieve() //
- .toEntity(String.class) //
- .doOnNext(entity -> logger.trace("{} Received: {}", traceTag, entity.getBody()))
+ .toEntity(clazz) //
+ .doOnNext(entity -> logger.trace("{} Received: {}", traceTag, entity.getBody())) //
.doOnError(throwable -> onHttpError(traceTag, throwable));
}
logger.debug("{} HTTP error status = '{}', body '{}'", traceTag, exception.getStatusCode(),
exception.getResponseBodyAsString());
} else {
- logger.debug("{} HTTP error: {}", traceTag, t.getMessage());
+ logger.debug("{} HTTP error", traceTag, t);
}
}
}
}
- SslContext createSslContextSecure(String trustStorePath, String trustStorePass)
+ private static synchronized KeyStore getTrustStore(String trustStorePath, String trustStorePass)
throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
+ if (clientTrustStore == null) {
+ KeyStore store = KeyStore.getInstance(KeyStore.getDefaultType());
+ store.load(new FileInputStream(ResourceUtils.getFile(trustStorePath)), trustStorePass.toCharArray());
+ clientTrustStore = store;
+ }
+ return clientTrustStore;
+ }
- final KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(new FileInputStream(ResourceUtils.getFile(trustStorePath)), trustStorePass.toCharArray());
+ private SslContext createSslContextRejectingUntrustedPeers(String trustStorePath, String trustStorePass)
+ throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
+ final KeyStore trustStore = getTrustStore(trustStorePath, trustStorePass);
List<Certificate> certificateList = Collections.list(trustStore.aliases()).stream() //
.filter(alias -> isCertificateEntry(trustStore, alias)) //
.map(alias -> getCertificate(trustStore, alias)) //
private SslContext createSslContext()
throws NoSuchAlgorithmException, CertificateException, KeyStoreException, IOException {
if (this.clientConfig.isTrustStoreUsed()) {
- return createSslContextSecure(this.clientConfig.trustStore(), this.clientConfig.trustStorePassword());
+ return createSslContextRejectingUntrustedPeers(this.clientConfig.trustStore(),
+ this.clientConfig.trustStorePassword());
} else {
+ // Trust anyone
return SslContextBuilder.forClient() //
.trustManager(InsecureTrustManagerFactory.INSTANCE) //
.build();
}
private WebClient createWebClient(String baseUrl, SslContext sslContext) {
- TcpClient tcpClient = TcpClient.create() //
+ ConnectionProvider connectionProvider = ConnectionProvider.newConnection();
+ TcpClient tcpClient = TcpClient.create(connectionProvider) //
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10_000) //
.secure(c -> c.sslContext(sslContext)) //
+
.doOnConnected(connection -> {
connection.addHandlerLast(new ReadTimeoutHandler(30));
connection.addHandlerLast(new WriteTimeoutHandler(30));
HttpClient httpClient = HttpClient.from(tcpClient);
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
+ ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() //
+ .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(-1)) //
+ .build();
+
return WebClient.builder() //
.clientConnector(connector) //
.baseUrl(baseUrl) //
+ .exchangeStrategies(exchangeStrategies) //
.build();
}