Revise and align Reactor client lifecycle management
Closes gh-32945
This commit is contained in:
parent
4f6f2c0d41
commit
7785f94c4c
|
|
@ -50,19 +50,21 @@ public class ReactorNettyClientRequestFactory implements ClientHttpRequestFactor
|
||||||
private static final Function<HttpClient, HttpClient> defaultInitializer = client -> client.compress(true);
|
private static final Function<HttpClient, HttpClient> defaultInitializer = client -> client.compress(true);
|
||||||
|
|
||||||
|
|
||||||
private HttpClient httpClient;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final ReactorResourceFactory resourceFactory;
|
private final ReactorResourceFactory resourceFactory;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Function<HttpClient, HttpClient> mapper;
|
private final Function<HttpClient, HttpClient> mapper;
|
||||||
|
|
||||||
private Duration exchangeTimeout = Duration.ofSeconds(5);
|
@Nullable
|
||||||
|
private Integer connectTimeout;
|
||||||
|
|
||||||
private Duration readTimeout = Duration.ofSeconds(10);
|
private Duration readTimeout = Duration.ofSeconds(10);
|
||||||
|
|
||||||
private volatile boolean running = true;
|
private Duration exchangeTimeout = Duration.ofSeconds(5);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile HttpClient httpClient;
|
||||||
|
|
||||||
private final Object lifecycleMonitor = new Object();
|
private final Object lifecycleMonitor = new Object();
|
||||||
|
|
||||||
|
|
@ -107,25 +109,11 @@ public class ReactorNettyClientRequestFactory implements ClientHttpRequestFactor
|
||||||
* @param mapper a mapper for further initialization of the created client
|
* @param mapper a mapper for further initialization of the created client
|
||||||
*/
|
*/
|
||||||
public ReactorNettyClientRequestFactory(ReactorResourceFactory resourceFactory, Function<HttpClient, HttpClient> mapper) {
|
public ReactorNettyClientRequestFactory(ReactorResourceFactory resourceFactory, Function<HttpClient, HttpClient> mapper) {
|
||||||
this.httpClient = createHttpClient(resourceFactory, mapper);
|
|
||||||
this.resourceFactory = resourceFactory;
|
this.resourceFactory = resourceFactory;
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
}
|
if (resourceFactory.isRunning()) {
|
||||||
|
this.httpClient = createHttpClient(resourceFactory, mapper);
|
||||||
|
}
|
||||||
private static HttpClient createHttpClient(ReactorResourceFactory resourceFactory, Function<HttpClient, HttpClient> mapper) {
|
|
||||||
ConnectionProvider provider = resourceFactory.getConnectionProvider();
|
|
||||||
Assert.notNull(provider, "No ConnectionProvider: is ReactorResourceFactory not initialized yet?");
|
|
||||||
return defaultInitializer.andThen(mapper).andThen(applyLoopResources(resourceFactory))
|
|
||||||
.apply(HttpClient.create(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Function<HttpClient, HttpClient> applyLoopResources(ReactorResourceFactory factory) {
|
|
||||||
return httpClient -> {
|
|
||||||
LoopResources resources = factory.getLoopResources();
|
|
||||||
Assert.notNull(resources, "No LoopResources: is ReactorResourceFactory not initialized yet?");
|
|
||||||
return httpClient.runOn(resources);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -138,7 +126,11 @@ public class ReactorNettyClientRequestFactory implements ClientHttpRequestFactor
|
||||||
*/
|
*/
|
||||||
public void setConnectTimeout(int connectTimeout) {
|
public void setConnectTimeout(int connectTimeout) {
|
||||||
Assert.isTrue(connectTimeout >= 0, "Timeout must be a non-negative value");
|
Assert.isTrue(connectTimeout >= 0, "Timeout must be a non-negative value");
|
||||||
this.httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout);
|
this.connectTimeout = connectTimeout;
|
||||||
|
HttpClient httpClient = this.httpClient;
|
||||||
|
if (httpClient != null) {
|
||||||
|
this.httpClient = httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.connectTimeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -150,8 +142,7 @@ public class ReactorNettyClientRequestFactory implements ClientHttpRequestFactor
|
||||||
*/
|
*/
|
||||||
public void setConnectTimeout(Duration connectTimeout) {
|
public void setConnectTimeout(Duration connectTimeout) {
|
||||||
Assert.notNull(connectTimeout, "ConnectTimeout must not be null");
|
Assert.notNull(connectTimeout, "ConnectTimeout must not be null");
|
||||||
Assert.isTrue(!connectTimeout.isNegative(), "Timeout must be a non-negative value");
|
setConnectTimeout((int) connectTimeout.toMillis());
|
||||||
this.httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, (int)connectTimeout.toMillis());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -192,52 +183,55 @@ public class ReactorNettyClientRequestFactory implements ClientHttpRequestFactor
|
||||||
this.exchangeTimeout = exchangeTimeout;
|
this.exchangeTimeout = exchangeTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private HttpClient createHttpClient(ReactorResourceFactory factory, Function<HttpClient, HttpClient> mapper) {
|
||||||
|
HttpClient httpClient = defaultInitializer.andThen(mapper)
|
||||||
|
.apply(HttpClient.create(factory.getConnectionProvider()));
|
||||||
|
httpClient = httpClient.runOn(factory.getLoopResources());
|
||||||
|
if (this.connectTimeout != null) {
|
||||||
|
httpClient = httpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.connectTimeout);
|
||||||
|
}
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
|
||||||
return new ReactorNettyClientRequest(this.httpClient, uri, httpMethod, this.exchangeTimeout, this.readTimeout);
|
HttpClient httpClient = this.httpClient;
|
||||||
|
if (httpClient == null) {
|
||||||
|
Assert.state(this.resourceFactory != null && this.mapper != null, "Illegal configuration");
|
||||||
|
httpClient = createHttpClient(this.resourceFactory, this.mapper);
|
||||||
|
}
|
||||||
|
return new ReactorNettyClientRequest(httpClient, uri, httpMethod, this.exchangeTimeout, this.readTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
if (this.resourceFactory != null && this.mapper != null) {
|
||||||
if (!isRunning()) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
if (this.resourceFactory != null && this.mapper != null) {
|
if (this.httpClient == null) {
|
||||||
this.httpClient = createHttpClient(this.resourceFactory, this.mapper);
|
this.httpClient = createHttpClient(this.resourceFactory, this.mapper);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
logger.warn("Restarting a ReactorNettyClientRequestFactory bean is only supported with externally managed Reactor Netty resources");
|
|
||||||
}
|
|
||||||
this.running = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
logger.warn("Restarting a ReactorNettyClientRequestFactory bean is only supported " +
|
||||||
|
"with externally managed Reactor Netty resources");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
if (this.resourceFactory != null && this.mapper != null) {
|
||||||
if (isRunning()) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
this.running = false;
|
this.httpClient = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void stop(Runnable callback) {
|
|
||||||
synchronized (this.lifecycleMonitor) {
|
|
||||||
stop();
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return this.running;
|
return (this.httpClient != null);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAutoStartup() {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,7 @@ public class ReactorResourceFactory
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
if (!isRunning()) {
|
if (!this.running) {
|
||||||
if (this.useGlobalResources) {
|
if (this.useGlobalResources) {
|
||||||
Assert.isTrue(this.loopResources == null && this.connectionProvider == null,
|
Assert.isTrue(this.loopResources == null && this.connectionProvider == null,
|
||||||
"'useGlobalResources' is mutually exclusive with explicitly configured resources");
|
"'useGlobalResources' is mutually exclusive with explicitly configured resources");
|
||||||
|
|
@ -267,7 +267,7 @@ public class ReactorResourceFactory
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
if (isRunning()) {
|
if (this.running) {
|
||||||
if (this.useGlobalResources) {
|
if (this.useGlobalResources) {
|
||||||
HttpResources.disposeLoopsAndConnectionsLater(this.shutdownQuietPeriod, this.shutdownTimeout).block();
|
HttpResources.disposeLoopsAndConnectionsLater(this.shutdownQuietPeriod, this.shutdownTimeout).block();
|
||||||
this.connectionProvider = null;
|
this.connectionProvider = null;
|
||||||
|
|
@ -306,4 +306,10 @@ public class ReactorResourceFactory
|
||||||
return this.running;
|
return this.running;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPhase() {
|
||||||
|
// Same as plain Lifecycle
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2023 the original author or authors.
|
* Copyright 2002-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
@ -54,24 +54,21 @@ public class ReactorClientHttpConnector implements ClientHttpConnector, SmartLif
|
||||||
private static final Function<HttpClient, HttpClient> defaultInitializer = client -> client.compress(true);
|
private static final Function<HttpClient, HttpClient> defaultInitializer = client -> client.compress(true);
|
||||||
|
|
||||||
|
|
||||||
private HttpClient httpClient;
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final ReactorResourceFactory resourceFactory;
|
private final ReactorResourceFactory resourceFactory;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Function<HttpClient, HttpClient> mapper;
|
private final Function<HttpClient, HttpClient> mapper;
|
||||||
|
|
||||||
private volatile boolean running = true;
|
@Nullable
|
||||||
|
private volatile HttpClient httpClient;
|
||||||
|
|
||||||
private final Object lifecycleMonitor = new Object();
|
private final Object lifecycleMonitor = new Object();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor. Initializes {@link HttpClient} via:
|
* Default constructor. Initializes {@link HttpClient} via:
|
||||||
* <pre class="code">
|
* <pre class="code">HttpClient.create().compress(true)</pre>
|
||||||
* HttpClient.create().compress()
|
|
||||||
* </pre>
|
|
||||||
*/
|
*/
|
||||||
public ReactorClientHttpConnector() {
|
public ReactorClientHttpConnector() {
|
||||||
this.httpClient = defaultInitializer.apply(HttpClient.create());
|
this.httpClient = defaultInitializer.apply(HttpClient.create());
|
||||||
|
|
@ -79,6 +76,18 @@ public class ReactorClientHttpConnector implements ClientHttpConnector, SmartLif
|
||||||
this.mapper = null;
|
this.mapper = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor with a pre-configured {@code HttpClient} instance.
|
||||||
|
* @param httpClient the client to use
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
public ReactorClientHttpConnector(HttpClient httpClient) {
|
||||||
|
Assert.notNull(httpClient, "HttpClient is required");
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
this.resourceFactory = null;
|
||||||
|
this.mapper = null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor with externally managed Reactor Netty resources, including
|
* Constructor with externally managed Reactor Netty resources, including
|
||||||
* {@link LoopResources} for event loop threads, and {@link ConnectionProvider}
|
* {@link LoopResources} for event loop threads, and {@link ConnectionProvider}
|
||||||
|
|
@ -98,37 +107,16 @@ public class ReactorClientHttpConnector implements ClientHttpConnector, SmartLif
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
*/
|
*/
|
||||||
public ReactorClientHttpConnector(ReactorResourceFactory resourceFactory, Function<HttpClient, HttpClient> mapper) {
|
public ReactorClientHttpConnector(ReactorResourceFactory resourceFactory, Function<HttpClient, HttpClient> mapper) {
|
||||||
this.httpClient = createHttpClient(resourceFactory, mapper);
|
|
||||||
this.resourceFactory = resourceFactory;
|
this.resourceFactory = resourceFactory;
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
|
if (resourceFactory.isRunning()) {
|
||||||
|
this.httpClient = createHttpClient(resourceFactory, mapper);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static HttpClient createHttpClient(ReactorResourceFactory resourceFactory, Function<HttpClient, HttpClient> mapper) {
|
private static HttpClient createHttpClient(ReactorResourceFactory factory, Function<HttpClient, HttpClient> mapper) {
|
||||||
ConnectionProvider provider = resourceFactory.getConnectionProvider();
|
return defaultInitializer.andThen(mapper).andThen(httpClient -> httpClient.runOn(factory.getLoopResources()))
|
||||||
Assert.notNull(provider, "No ConnectionProvider: is ReactorResourceFactory not initialized yet?");
|
.apply(HttpClient.create(factory.getConnectionProvider()));
|
||||||
return defaultInitializer.andThen(mapper).andThen(applyLoopResources(resourceFactory))
|
|
||||||
.apply(HttpClient.create(provider));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Function<HttpClient, HttpClient> applyLoopResources(ReactorResourceFactory factory) {
|
|
||||||
return httpClient -> {
|
|
||||||
LoopResources resources = factory.getLoopResources();
|
|
||||||
Assert.notNull(resources, "No LoopResources: is ReactorResourceFactory not initialized yet?");
|
|
||||||
return httpClient.runOn(resources);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor with a pre-configured {@code HttpClient} instance.
|
|
||||||
* @param httpClient the client to use
|
|
||||||
* @since 5.1
|
|
||||||
*/
|
|
||||||
public ReactorClientHttpConnector(HttpClient httpClient) {
|
|
||||||
Assert.notNull(httpClient, "HttpClient is required");
|
|
||||||
this.httpClient = httpClient;
|
|
||||||
this.resourceFactory = null;
|
|
||||||
this.mapper = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -136,12 +124,17 @@ public class ReactorClientHttpConnector implements ClientHttpConnector, SmartLif
|
||||||
public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
|
public Mono<ClientHttpResponse> connect(HttpMethod method, URI uri,
|
||||||
Function<? super ClientHttpRequest, Mono<Void>> requestCallback) {
|
Function<? super ClientHttpRequest, Mono<Void>> requestCallback) {
|
||||||
|
|
||||||
AtomicReference<ReactorClientHttpResponse> responseRef = new AtomicReference<>();
|
HttpClient httpClient = this.httpClient;
|
||||||
|
if (httpClient == null) {
|
||||||
|
Assert.state(this.resourceFactory != null && this.mapper != null, "Illegal configuration");
|
||||||
|
httpClient = createHttpClient(this.resourceFactory, this.mapper);
|
||||||
|
}
|
||||||
|
|
||||||
HttpClient.RequestSender requestSender = this.httpClient
|
HttpClient.RequestSender requestSender = httpClient
|
||||||
.request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name()));
|
.request(io.netty.handler.codec.http.HttpMethod.valueOf(method.name()));
|
||||||
|
|
||||||
requestSender = setUri(requestSender, uri);
|
requestSender = setUri(requestSender, uri);
|
||||||
|
AtomicReference<ReactorClientHttpResponse> responseRef = new AtomicReference<>();
|
||||||
|
|
||||||
return requestSender
|
return requestSender
|
||||||
.send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound)))
|
.send((request, outbound) -> requestCallback.apply(adaptRequest(method, uri, request, outbound)))
|
||||||
|
|
@ -176,46 +169,34 @@ public class ReactorClientHttpConnector implements ClientHttpConnector, SmartLif
|
||||||
return new ReactorClientHttpRequest(method, uri, request, nettyOutbound);
|
return new ReactorClientHttpRequest(method, uri, request, nettyOutbound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
if (this.resourceFactory != null && this.mapper != null) {
|
||||||
if (!isRunning()) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
if (this.resourceFactory != null && this.mapper != null) {
|
if (this.httpClient == null) {
|
||||||
this.httpClient = createHttpClient(this.resourceFactory, this.mapper);
|
this.httpClient = createHttpClient(this.resourceFactory, this.mapper);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
logger.warn("Restarting a ReactorClientHttpConnector bean is only supported with externally managed Reactor Netty resources");
|
|
||||||
}
|
|
||||||
this.running = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
logger.warn("Restarting a ReactorClientHttpConnector bean is only supported " +
|
||||||
|
"with externally managed Reactor Netty resources");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
synchronized (this.lifecycleMonitor) {
|
if (this.resourceFactory != null && this.mapper != null) {
|
||||||
if (isRunning()) {
|
synchronized (this.lifecycleMonitor) {
|
||||||
this.running = false;
|
this.httpClient = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public final void stop(Runnable callback) {
|
|
||||||
synchronized (this.lifecycleMonitor) {
|
|
||||||
stop();
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRunning() {
|
public boolean isRunning() {
|
||||||
return this.running;
|
return (this.httpClient != null);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isAutoStartup() {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,20 @@ class ReactorNettyClientRequestFactoryTests extends AbstractHttpRequestFactoryTe
|
||||||
requestFactory.start();
|
requestFactory.start();
|
||||||
assertThat(requestFactory.isRunning()).isTrue();
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
requestFactory.stop();
|
requestFactory.stop();
|
||||||
assertThat(requestFactory.isRunning()).isFalse();
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
|
requestFactory.start();
|
||||||
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void restartWithHttpClient() {
|
||||||
|
HttpClient httpClient = HttpClient.create();
|
||||||
|
ReactorNettyClientRequestFactory requestFactory = new ReactorNettyClientRequestFactory(httpClient);
|
||||||
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
|
requestFactory.start();
|
||||||
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
|
requestFactory.stop();
|
||||||
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
requestFactory.start();
|
requestFactory.start();
|
||||||
assertThat(requestFactory.isRunning()).isTrue();
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
@ -72,10 +85,12 @@ class ReactorNettyClientRequestFactoryTests extends AbstractHttpRequestFactoryTe
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void restartWithHttpClient() {
|
void lateStartWithExternalResourceFactory() {
|
||||||
HttpClient httpClient = HttpClient.create();
|
ReactorResourceFactory resourceFactory = new ReactorResourceFactory();
|
||||||
ReactorNettyClientRequestFactory requestFactory = new ReactorNettyClientRequestFactory(httpClient);
|
Function<HttpClient, HttpClient> mapper = Function.identity();
|
||||||
assertThat(requestFactory.isRunning()).isTrue();
|
ReactorNettyClientRequestFactory requestFactory = new ReactorNettyClientRequestFactory(resourceFactory, mapper);
|
||||||
|
assertThat(requestFactory.isRunning()).isFalse();
|
||||||
|
resourceFactory.start();
|
||||||
requestFactory.start();
|
requestFactory.start();
|
||||||
assertThat(requestFactory.isRunning()).isTrue();
|
assertThat(requestFactory.isRunning()).isTrue();
|
||||||
requestFactory.stop();
|
requestFactory.stop();
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sebastien Deleuze
|
* @author Sebastien Deleuze
|
||||||
|
* @since 6.1
|
||||||
*/
|
*/
|
||||||
class ReactorClientHttpConnectorTests {
|
class ReactorClientHttpConnectorTests {
|
||||||
|
|
||||||
|
|
@ -37,7 +38,20 @@ class ReactorClientHttpConnectorTests {
|
||||||
connector.start();
|
connector.start();
|
||||||
assertThat(connector.isRunning()).isTrue();
|
assertThat(connector.isRunning()).isTrue();
|
||||||
connector.stop();
|
connector.stop();
|
||||||
assertThat(connector.isRunning()).isFalse();
|
assertThat(connector.isRunning()).isTrue();
|
||||||
|
connector.start();
|
||||||
|
assertThat(connector.isRunning()).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void restartWithHttpClient() {
|
||||||
|
HttpClient httpClient = HttpClient.create();
|
||||||
|
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
|
||||||
|
assertThat(connector.isRunning()).isTrue();
|
||||||
|
connector.start();
|
||||||
|
assertThat(connector.isRunning()).isTrue();
|
||||||
|
connector.stop();
|
||||||
|
assertThat(connector.isRunning()).isTrue();
|
||||||
connector.start();
|
connector.start();
|
||||||
assertThat(connector.isRunning()).isTrue();
|
assertThat(connector.isRunning()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
@ -58,10 +72,12 @@ class ReactorClientHttpConnectorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void restartWithHttpClient() {
|
void lateStartWithExternalResourceFactory() {
|
||||||
HttpClient httpClient = HttpClient.create();
|
ReactorResourceFactory resourceFactory = new ReactorResourceFactory();
|
||||||
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
|
Function<HttpClient, HttpClient> mapper = Function.identity();
|
||||||
assertThat(connector.isRunning()).isTrue();
|
ReactorClientHttpConnector connector = new ReactorClientHttpConnector(resourceFactory, mapper);
|
||||||
|
assertThat(connector.isRunning()).isFalse();
|
||||||
|
resourceFactory.start();
|
||||||
connector.start();
|
connector.start();
|
||||||
assertThat(connector.isRunning()).isTrue();
|
assertThat(connector.isRunning()).isTrue();
|
||||||
connector.stop();
|
connector.stop();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue