Можно ли использовать 2 разных компонента повторной попытки для одного активатора службы в зависимости от выброшенного исключения?

Я хотел бы сделать серьезную повторную попытку для службы-активатора только в случае ConnectionException, для других исключений я хотел бы не использовать повторную попытку или очень легкую повторную попытку. Какую конфигурацию я могу использовать? Суть моей конфигурации ниже:

<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>

person Alex    schedule 19.07.2016    source источник


Ответы (1)


Нет, вы не можете использовать один совет по повторной попытке одновременно с другим. Стратегия <request-handler-advice-chain> состоит в том, чтобы оборачивать один совет в другой в том порядке, в котором они настраиваются в рамках <request-handler-advice-chain>. Итак, если вы объявите один retryAdvice, а затем другой, первый не будет достигнут, пока второй не закончит свою работу.

Я еще не вижу всей картины, как легко выполнить ваши требования, но я действительно уверен, что вам следует иметь дело с пользовательским RetryPolicy, где вы можете достичь целевого исключения через:

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

Обратите внимание на этот полезный объект RetryContext.

Также интересен хук как RetryListener абстракция, с помощью которой вы можете установить некоторые дополнительные атрибуты в этот RetryContext. Например в SI RequestHandlerRetryAdvice:

public <T, E extends Throwable> boolean open(RetryContext context, RetryCallback<T, E> callback) {
    context.setAttribute("message", messageHolder.get());
    return true;
}
person Artem Bilan    schedule 19.07.2016
comment
Вы имеете в виду ExceptionClassifierRetryPolicy? Если да, нужно ли мне перезаписать его моим пользовательским классом или я могу настроить его в XML? - person Alex; 20.07.2016
comment
1. Вы должны реализовать свой собственный RetryPolicy. Да ExceptionClassifierRetryPolicy может быть для вас образцом. 2. После этого вы можете настроить его в XML как обычный <bean> и внедрить в RetryTemplate bean-компонент. - person Artem Bilan; 20.07.2016