|
|
|
@ -59,6 +59,7 @@ import org.springframework.kafka.support.converter.MessagingMessageConverter;
|
|
|
|
|
import org.springframework.kafka.support.converter.RecordMessageConverter;
|
|
|
|
|
import org.springframework.kafka.test.utils.KafkaTestUtils;
|
|
|
|
|
import org.springframework.kafka.transaction.ChainedKafkaTransactionManager;
|
|
|
|
|
import org.springframework.kafka.transaction.KafkaAwareTransactionManager;
|
|
|
|
|
import org.springframework.kafka.transaction.KafkaTransactionManager;
|
|
|
|
|
import org.springframework.transaction.PlatformTransactionManager;
|
|
|
|
|
|
|
|
|
@ -81,10 +82,8 @@ public class KafkaAutoConfigurationTests {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void consumerProperties() {
|
|
|
|
|
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
|
|
|
|
.withPropertyValues("spring.kafka.bootstrap-servers=foo:1234",
|
|
|
|
|
"spring.kafka.properties.foo=bar",
|
|
|
|
|
"spring.kafka.properties.baz=qux",
|
|
|
|
|
this.contextRunner.withPropertyValues("spring.kafka.bootstrap-servers=foo:1234",
|
|
|
|
|
"spring.kafka.properties.foo=bar", "spring.kafka.properties.baz=qux",
|
|
|
|
|
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
|
|
|
|
|
"spring.kafka.ssl.key-password=p1",
|
|
|
|
|
"spring.kafka.ssl.key-store-location=classpath:ksLoc",
|
|
|
|
@ -160,20 +159,14 @@ public class KafkaAutoConfigurationTests {
|
|
|
|
|
assertThat(configs.get("baz")).isEqualTo("qux");
|
|
|
|
|
assertThat(configs.get("foo.bar.baz")).isEqualTo("qux.fiz.buz");
|
|
|
|
|
assertThat(configs.get("fiz.buz")).isEqualTo("fix.fox");
|
|
|
|
|
ConcurrentKafkaListenerContainerFactory<?, ?> factory = context
|
|
|
|
|
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
|
|
|
|
assertThat(KafkaTestUtils.getPropertyValue(factory, "errorHandler"))
|
|
|
|
|
.isSameAs(context.getBean("errorHandler"));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void producerProperties() {
|
|
|
|
|
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
|
|
|
|
.withPropertyValues("spring.kafka.clientId=cid",
|
|
|
|
|
this.contextRunner.withPropertyValues("spring.kafka.clientId=cid",
|
|
|
|
|
"spring.kafka.properties.foo.bar.baz=qux.fiz.buz",
|
|
|
|
|
"spring.kafka.producer.acks=all",
|
|
|
|
|
"spring.kafka.producer.batch-size=20",
|
|
|
|
|
"spring.kafka.producer.acks=all", "spring.kafka.producer.batch-size=20",
|
|
|
|
|
"spring.kafka.producer.bootstrap-servers=bar:1234", // test
|
|
|
|
|
// override
|
|
|
|
|
"spring.kafka.producer.buffer-memory=12345",
|
|
|
|
@ -414,7 +407,7 @@ public class KafkaAutoConfigurationTests {
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
|
@Test
|
|
|
|
|
public void listenerProperties() {
|
|
|
|
|
this.contextRunner.withUserConfiguration(TestConfiguration.class)
|
|
|
|
|
this.contextRunner
|
|
|
|
|
.withPropertyValues("spring.kafka.template.default-topic=testTopic",
|
|
|
|
|
"spring.kafka.listener.ack-mode=MANUAL",
|
|
|
|
|
"spring.kafka.listener.client-id=client",
|
|
|
|
@ -506,7 +499,6 @@ public class KafkaAutoConfigurationTests {
|
|
|
|
|
@Test
|
|
|
|
|
public void testConcurrentKafkaListenerContainerFactoryWithCustomMessageConverters() {
|
|
|
|
|
this.contextRunner.withUserConfiguration(MessageConverterConfiguration.class)
|
|
|
|
|
.withPropertyValues("spring.kafka.producer.transaction-id-prefix=test")
|
|
|
|
|
.run((context) -> {
|
|
|
|
|
ConcurrentKafkaListenerContainerFactory<?, ?> kafkaListenerContainerFactory = context
|
|
|
|
|
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
|
|
|
@ -514,11 +506,56 @@ public class KafkaAutoConfigurationTests {
|
|
|
|
|
kafkaListenerContainerFactory);
|
|
|
|
|
assertThat(dfa.getPropertyValue("messageConverter"))
|
|
|
|
|
.isSameAs(context.getBean("myMessageConverter"));
|
|
|
|
|
assertThat(kafkaListenerContainerFactory.getContainerProperties()
|
|
|
|
|
.getTransactionManager()).isSameAs(
|
|
|
|
|
context.getBean("chainedTransactionManager"));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testConcurrentKafkaListenerContainerFactoryWithCustomErrorHandler() {
|
|
|
|
|
this.contextRunner.withUserConfiguration(ErrorHandlerConfiguration.class)
|
|
|
|
|
.run((context) -> {
|
|
|
|
|
ConcurrentKafkaListenerContainerFactory<?, ?> factory = context
|
|
|
|
|
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
|
|
|
|
assertThat(KafkaTestUtils.getPropertyValue(factory, "errorHandler"))
|
|
|
|
|
.isSameAs(context.getBean("errorHandler"));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testConcurrentKafkaListenerContainerFactoryWithDefaultTransactionManager() {
|
|
|
|
|
this.contextRunner
|
|
|
|
|
.withPropertyValues("spring.kafka.producer.transaction-id-prefix=test")
|
|
|
|
|
.run((context) -> {
|
|
|
|
|
assertThat(context).hasSingleBean(KafkaAwareTransactionManager.class);
|
|
|
|
|
ConcurrentKafkaListenerContainerFactory<?, ?> factory = context
|
|
|
|
|
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
|
|
|
|
assertThat(factory.getContainerProperties().getTransactionManager())
|
|
|
|
|
.isSameAs(
|
|
|
|
|
context.getBean(KafkaAwareTransactionManager.class));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testConcurrentKafkaListenerContainerFactoryWithCustomTransactionManager() {
|
|
|
|
|
this.contextRunner.withUserConfiguration(TransactionManagerConfiguration.class)
|
|
|
|
|
.withPropertyValues("spring.kafka.producer.transaction-id-prefix=test")
|
|
|
|
|
.run((context) -> {
|
|
|
|
|
ConcurrentKafkaListenerContainerFactory<?, ?> factory = context
|
|
|
|
|
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
|
|
|
|
assertThat(factory.getContainerProperties().getTransactionManager())
|
|
|
|
|
.isSameAs(context.getBean("chainedTransactionManager"));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
public void testConcurrentKafkaListenerContainerFactoryWithCustomAfterRollbackProcessor() {
|
|
|
|
|
this.contextRunner
|
|
|
|
|
.withUserConfiguration(AfterRollbackProcessorConfiguration.class)
|
|
|
|
|
.run((context) -> {
|
|
|
|
|
ConcurrentKafkaListenerContainerFactory<?, ?> factory = context
|
|
|
|
|
.getBean(ConcurrentKafkaListenerContainerFactory.class);
|
|
|
|
|
DirectFieldAccessor dfa = new DirectFieldAccessor(factory);
|
|
|
|
|
assertThat(dfa.getPropertyValue("afterRollbackProcessor"))
|
|
|
|
|
.isSameAs(context.getBean("arp"));
|
|
|
|
|
.isSameAs(context.getBean("afterRollbackProcessor"));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -535,34 +572,43 @@ public class KafkaAutoConfigurationTests {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
protected static class TestConfiguration {
|
|
|
|
|
protected static class MessageConverterConfiguration {
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public SeekToCurrentErrorHandler errorHandler() {
|
|
|
|
|
return new SeekToCurrentErrorHandler();
|
|
|
|
|
public RecordMessageConverter myMessageConverter() {
|
|
|
|
|
return mock(RecordMessageConverter.class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
protected static class MessageConverterConfiguration {
|
|
|
|
|
protected static class ErrorHandlerConfiguration {
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public RecordMessageConverter myMessageConverter() {
|
|
|
|
|
return mock(RecordMessageConverter.class);
|
|
|
|
|
public SeekToCurrentErrorHandler errorHandler() {
|
|
|
|
|
return new SeekToCurrentErrorHandler();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
protected static class TransactionManagerConfiguration {
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
@Primary
|
|
|
|
|
public PlatformTransactionManager chainedTransactionManager(
|
|
|
|
|
KafkaTransactionManager<String, String> kafkaTransactionManager) {
|
|
|
|
|
|
|
|
|
|
return new ChainedKafkaTransactionManager<String, String>(
|
|
|
|
|
kafkaTransactionManager);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Configuration
|
|
|
|
|
protected static class AfterRollbackProcessorConfiguration {
|
|
|
|
|
|
|
|
|
|
@Bean
|
|
|
|
|
public AfterRollbackProcessor<Object, Object> arp() {
|
|
|
|
|
public AfterRollbackProcessor<Object, Object> afterRollbackProcessor() {
|
|
|
|
|
return (records, consumer, ex, recoverable) -> {
|
|
|
|
|
// no-op
|
|
|
|
|
};
|
|
|
|
|