How to abort just one request in 'rest-assured' framework?
For example, in 'apache' we could do after executing:
request.abort();
You can do time out like this. or is there is a specific case when you want to abort?
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000)
.setSocketTimeout(5000).build();
HttpClientConfig httpClientFactory = HttpClientConfig.httpClientConfig()
.httpClientFactory(() -> HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).build());
RestAssured.config = RestAssured.config().httpClient(httpClientFactory);
Related
I use a httpClient of apache in java to call REST APIs which is configured as below in a static block of class, what I want is to change the connection timeout per request. is it possible? how?
static {
PoolingHttpClientConnectionManager pool = new PoolingHttpClientConnectionManager();
pool.setMaxTotal(ChatSettings.HTTP_CLIENT_THREAD_POOL_SIZE);
httpClient = HttpClients
.custom()
.setConnectionManager(pool)
.setDefaultRequestConfig(
RequestConfig
.custom()
.setConnectTimeout(DEFAULT_HTTP_TIMEOUT)
.setSocketTimeout(DEFAULT_HTTP_TIMEOUT)
.build()
)
.build();
}
One thing you can implement for sure is to follow this example: https://github.com/apache/httpcomponents-client/blob/5.1.x/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientAbortMethod.java
It demonstrates how a client can fire a request, but eventually change it's mind and tell the server it no longer wants to receive the response.
Combine this with a 'watchdog' thread that fires after some time/when the time runs out.
I'm developing an SSE-client using WebFlux. What I want to achieve is to setup the client in a way, that
it automatically reconnects to the SSE-server, if the SSE-server was temporarily not available
it can also connect during run time, in case the SSE-server wasn't present from the start.
However, as far as I understand JavaScript-based clients, they are basically able to fulfill (1) and (2).
My question: is there a way to configure a WebFlux client to show the desired behaviors (1) and (2) (ideally "declaratively" via a builder and fluent coding style)? - I didn't find any information on how to do this, however, I assume that those are standard requirements for an SSE-client.
Here the basic code I'm using for my tests:
final SslContext sslContext
= SslContextBuilder
.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE)
.build();
final HttpClient httpClient
= HttpClient
.create()
.secure(t -> t.sslContext(sslContext));
final WebClient client
= WebClient
.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
final ParameterizedTypeReference<ServerSentEvent<String>> type = new ParameterizedTypeReference<ServerSentEvent<String>>() {};
final Flux<ServerSentEvent<String>> eventStream
= client.get()
.uri(endpointURL)
.exchange()
.flatMapMany(it -> it.bodyToFlux(type))
.repeat();
eventStream
.subscribe(
this::updateInformation
, error -> LOGGER.error("Error - {}", error.getMessage())
, () -> LOGGER.info("Got event stream completion signal."));
Spring docs says it is required to configure http client for WebClient manually to set timeouts: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder-reactor-timeout.
But since WebClient returns reactive Mono, it's possible (api-wise) to apply .timeout method.
Does it have the same effect?
Moreover, when one uses .timeout method, Reactor's TimeoutException is expected. Will the same error appear in the stream if configuration is done manually i.e. will doOnError(TimeoutException.class, ...) work?
My findings
Setting a timeout in a http client specific way will lead to http client specific exception i.e. WebClient doesn't wrap exceptions:
#Test
void test() {
var host = "localhost";
var endpoint = "/test";
var port = 8089;
var timeout = Duration.ofSeconds(3);
WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089));
wireMockServer.start();
WireMock.configureFor(host, wireMockServer.port());
WireMock.stubFor(get(urlEqualTo(endpoint))
.willReturn(aResponse().withFixedDelay((int) timeout.toMillis())));
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(client ->
client.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler((int) (timeout.toSeconds() / 2)))
.addHandlerLast(new WriteTimeoutHandler((int) (timeout.toSeconds() / 2)))));
WebClient webClient = WebClient.builder()
.baseUrl(format("http://%s:%d", host, port))
.clientConnector(new ReactorClientHttpConnector(httpClient)).build();
webClient.get().uri(endpoint).retrieve().bodyToMono(Recommendation.class).block();
}
This will lead to io.netty.handler.timeout.ReadTimeoutException.
.timeout(timeout.dividedBy(2)).block() leads to regular TimeoutException (java.util.concurrent) but it's still an open question whether a web client takes care about connections afterwards (probably not).
My solution is to use http client specific configuration to ensure native and correct way to utilize connections while adding new handler that wraps http client related exception into more generic ones (or java.util.concurrent.TimeoutException) so that WebClient clients won't depend on provider exceptions.
I am instantiating an Apache HTTP Components HttpClient using the following code:
CloseableHttpClient httpClient = HttpClients.custom()
.setProxy(new HttpHost(proxyServerAddress, proxyServerPort))
.disableConnectionState()
.disableCookieManagement()
.build();
But I would like to set the proxy only if an property (e.g. useProxy) is set to true. I can use an if-then-else pair of blocks based on the property value, but I was wondering if there is a better way to achieve this? My goal is to externalize the control of whether or not to use a proxy, using a configuration file property or via JAVA_OPTS.
How about:
HttpClientBuilder builder = HttpClients.custom()
.disableConnectionState()
.disableCookieManagement();
if( useProxy )
builder = builder.setProxy(new HttpHost(proxyServerAddress, proxyServerPort));
CloseableHttpClient httpClient = builder.build();
I have a problem I can't seem to grasp.
My relevant code is
final Builder requestConfigBuilder = RequestConfig.custom();
...
final HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setDefaultCookieStore();
clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
...
If I use this client I get from my builder, I can see all cookies being sent in my request as I would expect.
However, adding a cookie spec, like this:
final Builder requestConfigBuilder = RequestConfig.custom();
...
requestConfigBuilder.setCookieSpec(CookieSpecs.DEFAULT); //this causes problems
final HttpClientBuilder clientBuilder = HttpClientBuilder.create();
clientBuilder.setDefaultCookieStore(someCookieStoreVariable);
clientBuilder.setDefaultRequestConfig(requestConfigBuilder.build());
...
I see no cookies being sent in my request. The result is the same no matter which spec I choose from CookieSpecs.
Am I misunderstanding or misusing this, why doesn't this work? Is there some problem with me setting another cookiestore? I do need it for future references so it has to stay.
Check whether cookie domain and path are set properly.