98
98
import org .springframework .kafka .event .ListenerContainerIdleEvent ;
99
99
import org .springframework .kafka .event .ListenerContainerNoLongerIdleEvent ;
100
100
import org .springframework .kafka .listener .AbstractConsumerSeekAware ;
101
+ import org .springframework .kafka .listener .BatchInterceptor ;
101
102
import org .springframework .kafka .listener .CommonLoggingErrorHandler ;
102
103
import org .springframework .kafka .listener .ConcurrentMessageListenerContainer ;
103
104
import org .springframework .kafka .listener .ConsumerAwareErrorHandler ;
111
112
import org .springframework .kafka .listener .KafkaMessageListenerContainer ;
112
113
import org .springframework .kafka .listener .ListenerExecutionFailedException ;
113
114
import org .springframework .kafka .listener .MessageListenerContainer ;
115
+ import org .springframework .kafka .listener .RecordInterceptor ;
114
116
import org .springframework .kafka .listener .adapter .FilteringMessageListenerAdapter ;
115
117
import org .springframework .kafka .listener .adapter .MessagingMessageListenerAdapter ;
116
118
import org .springframework .kafka .listener .adapter .RecordFilterStrategy ;
180
182
"annotated25" , "annotated25reply1" , "annotated25reply2" , "annotated26" , "annotated27" , "annotated28" ,
181
183
"annotated29" , "annotated30" , "annotated30reply" , "annotated31" , "annotated32" , "annotated33" ,
182
184
"annotated34" , "annotated35" , "annotated36" , "annotated37" , "foo" , "manualStart" , "seekOnIdle" ,
183
- "annotated38" , "annotated38reply" , "annotated39" , "annotated40" , "annotated41" })
185
+ "annotated38" , "annotated38reply" , "annotated39" , "annotated40" , "annotated41" , "annotated42" ,
186
+ "annotated43" })
184
187
@ TestPropertySource (properties = "spel.props=fetch.min.bytes=420000,max.poll.records=10" )
185
188
public class EnableKafkaIntegrationTests {
186
189
@@ -600,7 +603,23 @@ public void testBatchRecords() throws Exception {
600
603
assertThat (this .config .listen12Message .getPayload ()).isInstanceOf (List .class );
601
604
List <?> errorPayload = (List <?>) this .config .listen12Message .getPayload ();
602
605
assertThat (errorPayload .size ()).isGreaterThanOrEqualTo (1 );
606
+
607
+ }
608
+
609
+ @ Test
610
+ public void testBatchInterceptor () throws Exception {
611
+ template .send ("annotated43" , null , "foo" );
612
+ template .send ("annotated43" , null , "bar" );
613
+ assertThat (this .listener .latch43 .await (30 , TimeUnit .SECONDS )).isTrue ();
614
+ assertThat (this .listener .payload ).isInstanceOf (List .class );
615
+ List <?> list = (List <?>) this .listener .payload ;
616
+ assertThat (list .size ()).isGreaterThan (0 );
617
+ assertThat (list .get (0 )).isInstanceOf (ConsumerRecord .class );
618
+ assertThat (this .config .batchBeforePoll ).isTrue ();
603
619
assertThat (this .config .batchIntercepted ).isTrue ();
620
+ assertThat (this .config .batchSuccess ).isTrue ();
621
+ assertThat (this .config .batchFailure ).isFalse ();
622
+ assertThat (this .config .batchFinishInvoke ).isTrue ();
604
623
}
605
624
606
625
@ Test
@@ -865,7 +884,6 @@ public void testKeyConversion() throws Exception {
865
884
this .bytesKeyTemplate .send ("annotated36" , "foo" .getBytes (), "bar" );
866
885
assertThat (this .listener .keyLatch .await (30 , TimeUnit .SECONDS )).isTrue ();
867
886
assertThat (this .listener .convertedKey ).isEqualTo ("foo" );
868
- assertThat (this .config .intercepted ).isTrue ();
869
887
try {
870
888
assertThat (this .meterRegistry .get ("kafka.consumer.coordinator.join.total" )
871
889
.tag ("consumerTag" , "bytesString" )
@@ -893,6 +911,17 @@ public void testKeyConversion() throws Exception {
893
911
.isInstanceOf (CommonLoggingErrorHandler .class );
894
912
}
895
913
914
+ @ Test
915
+ public void testRecordInterceptor () throws Exception {
916
+ this .bytesKeyTemplate .send ("annotated42" , "fooRecordInterceptor" .getBytes (), "barRecordInterceptor" );
917
+ assertThat (this .listener .latch42 .await (30 , TimeUnit .SECONDS )).isTrue ();
918
+ assertThat (this .config .recordBeforePoll ).isTrue ();
919
+ assertThat (this .config .recordIntercepted ).isTrue ();
920
+ assertThat (this .config .recordSuccess ).isTrue ();
921
+ assertThat (this .config .recordFailure ).isFalse ();
922
+ assertThat (this .config .recordFinishInvoke ).isTrue ();
923
+ }
924
+
896
925
@ Test
897
926
public void testProjection () throws InterruptedException {
898
927
template .send ("annotated37" , 0 , "{ \" username\" : \" SomeUsername\" , \" user\" : { \" name\" : \" SomeName\" }}" );
@@ -984,10 +1013,26 @@ public static class Config implements KafkaListenerConfigurer {
984
1013
985
1014
volatile Throwable globalErrorThrowable ;
986
1015
987
- volatile boolean intercepted ;
1016
+ volatile boolean recordBeforePoll ;
1017
+
1018
+ volatile boolean recordIntercepted ;
1019
+
1020
+ volatile boolean recordSuccess ;
1021
+
1022
+ volatile boolean recordFailure ;
1023
+
1024
+ volatile boolean recordFinishInvoke ;
1025
+
1026
+ volatile boolean batchBeforePoll ;
988
1027
989
1028
volatile boolean batchIntercepted ;
990
1029
1030
+ volatile boolean batchSuccess ;
1031
+
1032
+ volatile boolean batchFailure ;
1033
+
1034
+ volatile boolean batchFinishInvoke ;
1035
+
991
1036
@ Autowired
992
1037
private EmbeddedKafkaBroker embeddedKafka ;
993
1038
@@ -1132,9 +1177,32 @@ public KafkaListenerContainerFactory<?> bytesStringListenerContainerFactory() {
1132
1177
ConcurrentKafkaListenerContainerFactory <byte [], String > factory =
1133
1178
new ConcurrentKafkaListenerContainerFactory <>();
1134
1179
factory .setConsumerFactory (bytesStringConsumerFactory ());
1135
- factory .setRecordInterceptor (record -> {
1136
- this .intercepted = true ;
1137
- return record ;
1180
+ factory .setRecordInterceptor (new RecordInterceptor <>() {
1181
+ @ Override
1182
+ public ConsumerRecord <byte [], String > intercept (ConsumerRecord <byte [], String > record ) {
1183
+ Config .this .recordIntercepted = true ;
1184
+ return record ;
1185
+ }
1186
+
1187
+ @ Override
1188
+ public void success (ConsumerRecord <byte [], String > record , Consumer <byte [], String > consumer ) {
1189
+ Config .this .recordSuccess = true ;
1190
+ }
1191
+
1192
+ @ Override
1193
+ public void failure (ConsumerRecord <byte [], String > record , Exception exception , Consumer <byte [], String > consumer ) {
1194
+ Config .this .recordFailure = true ;
1195
+ }
1196
+
1197
+ @ Override
1198
+ public void beforePoll (Consumer <byte [], String > consumer ) {
1199
+ Config .this .recordBeforePoll = true ;
1200
+ }
1201
+
1202
+ @ Override
1203
+ public void finishInvoke (Consumer <byte [], String > consumer ) {
1204
+ Config .this .recordFinishInvoke = true ;
1205
+ }
1138
1206
});
1139
1207
factory .setCommonErrorHandler (new CommonLoggingErrorHandler ());
1140
1208
return factory ;
@@ -1149,9 +1217,32 @@ public KafkaListenerContainerFactory<?> batchFactory() {
1149
1217
factory .setRecordFilterStrategy (recordFilter ());
1150
1218
// always send to the same partition so the replies are in order for the test
1151
1219
factory .setReplyTemplate (partitionZeroReplyTemplate ());
1152
- factory .setBatchInterceptor ((records , consumer ) -> {
1153
- this .batchIntercepted = true ;
1154
- return records ;
1220
+ factory .setBatchInterceptor (new BatchInterceptor <>() {
1221
+ @ Override
1222
+ public ConsumerRecords <Integer , String > intercept (ConsumerRecords <Integer , String > records , Consumer <Integer , String > consumer ) {
1223
+ Config .this .batchIntercepted = true ;
1224
+ return records ;
1225
+ }
1226
+
1227
+ @ Override
1228
+ public void success (ConsumerRecords <Integer , String > records , Consumer <Integer , String > consumer ) {
1229
+ Config .this .batchSuccess = true ;
1230
+ }
1231
+
1232
+ @ Override
1233
+ public void failure (ConsumerRecords <Integer , String > records , Exception exception , Consumer <Integer , String > consumer ) {
1234
+ Config .this .batchFailure = true ;
1235
+ }
1236
+
1237
+ @ Override
1238
+ public void beforePoll (Consumer <Integer , String > consumer ) {
1239
+ Config .this .batchBeforePoll = true ;
1240
+ }
1241
+
1242
+ @ Override
1243
+ public void finishInvoke (Consumer <Integer , String > consumer ) {
1244
+ Config .this .batchFinishInvoke = true ;
1245
+ }
1155
1246
});
1156
1247
return factory ;
1157
1248
}
@@ -1734,6 +1825,10 @@ static class Listener implements ConsumerSeekAware {
1734
1825
1735
1826
final CountDownLatch latch21 = new CountDownLatch (1 );
1736
1827
1828
+ final CountDownLatch latch42 = new CountDownLatch (1 );
1829
+
1830
+ final CountDownLatch latch43 = new CountDownLatch (1 );
1831
+
1737
1832
final CountDownLatch validationLatch = new CountDownLatch (1 );
1738
1833
1739
1834
final CountDownLatch eventLatch = new CountDownLatch (1 );
@@ -2090,6 +2185,17 @@ public void bytesKey(String in, @Header(KafkaHeaders.RECEIVED_MESSAGE_KEY) Strin
2090
2185
this .keyLatch .countDown ();
2091
2186
}
2092
2187
2188
+ @ KafkaListener (topics = "annotated42" , containerFactory = "bytesStringListenerContainerFactory" )
2189
+ public void recordInterceptorListener (String in ) {
2190
+ this .latch42 .countDown ();
2191
+ }
2192
+
2193
+ @ KafkaListener (topics = "annotated43" , containerFactory = "batchFactory" )
2194
+ public void batchInterceptorListener (List <ConsumerRecord <?, ?>> records ) {
2195
+ this .payload = records ;
2196
+ this .latch43 .countDown ();
2197
+ }
2198
+
2093
2199
@ KafkaListener (topics = "annotated29" )
2094
2200
public void anonymousListener (String in ) {
2095
2201
}
0 commit comments