3030import static org .mockito .Mockito .spy ;
3131import static org .mockito .Mockito .times ;
3232import static org .mockito .Mockito .verify ;
33+ import static org .mockito .Mockito .verifyNoMoreInteractions ;
3334
3435import java .time .Duration ;
36+ import java .util .ArrayList ;
3537import java .util .Arrays ;
3638import java .util .Collection ;
3739import java .util .Collections ;
7375import org .springframework .kafka .support .DefaultKafkaHeaderMapper ;
7476import org .springframework .kafka .support .KafkaHeaders ;
7577import org .springframework .kafka .support .TopicPartitionInitialOffset ;
78+ import org .springframework .kafka .support .TransactionSupport ;
7679import org .springframework .kafka .test .EmbeddedKafkaBroker ;
7780import org .springframework .kafka .test .rule .EmbeddedKafkaRule ;
7881import org .springframework .kafka .test .utils .KafkaTestUtils ;
@@ -153,14 +156,18 @@ private void testConsumeAndProduceTransactionGuts(boolean chained, boolean handl
153156 ConsumerFactory cf = mock (ConsumerFactory .class );
154157 willReturn (consumer ).given (cf ).createConsumer ("group" , "" , null );
155158 Producer producer = mock (Producer .class );
156- final CountDownLatch closeLatch = new CountDownLatch (1 );
159+ final CountDownLatch closeLatch = new CountDownLatch (2 );
157160 willAnswer (i -> {
158161 closeLatch .countDown ();
159162 return null ;
160163 }).given (producer ).close ();
161164 ProducerFactory pf = mock (ProducerFactory .class );
162165 given (pf .transactionCapable ()).willReturn (true );
163- given (pf .createProducer ()).willReturn (producer );
166+ final List <String > transactionalIds = new ArrayList <>();
167+ willAnswer (i -> {
168+ transactionalIds .add (TransactionSupport .getTransactionIdSuffix ());
169+ return producer ;
170+ }).given (pf ).createProducer ();
164171 KafkaTransactionManager tm = new KafkaTransactionManager (pf );
165172 PlatformTransactionManager ptm = tm ;
166173 if (chained ) {
@@ -185,6 +192,11 @@ private void testConsumeAndProduceTransactionGuts(boolean chained, boolean handl
185192 assertThat (closeLatch .await (10 , TimeUnit .SECONDS )).isTrue ();
186193 InOrder inOrder = inOrder (producer );
187194 inOrder .verify (producer ).beginTransaction ();
195+ inOrder .verify (producer ).sendOffsetsToTransaction (Collections .singletonMap (topicPartition ,
196+ new OffsetAndMetadata (0 )), "group" );
197+ inOrder .verify (producer ).commitTransaction ();
198+ inOrder .verify (producer ).close ();
199+ inOrder .verify (producer ).beginTransaction ();
188200 ArgumentCaptor <ProducerRecord > captor = ArgumentCaptor .forClass (ProducerRecord .class );
189201 inOrder .verify (producer ).send (captor .capture (), any (Callback .class ));
190202 assertThat (captor .getValue ()).isEqualTo (new ProducerRecord ("bar" , "baz" ));
@@ -193,7 +205,10 @@ private void testConsumeAndProduceTransactionGuts(boolean chained, boolean handl
193205 inOrder .verify (producer ).commitTransaction ();
194206 inOrder .verify (producer ).close ();
195207 container .stop ();
196- verify (pf , times (1 )).createProducer ();
208+ verify (pf , times (2 )).createProducer ();
209+ verifyNoMoreInteractions (producer );
210+ assertThat (transactionalIds .get (0 )).isEqualTo ("group.foo.0" );
211+ assertThat (transactionalIds .get (0 )).isEqualTo ("group.foo.0" );
197212 }
198213
199214 @ SuppressWarnings ({ "rawtypes" , "unchecked" })
@@ -433,7 +448,7 @@ public void testRollbackRecord() throws Exception {
433448 }
434449 });
435450
436- @ SuppressWarnings ({ "rawtypes" , "unchecked" })
451+ @ SuppressWarnings ({ "rawtypes" })
437452 KafkaTransactionManager tm = new KafkaTransactionManager (pf );
438453 containerProps .setTransactionManager (tm );
439454 KafkaMessageListenerContainer <Integer , String > container =
0 commit comments