Java spring Kafka集成测试侦听器不工作
我正在尝试使用SpringBoot和SpringEmbeddedKafka进行集成测试。我能够向spring嵌入式Kafka服务器生成消息,但服务类中的侦听器不是测试侦听器,而是尝试使用记录和数据 带有所有bean的KafkaProducerConfigTest配置类Java spring Kafka集成测试侦听器不工作,java,spring-boot,spring-kafka,spring-kafka-test,Java,Spring Boot,Spring Kafka,Spring Kafka Test,我正在尝试使用SpringBoot和SpringEmbeddedKafka进行集成测试。我能够向spring嵌入式Kafka服务器生成消息,但服务类中的侦听器不是测试侦听器,而是尝试使用记录和数据 带有所有bean的KafkaProducerConfigTest配置类 @EnableKafka @TestConfiguration public class KafkaProducerConfigTest { @Bean public EmbeddedKafkaBroker embeddedKa
@EnableKafka
@TestConfiguration
public class KafkaProducerConfigTest {
@Bean
public EmbeddedKafkaBroker embeddedKafkaBroker() {
return new EmbeddedKafkaBroker(1,false,2,"test-events");
}
@Bean
public ProducerFactory<String, Object> producerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, embeddedKafkaBroker().getBrokersAsString());
props.put(ProducerConfig.RETRIES_CONFIG, 0);
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
return new DefaultKafkaProducerFactory<>(props);
}
@Bean
public KafkaTemplate<String, Object> kafkaTemplate() {
KafkaTemplate<String, Object> kafkaTemplate = new KafkaTemplate<>(producerFactory());
return kafkaTemplate;
}
@Bean("consumerFactory")
public ConsumerFactory<String, Object> createConsumerFactory() {
Map<String, Object> props = new HashMap<>();
props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, embeddedKafkaBroker().getBrokersAsString());
props.put(ConsumerConfig.GROUP_ID_CONFIG, "group1");
props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
return new DefaultKafkaConsumerFactory<>(props, new StringDeserializer(), new JsonDeserializer<>(Object.class,false));
}
@Bean("kafkaListenerContainerFactory")
public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(createConsumerFactory());
factory.setBatchListener(true);
factory.setMessageConverter(new BatchMessagingMessageConverter(converter()));
factory.getContainerProperties().setAckMode(AckMode.BATCH);
return factory;
}
@Bean
public StringJsonMessageConverter converter() {
return new StringJsonMessageConverter();
}
@Bean
public Listener listener() {
return new Listener();
}
public class Listener {
public final CountDownLatch latch = new CountDownLatch(1);
@Getter
public List<Professor> list;
@KafkaListener(topics = "test-events", containerFactory = "kafkaListenerContainerFactory")
public void listen1(List<Professor> foo) {
list=foo;
this.latch.countDown();
}
}
}
错误
基于@Gray Russel sir answer更新,但我仍然有一个问题在容器工厂中使用StringDeserializer和StringJsonMessageConverter或BytesDeserializer和BytesJsonMessageConverter;然后,框架可以根据方法签名确定目标类型,并将其传递给转换器
反序列化程序在堆栈中太远,无法进行推断。在容器工厂中使用StringDeserializer和StringJsonMessageConverter,或者使用BytesDeserializer和BytesJsonMessageConverter;然后,框架可以根据方法签名确定目标类型,并将其传递给转换器
反序列化程序太底层了,无法进行推断。对此讨论做出响应可能已经太晚了。 正如@Gary Russell在回复中提到的,只需使用StringDeserializer来反序列化对象 application.yml来配置Kafka: 卡夫卡事件类: 在应用程序类register StringJsonMessageConverter中,您也可以在其他地方创建此bean,这将字符串转换为所需的对象,即POI,如下所示:
@SpringBootApplication
@ComponentScan("org.ajeet.learnings.spring")
public class SpringBootKafkaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootKafkaApplication.class, args);
}
/**
* We are using a StringDeserializer in kafka consumer properties
* And this converter is converting the message from string to required type.
*
* @return RecordMessageConverter
*/
@Bean
public RecordMessageConverter converter() {
return new StringJsonMessageConverter();
}}
这是消费者:
这是制作人:
对这一讨论作出回应可能为时已晚。 正如@Gary Russell在回复中提到的,只需使用StringDeserializer来反序列化对象 application.yml来配置Kafka: 卡夫卡事件类: 在应用程序类register StringJsonMessageConverter中,您也可以在其他地方创建此bean,这将字符串转换为所需的对象,即POI,如下所示:
@SpringBootApplication
@ComponentScan("org.ajeet.learnings.spring")
public class SpringBootKafkaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootKafkaApplication.class, args);
}
/**
* We are using a StringDeserializer in kafka consumer properties
* And this converter is converting the message from string to required type.
*
* @return RecordMessageConverter
*/
@Bean
public RecordMessageConverter converter() {
return new StringJsonMessageConverter();
}}
这是消费者:
这是制作人:
长官,实际上我不想制造重复的问题,所以我只是更新了这里,即使我使用了StringJsonMessageConverter,我遇到了问题,我尝试使用StringDeserializer和StringJsonMessageConverter,然后我遇到了奇怪的不同问题,如果你想知道详情,我可以更新帖子谢谢你回复@grayrussell你编辑的配置仍然有一个JsonDeserializer。先生,实际上我不想重复问题,所以我只是更新了这里,即使我使用了StringJsonMessageConverter,我遇到了问题,我尝试了使用StringDeserializer和StringJsonMessageConverter,然后我遇到了奇怪的不同问题,如果你想要详细信息,我可以更新帖子,谢谢你回复@Grayrussell。你编辑的配置仍然有一个JsonDeserializer。
server:
port: 8080
servlet:
contextPath: /poi
spring:
kafka:
consumer:
bootstrap-servers: localhost:9092
group-id: rsvp-consumers
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
properties:
spring:
json:
type:
mapping: poi:org.ajeet.learnings.spring.springboot.model.POI
producer:
bootstrap-servers: localhost:9092
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
properties:
spring:
json:
type:
mapping: poi:org.ajeet.learnings.spring.springboot.model.POI
topics: spatial
public final class POI {
private final double longitude;
private final double latitude;
private final POI_Type type;
private final String description;
@JsonCreator
public POI(@JsonProperty("longitude") double longitude,
@JsonProperty("latitude") double latitude,
@JsonProperty("type") POI_Type type,
@JsonProperty("description") String description) {
this.longitude = longitude;
this.latitude = latitude;
this.type = type;
this.description = description;
}
public double getLongitude() {
return longitude;
}
public double getLatitude() {
return latitude;
}
public String getDescription() {
return description;
}}
@SpringBootApplication
@ComponentScan("org.ajeet.learnings.spring")
public class SpringBootKafkaApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootKafkaApplication.class, args);
}
/**
* We are using a StringDeserializer in kafka consumer properties
* And this converter is converting the message from string to required type.
*
* @return RecordMessageConverter
*/
@Bean
public RecordMessageConverter converter() {
return new StringJsonMessageConverter();
}}
@Service
public final class POIEventConsumer {
private final Logger LOG = LoggerFactory.getLogger(POIEventConsumer.class);
/**
* Read topic names from application.yaml
*
* @param pointOfInterest
* @throws IOException
*/
@KafkaListener(topics = "#{'${spring.kafka.topics}'.split(',')}")
public void consume(POI pointOfInterest) throws IOException {
LOG.info(pointOfInterest.toString());
} }
@Service
public class POIEventProducer {
private static final Logger LOG = LoggerFactory.getLogger(POIEventProducer.class);
@Value("${spring.kafka.topics}")
private String topic;
@Autowired
private KafkaTemplate<String, POI> kafkaTemplate;
public void sendMessage(POI pointOfInterest) {
this.kafkaTemplate.send(topic, pointOfInterest);
}}
@RestController
@RequestMapping(value = "/kafka")
public final class POIEventController {
private final Logger LOG = LoggerFactory.getLogger(POIEventController.class);
@Autowired
private POIEventProducer poiEventProducer;
/**
* Post request url: http://localhost:8080/poi/kafka/publish
* Example of request body: {"longitude":77.100281, "latitude": 28.556160, "type": "Airport", "description": "Indira Gandhi International Airport New Delhi"}
*
* @param pointOfInterest
*/
@RequestMapping(value = "/publish",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
public void sendMessageToKafkaTopic(@RequestBody POI pointOfInterest) {
this.poiEventProducer.sendMessage(pointOfInterest);
}}