0

Spring Retry を組み込んだ Spring Integration プロジェクトを継承しました。それがテストされたことがあるかどうかはわかりませんし、個別のテストもありません。そのため、単純なシナリオでそれを実行しようとしています。

RestTemplateexchangeメソッドをモックすることで、再試行ロジックをテストできるようにしたいと考えています。発生させたい例外を取得できますが、発生するのは 1 回だけです。再試行は行われません。

再試行アドバイスの XML は次のとおりです (retry-advice-context.xml):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

    <bean id="retryAdvice" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice" >
        <property name="retryTemplate">
            <bean class="org.springframework.retry.support.RetryTemplate">
                <property name="backOffPolicy">
                    <bean class="org.springframework.retry.backoff.ExponentialBackOffPolicy">
                        <property name="initialInterval" value="${retry.initialInterval}"/>
                        <property name="maxInterval" value="${retry.maxInterval}"/>
                        <property name="multiplier" value="${retry.multiplier}"/>
                    </bean>
                </property>

                <property name="retryPolicy">
                    <bean class="com.reachlocal.mediapublishing.shim.integration.retry.CustomRetryPolicy">
                        <constructor-arg name="maxAttempts" value="${retry.maxAttempts}" />
                        <constructor-arg name="retryableExceptions" ref="retryableExceptions" />
                    </bean>
                </property>
            </bean>
        </property>

        <property name="recoveryCallback">
            <bean class="org.springframework.integration.handler.advice.ErrorMessageSendingRecoverer">
                <constructor-arg ref="errorChannel" />
            </bean>
        </property>
    </bean>

    <util:map id="retryableExceptions"  map-class="java.util.HashMap" >
        <entry key="java.net.SocketException" value="true" />
        <entry key="com.examplel.ConnectionException" value="true" />
        <entry key="com.example.CustomException" value="true" />
    </util:map>

</beans>

以下は、SI 処理ファイルの一部です。

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:int="http://www.springframework.org/schema/integration"
       xmlns="http://www.springframework.org/schema/beans"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">

    <import resource="retry-advice-context.xml"/>

    <int:channel id="channel1">
    </int:channel>

    <int:header-value-router id="commandTypeRouter" input-channel="commandChannel"  <---DEFINED IN MASTER FILE
                             header-name="commandType" resolution-required="true">
        <int:mapping value="COMMAND_1" channel="channel1"/>
    </int:header-value-router>

    <int:chain id="command1Chain" input-channel="channel1" output-channel="commandProcessed">
        <int:header-enricher>
            <int:error-channel ref="errorChannel" />
        </int:header-enricher>
        <int:service-activator ref="eventDataWriter" method = "addEventStart"/>

        <int:service-activator ref="accountProcessor" method="processAccount">
            <int:request-handler-advice-chain><ref bean="retryAdvice" /></int:request-handler-advice-chain>
        </int:service-activator>
    </int:chain>
</beans>

したがって、再試行 BeanretryAdviceは、さまざまなチェーンの一部です。チェーンには他にもたくさんあるので、サービス層からの再試行ロジックをチェックできるようにしたいだけです。コードのどこにも Retry アノテーションはありません (必要かどうかはわかりません)。

いくつかの質問:

  1. サービス層から再試行機能をテストできますか? それともチェーン全体を実行する必要がありますか?
  2. 再試行メカニズムに必要なもの (注釈、その他の XML) が不足していませんか?

ところで、これは SI 4.1.3 を使用しています。

ありがとう。

更新 1:

私の環境で Gary のプロジェクトを実行することができました。その後、retry-advice-context.xmlファイルをメインの SI xml に追加しました。マップのみを含むように変更しRuntimeExceptionました。ログステートメントはExponentialBackoffPolicyステートメントを示しました。RetryTemplateデバッグ ログ ステートメントも取得していました。

もう少し理解を深めて、そこにあったものを実際のコードに翻訳し、より多くの成功を収めました。例外が発生し、最大 3 回再試行されるというログ ステートメントが表示されます。

残念ながら、私が得るものは次のとおりです。

17:29:26.154 DEBUG [task-scheduler-2][org.springframework.retry.support.RetryTemplate] Checking for rethrow: count=1
17:29:26.155 DEBUG [task-scheduler-2][org.springframework.retry.support.RetryTemplate] Retry failed last attempt: count=1

そのため、最初は最大 3 回再試行する必要があることを認識しています。しかし、1回の再試行の後に最後の試行が行われたと述べています。

Gary の作業コードでは、デバッグ ステートメントはRetry: count=2次の連続する試行に対して etc... を表示します。

sleepスポック テスト コードには、再試行が行われている間にステートメントがあります。そのまま時間を長くしたり短くしたりしました。

再試行コードを引き続き試行してデバッグし、1 回目の再試行で停止する理由を確認します。

4

1 に答える 1

1

追加の注釈や XML は必要ありません。

チェーンとサービスのid属性を指定すると、ハンドラーを個別にテストできます...

<int:chain id="myChain" input-channel="foo">
    <int:transformer expression="payload" />
    <int:service-activator id="myService" ref="bar">
        <int:request-handler-advice-chain>
            <int:ref bean="retry" />
        </int:request-handler-advice-chain>
    </int:service-activator>
</int:chain>

<bean id="retry" class="org.springframework.integration.handler.advice.RequestHandlerRetryAdvice" />

<bean id="bar" class="com.example.Bar" />

あるとBar...

public class Bar {

    private int count;

    public void bar(String in) {
        System.out.println(in);
        if (count++ < 2) {
            throw new RuntimeException("foo");
        }
    }

}

テスト:

public class So39604931ApplicationTests {

    @Autowired
    @Qualifier("myChain$child.myService.handler")
    public MessageHandler handler;

    @Test
    public void test() {
        handler.handleMessage(new GenericMessage<>("foo"));
    }

}

結果:

foo
foo
foo

org.springframework.retryまた、再試行の動作を確認するには、デバッグ ログをオンにする必要があります。

08:51:16.897 [main] DEBUG o.s.retry.support.RetryTemplate - Retry: count=0
foo
08:51:16.902 [main] DEBUG o.s.retry.support.RetryTemplate - Checking for rethrow: count=1
08:51:16.902 [main] DEBUG o.s.retry.support.RetryTemplate - Retry: count=1
foo
08:51:16.903 [main] DEBUG o.s.retry.support.RetryTemplate - Checking for rethrow: count=2
08:51:16.903 [main] DEBUG o.s.retry.support.RetryTemplate - Retry: count=2
foo
于 2016-09-21T12:49:40.717 に答える