1

I need to access the retry attempt number in spring cloud stream kafka transactional retry so that for a particular exception, based on the retry attempt number i can post the outcome to different topic

DreamCoder
  • 23
  • 5

1 Answers1

1

I assume you mean the delivery attempt in the consumer; you can use a ContainerCustomizer bean to set the deliveryAttemptHeader property to true.

/**
 * Set to true to populate the
 * {@link org.springframework.kafka.support.KafkaHeaders#DELIVERY_ATTEMPT} header when
 * the error handler or after rollback processor implements
 * {@code DeliveryAttemptAware}. There is a small overhead so this is false by
 * default.
 * @param deliveryAttemptHeader true to populate
 * @since 2.5
 */
public void setDeliveryAttemptHeader(boolean deliveryAttemptHeader) {
    this.deliveryAttemptHeader = deliveryAttemptHeader;
}

Then consume the entire Message<?> to examine the header.

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • Thanks for the direction, seems like a header deliveryAttempt is also added when we enable deliver attempt header, I see below headers `[headers={kafka_offset=5, scst_nativeHeadersPresent=true, kafka_consumer=org.apache.kafka.clients.consumer.KafkaConsumer@57d17787, deliveryAttempt=2, kafka_timestampType=CREATE_TIME, kafka_deliveryAttempt=[B@4d5c78b0, kafka_receivedPartitionId=4, kafka_receivedTopic=eu_ethoca_alertpersist, kafka_receivedTimestamp=1664455663685, contentType=application/*+avro, kafka_groupId=aps-processAlertQueueItem-test, target-protocol=streamBridge}]` – DreamCoder Sep 29 '22 at 13:03
  • That is a different count - that is a Spring Integration header, used when a `RetryTemplate` performs retrys. The kafka_deliveryAttempt is generated by the listener container; you should not configure both sets of retrys; otherwise they will be compounded; we recommend disabling retry in the binder (`maxAttempts=1`) and configuring the listener container to do the retries. – Gary Russell Sep 29 '22 at 14:06
  • In header `kafka_deliveryAttempt` I don't see any count, am I missing something? Also, we are not using `RetryTemplate` and just relying on transactional binder as mentioned in https://docs.spring.io/spring-cloud-stream-binder-kafka/docs/current/reference/html/spring-cloud-stream-binder-kafka.html#kafka-transactional-binder – DreamCoder Sep 30 '22 at 04:41
  • It's in binary form there; use `ByteBuffer.wrap(message.getHeaders().get(KafkaHeaders.DELIVERY_ATTEMPT), byte[].class).getInt()`. `maxattempts` is 3 by default, enabling retry in the binder; set it to 1 to disable. – Gary Russell Sep 30 '22 at 13:45
  • Please open an issue in spring-integration; the way we map the headers is inconsistent when a retry template exists or not. – Gary Russell Sep 30 '22 at 14:40
  • 1
    Here's the bottom line - when binder retries are enabled (default), `deliveryAttempt` contains the binder retry count; when retries are disabled, the `kafka_deliveryAttempt` is decoded into `deliveryAttempt`; in both cases, `kafka_deliveryAttempt` (binary) is present. – Gary Russell Sep 30 '22 at 15:14