Search in sources :

Example 1 with GetResult

use of org.apache.pulsar.metadata.api.GetResult in project starlight-for-kafka by datastax.

the class MessageFetchContext method handleEntries.

private void handleEntries(final List<Entry> entries, final TopicPartition topicPartition, final FetchRequest.PartitionData partitionData, final KafkaTopicConsumerManager tcm, final ManagedCursor cursor, final AtomicLong cursorOffset, final boolean readCommitted) {
    final long highWatermark = MessageMetadataUtils.getHighWatermark(cursor.getManagedLedger());
    // Add new offset back to TCM after entries are read successfully
    tcm.add(cursorOffset.get(), Pair.of(cursor, cursorOffset.get()));
    PartitionLog partitionLog = requestHandler.getReplicaManager().getPartitionLog(topicPartition, namespacePrefix);
    final long lso = (readCommitted ? partitionLog.firstUndecidedOffset().orElse(highWatermark) : highWatermark);
    List<Entry> committedEntries = entries;
    if (readCommitted) {
        committedEntries = getCommittedEntries(entries, lso);
        if (log.isDebugEnabled()) {
            log.debug("Request {}: read {} entries but only {} entries are committed", header, entries.size(), committedEntries.size());
        }
    } else {
        if (log.isDebugEnabled()) {
            log.debug("Request {}: read {} entries", header, entries.size());
        }
    }
    if (committedEntries.isEmpty()) {
        addErrorPartitionResponse(topicPartition, Errors.NONE);
        return;
    }
    // use compatible magic value by apiVersion
    short apiVersion = header.apiVersion();
    final byte magic;
    if (apiVersion <= 1) {
        magic = RecordBatch.MAGIC_VALUE_V0;
    } else if (apiVersion <= 3) {
        magic = RecordBatch.MAGIC_VALUE_V1;
    } else {
        magic = RecordBatch.CURRENT_MAGIC_VALUE;
    }
    CompletableFuture<String> groupNameFuture = requestHandler.getCurrentConnectedGroup().computeIfAbsent(clientHost, clientHost -> {
        CompletableFuture<String> future = new CompletableFuture<>();
        String groupIdPath = GroupIdUtils.groupIdPathFormat(clientHost, header.clientId());
        requestHandler.getMetadataStore().get(requestHandler.getGroupIdStoredPath() + groupIdPath).thenAccept(getResultOpt -> {
            if (getResultOpt.isPresent()) {
                GetResult getResult = getResultOpt.get();
                future.complete(new String(getResult.getValue() == null ? new byte[0] : getResult.getValue(), StandardCharsets.UTF_8));
            } else {
                future.complete("");
            }
        }).exceptionally(ex -> {
            future.completeExceptionally(ex);
            return null;
        });
        return future;
    });
    // this part is heavyweight, and we should not execute in the ManagedLedger Ordered executor thread
    groupNameFuture.whenCompleteAsync((groupName, ex) -> {
        if (ex != null) {
            log.error("Get groupId failed.", ex);
            groupName = "";
        }
        final long startDecodingEntriesNanos = MathUtils.nowInNano();
        final DecodeResult decodeResult = requestHandler.getEntryFormatter().decode(entries, magic);
        requestHandler.requestStats.getFetchDecodeStats().registerSuccessfulEvent(MathUtils.elapsedNanos(startDecodingEntriesNanos), TimeUnit.NANOSECONDS);
        decodeResults.add(decodeResult);
        final MemoryRecords kafkaRecords = decodeResult.getRecords();
        // collect consumer metrics
        decodeResult.updateConsumerStats(topicPartition, entries.size(), groupName, statsLogger);
        List<FetchResponse.AbortedTransaction> abortedTransactions;
        if (readCommitted) {
            abortedTransactions = partitionLog.getAbortedIndexList(partitionData.fetchOffset);
        } else {
            abortedTransactions = null;
        }
        responseData.put(topicPartition, new PartitionData<>(Errors.NONE, highWatermark, lso, // TODO: should it be changed to the logStartOffset?
        highWatermark, abortedTransactions, kafkaRecords));
        bytesReadable.getAndAdd(kafkaRecords.sizeInBytes());
        tryComplete();
    }, requestHandler.getDecodeExecutor());
}
Also used : MathUtils(org.apache.bookkeeper.common.util.MathUtils) IsolationLevel(org.apache.kafka.common.requests.IsolationLevel) NonDurableCursorImpl(org.apache.bookkeeper.mledger.impl.NonDurableCursorImpl) ResponseCallbackWrapper(org.apache.kafka.common.requests.ResponseCallbackWrapper) OpStatsLogger(org.apache.bookkeeper.stats.OpStatsLogger) ManagedCursor(org.apache.bookkeeper.mledger.ManagedCursor) Handle(io.netty.util.Recycler.Handle) Pair(org.apache.commons.lang3.tuple.Pair) RequestHeader(org.apache.kafka.common.requests.RequestHeader) Map(java.util.Map) RecordBatch(org.apache.kafka.common.record.RecordBatch) FetchResponse(org.apache.kafka.common.requests.FetchResponse) DelayedOperationPurgatory(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationPurgatory) PositionImpl(org.apache.bookkeeper.mledger.impl.PositionImpl) TopicPartition(org.apache.kafka.common.TopicPartition) PartitionLog(io.streamnative.pulsar.handlers.kop.storage.PartitionLog) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) MessageMetadataUtils(io.streamnative.pulsar.handlers.kop.utils.MessageMetadataUtils) TransactionCoordinator(io.streamnative.pulsar.handlers.kop.coordinator.transaction.TransactionCoordinator) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Recycler(io.netty.util.Recycler) ManagedLedgerException(org.apache.bookkeeper.mledger.ManagedLedgerException) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) MemoryRecords(org.apache.kafka.common.record.MemoryRecords) Errors(org.apache.kafka.common.protocol.Errors) FetchRequest(org.apache.kafka.common.requests.FetchRequest) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) AbstractResponse(org.apache.kafka.common.requests.AbstractResponse) Entry(org.apache.bookkeeper.mledger.Entry) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Resource(io.streamnative.pulsar.handlers.kop.security.auth.Resource) Lists(com.google.common.collect.Lists) GetResult(org.apache.pulsar.metadata.api.GetResult) THROTTLE_TIME_MS(org.apache.kafka.common.protocol.CommonFields.THROTTLE_TIME_MS) GroupIdUtils(io.streamnative.pulsar.handlers.kop.utils.GroupIdUtils) ManagedLedgerImpl(org.apache.bookkeeper.mledger.impl.ManagedLedgerImpl) DelayedOperation(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperation) KopTopic(io.streamnative.pulsar.handlers.kop.utils.KopTopic) ResourceType(io.streamnative.pulsar.handlers.kop.security.auth.ResourceType) MetadataCorruptedException(io.streamnative.pulsar.handlers.kop.exceptions.MetadataCorruptedException) KafkaHeaderAndRequest(io.streamnative.pulsar.handlers.kop.KafkaCommandDecoder.KafkaHeaderAndRequest) AclOperation(org.apache.kafka.common.acl.AclOperation) PartitionData(org.apache.kafka.common.requests.FetchResponse.PartitionData) TimeUnit(java.util.concurrent.TimeUnit) DecodeResult(io.streamnative.pulsar.handlers.kop.format.DecodeResult) AtomicLong(java.util.concurrent.atomic.AtomicLong) MarkDeleteCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.MarkDeleteCallback) DelayedOperationKey(io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationKey) ReadEntriesCallback(org.apache.bookkeeper.mledger.AsyncCallbacks.ReadEntriesCallback) ApiException(org.apache.kafka.common.errors.ApiException) GetResult(org.apache.pulsar.metadata.api.GetResult) DecodeResult(io.streamnative.pulsar.handlers.kop.format.DecodeResult) Entry(org.apache.bookkeeper.mledger.Entry) CompletableFuture(java.util.concurrent.CompletableFuture) PartitionLog(io.streamnative.pulsar.handlers.kop.storage.PartitionLog) MemoryRecords(org.apache.kafka.common.record.MemoryRecords)

Example 2 with GetResult

use of org.apache.pulsar.metadata.api.GetResult in project pulsar by apache.

the class RocksdbMetadataStoreTest method testOpenDbWithConfigFile.

@Test
public void testOpenDbWithConfigFile() throws Exception {
    MetadataStore store;
    Path tempDir;
    tempDir = Files.createTempDirectory("RocksdbMetadataStoreTest");
    log.info("Temp dir:{}", tempDir.toAbsolutePath());
    String optionFilePath = getClass().getClassLoader().getResource("rocksdb_option_file_example.ini").getPath();
    log.info("optionFilePath={}", optionFilePath);
    store = MetadataStoreFactory.create("rocksdb:" + tempDir.toAbsolutePath(), MetadataStoreConfig.builder().configFilePath(optionFilePath).build());
    Assert.assertTrue(store instanceof RocksdbMetadataStore);
    String path = "/test";
    byte[] data = "data".getBytes();
    // test put
    CompletableFuture<Stat> f = store.put(path, data, Optional.of(-1L));
    CompletableFuture<Stat> failedPut = store.put(path, data, Optional.of(100L));
    Assert.expectThrows(MetadataStoreException.BadVersionException.class, () -> {
        try {
            failedPut.get();
        } catch (ExecutionException t) {
            throw t.getCause();
        }
    });
    Assert.assertNotNull(f.get());
    log.info("put result:{}", f.get());
    Assert.assertNotNull(store.put(path + "/a", data, Optional.of(-1L)));
    Assert.assertNotNull(store.put(path + "/b", data, Optional.of(-1L)));
    Assert.assertNotNull(store.put(path + "/c", data, Optional.of(-1L)));
    // reopen db
    store.close();
    store = MetadataStoreFactory.create("rocksdb:" + tempDir.toAbsolutePath(), MetadataStoreConfig.builder().configFilePath(optionFilePath).build());
    // test get
    CompletableFuture<Optional<GetResult>> readResult = store.get(path);
    Assert.assertNotNull(readResult.get());
    Assert.assertTrue(readResult.get().isPresent());
    GetResult r = readResult.get().get();
    Assert.assertEquals(path, r.getStat().getPath());
    Assert.assertEquals(0, r.getStat().getVersion());
    Assert.assertEquals(data, r.getValue());
    store.close();
    FileUtils.deleteQuietly(tempDir.toFile());
}
Also used : MetadataStore(org.apache.pulsar.metadata.api.MetadataStore) Path(java.nio.file.Path) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) Stat(org.apache.pulsar.metadata.api.Stat) Optional(java.util.Optional) GetResult(org.apache.pulsar.metadata.api.GetResult) ExecutionException(java.util.concurrent.ExecutionException) Test(org.testng.annotations.Test)

Example 3 with GetResult

use of org.apache.pulsar.metadata.api.GetResult in project pulsar by apache.

the class MetadataStoreBatchingTest method testBigBatchSize.

@Test(dataProvider = "impl")
public void testBigBatchSize(String provider, Supplier<String> urlSupplier) throws Exception {
    @Cleanup MetadataStore store = MetadataStoreFactory.create(urlSupplier.get(), MetadataStoreConfig.builder().batchingEnabled(true).batchingMaxDelayMillis(1_000).build());
    String key1 = newKey();
    // Create 20 MB of data and try to read it out
    int dataSize = 500 * 1024;
    byte[] payload = new byte[dataSize];
    int N = 40;
    List<CompletableFuture<Stat>> putFutures = new ArrayList<>();
    for (int i = 0; i < N; i++) {
        putFutures.add(store.put(key1 + "/" + i, payload, Optional.empty()));
    }
    FutureUtil.waitForAll(putFutures).join();
    List<CompletableFuture<Optional<GetResult>>> getFutures = new ArrayList<>();
    for (int i = 0; i < N; i++) {
        getFutures.add(store.get(key1 + "/" + i));
    }
    FutureUtil.waitForAll(getFutures).join();
}
Also used : MetadataStore(org.apache.pulsar.metadata.api.MetadataStore) CompletableFuture(java.util.concurrent.CompletableFuture) GetResult(org.apache.pulsar.metadata.api.GetResult) ArrayList(java.util.ArrayList) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test)

Example 4 with GetResult

use of org.apache.pulsar.metadata.api.GetResult in project pulsar by apache.

the class MetadataStoreBatchingTest method testBatching.

@Test(dataProvider = "impl")
public void testBatching(String provider, Supplier<String> urlSupplier) throws Exception {
    @Cleanup MetadataStore store = MetadataStoreFactory.create(urlSupplier.get(), MetadataStoreConfig.builder().batchingEnabled(true).batchingMaxDelayMillis(1_000).build());
    String key1 = newKey();
    store.put(key1, new byte[0], Optional.empty()).join();
    String key2 = newKey();
    CompletableFuture<Optional<GetResult>> f1 = store.get(key1);
    CompletableFuture<Optional<GetResult>> f2 = store.get(key2);
    Optional<GetResult> r1 = f1.join();
    Optional<GetResult> r2 = f2.join();
    assertTrue(r1.isPresent());
    assertFalse(r2.isPresent());
}
Also used : MetadataStore(org.apache.pulsar.metadata.api.MetadataStore) Optional(java.util.Optional) GetResult(org.apache.pulsar.metadata.api.GetResult) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test)

Example 5 with GetResult

use of org.apache.pulsar.metadata.api.GetResult in project pulsar by apache.

the class MetadataStoreTest method testConcurrentPutGetOneKey.

@Test(dataProvider = "impl")
public void testConcurrentPutGetOneKey(String provider, Supplier<String> urlSupplier) throws Exception {
    MetadataStore store = MetadataStoreFactory.create(urlSupplier.get(), MetadataStoreConfig.builder().build());
    byte[] data = new byte[] { 0 };
    String path = newKey();
    int maxValue = 100;
    store.put(path, data, Optional.of(-1L)).join();
    AtomicInteger successWrites = new AtomicInteger(0);
    Runnable task = new Runnable() {

        @SneakyThrows
        @Override
        public void run() {
            byte value;
            while (true) {
                GetResult readResult = store.get(path).get().get();
                value = (byte) (readResult.getValue()[0] + 1);
                if (value <= maxValue) {
                    CompletableFuture<Void> putResult = store.put(path, new byte[] { value }, Optional.of(readResult.getStat().getVersion())).thenRun(successWrites::incrementAndGet);
                    try {
                        putResult.get();
                    } catch (Exception ignore) {
                    }
                    log.info("Put value {} success:{}. ", value, !putResult.isCompletedExceptionally());
                } else {
                    break;
                }
            }
        }
    };
    CompletableFuture<Void> t1 = CompletableFuture.completedFuture(null).thenRunAsync(task);
    CompletableFuture<Void> t2 = CompletableFuture.completedFuture(null).thenRunAsync(task);
    task.run();
    t1.join();
    t2.join();
    assertFalse(t1.isCompletedExceptionally());
    assertFalse(t2.isCompletedExceptionally());
    assertEquals(successWrites.get(), maxValue);
    assertEquals(store.get(path).get().get().getValue()[0], maxValue);
}
Also used : MetadataStore(org.apache.pulsar.metadata.api.MetadataStore) GetResult(org.apache.pulsar.metadata.api.GetResult) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) CompletionException(java.util.concurrent.CompletionException) NotFoundException(org.apache.pulsar.metadata.api.MetadataStoreException.NotFoundException) BadVersionException(org.apache.pulsar.metadata.api.MetadataStoreException.BadVersionException) Test(org.testng.annotations.Test)

Aggregations

GetResult (org.apache.pulsar.metadata.api.GetResult)62 ExecutionException (java.util.concurrent.ExecutionException)24 Test (org.testng.annotations.Test)24 Optional (java.util.Optional)18 MetadataStore (org.apache.pulsar.metadata.api.MetadataStore)18 CompletableFuture (java.util.concurrent.CompletableFuture)17 ReplicationException (org.apache.bookkeeper.replication.ReplicationException)15 Cleanup (lombok.Cleanup)13 EnumSet (java.util.EnumSet)12 MetadataStoreException (org.apache.pulsar.metadata.api.MetadataStoreException)12 Stat (org.apache.pulsar.metadata.api.Stat)12 CreateOption (org.apache.pulsar.metadata.api.extended.CreateOption)12 List (java.util.List)11 TimeUnit (java.util.concurrent.TimeUnit)11 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)9 Set (java.util.Set)9 CompletionException (java.util.concurrent.CompletionException)9 BeforeMethod (org.testng.annotations.BeforeMethod)9 Lists (com.google.common.collect.Lists)8 ArrayList (java.util.ArrayList)8