web-dev-qa-db-fra.com

Embarqué simple Kafka exemple de test avec démarrage à ressort

Editer FYI: exemple de travail avec gitHub


Je cherchais sur Internet et ne parvenais pas à trouver un exemple simple et pratique de test Kafka intégré).

Ma configuration est la suivante:

  • Botte de printemps
  • Multiple @ KafkaListener avec différents sujets dans une classe
  • Embarqué Kafka pour le test qui commence bien
  • Testez avec Kafkatemplate qui envoie à la rubrique mais les méthodes @ KafkaListener ne reçoivent rien, même après une très longue période de sommeil
  • Aucun message d’avertissement ou d’erreur ne s’affiche, seul le spam d’information provenant de Kafka dans les journaux)

Aidez-moi, s'il vous plaît. Il y a principalement des exemples sur-configurés ou sur-conçus. Je suis sûr que cela peut être fait simple. Merci les gars!

@Controller
public class KafkaController {

    private static final Logger LOG = getLogger(KafkaController.class);

    @KafkaListener(topics = "test.kafka.topic")
    public void receiveDunningHead(final String payload) {
        LOG.debug("Receiving event with payload [{}]", payload);
        //I will do database stuff here which i could check in db for testing
    }
}

private static String SENDER_TOPIC = "test.kafka.topic";

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

@Test
    public void testSend() throws InterruptedException, ExecutionException {

        Map<String, Object> senderProps = KafkaTestUtils.producerProps(embeddedKafka);

        KafkaProducer<Integer, String> producer = new KafkaProducer<>(senderProps);
        producer.send(new ProducerRecord<>(SENDER_TOPIC, 0, 0, "message00")).get();
        producer.send(new ProducerRecord<>(SENDER_TOPIC, 0, 1, "message01")).get();
        producer.send(new ProducerRecord<>(SENDER_TOPIC, 1, 0, "message10")).get();
        Thread.sleep(10000);
    }
20
Yuna Braska

Les tests intégrés Kafka fonctionnent pour moi avec les configurations ci-dessous,

Annotation sur la classe de test

@EnableKafka
@SpringBootTest(classes = {KafkaController.class}) // Specify @KafkaListener class if its not the same class,or not loaded with test config
@EmbeddedKafka(partitions = 1, controlledShutdown = false,
    brokerProperties = {"listeners=PLAINTEXT://localhost:3333", "port=3333"})
public class KafkaConsumerTest{
@Autowired
KafkaEmbedded kafkaEmbeded;

@Autowired
KafkaListenerEndpointRegistry kafkaListenerEndpointRegistry;

Avant l'annotation pour la méthode d'installation

@Before
public void setUp() throws Exception {
  for (MessageListenerContainer messageListenerContainer : kafkaListenerEndpointRegistry.getListenerContainers()) {
    ContainerTestUtils.waitForAssignment(messageListenerContainer, 
    kafkaEmbeded.getPartitionsPerTopic());
  }
}

Remarque: je n'utilise pas @ClassRule pour la création Kafka intégré plutôt que du câblage automatique)
@Autowired embeddedKafka

@Test
public void testReceive() throws Exception {
     kafkaTemplate.send(topic, data);
}

J'espère que cela t'aides!

Edit: Testez la classe de configuration marquée avec @TestConfiguration

@TestConfiguration
public class TestConfig {

@Bean
public ProducerFactory<String, String> producerFactory() {
    return new DefaultKafkaProducerFactory<>(KafkaTestUtils.producerProps(kafkaEmbedded));
}

@Bean
public KafkaTemplate<String, String> kafkaTemplate() {
    KafkaTemplate<String, String> kafkaTemplate = new KafkaTemplate<>(producerFactory());
    kafkaTemplate.setDefaultTopic(topic);
    return kafkaTemplate;
}

Maintenant @Test La méthode va automatiquement connecter KafkaTemplate et l’utiliser pour envoyer un message.

kafkaTemplate.send(topic, data);

Bloc de code de réponse mis à jour avec la ligne ci-dessus

23
Mayur

J'ai résolu le problème maintenant

@BeforeClass
public static void setUpBeforeClass() {
    System.setProperty("spring.kafka.bootstrap-servers", embeddedKafka.getBrokersAsString());
    System.setProperty("spring.cloud.stream.kafka.binder.zkNodes", embeddedKafka.getZookeeperConnectionString());
}

pendant que je déboguais, j'ai vu que le serveur kaka intégré prenait un port aléatoire.

Je ne pouvais pas trouver la configuration pour cela, donc je configure la même configuration que le serveur kafka). Cela semble toujours un peu moche pour moi.

J'aimerais avoir juste la ligne mentionnée @Mayur

@EmbeddedKafka(partitions = 1, controlledShutdown = false, brokerProperties = {"listeners=PLAINTEXT://localhost:9092", "port=9092"})

mais ne peut pas trouver la bonne dépendance sur Internet.

6
Yuna Braska

puisque la réponse acceptée ne compile ni ne fonctionne pour moi. Je trouve une autre solution basée sur https://blog.mimacom.com/testing-Apache-kafka-with-spring-boot/ ce que j'aimerais partager avec vous.

La dépendance est la version 'spring-kafka-test': '2.2.7.RELEASE'

@RunWith(SpringRunner.class)
@EmbeddedKafka(partitions = 1, topics = { "testTopic" })
@SpringBootTest
public class SimpleKafkaTest {

    private static final String TEST_TOPIC = "testTopic";

    @Autowired
    EmbeddedKafkaBroker embeddedKafkaBroker;

    @Test
    public void testReceivingKafkaEvents() {
        Consumer<Integer, String> consumer = configureConsumer();
        Producer<Integer, String> producer = configureProducer();

        producer.send(new ProducerRecord<>(TEST_TOPIC, 123, "my-test-value"));

        ConsumerRecord<Integer, String> singleRecord = KafkaTestUtils.getSingleRecord(consumer, TEST_TOPIC);
        assertThat(singleRecord).isNotNull();
        assertThat(singleRecord.key()).isEqualTo(123);
        assertThat(singleRecord.value()).isEqualTo("my-test-value");

        consumer.close();
        producer.close();
    }

    private Consumer<Integer, String> configureConsumer() {
        Map<String, Object> consumerProps = KafkaTestUtils.consumerProps("testGroup", "true", embeddedKafkaBroker);
        consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
        Consumer<Integer, String> consumer = new DefaultKafkaConsumerFactory<Integer, String>(consumerProps)
                .createConsumer();
        consumer.subscribe(Collections.singleton(TEST_TOPIC));
        return consumer;
    }

    private Producer<Integer, String> configureProducer() {
        Map<String, Object> producerProps = new HashMap<>(KafkaTestUtils.producerProps(embeddedKafkaBroker));
        return new DefaultKafkaProducerFactory<Integer, String>(producerProps).createProducer();
    }
}
0
LazR