簡體   English   中英

Spring Cloud Contracts - 沒有為主題設置消費者 [...]

[英]Spring Cloud Contracts - No consumer set up for topic [...]

我目前正在使用 Spring Cloud Contracts 開發 API 兼容性檢查。 我按照文檔說的設置了所有內容。 但是我遇到了一個問題 - java.lang.IllegalStateException: No consumer set up for topic [testSyncTopic] 該異常在KafkaStubMessages類中拋出。 所以我認為這是與圖書館相關的問題。 在我的項目中,我有兩個單獨的 Maven 項目。 他們每個人都是消費者和生產者(不同的主題)。 我的合同放在其他存儲庫中。

所以......我目前正在處理的場景是:我們有 2 個模塊 - 模塊 A 和 B。模塊 A 在主題 T1 和 T2 上向 Kafka 主題 t1 和 t2 發送消息,並從主題 T3 和 T4 接收消息 t3 和 t4 . 模塊 B 從 T1 和 T2 接收並發送到 T3 和 T4。

所有消費者測試都在每個模塊中通過。 但是生產者測試最終會出現主題中提到的錯誤。

我懷疑這是由存根創建錯誤引起的。 所以沒有設置合適的監聽器。

我嘗試了不同的 kafka 配置,但我相信事實並非如此。 我還檢查了 spring 雲合同配置,但一切似乎都正常。 生成帶有存根的適當 jar。 不幸的是,谷歌在這件事上幫不上什么忙。

如果您需要任何信息來幫助我,請隨時詢問。 我現在正在研究它幾天,所以我很絕望,真的需要你的幫助。

編輯:添加了堆棧跟蹤和相關代碼片段

堆棧跟蹤:

java.lang.IllegalStateException: No consumer set up for topic [testSyncTopic]

at org.springframework.cloud.contract.verifier.messaging.kafka.Receiver.receive(KafkaStubMessages.java:110)
at org.springframework.cloud.contract.verifier.messaging.kafka.KafkaStubMessages.receive(KafkaStubMessages.java:80)
at org.springframework.cloud.contract.verifier.messaging.kafka.KafkaStubMessages.receive(KafkaStubMessages.java:42)
at com.comarch.fsm.dispatcher.rest.ContractBaseTest.setup(ContractBaseTest.groovy:56)

基礎測試類配置:

@SpringBootTest
@EmbeddedKafka(bootstrapServersProperty = "spring.kafka.bootstrap-servers", brokerProperties = ["log.dir=target/embedded-kafka"])
@AutoConfigureStubRunner
abstract class BaseTestConfig extends Specification {
}

我的合同定義:

Pattern customDateTime() {
    Pattern.compile('([0-9]{4})-(1[0-2]|0[1-9])-(0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])Z')
}

Contract.make {
    label("sync")
    input {
        triggeredBy("sync()")
    }
    outputMessage {
        sentTo("testSyncTopic")
        body(
                syncStart: $(customDateTime())
        )
    }
}

ContractBaseTest 類:

abstract class ContractBaseTest extends BaseTestConfig {

    @Autowired
    private KafkaService kafkaService;

    def synchronizeData() {
        kafkaService.sendKafkaMessage("testSyncTopic", null, new SyncDto(new Date()));
    }
}

為什么你的基礎測試類有@AutoConfigureStubRunner它應該有@AutoConfigureMessageVerifier 看來您正在混合消費者和生產者方面。

請在此處查看 Kafka 生產者的示例: https : //github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_kafka 出於可讀性原因,我將復制粘貼到這里。

制作人

基類: https : //github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_kafka/src/test/java/com/example/BaseClass.java

package com.example;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
// remove::start[]
import org.springframework.cloud.contract.verifier.messaging.boot.AutoConfigureMessageVerifier;
import org.springframework.kafka.test.context.EmbeddedKafka;
// remove::end[]
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
// remove::start[]
@AutoConfigureMessageVerifier
@EmbeddedKafka(partitions = 1, topics = {"topic1"})
// remove::end[]
@ActiveProfiles("test")
public abstract class BaseClass {

    @Autowired
    Controller controller;

    public void trigger() {
        this.controller.sendFoo("example");
    }
}

在這里你可以找到控制器

package com.example;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import com.common.Foo1;

/**
 * @author Gary Russell
 * @since 2.2.1
 */
@RestController
public class Controller {

    @Autowired
    private KafkaTemplate<Object, Object> template;

    @PostMapping(path = "/send/foo/{what}")
    public void sendFoo(@PathVariable String what) {
        this.template.send("topic1", new Foo1(what));
    }

}

在這里你可以看到生產配置( application.yml

spring:
  kafka:
    producer:
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
logging.level.org.springframework.cloud.contract: debug

在這里你可以看到測試配置( application-test.yml

spring:
  kafka:
    bootstrap-servers: ${spring.embedded.kafka.brokers}
    consumer:
      properties:
        "key.serializer": "org.springframework.kafka.support.serializer.JsonSerializer"
        "key.deserializer": "org.springframework.kafka.support.serializer.JsonDeserializer"
      group-id: groupId

和合同( https://github.com/spring-cloud-samples/spring-cloud-contract-samples/blob/master/producer_kafka/src/test/resources/contracts/shouldSendFoo.groovy

import org.springframework.cloud.contract.spec.Contract

Contract.make {
    label("trigger")
    input {
        triggeredBy("trigger()")
    }
    outputMessage {
        sentTo("topic1")
        body([
                foo: "example"
        ])
    }
}

消費者

現在是消費者的時間( https://github.com/spring-cloud-samples/spring-cloud-contract-samples/tree/master/consumer_kafka

package com.example;

import org.assertj.core.api.BDDAssertions;
import org.awaitility.Awaitility;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
// remove::start[]
import org.springframework.cloud.contract.stubrunner.StubTrigger;
import org.springframework.cloud.contract.stubrunner.spring.AutoConfigureStubRunner;
import org.springframework.cloud.contract.stubrunner.spring.StubRunnerProperties;
import org.springframework.kafka.test.context.EmbeddedKafka;
// remove::end[]
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE)
// remove::start[]
@AutoConfigureStubRunner(ids = "com.example:beer-api-producer-kafka", stubsMode = StubRunnerProperties.StubsMode.LOCAL)
@EmbeddedKafka(topics = "topic1")
// remove::end[]
@ActiveProfiles("test")
public class ApplicationTests {

    // remove::start[]
    @Autowired
    StubTrigger trigger;
    @Autowired
    Application application;

    @Test
    public void contextLoads() {
        this.trigger.trigger("trigger");

        Awaitility.await().untilAsserted(() -> {
            BDDAssertions.then(this.application.storedFoo).isNotNull();
            BDDAssertions.then(this.application.storedFoo.getFoo()).contains("example");
        });
    }
    // remove::end[]

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM