Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/spring-boot/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 卡夫卡消费记录返回空值_Spring Boot_Spring Kafka - Fatal编程技术网

Spring boot 卡夫卡消费记录返回空值

Spring boot 卡夫卡消费记录返回空值,spring-boot,spring-kafka,Spring Boot,Spring Kafka,尝试在spring引导应用程序中实现单元测试时,我无法检索消费者记录,尽管使用自己的POJO的自定义序列化程序正在工作。我与kafka控制台使用者进行了检查,每次运行测试时都会生成一条新消息并显示在控制台上。 要获取记录而不是null,我必须做什么 @RunWith(SpringRunner.class) @SpringBootTest @DisplayName("Testing GlobalMessageTest") @DirtiesContext public class NumberPla

尝试在spring引导应用程序中实现单元测试时,我无法检索
消费者记录
,尽管使用自己的POJO的自定义序列化程序正在工作。我与kafka控制台使用者进行了检查,每次运行测试时都会生成一条新消息并显示在控制台上。 要获取记录而不是
null
,我必须做什么

@RunWith(SpringRunner.class)
@SpringBootTest
@DisplayName("Testing GlobalMessageTest")
@DirtiesContext
public class NumberPlateSenderTest {

private static Logger log = LogManager.getLogger(NumberPlateSenderTest.class);

@Autowired
KafkaeskAdapterApplication kafkaeskAdapterApplication;

@Autowired
private NumberPlateSender numberPlateSender;

private KafkaMessageListenerContainer<String, NumberPlate> container;
private BlockingQueue<ConsumerRecord<String, NumberPlate>> records;

private static final String SENDER_TOPIC = "numberplate_test_topic";

@ClassRule
public static KafkaEmbedded embeddedKafka = new KafkaEmbedded(1, true, SENDER_TOPIC);

@Before
public void setUp() throws Exception {
    // set up the Kafka consumer properties
    Map<String, Object> consumerProperties = KafkaTestUtils.consumerProps("sender", "false", embeddedKafka);
    consumerProperties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
    consumerProperties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, NumberPlateDeserializer.class);


    // create a Kafka consumer factory
    DefaultKafkaConsumerFactory<String, NumberPlate> consumerFactory =
            new DefaultKafkaConsumerFactory<>(consumerProperties);

    // set the topic that needs to be consumed
    ContainerProperties containerProperties = new ContainerProperties(SENDER_TOPIC);

    // create a Kafka MessageListenerContainer
    container = new KafkaMessageListenerContainer<>(consumerFactory, containerProperties);

    // create a thread safe queue to store the received message
    records = new LinkedBlockingQueue<>();

    // setup a Kafka message listener
    container.setupMessageListener((MessageListener<String, NumberPlate>) record -> {
        log.info("Message Listener received message='{}'", record.toString());
        records.add(record);
    });

    // start the container and underlying message listener
    container.start();

    // wait until the container has the required number of assigned partitions
    ContainerTestUtils.waitForAssignment(container, embeddedKafka.getPartitionsPerTopic());
}

@DisplayName("Should send a Message to a Producer and retrieve it")
@Test
public void TestProducer() throws InterruptedException {
    //Test instance of Numberplate to send
    NumberPlate localNumberplate = new NumberPlate();
    byte[] bytes = "0x33".getBytes();
    localNumberplate.setImageBlob(bytes);
    localNumberplate.setNumberString("ABC123");
    log.info(localNumberplate.toString());

    //Send it
    numberPlateSender.sendNumberPlateMessage(localNumberplate);

    //Retrieve it
    ConsumerRecord<String, NumberPlate> received = records.poll(3, TimeUnit.SECONDS);
    log.info("Received the following content of ConsumerRecord: {}", received);

    if (received == null) {
        assert false;
    } else {
        NumberPlate retrNumberplate = received.value();
        Assert.assertEquals(retrNumberplate, localNumberplate);
    }
}

@After
public void tearDown() {
    // stop the container
    container.stop();
}
@RunWith(SpringRunner.class)
@春靴测试
@DisplayName(“测试GlobalMessageTest”)
@肮脏的环境
公共类编号PlateSenderTest{
私有静态记录器log=LogManager.getLogger(NumberPlateSenderTest.class);
@自动连线
卡夫卡式应用卡夫卡式应用;
@自动连线
私人号码PlateSender号码PlateSender;
卡夫卡专用集装箱;
私有阻塞队列记录;
私有静态最终字符串发送器\u TOPIC=“numberplate\u test\u TOPIC”;
@阶级规则
public static kafkamebedded embedded kafka=新的kafkamebedded(1,true,发送方\主题);
@以前
public void setUp()引发异常{
//设置卡夫卡消费者属性
Map consumerProperties=KafkaTestUtils.consumerProps(“发送方”,“假”,嵌入kafka);
consumerProperties.put(ConsumerConfig.KEY\u反序列化程序\u类\u配置,StringDeserializer.CLASS);
consumerProperties.put(ConsumerConfig.VALUE\u反序列化程序\u类\u配置,NumberPlateDeserializer.CLASS);
//创建卡夫卡消费品工厂
默认卡夫卡消费者工厂消费者工厂=
新的默认卡夫卡消费者工厂(消费者财产);
//设置需要使用的主题
ContainerProperties ContainerProperties=新的ContainerProperty(发送者主题);
//创建Kafka MessageListenerContainer
容器=新的KafkaMessageListenerContainer(consumerFactory、containerProperties);
//创建线程安全队列以存储收到的消息
记录=新建LinkedBlockingQueue();
//设置卡夫卡消息侦听器
container.setupMessageListener((MessageListener)记录->{
log.info(“消息侦听器接收到消息='{}',record.toString());
记录。添加(记录);
});
//启动容器和底层消息侦听器
container.start();
//等待容器具有所需数量的分配分区
ContainerTestUtils.waitForAssignment(容器,embeddedKafka.getPartitionsPerTopic());
}
@DisplayName(“应向制作人发送消息并检索它”)
@试验
public void TestProducer()引发InterruptedException{
//要发送的Numberplate的测试实例
NumberPlate localNumberplate=新NumberPlate();
byte[]bytes=“0x33”。getBytes();
localNumberplate.setImageBlob(字节);
localNumberplate.setNumberString(“ABC123”);
log.info(localNumberplate.toString());
//发送它
numberPlateSender.sendNumberPlateMessage(localNumberplate);
//找回它
接收到的ConsumerRecord=记录。轮询(3,时间单位。秒);
log.info(“收到了ConsumerRecord的以下内容:{}”,已收到);
如果(接收==null){
断言错误;
}否则{
NumberPlate retrNumberplate=received.value();
Assert.assertEquals(retrNumberplate、localNumberplate);
}
}
@之后
公共无效拆卸(){
//停止容器
container.stop();
}
}

完整的代码可以在我的网站上看到。 我阅读了大量不同的SO问题并在网上搜索,但找不到一种方法来说明我的代码有什么问题。其他用户也发布了类似的问题,但没有效果

在我的Craptop上运行的卡夫卡版本是kafka_2.11-1.0.1


springframework kafka客户端的版本为2.1.5。发布版

您的问题是,您启动了针对嵌入式kafka的消费者,但将数据发送到了真实的消费者。我不知道你的目标是什么,但我让它针对嵌入式卡夫卡工作,如下所示:

@BeforeClass
public static void setup() {
    System.setProperty("kafka.bootstrapAddress", embeddedKafka.getBrokersAsString());
}
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    NumberPlate that = (NumberPlate) o;
    return Objects.equals(numberString, that.numberString) &&
            Arrays.equals(imageBlob, that.imageBlob);
}

@Override
public int hashCode() {
    int result = Objects.hash(numberString);
    result = 31 * result + Arrays.hashCode(imageBlob);
    return result;
}
我使用嵌入的kafka提供的代理地址覆盖生产者的
kafka.bootstrapAddress
配置属性

在这种情况下,我失败了:

java.lang.AssertionError: expected: dev.semo.kafkaeskadapter.models.NumberPlate<NumberPlate{numberString='ABC123', imageBlob=[48, 120, 51, 51]}> but was: dev.semo.kafkaeskadapter.models.NumberPlate<NumberPlate{numberString='ABC123', imageBlob=[48, 120, 51, 51]}>
Expected :dev.semo.kafkaeskadapter.models.NumberPlate<NumberPlate{numberString='ABC123', imageBlob=[48, 120, 51, 51]}> 
Actual   :dev.semo.kafkaeskadapter.models.NumberPlate<NumberPlate{numberString='ABC123', imageBlob=[48, 120, 51, 51]}>
同时,您的
NumberPlate
没有提供正确的
equals()
实现。大概是这样的:

@BeforeClass
public static void setup() {
    System.setProperty("kafka.bootstrapAddress", embeddedKafka.getBrokersAsString());
}
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    NumberPlate that = (NumberPlate) o;
    return Objects.equals(numberString, that.numberString) &&
            Arrays.equals(imageBlob, that.imageBlob);
}

@Override
public int hashCode() {
    int result = Objects.hash(numberString);
    result = 31 * result + Arrays.hashCode(imageBlob);
    return result;
}

感谢您提供整个项目来播放和复制!使用“问答”游戏,我们将在这里花费太多时间:-)。

感谢您的时间和建议。我会推动它,并感谢你的帮助。耶!