Spring 服务激活器映射到kafka成功通道作为输入通道,但未能在kafka发送成功时执行

Spring 服务激活器映射到kafka成功通道作为输入通道,但未能在kafka发送成功时执行,spring,apache-kafka,spring-integration,spring-kafka,Spring,Apache Kafka,Spring Integration,Spring Kafka,所以我已经为Kafka出站消息适配器配置了成功和失败通道,这样我就可以根据Kafka发布的结果进行一些后处理 @Bean public KafkaProducerMessageHandler<String, String> kafkaProducerMessageHandler() { KafkaProducerMessageHandler<String, String> handler = new KafkaProducerMessageHandler<&

所以我已经为Kafka出站消息适配器配置了成功和失败通道,这样我就可以根据Kafka发布的结果进行一些后处理

@Bean
public KafkaProducerMessageHandler<String, String> kafkaProducerMessageHandler() {
    KafkaProducerMessageHandler<String, String> handler = new KafkaProducerMessageHandler<>(kafkaTemplate());
    handler.setHeaderMapper(mapper());
    handler.setLoggingEnabled(TRUE);
    handler.setTopicExpression(
            new SpelExpressionParser()
                    .parseExpression(
                            "headers['" + upstreamType + "'] + '_' + headers['" + upstreamTypeInstance + "']"));
    handler.setMessageKeyExpression(new SpelExpressionParser().parseExpression("payload['key']"));
    handler.setSendSuccessChannel(kafkaPublishSuccessChannel());
    handler.setSendFailureChannel(kafkaFailuresChannel());
    return handler;
} 
我希望在未成功发布的情况下调用service activator

@Test
public void testPushNotificationIsSavedToMongo(
        @Value("classpath:webhooks/jira/test-payload.json") Resource jiraWebhookPayload) throws IOException, InterruptedException {

    //publish messsge to KAfka TOpic
      ...
    //assert message saved in MongoDB
    assertThat(mongoTemplate.findAll(DBObject.class, "alm_jira_some-project")).extracting("key")
            .containsOnly("JRASERVER-2000");
}

最后一个断言失败,并且在日志中,在producer发布到topic之后,我没有看到任何对success channel的调用。

正如Gary在他的评论中所说的那样,
sendSuccessChannel
是在与主JUnit运行程序不同的线程上异步调用的。它实际上是对Kafka客户端中
Future
completion的回调

因此,为了确保在发送到Kafka后所有内容都已登录到MongoDB,您需要更复杂的断言,而不仅仅是一个简单的
findAll()
。您需要在一段时间内多次迭代这样的调用,以确保其他线程已经完成了将消息发送到该通道并将文档存储到MongoDb集合中的工作


为此,我可以推荐一个我们在自己的测试中真正使用的等待工具:

您在等待成功消息吗?它在不同的线程上异步返回,因此您需要某种机制来等待它发生。e、 g.通道拦截器对锁存器进行倒计时。调用
setSync(true)
是否仅用于测试帮助?
@Test
public void testPushNotificationIsSavedToMongo(
        @Value("classpath:webhooks/jira/test-payload.json") Resource jiraWebhookPayload) throws IOException, InterruptedException {

    //publish messsge to KAfka TOpic
      ...
    //assert message saved in MongoDB
    assertThat(mongoTemplate.findAll(DBObject.class, "alm_jira_some-project")).extracting("key")
            .containsOnly("JRASERVER-2000");
}