@Test(expected = IllegalStateException.class) public void shouldThrowOnCommitIfTransactionsNotInitialized() { buildMockProducer(true); producer.commitTransaction(); }
@Test public void shouldCountCommittedTransaction() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); assertThat(producer.commitCount(), equalTo(0L)); producer.commitTransaction(); assertThat(producer.commitCount(), equalTo(1L)); }
@Test public void shouldPublishMessagesOnlyAfterCommitIfTransactionsAreEnabled() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); producer.send(record1); producer.send(record2); assertTrue(producer.history().isEmpty()); producer.commitTransaction(); List<ProducerRecord<byte[], byte[]>> expectedResult = new ArrayList<>(); expectedResult.add(record1); expectedResult.add(record2); assertThat(producer.history(), equalTo(expectedResult)); }
@Test public void shouldPreserveCommittedMessagesOnAbortIfTransactionsAreEnabled() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); producer.send(record1); producer.send(record2); producer.commitTransaction(); producer.beginTransaction(); producer.abortTransaction(); List<ProducerRecord<byte[], byte[]>> expectedResult = new ArrayList<>(); expectedResult.add(record1); expectedResult.add(record2); assertThat(producer.history(), equalTo(expectedResult)); }
@Test public void shouldThrowOnCommitTransactionIfNoTransactionGotStarted() { buildMockProducer(true); producer.initTransactions(); try { producer.commitTransaction(); fail("Should have thrown as producer has no open transaction"); } catch (IllegalStateException e) { } }
@Test public void shouldFlushOnCommitForNonAutoCompleteIfTransactionsAreEnabled() { buildMockProducer(false); producer.initTransactions(); producer.beginTransaction(); Future<RecordMetadata> md1 = producer.send(record1); Future<RecordMetadata> md2 = producer.send(record2); assertFalse(md1.isDone()); assertFalse(md2.isDone()); producer.commitTransaction(); assertTrue(md1.isDone()); assertTrue(md2.isDone()); }
@Test public void shouldThrowOnCommitTransactionIfProducerIsClosed() { buildMockProducer(true); producer.close(); try { producer.commitTransaction(); fail("Should have thrown as producer is already closed"); } catch (IllegalStateException e) { } }
@Test public void shouldNotCountAbortedTransaction() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); producer.abortTransaction(); producer.beginTransaction(); producer.commitTransaction(); assertThat(producer.commitCount(), equalTo(1L)); }
@Test public void shouldPreserveCommittedConsumerGroupsOffsetsOnAbortIfTransactionsAreEnabled() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); String group = "g"; Map<TopicPartition, OffsetAndMetadata> groupCommit = new HashMap<TopicPartition, OffsetAndMetadata>() { { put(new TopicPartition(topic, 0), new OffsetAndMetadata(42L, null)); put(new TopicPartition(topic, 1), new OffsetAndMetadata(73L, null)); } }; producer.sendOffsetsToTransaction(groupCommit, group); producer.commitTransaction(); producer.beginTransaction(); producer.abortTransaction(); Map<String, Map<TopicPartition, OffsetAndMetadata>> expectedResult = new HashMap<>(); expectedResult.put(group, groupCommit); assertThat(producer.consumerGroupOffsetsHistory(), equalTo(Collections.singletonList(expectedResult))); }
@Test public void shouldThrowOnCommitTransactionIfProducerGotFenced() { buildMockProducer(true); producer.initTransactions(); producer.fenceProducer(); try { producer.commitTransaction(); fail("Should have thrown as producer is fenced off"); } catch (ProducerFencedException e) { } }
@Test public void shouldPublishConsumerGroupOffsetsOnlyAfterCommitIfTransactionsAreEnabled() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); String group1 = "g1"; Map<TopicPartition, OffsetAndMetadata> group1Commit = new HashMap<TopicPartition, OffsetAndMetadata>() { { put(new TopicPartition(topic, 0), new OffsetAndMetadata(42L, null)); put(new TopicPartition(topic, 1), new OffsetAndMetadata(73L, null)); } }; String group2 = "g2"; Map<TopicPartition, OffsetAndMetadata> group2Commit = new HashMap<TopicPartition, OffsetAndMetadata>() { { put(new TopicPartition(topic, 0), new OffsetAndMetadata(101L, null)); put(new TopicPartition(topic, 1), new OffsetAndMetadata(21L, null)); } }; producer.sendOffsetsToTransaction(group1Commit, group1); producer.sendOffsetsToTransaction(group2Commit, group2); assertTrue(producer.consumerGroupOffsetsHistory().isEmpty()); Map<String, Map<TopicPartition, OffsetAndMetadata>> expectedResult = new HashMap<>(); expectedResult.put(group1, group1Commit); expectedResult.put(group2, group2Commit); producer.commitTransaction(); assertThat(producer.consumerGroupOffsetsHistory(), equalTo(Collections.singletonList(expectedResult))); }
producer.commitTransaction(); assertThat(producer.consumerGroupOffsetsHistory(), equalTo(Collections.singletonList(expectedResult)));
@Test public void shouldDropMessagesOnAbortIfTransactionsAreEnabled() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); producer.send(record1); producer.send(record2); producer.abortTransaction(); assertTrue(producer.history().isEmpty()); producer.beginTransaction(); producer.commitTransaction(); assertTrue(producer.history().isEmpty()); }
@Test public void shouldDropConsumerGroupOffsetsOnAbortIfTransactionsAreEnabled() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); String group = "g"; Map<TopicPartition, OffsetAndMetadata> groupCommit = new HashMap<TopicPartition, OffsetAndMetadata>() { { put(new TopicPartition(topic, 0), new OffsetAndMetadata(42L, null)); put(new TopicPartition(topic, 1), new OffsetAndMetadata(73L, null)); } }; producer.sendOffsetsToTransaction(groupCommit, group); producer.abortTransaction(); producer.beginTransaction(); producer.commitTransaction(); assertTrue(producer.consumerGroupOffsetsHistory().isEmpty()); }
@Test public void shouldCommitEmptyTransaction() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); producer.commitTransaction(); assertFalse(producer.transactionInFlight()); assertTrue(producer.transactionCommitted()); assertFalse(producer.transactionAborted()); }
@Test public void shouldResetSentOffsetsFlagOnlyWhenBeginningNewTransaction() { buildMockProducer(true); producer.initTransactions(); producer.beginTransaction(); assertFalse(producer.sentOffsets()); Map<TopicPartition, OffsetAndMetadata> groupCommit = new HashMap<TopicPartition, OffsetAndMetadata>() { { put(new TopicPartition(topic, 0), new OffsetAndMetadata(42L, null)); } }; producer.sendOffsetsToTransaction(groupCommit, "groupId"); producer.commitTransaction(); // commit should not reset "sentOffsets" flag assertTrue(producer.sentOffsets()); producer.beginTransaction(); assertFalse(producer.sentOffsets()); }
@Test public void testFencedOnBegin() { MockProducer<String, String> producer = spy(new MockProducer<>()); producer.initTransactions(); producer.fenceProducer(); @SuppressWarnings("unchecked") ProducerFactory<String, String> pf = mock(ProducerFactory.class); given(pf.transactionCapable()).willReturn(true); given(pf.createProducer()).willReturn(producer); KafkaTemplate<String, String> template = new KafkaTemplate<>(pf); template.setDefaultTopic(STRING_KEY_TOPIC); assertThatThrownBy(() -> template.executeInTransaction(t -> { return null; })).isInstanceOf(ProducerFencedException.class); assertThat(producer.transactionCommitted()).isFalse(); assertThat(producer.transactionAborted()).isFalse(); assertThat(producer.closed()).isTrue(); verify(producer, never()).commitTransaction(); }
@Test public void testAbort() { MockProducer<String, String> producer = spy(new MockProducer<>()); producer.initTransactions(); @SuppressWarnings("unchecked") ProducerFactory<String, String> pf = mock(ProducerFactory.class); given(pf.transactionCapable()).willReturn(true); given(pf.createProducer()).willReturn(producer); KafkaTemplate<String, String> template = new KafkaTemplate<>(pf); template.setDefaultTopic(STRING_KEY_TOPIC); assertThatThrownBy(() -> template.executeInTransaction(t -> { throw new RuntimeException("foo"); })).isExactlyInstanceOf(RuntimeException.class).withFailMessage("foo"); assertThat(producer.transactionCommitted()).isFalse(); assertThat(producer.transactionAborted()).isTrue(); assertThat(producer.closed()).isTrue(); verify(producer, never()).commitTransaction(); }