幂等Amqp.inboundAdapter()

时间:2016-10-27 16:17:34

标签: spring-integration spring-amqp

我如何实现幂等Amqp.inboundAdapter()?

我尝试使用IdempotentReceiverInterceptor,但它不能与MessageProducers一起使用。

修改

@Bean
IntegrationFlow someFlow(/*...*/) {
    return IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, "myqueue")
        .transform(Transformers.fromJson(), c -> c.advice(idempotentInterceptor))
        .channel("anotherChannel.input")
        .get();
}

1 个答案:

答案 0 :(得分:0)

您可以简单地将拦截器应用于入站适配器下游的第一个组件。如果第一个频道是pub / sub,则添加一个桥。

或者,您可以编写自定义建议并将其添加到入站适配器的容器建议链中。

修改

@SpringBootApplication
public class So40289644Application {

    public static void main(String[] args) throws Exception {
        ConfigurableApplicationContext context = SpringApplication.run(So40289644Application.class, args);
        RabbitTemplate template = context.getBean(RabbitTemplate.class);
        template.convertAndSend("myqueue", "foo");
        template.convertAndSend("myqueue", "bar");
        context.getBean(CountDownLatch.class).await(10, TimeUnit.SECONDS);
        context.getBean(RabbitAdmin.class).declareQueue(new Queue("myqueue"));
        context.close();
    }

    @Bean
    public Jackson2JsonMessageConverter converter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public CountDownLatch latch() {
        return new CountDownLatch(1);
    }

    @Bean
    IntegrationFlow someFlow(ConnectionFactory connectionFactory) {
        return IntegrationFlows.from(Amqp.inboundAdapter(connectionFactory, "myqueue"))
                .channel("in")
                .get();
    }

    @Bean
    @Transformer(inputChannel = "in", adviceChain = "idempotentInterceptor", outputChannel = "next")
    public JsonToObjectTransformer transformer() {
        return Transformers.fromJson();
    }

    @Bean
    IntegrationFlow remaining() {
        return IntegrationFlows.from("next")
            .handle(m -> {
                System.out.println(m);
                latch().countDown();
            })
            .get();
    }

    @Bean
    public IdempotentReceiverInterceptor idempotentInterceptor() {
        IdempotentReceiverInterceptor interceptor = new IdempotentReceiverInterceptor(
                m -> !(new String(((byte[]) m.getPayload())).equals("\"foo\"")));
        interceptor.setDiscardChannel(new NullChannel());
        return interceptor;
    }

    @Bean
    public Queue queue() {
        return new Queue("myqueue");
    }