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);
}
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();
}
}
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));
}
});
}
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));
}
}
}
});
}
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));
}
});
}
Aggregations