1

I would like to do a serious retry for the service-activator only in case of a ConnectionException, for other exceptions I would like not to use a retry or a very light retry. What configuration can I use? The essence of my configuration is below:

<int:channel id="sDZCreationErrorChannel">
    <int:interceptors>
        <int:wire-tap channel="errorLogger"/>
    </int:interceptors>
</int:channel>

<int:channel id="sDZConnectionErrorChannel">
    <int:interceptors>
        <int:wire-tap channel="errorLogger"/>
    </int:interceptors>
</int:channel>

<int:chain input-channel="sDZCreationErrorChannel" output-channel="outboundMailChannel">
    <int-mail:header-enricher>
        <int-mail:to value="${integration.sdz.email.to}"/>
        <int-mail:subject value="${integration.sdz.email.subject.creation}"/>
    </int-mail:header-enricher>
    <int:transformer ref="integrationEmailTransformer" method="transformToEmail"/>
</int:chain>

<int:chain input-channel="sDZConnectionErrorChannel" output-channel="outboundMailChannel">
    <int-mail:header-enricher>
        <int-mail:to value="${integration.sdz.email.to}"/>
        <int-mail:subject value="${integration.sdz.email.subject.noconnection}"/>
    </int-mail:header-enricher>
    <int:transformer ref="integrationEmailTransformer" method="transformToEmail"/>
</int:chain>

<int:channel id="sDZCreationChannel">
    <int:queue/>
</int:channel>

<!-- Processing Creation Chain -->
<int:chain input-channel="sDZCreationChannel" output-channel="debugLogger" 
    auto-startup="#{environment.getProperty('sd.zoo.enabled') == 'connect'}">
    <int:poller fixed-delay="500" />
    <int:filter ref="sDZIntegrationExistingRequestSentFilter" method="filter"/>
    <int:transformer ref="sDZCreationTransformer" method="transformOrder"/>
    <int:service-activator ref="sDZCreationServiceImpl" method="activateConfirmationCodes">
        <int:request-handler-advice-chain>
            <ref bean="retryAdvice"/>
        </int:request-handler-advice-chain>
    </int:service-activator>
</int:chain>

<int:exception-type-router input-channel="errorChannel" default-output-channel="integrationDeadLetterErrorChannel">
    <int:mapping exception-type="com.smartdestinations.connect.integration.exception.sdz.SDZCreationResponseException" channel="sDZCreationErrorChannel"/>
    <int:mapping exception-type="com.smartdestinations.connect.integration.exception.sdz.SDZConnectionException" channel="sDZConnectionErrorChannel"/>
</int:exception-type-router>
Alex
  • 7,007
  • 18
  • 69
  • 114

1 Answers1

1

No, you can't use one retry advice alongside with other. The <request-handler-advice-chain> strategy is to wrap one advice into another with the order how they are configured within the <request-handler-advice-chain>. So, if you declare one retryAdvice and then another, the first one won't be reached until the second will finish its work.

I don't see the whole picture yet how to easy achieve your requirements, but I really sure that you should deal with custom RetryPolicy, where you can reach a target exception via:

public boolean canRetry(RetryContext context) {
    Throwable t = context.getLastThrowable();
    ...
}

Pay attention to that useful RetryContext object.

There is also interested hook as a RetryListener abstraction with which you can set some additional attributes into that RetryContext. For example in the SI RequestHandlerRetryAdvice:

public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
    context.setAttribute("message", messageHolder.get());
    return true;
}
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • Do you mean ExceptionClassifierRetryPolicy? If yes, do I need to overwrite it by my custom class or I can configure it in XML? – Alex Jul 19 '16 at 21:45
  • 1. You have to implement your own `RetryPolicy`. Yes `ExceptionClassifierRetryPolicy` can be as sample for you. 2. You can to configure it in the XML afterward as regular `` and inject it into `RetryTemplate` bean. – Artem Bilan Jul 19 '16 at 21:49