2015-03-19 4 views
1

Я создал простой пример, чтобы узнать о повторных попытках и советах. Вот пример конфигурации:Повторные попытки и советы по интеграции весов

@Configuration 
@EnableIntegration 
@IntegrationComponentScan 
@ComponentScan 
public class SimpleConfiguration2 { 
    @Bean 
    public DirectChannel requestChannel() { 
    return new DirectChannel(); 
    } 

    @Bean 
    public DirectChannel aChannel() { 
    return new DirectChannel(); 
    } 

    @Bean 
    public DirectChannel retryLaterChannel() { 
    return new DirectChannel(); 
    } 

    @Bean 
    public DirectChannel tapChannel() { 
    return new DirectChannel(); 
    } 

    @Bean 
    public DirectChannel endChannel() { 
    return new DirectChannel(); 
    } 

    @Bean 
    public ExceptionThrowingTransformer exceptionThrowingTransformer() { 
    return new ExceptionThrowingTransformer(); 
    } 

    @Bean 
    public IntegrationFlow initFlow() { 
    return IntegrationFlows.from(requestChannel()) 
          .gateway(aChannel(), e -> e.advice(retryAdvice()) 
                 .errorChannel(retryLaterChannel())) 
          .get(); 
    } 

    @Bean 
    public Advice retryAdvice() { 
    final RequestHandlerRetryAdvice advice = new RequestHandlerRetryAdvice(); 
    advice.setRetryTemplate(retryTemplate()); 
    return advice; 
    } 

    @Bean 
    public RetryTemplate retryTemplate() { 
    final RetryTemplate ret = new RetryTemplate(); 
    ret.setRetryPolicy(retryPolicy()); 
    ret.setThrowLastExceptionOnExhausted(false); 
    return ret; 
    } 

    @Bean 
    public RetryPolicy retryPolicy() { 
    final Map<Class<? extends Throwable>, Boolean> map = new HashMap<Class<? extends Throwable>, Boolean>() {{ 
     put(RuntimeException.class, true); 
     } 
     private static final long serialVersionUID = -1L; 
    }; 
    final RetryPolicy ret = new SimpleRetryPolicy(3, map, true); 
    return ret; 
    } 

    @Bean 
    public IntegrationFlow aChannelFlow() { 
    return IntegrationFlows.from(aChannel()) 
          .transform("C: "::concat) 
          .transform(exceptionThrowingTransformer()) 
          .channel(endChannel()) 
          .get(); 
    } 

    @Bean 
    public IntegrationFlow endFlow() { 
    return IntegrationFlows.from(endChannel()) 
          .handle(String.class, (p, h) -> p) 
          .get(); 
    } 

    @Bean 
    public IntegrationFlow retryLaterFlow() { 
    return IntegrationFlows.from(retryLaterChannel()) 
          .wireTap(tapChannel()) 
//       .bridge(null) 
//       .handle(String.class, (p, h) -> p) 
          .get(); 
    } 

    @Bean 
    public IntegrationFlow tapFlow() { 
    return IntegrationFlows.from(tapChannel()) 
          .handle(m -> System.err.println("tap [" + Thread.currentThread().getName() + "] " + m.getPayload())) 
          .get(); 
    } 
} 

и вот ExceptionThrowingTransformer:

public class ExceptionThrowingTransformer implements GenericTransformer<String, String> { 
    @Override 
    public String transform(final String source) { 
    printAndThrow(); 
    return Thread.currentThread().getName() + " " + source; 
    } 

    private void printAndThrow() { 
    if(numFail > 0) { 
     numFail--; 
     final String msg = numFail > 0 ? " will fail " + numFail + " more times" 
            : "last failure"; 
     System.out.println(Thread.currentThread().getName() + " ExceptionThrowingTransformer " + msg); 
     throw new RuntimeException(); 
    } 
    } 
    private static int numFail = 2; 
} 

Вот тестовый модуль:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = SimpleConfiguration2.class) 
public class DependenciesApplicationTests { 
    @Test 
    public void t1() { 
    System.out.println(gw.echo("MSG1")); 
    } 

    @Autowired 
    private EchoGateway gw; 
} 

и эхо-шлюз:

@MessagingGateway(defaultReplyTimeout=600) 
public interface EchoGateway { 
    @Gateway(requestChannel = "requestChannel") 
    String echo(String message); 
} 

Вопрос 1: Если я запускаю код, как есть, для ввода «msg1», который получает помещенный на requestChannel, я получаю следующий результат:

main ExceptionThrowingTransformer will fail 1 more times 
tap [main] org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException 
main ExceptionThrowingTransformer last failure 
tap [main] org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException 
main C: MSG1 

тогда как я ожидал бы увидеть что-то вроде:

main ExceptionThrowingTransformer will fail 1 more times 
main ExceptionThrowingTransformer last failure 
main C: MSG1 

повторение происходит, но все же исходное исключение распространяется на errorChannel, указанный в шлюзе initFlow. Есть ли способ предотвратить это?

Вопрос 2: Когда numFail изменяется на 3, к тому же выход, как в вопросе 1, исключение возвращается вызывающему:

org.springframework.messaging.MessagingException: failure occurred in error-handling flow; nested exception is org.springframework.messaging.MessageDeliveryException: Dispatcher has no subscribers for channel 'application:-1.retryLaterChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers 

Если только первый комментарий в retryLaterFlow является раскомментирована, исключение брошено исключениеThrowingTransformer возвращается вызывающему. Почему это, учитывая, что retryTemplate имеет setThrowLastExceptionOnExhausted (false)?

Вопрос 3: Если только второй комментарий в retryLaterFlow является раскомментирована, выход выглядит следующим образом:

main ExceptionThrowingTransformer will fail 2 more times 
tap [main] org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException 
org.springframework.integration.transformer.MessageTransformationException: ; nested exception is org.springframework.messaging.MessageHandlingException: ; nested exception is java.lang.RuntimeException 

Почему не повторная попытка вступить в силу? (Ответ на вопрос 1 также может ответить на этот вопрос)

ответ

0

У вас есть два шлюза (начальный и средний поток), и вы консультируете шлюз с промежуточным потоком, чтобы он работал должным образом.

Вы должны сообщить об этом трансформатору, чтобы получить ожидаемый результат.

Смежные вопросы