wso2timeoutjmsesbproducer

WSO2 esb as a jms producer with failover transport timeout


Using wso2 esb 4.9.0, I would like to have an HTTP api pushing messages in a JMS queue (activemq). The jms send should use failover, but if none of the activemq brokers are available, it should execute the faultsequence after a timeout (for example 15 secondes) (In the faultsequence, an http response should be send to the original client with an http error code 500 and a JSON body)

I tried using the following url for my activemq connection factory:

<parameter name="java.naming.provider.url" locked="false">failover:(tcp://localhost:61616)?timeout=3000</parameter>

I also tried setting the timeout parameter in the uri in my api.xml (omitting other parameters):

<send>
    <endpoint>
        <address uri="jms:/MyQueue?java.naming.provider.url=failover:(tcp://localhost:616161)?timeout=3000"/>
    </endpoint>
</send>

My api still blocks indefinitely when I kill all my activemq brokers:

curl -XPOST -H "Content-Type: application/json" -d '{}' -k "https://localhost:8243/myApi/send"
^C # I have to kill it manually; instead it should return an error

How do I implement this with wso2 esb ?

See the activemq failover transport reference for the documentation of the timeout parameter : http://activemq.apache.org/failover-transport-reference.html

Notes

Under the Failover transport send operations will, by default, block indefinitely when the broker becomes unavailable. There are two options available for handling this scenario. First, either set a TransportListener directly on the ActiveMQConnectionFactory, so that it is in place before any request that may require a network hop or second, set the timeout option. The timeout option causes the current send operation to fail after the specified timeout.

Example:

failover:(tcp://primary:61616)?timeout=3000

In this example if the connection isn't established the send operation will timeout after 3 seconds. It is important to note that the connection is not killed when a timeout occurs. It is possible, therefore, to resend the affected message(s) later using the same connection once a broker becomes available.


Solution

  • In my case this was a connection creation so setting startupMaxReconnectAttempts=X allowed me to "timeout" after a number of reconnection attempts. With the default settings (exponential backoff), a value of X=10 timeouts after about 5 seconds. So I used

    <address uri="jms:/MyQueue?java.naming.provider.url=failover:(tcp://localhost:616161)?startupMaxReconnectAttempts=10"/>