Skip to content

Commit a3de533

Browse files
rctayartembilan
authored andcommitted
Document (de)serialization config properties
When reading the reference manual, it is likely that one would encounter the "Introduction" and start with the "consumer properties map" approach to configuring deserialization. However, in the course of troubleshooting consumer failures (eg. deserialization errors), one might read further into the manual and encounter the "Serialization, Deserialization, and Message Conversion" section, and pass instances of deserializers to the consumer factory in an attempt to fix the failures, and might miss out that in fact consumer properties map now has no effect. Mention this in the documentation, and add a test case illustrating this is the expected behavior.
1 parent cd6c2aa commit a3de533

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

spring-kafka/src/test/java/org/springframework/kafka/listener/KafkaMessageListenerContainerTests.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
* @author Artem Bilan
114114
* @author Loic Talhouarne
115115
* @author Lukasz Kaminski
116+
* @author Ray Chuan Tay
116117
*/
117118
@EmbeddedKafka(topics = { KafkaMessageListenerContainerTests.topic1, KafkaMessageListenerContainerTests.topic2,
118119
KafkaMessageListenerContainerTests.topic3, KafkaMessageListenerContainerTests.topic4,
@@ -176,6 +177,8 @@ public class KafkaMessageListenerContainerTests {
176177

177178
public static final String topic23 = "testTopic23";
178179

180+
public static final String topic24 = "testTopic24";
181+
179182
private static EmbeddedKafkaBroker embeddedKafka;
180183

181184
@BeforeAll
@@ -1893,6 +1896,47 @@ public void testJsonSerDeConfiguredType() throws Exception {
18931896
this.logger.info("Stop JSON1");
18941897
}
18951898

1899+
@Test
1900+
public void testJsonSerDeWithInstanceDoesNotUseConfiguration() throws Exception {
1901+
this.logger.info("Start JSON1a");
1902+
Class<Foo1> consumerConfigValueDefaultType = Foo1.class;
1903+
Map<String, Object> props = KafkaTestUtils.consumerProps("testJson", "false", embeddedKafka);
1904+
props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
1905+
props.put(JsonDeserializer.VALUE_DEFAULT_TYPE, consumerConfigValueDefaultType);
1906+
DefaultKafkaConsumerFactory<Integer, Foo> cf = new DefaultKafkaConsumerFactory<>(props, null, new JsonDeserializer<>(Foo.class));
1907+
ContainerProperties containerProps = new ContainerProperties(topic24);
1908+
1909+
final CountDownLatch latch = new CountDownLatch(1);
1910+
final AtomicReference<ConsumerRecord<?, ?>> received = new AtomicReference<>();
1911+
containerProps.setMessageListener((MessageListener<Integer, Foo>) record -> {
1912+
KafkaMessageListenerContainerTests.this.logger.info("json: " + record);
1913+
received.set(record);
1914+
latch.countDown();
1915+
});
1916+
1917+
KafkaMessageListenerContainer<Integer, Foo> container =
1918+
new KafkaMessageListenerContainer<>(cf, containerProps);
1919+
container.setBeanName("testJson1a");
1920+
container.start();
1921+
1922+
ContainerTestUtils.waitForAssignment(container, embeddedKafka.getPartitionsPerTopic());
1923+
1924+
Map<String, Object> senderProps = KafkaTestUtils.producerProps(embeddedKafka);
1925+
senderProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
1926+
DefaultKafkaProducerFactory<Integer, Foo> pf = new DefaultKafkaProducerFactory<>(senderProps);
1927+
KafkaTemplate<Integer, Foo> template = new KafkaTemplate<>(pf);
1928+
template.setDefaultTopic(topic24);
1929+
template.sendDefault(0, new Foo("bar"));
1930+
template.flush();
1931+
assertThat(latch.await(60, TimeUnit.SECONDS)).isTrue();
1932+
assertThat(received.get().value())
1933+
.isInstanceOf(Foo.class)
1934+
.isNotInstanceOf(consumerConfigValueDefaultType);
1935+
container.stop();
1936+
pf.destroy();
1937+
this.logger.info("Stop JSON1a");
1938+
}
1939+
18961940
@Test
18971941
public void testJsonSerDeHeaderSimpleType() throws Exception {
18981942
this.logger.info("Start JSON2");

src/reference/asciidoc/kafka.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2740,7 +2740,8 @@ A `JacksonMimeTypeModule` can be registered as a bean in the application context
27402740
Also starting with version 2.3, the `JsonDeserializer` provides `TypeReference`-based constructors for better handling of target generic container types.
27412741

27422742
Starting with version 2.1, you can convey type information in record `Headers`, allowing the handling of multiple types.
2743-
In addition, you can configure the serializer and deserializer by using the following Kafka properties:
2743+
In addition, you can configure the serializer and deserializer by using the following Kafka properties.
2744+
They have no effect if you have provided `Serializer` and `Deserializer` instances for `KafkaConsumer` and `KafkaProducer`, respectively.
27442745

27452746
* `JsonSerializer.ADD_TYPE_INFO_HEADERS` (default `true`): You can set it to `false` to disable this feature on the `JsonSerializer` (sets the `addTypeInfo` property).
27462747
* `JsonSerializer.TYPE_MAPPINGS` (default `empty`): See <<serdes-mapping-types>>.

0 commit comments

Comments
 (0)