|
1 | 1 | /* |
2 | | - * Copyright 2016-2020 the original author or authors. |
| 2 | + * Copyright 2016-2021 the original author or authors. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
100 | 100 | import org.springframework.messaging.support.ErrorMessage; |
101 | 101 | import org.springframework.messaging.support.GenericMessage; |
102 | 102 | import org.springframework.transaction.PlatformTransactionManager; |
| 103 | +import org.springframework.transaction.TransactionDefinition; |
| 104 | +import org.springframework.transaction.TransactionException; |
| 105 | +import org.springframework.transaction.support.AbstractPlatformTransactionManager; |
| 106 | +import org.springframework.transaction.support.DefaultTransactionStatus; |
| 107 | +import org.springframework.transaction.support.TransactionTemplate; |
103 | 108 | import org.springframework.util.concurrent.ListenableFuture; |
104 | 109 | import org.springframework.util.concurrent.SettableListenableFuture; |
105 | 110 |
|
@@ -598,6 +603,37 @@ protected Producer createTransactionalProducer(String txIdPrefix) { |
598 | 603 | assertThat(txId.get()).isEqualTo("overridden.tx.id."); |
599 | 604 | } |
600 | 605 |
|
| 606 | + @SuppressWarnings({ "rawtypes", "unchecked" }) |
| 607 | + @Test |
| 608 | + void testTransactionSynch() { |
| 609 | + Producer producer = mock(Producer.class); |
| 610 | + ProducerFactory pf = mock(ProducerFactory.class); |
| 611 | + given(pf.transactionCapable()).willReturn(true); |
| 612 | + given(pf.createProducer(isNull())).willReturn(producer); |
| 613 | + ListenableFuture future = mock(ListenableFuture.class); |
| 614 | + willReturn(future).given(producer).send(any(ProducerRecord.class), any(Callback.class)); |
| 615 | + KafkaTemplate template = new KafkaTemplate(pf); |
| 616 | + KafkaProducerMessageHandler handler = new KafkaProducerMessageHandler(template); |
| 617 | + handler.setTopicExpression(new LiteralExpression("bar")); |
| 618 | + handler.setBeanFactory(mock(BeanFactory.class)); |
| 619 | + handler.afterPropertiesSet(); |
| 620 | + handler.start(); |
| 621 | + try { |
| 622 | + new TransactionTemplate(new SomeOtherTransactionManager()).executeWithoutResult(status -> { |
| 623 | + handler.handleMessage(new GenericMessage<>("foo")); |
| 624 | + throw new IllegalStateException("test"); |
| 625 | + }); |
| 626 | + } |
| 627 | + catch (IllegalStateException ex) { |
| 628 | + } |
| 629 | + handler.stop(); |
| 630 | + verify(producer).beginTransaction(); |
| 631 | + verify(producer).send(any(ProducerRecord.class), any(Callback.class)); |
| 632 | + verify(producer).abortTransaction(); |
| 633 | + verify(producer).close(any()); |
| 634 | + verifyNoMoreInteractions(producer); |
| 635 | + } |
| 636 | + |
601 | 637 | @SuppressWarnings({ "unchecked", "rawtypes" }) |
602 | 638 | @Test |
603 | 639 | void testConsumeAndProduceTransactionTxIdOverride() throws Exception { |
@@ -747,4 +783,26 @@ void testNoFlush() { |
747 | 783 | handler.stop(); |
748 | 784 | } |
749 | 785 |
|
| 786 | + @SuppressWarnings("serial") |
| 787 | + static class SomeOtherTransactionManager extends AbstractPlatformTransactionManager { |
| 788 | + |
| 789 | + @Override |
| 790 | + protected Object doGetTransaction() throws TransactionException { |
| 791 | + return new Object(); |
| 792 | + } |
| 793 | + |
| 794 | + @Override |
| 795 | + protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { |
| 796 | + } |
| 797 | + |
| 798 | + @Override |
| 799 | + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { |
| 800 | + } |
| 801 | + |
| 802 | + @Override |
| 803 | + protected void doRollback(DefaultTransactionStatus status) throws TransactionException { |
| 804 | + } |
| 805 | + |
| 806 | + } |
| 807 | + |
750 | 808 | } |
0 commit comments