Skip to content

Commit a38f824

Browse files
garyrussellartembilan
authored andcommitted
GH-1787: Only Validate Once
Resolves #1787 The validator was invoked twice with a class-level `@KafkaListener` when no default `@KafkaHandler` is present.
1 parent 43dd7e3 commit a38f824

File tree

2 files changed

+41
-2
lines changed

2 files changed

+41
-2
lines changed

spring-kafka/src/main/java/org/springframework/kafka/listener/adapter/DelegatingInvocableHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ public Object getBean() {
204204
public Object invoke(Message<?> message, Object... providedArgs) throws Exception { //NOSONAR
205205
Class<? extends Object> payloadClass = message.getPayload().getClass();
206206
InvocableHandlerMethod handler = getHandlerForPayload(payloadClass);
207-
if (this.validator != null) {
207+
if (this.validator != null && this.defaultHandler != null) {
208208
MethodParameter parameter = this.payloadMethodParameters.get(handler);
209209
if (parameter != null) {
210210
this.validator.validate(message, parameter, message.getPayload());

spring-kafka/src/test/java/org/springframework/kafka/annotation/EnableKafkaIntegrationTests.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@
177177
"annotated25", "annotated25reply1", "annotated25reply2", "annotated26", "annotated27", "annotated28",
178178
"annotated29", "annotated30", "annotated30reply", "annotated31", "annotated32", "annotated33",
179179
"annotated34", "annotated35", "annotated36", "annotated37", "foo", "manualStart", "seekOnIdle",
180-
"annotated38", "annotated38reply", "annotated39" })
180+
"annotated38", "annotated38reply", "annotated39", "annotated40" })
181181
public class EnableKafkaIntegrationTests {
182182

183183
private static final String DEFAULT_TEST_GROUP_ID = "testAnnot";
@@ -202,6 +202,9 @@ public class EnableKafkaIntegrationTests {
202202
@Autowired
203203
public MultiJsonListenerBean multiJsonListener;
204204

205+
@Autowired
206+
public MultiListenerNoDefault multiNoDefault;
207+
205208
@Autowired
206209
public KafkaTemplate<Integer, String> template;
207210

@@ -446,7 +449,19 @@ public void testMultiJson() throws Exception {
446449
assertThat(this.multiJsonListener.baz.getBar()).isEqualTo("two");
447450
assertThat(this.multiJsonListener.bar.getBar()).isEqualTo("three");
448451
assertThat(this.multiJsonListener.bar).isInstanceOf(Qux.class);
452+
assertThat(this.multiJsonListener.validated).isNotNull();
449453
assertThat(this.multiJsonListener.validated.isValidated()).isTrue();
454+
assertThat(this.multiJsonListener.validated.valCount).isEqualTo(1);
455+
}
456+
457+
@Test
458+
public void testMultiValidateNoDefaultHandler() throws Exception {
459+
this.kafkaJsonTemplate.setDefaultTopic("annotated40");
460+
this.kafkaJsonTemplate.send(new GenericMessage<>(new ValidatedClass(5)));
461+
assertThat(this.multiNoDefault.latch1.await(60, TimeUnit.SECONDS)).isTrue();
462+
assertThat(this.multiNoDefault.validated).isNotNull();
463+
assertThat(this.multiNoDefault.validated.isValidated()).isTrue();
464+
assertThat(this.multiNoDefault.validated.valCount).isEqualTo(1);
450465
}
451466

452467
@Test
@@ -1306,6 +1321,11 @@ public MultiJsonListenerBean multiJsonListener() {
13061321
return new MultiJsonListenerBean();
13071322
}
13081323

1324+
@Bean
1325+
public MultiListenerNoDefault multiNoDefault() {
1326+
return new MultiListenerNoDefault();
1327+
}
1328+
13091329
@Bean
13101330
public MultiListenerSendTo multiListenerSendTo() {
13111331
return new MultiListenerSendTo();
@@ -2218,6 +2238,21 @@ public void defaultHandler(Bar bar) {
22182238

22192239
}
22202240

2241+
@KafkaListener(id = "multiNoDefault", topics = "annotated40", containerFactory = "kafkaJsonListenerContainerFactory2")
2242+
static class MultiListenerNoDefault {
2243+
2244+
final CountDownLatch latch1 = new CountDownLatch(1);
2245+
2246+
volatile ValidatedClass validated;
2247+
2248+
@KafkaHandler
2249+
public void bar(@Valid ValidatedClass val) {
2250+
this.validated = val;
2251+
this.latch1.countDown();
2252+
}
2253+
2254+
}
2255+
22212256
@KafkaListener(id = "multiSendTo", topics = "annotated25")
22222257
@SendTo("annotated25reply1")
22232258
static class MultiListenerSendTo {
@@ -2348,6 +2383,7 @@ public static class ValidatedClass {
23482383

23492384
private volatile boolean validated;
23502385

2386+
volatile int valCount;
23512387

23522388
public ValidatedClass() {
23532389
}
@@ -2370,6 +2406,9 @@ public boolean isValidated() {
23702406

23712407
public void setValidated(boolean validated) {
23722408
this.validated = validated;
2409+
if (validated) { // don't count the json deserialization call
2410+
this.valCount++;
2411+
}
23732412
}
23742413

23752414
}

0 commit comments

Comments
 (0)