javaspringrestclientbuilder

Spring external client timeout


In our Spring Application we rely on an external system. We want to set a timeout on the requests to that system, but can't figure out how to configure this.

We use this:

   return clientBuilder.build()
            .target(baseUrl)
            .register(jsonProvider)
            .register(jsonAcceptHeaderClientRequestFilter)
            .register(new LoggingFilter());

I've tried this: How to set the connection and read timeout with Jersey 2.x? and many other suggestions, but can't get it to work. Any suggestions would be appreciated.

Update of things that do not work:

.property("http.connection.timeout", 1)
.property("http.receive.timeout", 1)

As well as

.property(ClientProperties.CONNECT_TIMEOUT,1)
.property(ClientProperties.READ_TIMEOUT,1)

Solution

  • As confirmed in the answer linked in your question, one of the comments by @df778899 and as per my tests, the below usage works alright, for jersey client

    target(baseUrl)
    .property(ClientProperties.CONNECT_TIMEOUT, 1000)
    .property(ClientProperties.READ_TIMEOUT, 1000)
    

    And produces java.net.SocketTimeoutException, if the external server fails to respond within the set time.

    For, Apache CXF client, I have tested below snippet and it works for read timeouts. And, this is the official reference. Search for the parameters used in the below snippet in that page.

    Note: For the versions from when this was supported, check this JIRA.

    target(baseUrl)
    .property("http.connection.timeout", 5000)
    .property("http.receive.timeout", 5000)
    

    Update : Below content may not be required by OP, but retaining for academics sake. .

    My hunch is, you are after a different goal. It seems to me that your external system is actually responding, but maybe at a rate slower than you would desire OR the response itself is bigger which in turn takes a longer time to consume than you desire?

    In such cases, you may tune the timeout parameters. But, they work on a recurrent socket read basis. So, consider that you set the timeout to X and your response data is Y bytes. A slow read may mean that a socket.read() call is coming out with data but the content is 1/2 bytes. X applies to each read. So the full read may, in theory take X*Y ms.

    If above is indeed your issue, then you may have to solve this using an external timekeeper. For example, you can:

    1. Make the external service call via ExecutorService.submit(Callable< T> task)
    2. And then, call resulting Future.get(long timeout, TimeUnit unit)