Search in sources :

Example 1 with CommitRecordMetadataAndOffset

use of io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset in project starlight-for-kafka by datastax.

the class GroupMetadataManagerTest method testLoadTransactionalOffsetCommitsFromMultipleProducers.

@Test
public void testLoadTransactionalOffsetCommitsFromMultipleProducers() throws Exception {
    long firstProducerId = 1000L;
    short firstProducerEpoch = 2;
    long secondProducerId = 1001L;
    short secondProducerEpoch = 3;
    Map<TopicPartition, Long> committedOffsetsFirstProducer = new HashMap<>();
    committedOffsetsFirstProducer.put(new TopicPartition("foo", 0), 23L);
    committedOffsetsFirstProducer.put(new TopicPartition("foo", 1), 455L);
    committedOffsetsFirstProducer.put(new TopicPartition("bar", 0), 8992L);
    Map<TopicPartition, Long> committedOffsetsSecondProducer = new HashMap<>();
    committedOffsetsSecondProducer.put(new TopicPartition("foo", 2), 231L);
    committedOffsetsSecondProducer.put(new TopicPartition("foo", 3), 4551L);
    committedOffsetsSecondProducer.put(new TopicPartition("bar", 1), 89921L);
    ByteBuffer buffer = ByteBuffer.allocate(1024);
    int nextOffset = 0;
    int firstProduceRecordOffset = nextOffset;
    nextOffset += appendTransactionalOffsetCommits(buffer, firstProducerId, firstProducerEpoch, nextOffset, committedOffsetsFirstProducer, NAMESPACE_PREFIX);
    nextOffset += completeTransactionalOffsetCommit(buffer, firstProducerId, firstProducerEpoch, nextOffset, true);
    int secondProduceRecordOffset = nextOffset;
    nextOffset += appendTransactionalOffsetCommits(buffer, secondProducerId, secondProducerEpoch, nextOffset, committedOffsetsSecondProducer, NAMESPACE_PREFIX);
    nextOffset += completeTransactionalOffsetCommit(buffer, secondProducerId, secondProducerEpoch, nextOffset, true);
    buffer.flip();
    byte[] key = groupMetadataKey(groupId);
    Producer<ByteBuffer> producer = groupMetadataManager.getOffsetsTopicProducer(groupPartitionId).get();
    producer.newMessage().keyBytes(key).value(buffer).eventTime(Time.SYSTEM.milliseconds()).send();
    CompletableFuture<GroupMetadata> onLoadedFuture = new CompletableFuture<>();
    groupMetadataManager.scheduleLoadGroupAndOffsets(groupPartitionId, groupMetadata -> onLoadedFuture.complete(groupMetadata)).get();
    GroupMetadata group = onLoadedFuture.get();
    GroupMetadata groupInCache = groupMetadataManager.getGroup(groupId).orElseGet(() -> {
        fail("Group was not loaded into the cache");
        return null;
    });
    assertSame(group, groupInCache);
    assertEquals(groupId, group.groupId());
    assertEquals(Empty, group.currentState());
    // Ensure that only the committed offsets are materialized, and that there are no pending commits
    // for the producer. This allows us to be certain that the aborted offset commits are truly discarded.
    assertEquals(committedOffsetsFirstProducer.size() + committedOffsetsSecondProducer.size(), group.allOffsets().size());
    committedOffsetsFirstProducer.forEach((tp, offset) -> {
        assertEquals(Optional.of(offset), group.offset(tp, NAMESPACE_PREFIX).map(OffsetAndMetadata::offset));
        assertEquals(Optional.of((long) firstProduceRecordOffset), group.offsetWithRecordMetadata(tp).flatMap(CommitRecordMetadataAndOffset::appendedBatchOffset));
    });
    committedOffsetsSecondProducer.forEach((tp, offset) -> {
        assertEquals(Optional.of(offset), group.offset(tp, NAMESPACE_PREFIX).map(OffsetAndMetadata::offset));
        assertEquals(Optional.of((long) secondProduceRecordOffset), group.offsetWithRecordMetadata(tp).flatMap(CommitRecordMetadataAndOffset::appendedBatchOffset));
    });
}
Also used : MathUtils(org.apache.bookkeeper.common.util.MathUtils) Producer(org.apache.pulsar.client.api.Producer) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test) AfterMethod(org.testng.annotations.AfterMethod) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) ByteBuffer(java.nio.ByteBuffer) Record(org.apache.kafka.common.record.Record) PartitionData(org.apache.kafka.common.requests.OffsetFetchResponse.PartitionData) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Mockito.doAnswer(org.mockito.Mockito.doAnswer) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) Empty(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupState.Empty) Assert.assertFalse(org.testng.Assert.assertFalse) TimestampType(org.apache.kafka.common.record.TimestampType) Assert.assertSame(org.testng.Assert.assertSame) TopicPartition(org.apache.kafka.common.TopicPartition) MemoryRecordsBuilder(org.apache.kafka.common.record.MemoryRecordsBuilder) CompressionType(org.apache.kafka.common.record.CompressionType) OrderedScheduler(org.apache.bookkeeper.common.util.OrderedScheduler) Time(org.apache.kafka.common.utils.Time) ImmutableMap(com.google.common.collect.ImmutableMap) KopProtocolHandlerTestBase(io.streamnative.pulsar.handlers.kop.KopProtocolHandlerTestBase) AbstractRecords(org.apache.kafka.common.record.AbstractRecords) BeforeMethod(org.testng.annotations.BeforeMethod) GroupMetadataConstants.groupMetadataValue(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.groupMetadataValue) Assert.assertNotNull(org.testng.Assert.assertNotNull) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Stable(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupState.Stable) Consumer(org.apache.pulsar.client.api.Consumer) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) Optional(java.util.Optional) Errors(org.apache.kafka.common.protocol.Errors) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) GroupMetadataConstants.offsetCommitKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.offsetCommitKey) BaseKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataManager.BaseKey) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) Assert.assertNull(org.testng.Assert.assertNull) PreparingRebalance(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupState.PreparingRebalance) Assert.assertEquals(org.testng.Assert.assertEquals) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) EndTransactionMarker(org.apache.kafka.common.record.EndTransactionMarker) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.pulsar.client.api.Message) GroupMetadataConstants.groupMetadataKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.groupMetadataKey) Mockito.spy(org.mockito.Mockito.spy) SubscriptionInitialPosition(org.apache.pulsar.client.api.SubscriptionInitialPosition) GroupMetadataKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataManager.GroupMetadataKey) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) ProducerBuilder(org.apache.pulsar.client.api.ProducerBuilder) Lists(com.google.common.collect.Lists) KafkaProtocolHandler(io.streamnative.pulsar.handlers.kop.KafkaProtocolHandler) GroupTopicPartition(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataManager.GroupTopicPartition) OffsetFetchResponse(org.apache.kafka.common.requests.OffsetFetchResponse) GroupMetadataConstants.offsetCommitValue(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.offsetCommitValue) KopTopic(io.streamnative.pulsar.handlers.kop.utils.KopTopic) Assert.fail(org.testng.Assert.fail) MockTime(io.streamnative.pulsar.handlers.kop.utils.timer.MockTime) OffsetKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataManager.OffsetKey) Schema(org.apache.pulsar.client.api.Schema) SimpleRecord(org.apache.kafka.common.record.SimpleRecord) MessageId(org.apache.pulsar.client.api.MessageId) Assert.assertTrue(org.testng.Assert.assertTrue) ReaderBuilder(org.apache.pulsar.client.api.ReaderBuilder) CommitRecordMetadataAndOffset(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset) Collections(java.util.Collections) HashMap(java.util.HashMap) ByteBuffer(java.nio.ByteBuffer) CompletableFuture(java.util.concurrent.CompletableFuture) TopicPartition(org.apache.kafka.common.TopicPartition) GroupTopicPartition(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataManager.GroupTopicPartition) ArgumentMatchers.anyLong(org.mockito.ArgumentMatchers.anyLong) Test(org.testng.annotations.Test)

Example 2 with CommitRecordMetadataAndOffset

use of io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset in project starlight-for-kafka by datastax.

the class GroupMetadataManager method unsafeLoadNextMetadataMessage.

private void unsafeLoadNextMetadataMessage(CompletableFuture<Reader<ByteBuffer>> metadataConsumer, MessageId endMessageId, CompletableFuture<Void> resultFuture, Consumer<GroupMetadata> onGroupLoaded, Map<GroupTopicPartition, CommitRecordMetadataAndOffset> loadedOffsets, Map<Long, Map<GroupTopicPartition, CommitRecordMetadataAndOffset>> pendingOffsets, Map<String, GroupMetadata> loadedGroups, Set<String> removedGroups) {
    if (shuttingDown.get()) {
        resultFuture.completeExceptionally(new Exception("Group metadata manager is shutting down"));
        return;
    }
    if (log.isTraceEnabled()) {
        log.trace("Reading the next metadata message from topic {}", metadataConsumer.join().getTopic());
    }
    BiConsumer<Message<ByteBuffer>, Throwable> readNextComplete = (message, cause) -> {
        if (log.isTraceEnabled()) {
            log.trace("Metadata consumer received a metadata message from {} @ {}", metadataConsumer.join().getTopic(), message.getMessageId());
        }
        if (null != cause) {
            resultFuture.completeExceptionally(cause);
            return;
        }
        if (message.getMessageId().compareTo(endMessageId) >= 0) {
            // reach the end of partition
            processLoadedAndRemovedGroups(resultFuture, onGroupLoaded, loadedOffsets, pendingOffsets, loadedGroups, removedGroups);
            return;
        }
        if (!message.hasKey()) {
            // the messages without key are placeholders
            loadNextMetadataMessage(metadataConsumer, endMessageId, resultFuture, onGroupLoaded, loadedOffsets, pendingOffsets, loadedGroups, removedGroups);
            return;
        }
        ByteBuffer buffer = message.getValue();
        MemoryRecords memRecords = MemoryRecords.readableRecords(buffer);
        memRecords.batches().forEach(batch -> {
            boolean isTxnOffsetCommit = batch.isTransactional();
            if (batch.isControlBatch()) {
                Iterator<Record> recordIterator = batch.iterator();
                if (recordIterator.hasNext()) {
                    Record record = recordIterator.next();
                    ControlRecordType controlRecord = ControlRecordType.parse(record.key());
                    if (controlRecord == ControlRecordType.COMMIT) {
                        pendingOffsets.getOrDefault(batch.producerId(), Collections.emptyMap()).forEach((groupTopicPartition, commitRecordMetadataAndOffset) -> {
                            if (!loadedOffsets.containsKey(groupTopicPartition) || loadedOffsets.get(groupTopicPartition).olderThan(commitRecordMetadataAndOffset)) {
                                loadedOffsets.put(groupTopicPartition, commitRecordMetadataAndOffset);
                            }
                        });
                    }
                    pendingOffsets.remove(batch.producerId());
                }
            } else {
                Optional<Long> batchBaseOffset = Optional.empty();
                for (Record record : batch) {
                    checkArgument(record.hasKey(), "Group metadata/offset entry key should not be null");
                    if (!batchBaseOffset.isPresent()) {
                        batchBaseOffset = Optional.of(record.offset());
                    }
                    BaseKey bk = readMessageKey(record.key());
                    if (log.isTraceEnabled()) {
                        log.trace("Applying metadata record {} received from {}", bk, metadataConsumer.join().getTopic());
                    }
                    if (bk instanceof OffsetKey) {
                        OffsetKey offsetKey = (OffsetKey) bk;
                        if (isTxnOffsetCommit && !pendingOffsets.containsKey(batch.producerId())) {
                            pendingOffsets.put(batch.producerId(), new HashMap<>());
                        }
                        // load offset
                        GroupTopicPartition groupTopicPartition = offsetKey.key();
                        if (!record.hasValue()) {
                            if (isTxnOffsetCommit) {
                                pendingOffsets.get(batch.producerId()).remove(groupTopicPartition);
                            } else {
                                loadedOffsets.remove(groupTopicPartition);
                            }
                        } else {
                            OffsetAndMetadata offsetAndMetadata = readOffsetMessageValue(record.value());
                            CommitRecordMetadataAndOffset commitRecordMetadataAndOffset = new CommitRecordMetadataAndOffset(batchBaseOffset, offsetAndMetadata);
                            if (isTxnOffsetCommit) {
                                pendingOffsets.get(batch.producerId()).put(groupTopicPartition, commitRecordMetadataAndOffset);
                            } else {
                                loadedOffsets.put(groupTopicPartition, commitRecordMetadataAndOffset);
                            }
                        }
                    } else if (bk instanceof GroupMetadataKey) {
                        GroupMetadataKey groupMetadataKey = (GroupMetadataKey) bk;
                        String gid = groupMetadataKey.key();
                        GroupMetadata gm = readGroupMessageValue(gid, record.value());
                        if (gm != null) {
                            removedGroups.remove(gid);
                            loadedGroups.put(gid, gm);
                        } else {
                            loadedGroups.remove(gid);
                            removedGroups.add(gid);
                        }
                    } else {
                        resultFuture.completeExceptionally(new IllegalStateException("Unexpected message key " + bk + " while loading offsets and group metadata"));
                        return;
                    }
                }
            }
        });
        loadNextMetadataMessage(metadataConsumer, endMessageId, resultFuture, onGroupLoaded, loadedOffsets, pendingOffsets, loadedGroups, removedGroups);
    };
    metadataConsumer.thenComposeAsync(r -> r.readNextAsync()).whenCompleteAsync((message, cause) -> {
        try {
            readNextComplete.accept(message, cause);
        } catch (Throwable completeCause) {
            log.error("Unknown exception caught when processing the received metadata message from topic {}", metadataConsumer.join().getTopic(), completeCause);
            resultFuture.completeExceptionally(completeCause);
        }
    }, scheduler);
}
Also used : MathUtils(org.apache.bookkeeper.common.util.MathUtils) Accessors(lombok.experimental.Accessors) KafkaResponseUtils(io.streamnative.pulsar.handlers.kop.utils.KafkaResponseUtils) Producer(org.apache.pulsar.client.api.Producer) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) ByteBuffer(java.nio.ByteBuffer) Record(org.apache.kafka.common.record.Record) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) PartitionData(org.apache.kafka.common.requests.OffsetFetchResponse.PartitionData) PARTITIONED_TOPIC_SUFFIX(org.apache.pulsar.common.naming.TopicName.PARTITIONED_TOPIC_SUFFIX) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) Triple(org.apache.commons.lang3.tuple.Triple) TimestampType(org.apache.kafka.common.record.TimestampType) TopicPartition(org.apache.kafka.common.TopicPartition) MemoryRecordsBuilder(org.apache.kafka.common.record.MemoryRecordsBuilder) CompressionType(org.apache.kafka.common.record.CompressionType) Time(org.apache.kafka.common.utils.Time) AbstractRecords(org.apache.kafka.common.record.AbstractRecords) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) GroupMetadataConstants.groupMetadataValue(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.groupMetadataValue) MessageMetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MessageMetadataUtils) FutureUtils(org.apache.bookkeeper.common.concurrent.FutureUtils) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) CoreUtils(io.streamnative.pulsar.handlers.kop.utils.CoreUtils) MessageIdImpl(org.apache.pulsar.client.impl.MessageIdImpl) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) FutureUtil(org.apache.pulsar.common.util.FutureUtil) Stream(java.util.stream.Stream) Optional(java.util.Optional) Errors(org.apache.kafka.common.protocol.Errors) GroupMetadataConstants.readOffsetMessageValue(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.readOffsetMessageValue) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) GroupMetadataConstants.offsetCommitKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.offsetCommitKey) Getter(lombok.Getter) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) Message(org.apache.pulsar.client.api.Message) GroupMetadataConstants.groupMetadataKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.groupMetadataKey) Function(java.util.function.Function) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) GROUP_METADATA_TOPIC_NAME(org.apache.kafka.common.internals.Topic.GROUP_METADATA_TOPIC_NAME) HashSet(java.util.HashSet) ProducerBuilder(org.apache.pulsar.client.api.ProducerBuilder) Lists(com.google.common.collect.Lists) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) BiConsumer(java.util.function.BiConsumer) CURRENT_GROUP_VALUE_SCHEMA_VERSION(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.CURRENT_GROUP_VALUE_SCHEMA_VERSION) GroupMetadataConstants.readMessageKey(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.readMessageKey) CoreUtils.inLock(io.streamnative.pulsar.handlers.kop.utils.CoreUtils.inLock) GroupMetadataConstants.readGroupMessageValue(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.readGroupMessageValue) GroupMetadataConstants.offsetCommitValue(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.offsetCommitValue) OffsetCommitRequest(org.apache.kafka.common.requests.OffsetCommitRequest) Iterator(java.util.Iterator) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Reader(org.apache.pulsar.client.api.Reader) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) SimpleRecord(org.apache.kafka.common.record.SimpleRecord) MessageId(org.apache.pulsar.client.api.MessageId) Data(lombok.Data) ReaderBuilder(org.apache.pulsar.client.api.ReaderBuilder) VisibleForTesting(com.google.common.annotations.VisibleForTesting) CommitRecordMetadataAndOffset(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset) Collections(java.util.Collections) Message(org.apache.pulsar.client.api.Message) Optional(java.util.Optional) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ByteBuffer(java.nio.ByteBuffer) Iterator(java.util.Iterator) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) CommitRecordMetadataAndOffset(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset) Record(org.apache.kafka.common.record.Record) SimpleRecord(org.apache.kafka.common.record.SimpleRecord) ControlRecordType(org.apache.kafka.common.record.ControlRecordType) MemoryRecords(org.apache.kafka.common.record.MemoryRecords)

Example 3 with CommitRecordMetadataAndOffset

use of io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset in project starlight-for-kafka by datastax.

the class GroupMetadataTest method testOffsetCommitWithAnotherPending.

@Test
public void testOffsetCommitWithAnotherPending() {
    TopicPartition partition = new TopicPartition("foo", 0);
    OffsetAndMetadata firstOffset = OffsetAndMetadata.apply(37);
    OffsetAndMetadata secondOffset = OffsetAndMetadata.apply(57);
    Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
    offsets.put(partition, firstOffset);
    group.prepareOffsetCommit(offsets);
    assertTrue(group.hasOffsets());
    assertEquals(Optional.empty(), group.offset(partition, NAMESPACE_PREFIX));
    offsets = new HashMap<>();
    offsets.put(partition, secondOffset);
    group.prepareOffsetCommit(offsets);
    assertTrue(group.hasOffsets());
    group.onOffsetCommitAppend(partition, new CommitRecordMetadataAndOffset(Optional.of(4L), firstOffset));
    assertTrue(group.hasOffsets());
    assertEquals(Optional.of(firstOffset), group.offset(partition, NAMESPACE_PREFIX));
    group.onOffsetCommitAppend(partition, new CommitRecordMetadataAndOffset(Optional.of(5L), secondOffset));
    assertTrue(group.hasOffsets());
    assertEquals(Optional.of(secondOffset), group.offset(partition, NAMESPACE_PREFIX));
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TopicPartition(org.apache.kafka.common.TopicPartition) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) CommitRecordMetadataAndOffset(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset) Test(org.junit.Test)

Example 4 with CommitRecordMetadataAndOffset

use of io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset in project starlight-for-kafka by datastax.

the class GroupMetadataTest method testTransactionalCommitIsAbortedAndConsumerCommitWins.

@Test
public void testTransactionalCommitIsAbortedAndConsumerCommitWins() {
    TopicPartition partition = new TopicPartition("foo", 0);
    long producerId = 13232L;
    OffsetAndMetadata txnOffsetCommit = OffsetAndMetadata.apply(37);
    OffsetAndMetadata consumerOffsetCommit = OffsetAndMetadata.apply(57);
    Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
    offsets.put(partition, txnOffsetCommit);
    group.prepareTxnOffsetCommit(producerId, offsets);
    assertTrue(group.hasOffsets());
    assertEquals(Optional.empty(), group.offset(partition, NAMESPACE_PREFIX));
    offsets = new HashMap<>();
    offsets.put(partition, consumerOffsetCommit);
    group.prepareOffsetCommit(offsets);
    assertTrue(group.hasOffsets());
    group.onOffsetCommitAppend(partition, new CommitRecordMetadataAndOffset(Optional.of(3L), consumerOffsetCommit));
    group.onTxnOffsetCommitAppend(producerId, partition, new CommitRecordMetadataAndOffset(Optional.of(4L), txnOffsetCommit));
    assertTrue(group.hasOffsets());
    // The transactional offset commit hasn't been committed yet, so we should materialize the consumer
    // offset commit.
    assertEquals(Optional.of(consumerOffsetCommit), group.offset(partition, NAMESPACE_PREFIX));
    group.completePendingTxnOffsetCommit(producerId, false);
    assertTrue(group.hasOffsets());
    // The transactional offset commit should be discarded and the consumer offset commit should continue to be
    // materialized.
    assertFalse(group.hasPendingOffsetCommitsFromProducer(producerId));
    assertEquals(Optional.of(consumerOffsetCommit), group.offset(partition, NAMESPACE_PREFIX));
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TopicPartition(org.apache.kafka.common.TopicPartition) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) CommitRecordMetadataAndOffset(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset) Test(org.junit.Test)

Example 5 with CommitRecordMetadataAndOffset

use of io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset in project starlight-for-kafka by datastax.

the class GroupMetadataTest method testOffsetCommitFailureWithAnotherPending.

@Test
public void testOffsetCommitFailureWithAnotherPending() {
    TopicPartition partition = new TopicPartition("foo", 0);
    OffsetAndMetadata firstOffset = OffsetAndMetadata.apply(37);
    OffsetAndMetadata secondOffset = OffsetAndMetadata.apply(57);
    Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
    offsets.put(partition, firstOffset);
    group.prepareOffsetCommit(offsets);
    assertTrue(group.hasOffsets());
    assertEquals(Optional.empty(), group.offset(partition, NAMESPACE_PREFIX));
    offsets = new HashMap<>();
    offsets.put(partition, secondOffset);
    group.prepareOffsetCommit(offsets);
    assertTrue(group.hasOffsets());
    group.failPendingOffsetWrite(partition, firstOffset);
    assertTrue(group.hasOffsets());
    assertEquals(Optional.empty(), group.offset(partition, NAMESPACE_PREFIX));
    group.onOffsetCommitAppend(partition, new CommitRecordMetadataAndOffset(Optional.of(3L), secondOffset));
    assertTrue(group.hasOffsets());
    assertEquals(Optional.of(secondOffset), group.offset(partition, NAMESPACE_PREFIX));
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) TopicPartition(org.apache.kafka.common.TopicPartition) OffsetAndMetadata(io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata) CommitRecordMetadataAndOffset(io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset) Test(org.junit.Test)

Aggregations

CommitRecordMetadataAndOffset (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadata.CommitRecordMetadataAndOffset)20 OffsetAndMetadata (io.streamnative.pulsar.handlers.kop.offset.OffsetAndMetadata)20 TopicPartition (org.apache.kafka.common.TopicPartition)20 HashMap (java.util.HashMap)18 LinkedHashMap (java.util.LinkedHashMap)12 Test (org.junit.Test)12 Lists (com.google.common.collect.Lists)6 Sets (com.google.common.collect.Sets)6 GroupMetadataConstants.groupMetadataKey (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.groupMetadataKey)6 GroupMetadataConstants.groupMetadataValue (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.groupMetadataValue)6 GroupMetadataConstants.offsetCommitKey (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.offsetCommitKey)6 GroupMetadataConstants.offsetCommitValue (io.streamnative.pulsar.handlers.kop.coordinator.group.GroupMetadataConstants.offsetCommitValue)6 ByteBuffer (java.nio.ByteBuffer)6 ArrayList (java.util.ArrayList)6 Collections (java.util.Collections)6 List (java.util.List)6 Map (java.util.Map)6 Optional (java.util.Optional)6 CompletableFuture (java.util.concurrent.CompletableFuture)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)6