Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Incluindo timeout numa rota Camel

Olá pessoal,

Preciso incluir o timeout para uma requisição http/get originada de uma rota Camel. Já tentei de várias formas, mas sem conseguir sucesso. Vou resumir algumas das coisas que testei para achar essa solução e os motivos de não ter tido êxito em cada uma.

(1) Inicialmente, ao criar a rota usava os atributos:

    .keepAliveTime(3000)
    .timeUnit(TimeUnit.MICROSECONDS)

Mas esse atributo não define timeout. Como resultado, segue-se o que parece ser o tratamento padrão do Camel: 3 tentativas de conexão com o endpoint (deixado propositalmente inacessível) com lançamento de exceção. Segue trecho resumido:

    2018-08-24 16:55:55,048 DEBUG http-nio-8081-exec-2 httpclient.HttpMethodDirector:443 - Connection timed out: connect
java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
        at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
        at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
        at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
        at java.net.PlainSocketImpl.connect(Unknown Source)
        at java.net.SocksSocketImpl.connect(Unknown Source)
... more stack...
    at java.lang.Thread.run(Unknown Source)
2018-08-24 16:56:38,333  INFO http-nio-8081-exec-2 httpclient.HttpMethodDirector:445 - Retrying request
2018-08-24 16:56:38,417 DEBUG http-nio-8081-exec-2 httpclient.HttpConnection:692 - Open connection to 10.8.4.9:8080/service

(2) Ao ver a resposta a essa pergunta: https://stackoverflow.com/questions/52011044/manage-timeout-with-apache-camel testei adicionar o seguinte argumento na url do endpoint passada pra o Camel:

?httpClient.soTimeout=300

Mesmo resultado: 3 tentativas + exception

(3) Testei também controlar a quantidade máxima de tentativas e tratar a exception com os atributos abaixo, mas sem sucesso.

onException(ConnectException.class)
.maximumRedeliveries(0);

Tudo o que eu preciso, é o seguinte comportamento: numa única tentativa de chamada ao serviço, seja levantada uma exceção caso a resposta não seja dentro do tempo definido pelo timeout.

1 resposta
solução!

Oi Cássio,

Eu testei de um jeito que funcionou a configuração do timeout.

Basta você adicionar o seguinte código antes da configuração da sua rota:

HttpComponent httpComponent = camelContext.getComponent("http", HttpComponent.class);
httpComponent.setHttpClientConfigurer(new HttpClientConfigurer() {
    @Override
    public void configureHttpClient(HttpClient client) {
        DefaultHttpMethodRetryHandler retryhandler = new DefaultHttpMethodRetryHandler(0, false);
        client.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryhandler);
        client.getParams().setSoTimeout(5000); 
    }
});

No caso eu configurei para o componente HTTP somente tentar uma única vez, e que o timeout para esperar antes de jogar a exception seja de 5 segundos.

Mas no caso isso somente funciona se o serviço estiver online, mas demorar mais do que 5 segundos para responder.

Se tiver offline o camel já joga exception imediatamente, pois considera que o serviço está fora do ar, e não que ocorreu um timeout na chamada.