List of usage examples for org.springframework.kafka.core ProducerFactory transactionCapable
default boolean transactionCapable()
From source file:org.springframework.kafka.listener.TransactionalContainerTests.java
@SuppressWarnings({ "rawtypes", "unchecked" })
private void testConsumeAndProduceTransactionGuts(boolean chained, boolean handleError) throws Exception {
Consumer consumer = mock(Consumer.class);
final TopicPartition topicPartition = new TopicPartition("foo", 0);
willAnswer(i -> {//from w ww. j a v a2 s. c o m
((ConsumerRebalanceListener) i.getArgument(1))
.onPartitionsAssigned(Collections.singletonList(topicPartition));
return null;
}).given(consumer).subscribe(any(Collection.class), any(ConsumerRebalanceListener.class));
ConsumerRecords records = new ConsumerRecords(Collections.singletonMap(topicPartition,
Collections.singletonList(new ConsumerRecord<>("foo", 0, 0, "key", "value"))));
final AtomicBoolean done = new AtomicBoolean();
willAnswer(i -> {
if (done.compareAndSet(false, true)) {
return records;
} else {
Thread.sleep(500);
return null;
}
}).given(consumer).poll(any(Duration.class));
ConsumerFactory cf = mock(ConsumerFactory.class);
willReturn(consumer).given(cf).createConsumer("group", "", null);
Producer producer = mock(Producer.class);
final CountDownLatch closeLatch = new CountDownLatch(2);
willAnswer(i -> {
closeLatch.countDown();
return null;
}).given(producer).close();
ProducerFactory pf = mock(ProducerFactory.class);
given(pf.transactionCapable()).willReturn(true);
final List<String> transactionalIds = new ArrayList<>();
willAnswer(i -> {
transactionalIds.add(TransactionSupport.getTransactionIdSuffix());
return producer;
}).given(pf).createProducer();
KafkaTransactionManager tm = new KafkaTransactionManager(pf);
PlatformTransactionManager ptm = tm;
if (chained) {
ptm = new ChainedKafkaTransactionManager(new SomeOtherTransactionManager(), tm);
}
ContainerProperties props = new ContainerProperties("foo");
props.setGroupId("group");
props.setTransactionManager(ptm);
final KafkaTemplate template = new KafkaTemplate(pf);
props.setMessageListener((MessageListener) m -> {
template.send("bar", "baz");
if (handleError) {
throw new RuntimeException("fail");
}
});
KafkaMessageListenerContainer container = new KafkaMessageListenerContainer<>(cf, props);
container.setBeanName("commit");
if (handleError) {
container.setErrorHandler((e, data) -> {
});
}
container.start();
assertThat(closeLatch.await(10, TimeUnit.SECONDS)).isTrue();
InOrder inOrder = inOrder(producer);
inOrder.verify(producer).beginTransaction();
inOrder.verify(producer).sendOffsetsToTransaction(
Collections.singletonMap(topicPartition, new OffsetAndMetadata(0)), "group");
inOrder.verify(producer).commitTransaction();
inOrder.verify(producer).close();
inOrder.verify(producer).beginTransaction();
ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class);
inOrder.verify(producer).send(captor.capture(), any(Callback.class));
assertThat(captor.getValue()).isEqualTo(new ProducerRecord("bar", "baz"));
inOrder.verify(producer).sendOffsetsToTransaction(
Collections.singletonMap(topicPartition, new OffsetAndMetadata(1)), "group");
inOrder.verify(producer).commitTransaction();
inOrder.verify(producer).close();
container.stop();
verify(pf, times(2)).createProducer();
verifyNoMoreInteractions(producer);
assertThat(transactionalIds.get(0)).isEqualTo("group.foo.0");
assertThat(transactionalIds.get(0)).isEqualTo("group.foo.0");
}
From source file:org.springframework.kafka.listener.TransactionalContainerTests.java
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test/*ww w. ja va 2s .c o m*/
public void testConsumeAndProduceTransactionRollback() throws Exception {
Consumer consumer = mock(Consumer.class);
final TopicPartition topicPartition0 = new TopicPartition("foo", 0);
final TopicPartition topicPartition1 = new TopicPartition("foo", 1);
Map<TopicPartition, List<ConsumerRecord<String, String>>> recordMap = new HashMap<>();
recordMap.put(topicPartition0,
Collections.singletonList(new ConsumerRecord<>("foo", 0, 0, "key", "value")));
recordMap.put(topicPartition1,
Collections.singletonList(new ConsumerRecord<>("foo", 1, 0, "key", "value")));
ConsumerRecords records = new ConsumerRecords(recordMap);
final AtomicBoolean done = new AtomicBoolean();
willAnswer(i -> {
if (done.compareAndSet(false, true)) {
return records;
} else {
Thread.sleep(500);
return null;
}
}).given(consumer).poll(any(Duration.class));
final CountDownLatch seekLatch = new CountDownLatch(2);
willAnswer(i -> {
seekLatch.countDown();
return null;
}).given(consumer).seek(any(), anyLong());
ConsumerFactory cf = mock(ConsumerFactory.class);
willReturn(consumer).given(cf).createConsumer("group", "", null);
Producer producer = mock(Producer.class);
final CountDownLatch closeLatch = new CountDownLatch(1);
willAnswer(i -> {
closeLatch.countDown();
return null;
}).given(producer).close();
ProducerFactory pf = mock(ProducerFactory.class);
given(pf.transactionCapable()).willReturn(true);
given(pf.createProducer()).willReturn(producer);
KafkaTransactionManager tm = new KafkaTransactionManager(pf);
ContainerProperties props = new ContainerProperties(new TopicPartitionInitialOffset("foo", 0),
new TopicPartitionInitialOffset("foo", 1));
props.setGroupId("group");
props.setTransactionManager(tm);
final KafkaTemplate template = new KafkaTemplate(pf);
props.setMessageListener((MessageListener) m -> {
template.send("bar", "baz");
throw new RuntimeException("fail");
});
KafkaMessageListenerContainer container = new KafkaMessageListenerContainer<>(cf, props);
container.setBeanName("rollback");
container.start();
assertThat(closeLatch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(seekLatch.await(10, TimeUnit.SECONDS)).isTrue();
InOrder inOrder = inOrder(producer);
inOrder.verify(producer).beginTransaction();
ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class);
verify(producer).send(captor.capture(), any(Callback.class));
assertThat(captor.getValue()).isEqualTo(new ProducerRecord("bar", "baz"));
inOrder.verify(producer, never()).sendOffsetsToTransaction(anyMap(), anyString());
inOrder.verify(producer, never()).commitTransaction();
inOrder.verify(producer).abortTransaction();
inOrder.verify(producer).close();
verify(consumer).seek(topicPartition0, 0);
verify(consumer).seek(topicPartition1, 0);
verify(consumer, never()).commitSync(anyMap());
container.stop();
verify(pf, times(1)).createProducer();
}
From source file:org.springframework.kafka.listener.TransactionalContainerTests.java
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test/* w w w. ja v a 2s. c o m*/
public void testConsumeAndProduceTransactionRollbackBatch() throws Exception {
Consumer consumer = mock(Consumer.class);
final TopicPartition topicPartition0 = new TopicPartition("foo", 0);
final TopicPartition topicPartition1 = new TopicPartition("foo", 1);
Map<TopicPartition, List<ConsumerRecord<String, String>>> recordMap = new HashMap<>();
recordMap.put(topicPartition0,
Collections.singletonList(new ConsumerRecord<>("foo", 0, 0, "key", "value")));
recordMap.put(topicPartition1,
Collections.singletonList(new ConsumerRecord<>("foo", 1, 0, "key", "value")));
ConsumerRecords records = new ConsumerRecords(recordMap);
final AtomicBoolean done = new AtomicBoolean();
willAnswer(i -> {
if (done.compareAndSet(false, true)) {
return records;
} else {
Thread.sleep(500);
return null;
}
}).given(consumer).poll(any(Duration.class));
final CountDownLatch seekLatch = new CountDownLatch(2);
willAnswer(i -> {
seekLatch.countDown();
return null;
}).given(consumer).seek(any(), anyLong());
ConsumerFactory cf = mock(ConsumerFactory.class);
willReturn(consumer).given(cf).createConsumer("group", "", null);
Producer producer = mock(Producer.class);
final CountDownLatch closeLatch = new CountDownLatch(1);
willAnswer(i -> {
closeLatch.countDown();
return null;
}).given(producer).close();
ProducerFactory pf = mock(ProducerFactory.class);
given(pf.transactionCapable()).willReturn(true);
given(pf.createProducer()).willReturn(producer);
KafkaTransactionManager tm = new KafkaTransactionManager(pf);
ContainerProperties props = new ContainerProperties(new TopicPartitionInitialOffset("foo", 0),
new TopicPartitionInitialOffset("foo", 1));
props.setGroupId("group");
props.setTransactionManager(tm);
final KafkaTemplate template = new KafkaTemplate(pf);
props.setMessageListener((BatchMessageListener) recordlist -> {
template.send("bar", "baz");
throw new RuntimeException("fail");
});
KafkaMessageListenerContainer container = new KafkaMessageListenerContainer<>(cf, props);
container.setBeanName("rollback");
container.start();
assertThat(closeLatch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(seekLatch.await(10, TimeUnit.SECONDS)).isTrue();
InOrder inOrder = inOrder(producer);
inOrder.verify(producer).beginTransaction();
ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class);
verify(producer).send(captor.capture(), any(Callback.class));
assertThat(captor.getValue()).isEqualTo(new ProducerRecord("bar", "baz"));
inOrder.verify(producer, never()).sendOffsetsToTransaction(anyMap(), anyString());
inOrder.verify(producer, never()).commitTransaction();
inOrder.verify(producer).abortTransaction();
inOrder.verify(producer).close();
verify(consumer).seek(topicPartition0, 0);
verify(consumer).seek(topicPartition1, 0);
verify(consumer, never()).commitSync(anyMap());
container.stop();
verify(pf, times(1)).createProducer();
}
From source file:org.springframework.kafka.listener.TransactionalContainerTests.java
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test/*from w w w . j ava 2 s . c o m*/
public void testConsumeAndProduceTransactionExternalTM() throws Exception {
Consumer consumer = mock(Consumer.class);
final TopicPartition topicPartition = new TopicPartition("foo", 0);
willAnswer(i -> {
((ConsumerRebalanceListener) i.getArgument(1))
.onPartitionsAssigned(Collections.singletonList(topicPartition));
return null;
}).given(consumer).subscribe(any(Collection.class), any(ConsumerRebalanceListener.class));
final ConsumerRecords records = new ConsumerRecords(Collections.singletonMap(topicPartition,
Collections.singletonList(new ConsumerRecord<>("foo", 0, 0, "key", "value"))));
final AtomicBoolean done = new AtomicBoolean();
willAnswer(i -> {
if (done.compareAndSet(false, true)) {
return records;
} else {
Thread.sleep(500);
return null;
}
}).given(consumer).poll(any(Duration.class));
ConsumerFactory cf = mock(ConsumerFactory.class);
willReturn(consumer).given(cf).createConsumer("group", "", null);
Producer producer = mock(Producer.class);
final CountDownLatch closeLatch = new CountDownLatch(1);
willAnswer(i -> {
closeLatch.countDown();
return null;
}).given(producer).close();
final ProducerFactory pf = mock(ProducerFactory.class);
given(pf.transactionCapable()).willReturn(true);
given(pf.createProducer()).willReturn(producer);
ContainerProperties props = new ContainerProperties("foo");
props.setGroupId("group");
props.setTransactionManager(new SomeOtherTransactionManager());
final KafkaTemplate template = new KafkaTemplate(pf);
props.setMessageListener((MessageListener<String, String>) m -> {
template.send("bar", "baz");
template.sendOffsetsToTransaction(Collections.singletonMap(new TopicPartition(m.topic(), m.partition()),
new OffsetAndMetadata(m.offset() + 1)));
});
KafkaMessageListenerContainer container = new KafkaMessageListenerContainer<>(cf, props);
container.setBeanName("commit");
container.start();
assertThat(closeLatch.await(10, TimeUnit.SECONDS)).isTrue();
InOrder inOrder = inOrder(producer);
inOrder.verify(producer).beginTransaction();
ArgumentCaptor<ProducerRecord> captor = ArgumentCaptor.forClass(ProducerRecord.class);
inOrder.verify(producer).send(captor.capture(), any(Callback.class));
assertThat(captor.getValue()).isEqualTo(new ProducerRecord("bar", "baz"));
inOrder.verify(producer).sendOffsetsToTransaction(
Collections.singletonMap(topicPartition, new OffsetAndMetadata(1)), "group");
inOrder.verify(producer).commitTransaction();
inOrder.verify(producer).close();
container.stop();
verify(pf).createProducer();
}