4646import org .springframework .core .AttributeAccessor ;
4747import org .springframework .core .convert .converter .Converter ;
4848import org .springframework .core .serializer .support .DeserializingConverter ;
49+ import org .springframework .integration .IntegrationMessageHeaderAccessor ;
4950import org .springframework .integration .aws .support .AwsHeaders ;
5051import org .springframework .integration .endpoint .MessageProducerSupport ;
5152import org .springframework .integration .mapping .InboundMessageMapper ;
@@ -159,6 +160,8 @@ public class KinesisMessageDrivenChannelAdapter extends MessageProducerSupport i
159160
160161 private LockRegistry lockRegistry ;
161162
163+ private boolean bindSourceRecord ;
164+
162165 private volatile boolean active ;
163166
164167 private volatile int consumerInvokerMaxCapacity ;
@@ -235,7 +238,7 @@ public void setCheckpointMode(CheckpointMode checkpointMode) {
235238 /**
236239 * Sets the interval between 2 checkpoints. Only used when checkpointMode is periodic.
237240 * @param checkpointsInterval interval between 2 checkpoints (in milliseconds)
238- * @since 2.2.0
241+ * @since 2.2
239242 */
240243 public void setCheckpointsInterval (long checkpointsInterval ) {
241244 this .checkpointsInterval = checkpointsInterval ;
@@ -311,6 +314,17 @@ public void setLockRegistry(LockRegistry lockRegistry) {
311314 this .lockRegistry = lockRegistry ;
312315 }
313316
317+ /**
318+ * Set to true to bind the source consumer record in the header named
319+ * {@link IntegrationMessageHeaderAccessor#SOURCE_DATA}.
320+ * Does not apply to batch listeners.
321+ * @param bindSourceRecord true to bind.
322+ * @since 2.2
323+ */
324+ public void setBindSourceRecord (boolean bindSourceRecord ) {
325+ this .bindSourceRecord = bindSourceRecord ;
326+ }
327+
314328 @ Override
315329 protected void onInit () {
316330 super .onInit ();
@@ -527,7 +541,8 @@ private void populateShardsForStream(final String stream, final CountDownLatch s
527541 }
528542
529543 if (describeStreamResult == null ||
530- !StreamStatus .ACTIVE .toString ().equals (describeStreamResult .getStreamDescription ().getStreamStatus ())) {
544+ !StreamStatus .ACTIVE .toString ().equals (
545+ describeStreamResult .getStreamDescription ().getStreamStatus ())) {
531546
532547 if (describeStreamRetries ++ > this .describeStreamRetries ) {
533548 ResourceNotFoundException resourceNotFoundException =
@@ -541,7 +556,7 @@ private void populateShardsForStream(final String stream, final CountDownLatch s
541556 continue ;
542557 }
543558 catch (InterruptedException e ) {
544- Thread .interrupted ();
559+ Thread .currentThread (). interrupt ();
545560 throw new IllegalStateException ("The [describeStream] thread for the stream ["
546561 + stream + "] has been interrupted." , e );
547562 }
@@ -729,10 +744,9 @@ public void run() {
729744 }
730745 }
731746
732- for ( Iterator <ShardConsumer > iterator =
747+ Iterator <ShardConsumer > iterator =
733748 KinesisMessageDrivenChannelAdapter .this .shardConsumers .values ().iterator ();
734- iterator .hasNext (); ) {
735-
749+ while (iterator .hasNext ()) {
736750 ShardConsumer shardConsumer = iterator .next ();
737751 shardConsumer .execute ();
738752 if (ConsumerState .STOP == shardConsumer .state ) {
@@ -795,7 +809,8 @@ private final class ShardConsumer {
795809 ShardConsumer (KinesisShardOffset shardOffset ) {
796810 this .shardOffset = new KinesisShardOffset (shardOffset );
797811 this .key = buildCheckpointKeyForShard (shardOffset .getStream (), shardOffset .getShard ());
798- this .checkpointer = new ShardCheckpointer (KinesisMessageDrivenChannelAdapter .this .checkpointStore , this .key );
812+ this .checkpointer = new ShardCheckpointer (KinesisMessageDrivenChannelAdapter .this .checkpointStore ,
813+ this .key );
799814 }
800815
801816 void setNotifier (Runnable notifier ) {
@@ -838,7 +853,8 @@ void execute() {
838853 if (logger .isInfoEnabled () && this .state == ConsumerState .NEW ) {
839854 logger .info ("The [" + this + "] has been started." );
840855 }
841- GetShardIteratorRequest shardIteratorRequest = this .shardOffset .toShardIteratorRequest ();
856+ GetShardIteratorRequest shardIteratorRequest =
857+ this .shardOffset .toShardIteratorRequest ();
842858 this .shardIterator =
843859 KinesisMessageDrivenChannelAdapter .this .amazonKinesis
844860 .getShardIterator (shardIteratorRequest )
@@ -1034,8 +1050,8 @@ private void processRecords(List<Record> records) {
10341050 }
10351051 else if (CheckpointMode .periodic .equals (KinesisMessageDrivenChannelAdapter .this .checkpointMode ) &&
10361052 System .currentTimeMillis () > nextCheckpointTimeInMillis ) {
1037- this .checkpointer .checkpoint ();
1038- this .nextCheckpointTimeInMillis = System .currentTimeMillis () + checkpointsInterval ;
1053+ this .checkpointer .checkpoint ();
1054+ this .nextCheckpointTimeInMillis = System .currentTimeMillis () + checkpointsInterval ;
10391055 }
10401056 }
10411057
@@ -1068,6 +1084,10 @@ private AbstractIntegrationMessageBuilder<Object> prepareMessageForRecord(Record
10681084 .setHeader (AwsHeaders .RECEIVED_PARTITION_KEY , record .getPartitionKey ())
10691085 .setHeader (AwsHeaders .RECEIVED_SEQUENCE_NUMBER , record .getSequenceNumber ());
10701086
1087+ if (KinesisMessageDrivenChannelAdapter .this .bindSourceRecord ) {
1088+ messageBuilder .setHeader (IntegrationMessageHeaderAccessor .SOURCE_DATA , record );
1089+ }
1090+
10711091 if (messageToUse != null ) {
10721092 messageBuilder .copyHeadersIfAbsent (messageToUse .getHeaders ());
10731093 }
@@ -1157,8 +1177,8 @@ public void run() {
11571177 shardConsumer .task .run ();
11581178 }
11591179 catch (Exception e ) {
1160- logger .info ("Got an exception " + e + " during [" + shardConsumer + "] task invocation. \n " +
1161- "Process will be retried on the next iteration." );
1180+ logger .info ("Got an exception " + e + " during [" + shardConsumer + "] task invocation"
1181+ + ". \n Process will be retried on the next iteration." );
11621182 }
11631183 }
11641184 }
0 commit comments