Search in sources :

Example 6 with GetResult

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

the class MetadataStoreTest method insertionTestWithExpectedVersion.

@Test(dataProvider = "impl")
public void insertionTestWithExpectedVersion(String provider, Supplier<String> urlSupplier) throws Exception {
    @Cleanup MetadataStore store = MetadataStoreFactory.create(urlSupplier.get(), MetadataStoreConfig.builder().build());
    String key1 = newKey();
    try {
        store.put(key1, "value-1".getBytes(), Optional.of(0L)).join();
        fail("Should have failed");
    } catch (CompletionException e) {
        assertException(e, BadVersionException.class);
    }
    try {
        store.put(key1, "value-1".getBytes(), Optional.of(1L)).join();
        fail("Should have failed");
    } catch (CompletionException e) {
        assertException(e, BadVersionException.class);
    }
    store.put(key1, "value-1".getBytes(), Optional.of(-1L)).join();
    assertTrue(store.exists(key1).join());
    Optional<GetResult> optRes = store.get(key1).join();
    assertTrue(optRes.isPresent());
    assertEquals(optRes.get().getValue(), "value-1".getBytes());
    assertEquals(optRes.get().getStat().getVersion(), 0);
    try {
        store.put(key1, "value-2".getBytes(), Optional.of(-1L)).join();
        fail("Should have failed");
    } catch (CompletionException e) {
        assertException(e, BadVersionException.class);
    }
    try {
        store.put(key1, "value-2".getBytes(), Optional.of(1L)).join();
        fail("Should have failed");
    } catch (CompletionException e) {
        assertException(e, BadVersionException.class);
    }
    assertTrue(store.exists(key1).join());
    optRes = store.get(key1).join();
    assertTrue(optRes.isPresent());
    assertEquals(optRes.get().getValue(), "value-1".getBytes());
    assertEquals(optRes.get().getStat().getVersion(), 0);
    store.put(key1, "value-2".getBytes(), Optional.of(0L)).join();
    assertTrue(store.exists(key1).join());
    optRes = store.get(key1).join();
    assertTrue(optRes.isPresent());
    assertEquals(optRes.get().getValue(), "value-2".getBytes());
    assertEquals(optRes.get().getStat().getVersion(), 1);
}
Also used : MetadataStore(org.apache.pulsar.metadata.api.MetadataStore) GetResult(org.apache.pulsar.metadata.api.GetResult) CompletionException(java.util.concurrent.CompletionException) BadVersionException(org.apache.pulsar.metadata.api.MetadataStoreException.BadVersionException) Cleanup(lombok.Cleanup) Test(org.testng.annotations.Test)

Example 7 with GetResult

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

the class RocksdbMetadataStore method storeGet.

@Override
public CompletableFuture<Optional<GetResult>> storeGet(String path) {
    if (log.isDebugEnabled()) {
        log.debug("getFromStore.path={},instanceId={}", path, instanceId);
    }
    try {
        dbStateLock.readLock().lock();
        if (state == State.CLOSED) {
            throw new MetadataStoreException.AlreadyClosedException("");
        }
        byte[] value = db.get(optionCache, toBytes(path));
        if (value == null) {
            return CompletableFuture.completedFuture(Optional.empty());
        }
        MetaValue metaValue = MetaValue.parse(value);
        if (metaValue.ephemeral && metaValue.owner != instanceId) {
            delete(path, Optional.empty());
            return CompletableFuture.completedFuture(Optional.empty());
        }
        GetResult result = new GetResult(metaValue.getData(), new Stat(path, metaValue.getVersion(), metaValue.getCreatedTimestamp(), metaValue.getModifiedTimestamp(), metaValue.ephemeral, metaValue.getOwner() == instanceId));
        return CompletableFuture.completedFuture(Optional.of(result));
    } catch (Throwable e) {
        return FutureUtil.failedFuture(MetadataStoreException.wrap(e));
    } finally {
        dbStateLock.readLock().unlock();
    }
}
Also used : Stat(org.apache.pulsar.metadata.api.Stat) GetResult(org.apache.pulsar.metadata.api.GetResult)

Example 8 with GetResult

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

the class ResourceLockImpl method doRevalidate.

private synchronized CompletableFuture<Void> doRevalidate(T newValue) {
    if (log.isDebugEnabled()) {
        log.debug("doRevalidate with newValue={}, version={}", newValue, version);
    }
    return store.get(path).thenCompose(optGetResult -> {
        if (!optGetResult.isPresent()) {
            // The lock just disappeared, try to acquire it again
            // Reset the expectation on the version
            setVersion(-1L);
            return acquireWithNoRevalidation(newValue).thenRun(() -> log.info("Successfully re-acquired missing lock at {}", path));
        }
        GetResult res = optGetResult.get();
        if (!res.getStat().isEphemeral()) {
            return FutureUtils.exception(new LockBusyException("Path " + path + " is already created as non-ephemeral"));
        }
        T existingValue;
        try {
            existingValue = serde.deserialize(path, res.getValue(), res.getStat());
        } catch (Throwable t) {
            return FutureUtils.exception(t);
        }
        synchronized (ResourceLockImpl.this) {
            if (newValue.equals(existingValue)) {
                if (res.getStat().isCreatedBySelf()) {
                    // If the new lock belongs to the same session, there's no
                    // need to recreate it.
                    version = res.getStat().getVersion();
                    value = newValue;
                    return CompletableFuture.completedFuture(null);
                } else {
                    // The lock needs to get recreated since it belong to an earlier
                    // session which maybe expiring soon
                    log.info("Deleting stale lock at {}", path);
                    return store.delete(path, Optional.of(res.getStat().getVersion())).thenRun(() -> setVersion(-1L)).thenCompose(__ -> acquireWithNoRevalidation(newValue)).thenRun(() -> log.info("Successfully re-acquired stale lock at {}", path));
                }
            }
            if (!res.getStat().isCreatedBySelf()) {
                return FutureUtils.exception(new LockBusyException("Resource at " + path + " is already locked"));
            }
            return store.delete(path, Optional.of(res.getStat().getVersion())).thenRun(() -> setVersion(-1L)).thenCompose(__ -> acquireWithNoRevalidation(newValue)).thenRun(() -> log.info("Successfully re-acquired lock at {}", path));
        }
    });
}
Also used : MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) LockBusyException(org.apache.pulsar.metadata.api.MetadataStoreException.LockBusyException) CreateOption(org.apache.pulsar.metadata.api.extended.CreateOption) CompletableFuture(java.util.concurrent.CompletableFuture) MetadataStoreExtended(org.apache.pulsar.metadata.api.extended.MetadataStoreExtended) FutureUtils(org.apache.bookkeeper.common.concurrent.FutureUtils) Slf4j(lombok.extern.slf4j.Slf4j) GetResult(org.apache.pulsar.metadata.api.GetResult) MetadataSerde(org.apache.pulsar.metadata.api.MetadataSerde) ResourceLock(org.apache.pulsar.metadata.api.coordination.ResourceLock) BadVersionException(org.apache.pulsar.metadata.api.MetadataStoreException.BadVersionException) Optional(java.util.Optional) EnumSet(java.util.EnumSet) GetResult(org.apache.pulsar.metadata.api.GetResult) LockBusyException(org.apache.pulsar.metadata.api.MetadataStoreException.LockBusyException)

Example 9 with GetResult

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

the class EtcdMetadataStore method handleBatchOperationResult.

private void handleBatchOperationResult(TxnResponse txnResponse, List<MetadataOp> ops) {
    executor.execute(() -> {
        if (!txnResponse.isSucceeded()) {
            if (ops.size() > 1) {
                // Retry individually
                ops.forEach(o -> batchOperation(Collections.singletonList(o)));
            } else {
                ops.get(0).getFuture().completeExceptionally(new MetadataStoreException.BadVersionException("Bad version"));
            }
            return;
        }
        int getIdx = 0;
        int deletedIdx = 0;
        int putIdx = 0;
        for (MetadataOp op : ops) {
            switch(op.getType()) {
                case GET:
                    {
                        OpGet get = op.asGet();
                        GetResponse gr = txnResponse.getGetResponses().get(getIdx++);
                        if (gr.getCount() == 0) {
                            get.getFuture().complete(Optional.empty());
                        } else {
                            KeyValue kv = gr.getKvs().get(0);
                            boolean isEphemeral = kv.getLease() != 0;
                            boolean createdBySelf = kv.getLease() == leaseId;
                            get.getFuture().complete(Optional.of(new GetResult(kv.getValue().getBytes(), new Stat(get.getPath(), kv.getVersion() - 1, 0, 0, isEphemeral, createdBySelf))));
                        }
                        break;
                    }
                case PUT:
                    {
                        OpPut put = op.asPut();
                        PutResponse pr = txnResponse.getPutResponses().get(putIdx++);
                        KeyValue prevKv = pr.getPrevKv();
                        if (prevKv == null) {
                            put.getFuture().complete(new Stat(put.getPath(), 0, 0, 0, put.isEphemeral(), true));
                        } else {
                            put.getFuture().complete(new Stat(put.getPath(), prevKv.getVersion(), 0, 0, put.isEphemeral(), true));
                        }
                        break;
                    }
                case DELETE:
                    {
                        OpDelete del = op.asDelete();
                        DeleteResponse dr = txnResponse.getDeleteResponses().get(deletedIdx++);
                        if (dr.getDeleted() == 0) {
                            del.getFuture().completeExceptionally(new MetadataStoreException.NotFoundException());
                        } else {
                            del.getFuture().complete(null);
                        }
                        break;
                    }
                case GET_CHILDREN:
                    {
                        OpGetChildren getChildren = op.asGetChildren();
                        GetResponse gr = txnResponse.getGetResponses().get(getIdx++);
                        String basePath = getChildren.getPath() + "/";
                        Set<String> children = gr.getKvs().stream().map(kv -> kv.getKey().toString(StandardCharsets.UTF_8)).map(p -> p.replace(basePath, "")).map(k -> k.split("/", 2)[0]).collect(Collectors.toCollection(TreeSet::new));
                        getChildren.getFuture().complete(new ArrayList<>(children));
                    }
            }
        }
    });
}
Also used : DeleteOption(io.etcd.jetcd.options.DeleteOption) WatchEvent(io.etcd.jetcd.watch.WatchEvent) AbstractBatchedMetadataStore(org.apache.pulsar.metadata.impl.batching.AbstractBatchedMetadataStore) TxnResponse(io.etcd.jetcd.kv.TxnResponse) Notification(org.apache.pulsar.metadata.api.Notification) StreamObserver(io.grpc.stub.StreamObserver) Status(io.grpc.Status) EnumSet(java.util.EnumSet) GetOption(io.etcd.jetcd.options.GetOption) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) KV(io.etcd.jetcd.KV) Stat(org.apache.pulsar.metadata.api.Stat) Op(io.etcd.jetcd.op.Op) PutOption(io.etcd.jetcd.options.PutOption) Set(java.util.Set) CloseableClient(io.etcd.jetcd.support.CloseableClient) CompletionException(java.util.concurrent.CompletionException) MetadataStoreConfig(org.apache.pulsar.metadata.api.MetadataStoreConfig) OpGet(org.apache.pulsar.metadata.impl.batching.OpGet) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) SessionEvent(org.apache.pulsar.metadata.api.extended.SessionEvent) Txn(io.etcd.jetcd.Txn) Optional(java.util.Optional) PutResponse(io.etcd.jetcd.kv.PutResponse) Cmp(io.etcd.jetcd.op.Cmp) Client(io.etcd.jetcd.Client) CompletableFuture(java.util.concurrent.CompletableFuture) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) DeleteResponse(io.etcd.jetcd.kv.DeleteResponse) GetResult(org.apache.pulsar.metadata.api.GetResult) ByteSequence(io.etcd.jetcd.ByteSequence) GetResponse(io.etcd.jetcd.kv.GetResponse) MetadataOp(org.apache.pulsar.metadata.impl.batching.MetadataOp) LeaseKeepAliveResponse(io.etcd.jetcd.lease.LeaseKeepAliveResponse) CreateOption(org.apache.pulsar.metadata.api.extended.CreateOption) OpPut(org.apache.pulsar.metadata.impl.batching.OpPut) CmpTarget(io.etcd.jetcd.op.CmpTarget) OpDelete(org.apache.pulsar.metadata.impl.batching.OpDelete) KeyValue(io.etcd.jetcd.KeyValue) StatusRuntimeException(io.grpc.StatusRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) WatchResponse(io.etcd.jetcd.watch.WatchResponse) NotificationType(org.apache.pulsar.metadata.api.NotificationType) WatchOption(io.etcd.jetcd.options.WatchOption) OpGetChildren(org.apache.pulsar.metadata.impl.batching.OpGetChildren) Collections(java.util.Collections) OpGetChildren(org.apache.pulsar.metadata.impl.batching.OpGetChildren) KeyValue(io.etcd.jetcd.KeyValue) OpPut(org.apache.pulsar.metadata.impl.batching.OpPut) EnumSet(java.util.EnumSet) Set(java.util.Set) TreeSet(java.util.TreeSet) GetResult(org.apache.pulsar.metadata.api.GetResult) ArrayList(java.util.ArrayList) PutResponse(io.etcd.jetcd.kv.PutResponse) GetResponse(io.etcd.jetcd.kv.GetResponse) OpDelete(org.apache.pulsar.metadata.impl.batching.OpDelete) MetadataStoreException(org.apache.pulsar.metadata.api.MetadataStoreException) Stat(org.apache.pulsar.metadata.api.Stat) DeleteResponse(io.etcd.jetcd.kv.DeleteResponse) TreeSet(java.util.TreeSet) OpGet(org.apache.pulsar.metadata.impl.batching.OpGet) MetadataOp(org.apache.pulsar.metadata.impl.batching.MetadataOp)

Example 10 with GetResult

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

the class MetadataCacheImpl method readValueFromStore.

private CompletableFuture<Optional<CacheGetResult<T>>> readValueFromStore(String path) {
    return store.get(path).thenCompose(optRes -> {
        if (!optRes.isPresent()) {
            return FutureUtils.value(Optional.empty());
        }
        try {
            GetResult res = optRes.get();
            T obj = serde.deserialize(path, res.getValue(), res.getStat());
            return FutureUtils.value(Optional.of(new CacheGetResult<>(obj, res.getStat())));
        } catch (Throwable t) {
            return FutureUtils.exception(new ContentDeserializationException("Failed to deserialize payload for key '" + path + "'", t));
        }
    });
}
Also used : CacheGetResult(org.apache.pulsar.metadata.api.CacheGetResult) GetResult(org.apache.pulsar.metadata.api.GetResult) CacheGetResult(org.apache.pulsar.metadata.api.CacheGetResult) ContentDeserializationException(org.apache.pulsar.metadata.api.MetadataStoreException.ContentDeserializationException)

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