Skip to content

Commit

Permalink
Merge pull request #1470 from garyrussell/ARBPDecorate
Browse files Browse the repository at this point in the history
Decorate exceptions for AfterRollbackProcessor
  • Loading branch information
garyrussell authored Apr 29, 2020
1 parent f9535fc commit 2d7eeab
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1376,12 +1376,14 @@ private void batchAfterRollback(final ConsumerRecords<K, V> records,
final List<ConsumerRecord<K, V>> recordList, RuntimeException e,
AfterRollbackProcessor<K, V> afterRollbackProcessorToUse) {

RuntimeException rollbackException = decorateException(e);
try {
if (recordList == null) {
afterRollbackProcessorToUse.process(createRecordList(records), this.consumer, e, false);
afterRollbackProcessorToUse.process(createRecordList(records), this.consumer, rollbackException,
false);
}
else {
afterRollbackProcessorToUse.process(recordList, this.consumer, e, false);
afterRollbackProcessorToUse.process(recordList, this.consumer, rollbackException, false);
}
}
catch (KafkaException ke) {
Expand Down Expand Up @@ -1607,7 +1609,7 @@ public void doInTransactionWithoutResult(TransactionStatus s) {
}
catch (RuntimeException e) {
this.logger.error(e, "Transaction rolled back");
recordAfterRollback(iterator, record, e);
recordAfterRollback(iterator, record, decorateException(e));
}
finally {
if (this.producerPerConsumerPartition) {
Expand Down Expand Up @@ -1838,8 +1840,8 @@ private void invokeErrorHandler(final ConsumerRecord<K, V> record,
}
}

private Exception decorateException(RuntimeException e) {
Exception toHandle = e;
private RuntimeException decorateException(RuntimeException e) {
RuntimeException toHandle = e;
if (toHandle instanceof ListenerExecutionFailedException) {
toHandle = new ListenerExecutionFailedException(toHandle.getMessage(), this.consumerGroupId,
toHandle.getCause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
public void testMaxFailures() throws Exception {
logger.info("Start testMaxFailures");
Map<String, Object> props = KafkaTestUtils.consumerProps("txTestMaxFailures", "false", embeddedKafka);
props.put(ConsumerConfig.GROUP_ID_CONFIG, "group");
props.put(ConsumerConfig.GROUP_ID_CONFIG, "groupInARBP");
props.put(ConsumerConfig.ISOLATION_LEVEL_CONFIG, "read_committed");
DefaultKafkaConsumerFactory<Integer, String> cf = new DefaultKafkaConsumerFactory<>(props);
ContainerProperties containerProps = new ContainerProperties(topic3);
Expand Down Expand Up @@ -650,9 +650,10 @@ public void accept(ConsumerRecord<?, ?> record, Exception exception) {
Map<String, Object> map = new HashMap<>();
mapper.toHeaders(dltRecord.headers(), map);
MessageHeaders headers = new MessageHeaders(map);
assertThat(new String(headers.get(KafkaHeaders.DLT_EXCEPTION_FQCN, byte[].class))).contains("RuntimeException");
assertThat(new String(headers.get(KafkaHeaders.DLT_EXCEPTION_FQCN, byte[].class)))
.contains("ListenerExecutionFailedException");
assertThat(headers.get(KafkaHeaders.DLT_EXCEPTION_MESSAGE, byte[].class))
.isEqualTo("fail for max failures".getBytes());
.contains("fail for max failures".getBytes());
assertThat(headers.get(KafkaHeaders.DLT_EXCEPTION_STACKTRACE)).isNotNull();
assertThat(headers.get(KafkaHeaders.DLT_ORIGINAL_OFFSET, byte[].class)[3]).isEqualTo((byte) 0);
assertThat(headers.get(KafkaHeaders.DLT_ORIGINAL_PARTITION, byte[].class)[3]).isEqualTo((byte) 0);
Expand All @@ -663,7 +664,11 @@ public void accept(ConsumerRecord<?, ?> record, Exception exception) {
pf.destroy();
assertThat(stopLatch.await(10, TimeUnit.SECONDS)).isTrue();
verify(afterRollbackProcessor, times(4)).isProcessInTransaction();
verify(afterRollbackProcessor, times(4)).process(any(), any(), any(), anyBoolean());
ArgumentCaptor<Exception> captor = ArgumentCaptor.forClass(Exception.class);
verify(afterRollbackProcessor, times(4)).process(any(), any(), captor.capture(), anyBoolean());
assertThat(captor.getValue()).isInstanceOf(ListenerExecutionFailedException.class)
.extracting(ex -> ((ListenerExecutionFailedException) ex).getGroupId())
.isEqualTo("groupInARBP");
verify(afterRollbackProcessor).clearThreadState();
verify(dlTemplate).send(any(ProducerRecord.class));
verify(dlTemplate).sendOffsetsToTransaction(
Expand Down

0 comments on commit 2d7eeab

Please sign in to comment.