21
21
import java .util .Arrays ;
22
22
import java .util .List ;
23
23
import java .util .UUID ;
24
- import java .util .stream . Collectors ;
24
+ import java .util .function . Consumer ;
25
25
26
26
import javax .annotation .Nullable ;
27
27
40
40
import software .amazon .kinesis .common .InitialPositionInStreamExtended ;
41
41
import software .amazon .kinesis .common .StreamConfig ;
42
42
import software .amazon .kinesis .common .StreamIdentifier ;
43
+ import software .amazon .kinesis .coordinator .CoordinatorConfig ;
43
44
import software .amazon .kinesis .coordinator .Scheduler ;
44
45
import software .amazon .kinesis .exceptions .InvalidStateException ;
45
46
import software .amazon .kinesis .exceptions .ShutdownException ;
46
47
import software .amazon .kinesis .exceptions .ThrottlingException ;
48
+ import software .amazon .kinesis .leases .LeaseManagementConfig ;
47
49
import software .amazon .kinesis .lifecycle .LifecycleConfig ;
48
50
import software .amazon .kinesis .lifecycle .events .InitializationInput ;
49
51
import software .amazon .kinesis .lifecycle .events .LeaseLostInput ;
55
57
import software .amazon .kinesis .metrics .NullMetricsFactory ;
56
58
import software .amazon .kinesis .processor .FormerStreamsLeasesDeletionStrategy ;
57
59
import software .amazon .kinesis .processor .MultiStreamTracker ;
60
+ import software .amazon .kinesis .processor .ProcessorConfig ;
58
61
import software .amazon .kinesis .processor .RecordProcessorCheckpointer ;
59
62
import software .amazon .kinesis .processor .ShardRecordProcessor ;
60
63
import software .amazon .kinesis .processor .ShardRecordProcessorFactory ;
@@ -151,6 +154,20 @@ public class KclMessageDrivenChannelAdapter extends MessageProducerSupport
151
154
152
155
private MetricsLevel metricsLevel = MetricsLevel .DETAILED ;
153
156
157
+ private Consumer <CoordinatorConfig > coordinatorConfigCustomizer = (config ) -> {
158
+ };
159
+
160
+ private Consumer <LifecycleConfig > lifecycleConfigCustomizer = (config ) -> {
161
+ };
162
+
163
+ private Consumer <MetricsConfig > metricsConfigCustomizer = (config ) -> {
164
+ };
165
+
166
+ private Consumer <LeaseManagementConfig > leaseManagementConfigCustomizer = (config ) -> {
167
+ };
168
+
169
+ private boolean emptyRecordList ;
170
+
154
171
public KclMessageDrivenChannelAdapter (String ... streams ) {
155
172
this (KinesisAsyncClient .create (), CloudWatchAsyncClient .create (), DynamoDbAsyncClient .create (), streams );
156
173
}
@@ -283,9 +300,70 @@ public void setMetricsLevel(MetricsLevel metricsLevel) {
283
300
this .metricsLevel = metricsLevel ;
284
301
}
285
302
303
+ /**
304
+ * Set a {@link Consumer} to configure a {@link CoordinatorConfig}.
305
+ * @param coordinatorConfigCustomizer the {@link Consumer} to configure a {@link CoordinatorConfig}.
306
+ * @since 3.0.8
307
+ * @see CoordinatorConfig
308
+ */
309
+ public void setCoordinatorConfigCustomizer (Consumer <CoordinatorConfig > coordinatorConfigCustomizer ) {
310
+ Assert .notNull (coordinatorConfigCustomizer , "'coordinatorConfigCustomizer' must not be null" );
311
+ this .coordinatorConfigCustomizer = coordinatorConfigCustomizer ;
312
+ }
313
+
314
+ /**
315
+ * Set a {@link Consumer} to configure a {@link LifecycleConfig}.
316
+ * @param lifecycleConfigCustomizer the {@link Consumer} to configure a {@link LifecycleConfig}.
317
+ * @since 3.0.8
318
+ * @see LifecycleConfig
319
+ */
320
+ public void setLifecycleConfigCustomizer (Consumer <LifecycleConfig > lifecycleConfigCustomizer ) {
321
+ Assert .notNull (lifecycleConfigCustomizer , "'lifecycleConfigCustomizer' must not be null" );
322
+ this .lifecycleConfigCustomizer = lifecycleConfigCustomizer ;
323
+ }
324
+
325
+ /**
326
+ * Set a {@link Consumer} to configure a {@link MetricsConfig}.
327
+ * May override whatever could be set individually, like {@link #setMetricsLevel(MetricsLevel)}.
328
+ * @param metricsConfigCustomizer the {@link Consumer} to configure a {@link MetricsConfig}.
329
+ * @since 3.0.8
330
+ * @see MetricsConfig
331
+ */
332
+ public void setMetricsConfigCustomizer (Consumer <MetricsConfig > metricsConfigCustomizer ) {
333
+ Assert .notNull (metricsConfigCustomizer , "'metricsConfigCustomizer' must not be null" );
334
+ this .metricsConfigCustomizer = metricsConfigCustomizer ;
335
+ }
336
+
337
+ /**
338
+ * Set a {@link Consumer} to configure a {@link LeaseManagementConfig}.
339
+ * @param leaseManagementConfigCustomizer the {@link Consumer} to configure a {@link LeaseManagementConfig}.
340
+ * @since 3.0.8
341
+ * @see LeaseManagementConfig
342
+ */
343
+ public void setLeaseManagementConfigCustomizer (Consumer <LeaseManagementConfig > leaseManagementConfigCustomizer ) {
344
+ Assert .notNull (leaseManagementConfigCustomizer , "'leaseManagementConfigCustomizer' must not be null" );
345
+ this .leaseManagementConfigCustomizer = leaseManagementConfigCustomizer ;
346
+ }
347
+
348
+ /**
349
+ * Whether to return an empty record list from consumer to the processor.
350
+ * Works only in {@link ListenerMode#batch} mode.
351
+ * The message will be sent into the output channel with an empty {@link List} as a payload.
352
+ * @param emptyRecordList true to return an empty record list.
353
+ * @since 3.0.8
354
+ * @see ProcessorConfig#callProcessRecordsEvenForEmptyRecordList(boolean)
355
+ */
356
+ public void setEmptyRecordList (boolean emptyRecordList ) {
357
+ this .emptyRecordList = emptyRecordList ;
358
+ }
359
+
286
360
@ Override
287
361
protected void onInit () {
288
362
super .onInit ();
363
+ if (this .listenerMode .equals (ListenerMode .record ) && this .emptyRecordList ) {
364
+ this .emptyRecordList = false ;
365
+ logger .warn ("The 'emptyRecordList' is processed only in the [ListenerMode.batch]." );
366
+ }
289
367
this .config =
290
368
new ConfigsBuilder (buildStreamTracker (),
291
369
this .consumerGroup ,
@@ -316,8 +394,9 @@ protected void doStart() {
316
394
+ "because it does not make sense in case of [ListenerMode.batch]." );
317
395
}
318
396
319
- LifecycleConfig lifecycleConfig = this .config .lifecycleConfig ();
397
+ LifecycleConfig lifecycleConfig = this .config .lifecycleConfig ();
320
398
lifecycleConfig .taskBackoffTimeMillis (this .consumerBackoff );
399
+ this .lifecycleConfigCustomizer .accept (lifecycleConfig );
321
400
322
401
RetrievalSpecificConfig retrievalSpecificConfig ;
323
402
String singleStreamName = this .streams .length == 1 ? this .streams [0 ] : null ;
@@ -342,15 +421,25 @@ protected void doStart() {
342
421
if (MetricsLevel .NONE .equals (this .metricsLevel )) {
343
422
metricsConfig .metricsFactory (new NullMetricsFactory ());
344
423
}
424
+ this .metricsConfigCustomizer .accept (metricsConfig );
425
+
426
+ CoordinatorConfig coordinatorConfig = this .config .coordinatorConfig ();
427
+ this .coordinatorConfigCustomizer .accept (coordinatorConfig );
428
+
429
+ LeaseManagementConfig leaseManagementConfig = this .config .leaseManagementConfig ();
430
+ this .leaseManagementConfigCustomizer .accept (leaseManagementConfig );
431
+
432
+ ProcessorConfig processorConfig = this .config .processorConfig ()
433
+ .callProcessRecordsEvenForEmptyRecordList (this .emptyRecordList );
345
434
346
435
this .scheduler =
347
436
new Scheduler (
348
437
this .config .checkpointConfig (),
349
- this . config . coordinatorConfig () ,
350
- this . config . leaseManagementConfig () ,
438
+ coordinatorConfig ,
439
+ leaseManagementConfig ,
351
440
lifecycleConfig ,
352
441
metricsConfig ,
353
- this . config . processorConfig () ,
442
+ processorConfig ,
354
443
retrievalConfig );
Has conversations. Original line has conversations. 355
444
356
445
this .executor .execute (this .scheduler );
@@ -542,7 +631,7 @@ private void processMultipleRecords(List<KinesisClientRecord> records,
542
631
records .stream ()
543
632
.map (this ::prepareMessageForRecord )
544
633
.map (AbstractIntegrationMessageBuilder ::build )
545
- .collect ( Collectors . toList () );
634
+ .toList ();
546
635
547
636
messageBuilder = getMessageBuilderFactory ().withPayload (payload );
548
637
}
@@ -557,7 +646,7 @@ else if (KclMessageDrivenChannelAdapter.this.converter != null) {
557
646
558
647
return KclMessageDrivenChannelAdapter .this .converter .convert (r .data ().array ());
559
648
})
560
- .collect ( Collectors . toList () );
649
+ .toList ();
561
650
562
651
messageBuilder = getMessageBuilderFactory ().withPayload (payload )
563
652
.setHeader (AwsHeaders .RECEIVED_PARTITION_KEY , partitionKeys )