max
max

Reputation: 53

Mule 3.7 until successful failureExpression not working

I am using until-successful to retry calling a web service only when it is down.
Below is what I have tried:

<until-successful maxRetries="10" failureExpression="#[(message.inboundProperties['http.status'] != 200) &amp;&amp; (message.inboundProperties['http.status'] != 500)]" synchronous="true" millisBetweenRetries="5000">

<flow-ref name="callSubFlow" doc:name="Flow Reference"/>

If I get a HTTP response 500 I also do not want to retry calling the web service. I have mocked a web service and when it returns a HTTP 500 response the until successful keeps retrying calling the web service. What is wrong with the failureExpression above?

Thanks

Upvotes: 0

Views: 1445

Answers (3)

max
max

Reputation: 53

Here is how if fixed my issue. I created another flow that catches only the Web Service 500 error. The until -successful then does not retry to call the web service again.

<until-successful maxRetries="${webservice.timeout.max.retries}" failureExpression="#[exception != null &amp;&amp; (exception.causedBy(java.net.ConnectException) || exception.causedBy(java.net.SocketTimeoutException) || exception.causedBy(java.util.concurrent.TimeoutException) || exception.causedBy(java.net.SocketException))]" 
synchronous="true" millisBetweenRetries="5000" >
 <processor-chain doc:name="Processor Chain">


      <set-payload value="#[payLoad]" />
      <flow-ref name="Flow1" />

  </processor-chain>
</until-successful>

<flow name="Flow1">
<ws:consumer config-ref="WSConsumerConfig" operation="execute"  />
    <choice-exception-strategy doc:name="Choice Exception Strategy">


      <catch-exception-strategy doc:name="Catch Exception Strategy" when="#[exception != null &amp;&amp; exception.causedBy(org.mule.module.ws.consumer.SoapFaultException)]">

        <logger message="SoapFaultException occurred." level="INFO" doc:name="Logger"/>
        <set-payload value="#[exception]" doc:name="Set Payload"></set-payload>
     </catch-exception-strategy>

    </choice-exception-strategy>
</flow>

Upvotes: 1

Star
Star

Reputation: 1503

You also need to tell HTTP Request component that 500 is the Non-failure scenario in this case. Because By default 200 is the success scenario, other than anything needs to be mention in 'success-status-code-validator'.

<until-successful maxRetries="5" synchronous="true" doc:name="Until Successful" failureExpression="#[  message.inboundProperties['http.status'] != 200  &amp;&amp; message.inboundProperties['http.status'] != 500     ]" millisBetweenRetries="1000">
        <http:request config-ref="HTTP_Request_Configuration" path="test1" method="GET" doc:name="HTTP">
            <http:success-status-code-validator values="200,500"/>. 
        </http:request>
</until-successful>

Instead of Directly using HTTP here, Believe you used callSubFlow there where you used HTTP-request, mention in <http:success-status-code-validator values="200,500"/> as success. So it don't retry in this case, works as expected. If you want to handle 500 as separate logic other than 200, you can do condition check after http:request by checking its message.inboundProperties['http.status'] and can proceed with logic based on 200 or 500.

It is failed in your case, because Http-request saying '500' as failure and Until mentioned as Non-failure.

Upvotes: 0

tortoise
tortoise

Reputation: 613

There is a lot of confusion around this expression. As per documentation,

FAILURE : "A message processor within the until-successful scope throws an exception or contains an exception payload. Also, if an expression is provided in the attribute failureExpression and it evaluates to true."

https://docs.mulesoft.com/mule-user-guide/v/3.6/until-successful-scope#success-and-failure

The catch here is that with the current implementation of Mule 'failureExpression' is checked and used when no exception is thrown. Otherwise it does always retry in case of exception. Solution for your problem would be to have a catch block for particular exception and then set a property, in failureExpression evaluate that property to retry in until successful. Basically, you would be using recursion technique kind of code for retrying.

Example for your code:

<until-successful maxRetries="10" failureExpression="#[flowVars['errorInActualOutboundFlow']]" synchronous="true" millisBetweenRetries="5000">
   <flow-ref name="callActualOutboundFlow" doc:name="Flow Reference"/>
</until-successful>

Actual Outbound Flow:

 <flow name="callActualOutboundFlow" processingStrategy="synchronous">        
    <http:request config-ref="HTTP_Request_Configuration" path="/" method="GET" doc:name="HTTP"/>
    <choice-exception-strategy doc:name="Choice Exception Strategy"> 
        <catch-exception-strategy doc:name="Catch Exception Strategy" when="#[exception.causedBy(java.net.ConnectException)]">
           <logger message="#### Until-Successful will retry in this case " level="INFO" doc:name="Logger"/>
           <set-variable variableName="errorInActualOutboundFlow" value="#[true]" doc:name="Variable"/>
        </catch-exception-strategy>
        <catch-exception-strategy doc:name="Catch Exception Strategy">
            <set-variable variableName="errorInActualOutboundFlow" value="#[false]" doc:name="Copy_of_Variable"/>

Upvotes: 2

Related Questions