use of org.apache.pulsar.metadata.api.Notification in project incubator-pulsar by apache.
the class RocksdbMetadataStore method storePut.
@Override
protected CompletableFuture<Stat> storePut(String path, byte[] data, Optional<Long> expectedVersion, EnumSet<CreateOption> options) {
if (log.isDebugEnabled()) {
log.debug("storePut.path={},instanceId={}", path, instanceId);
}
try {
dbStateLock.readLock().lock();
if (state == State.CLOSED) {
throw new MetadataStoreException.AlreadyClosedException("");
}
try (Transaction transaction = db.beginTransaction(optionSync)) {
byte[] pathBytes = toBytes(path);
byte[] oldValueData = transaction.getForUpdate(optionDontCache, pathBytes, false);
MetaValue metaValue = MetaValue.parse(oldValueData);
if (expectedVersion.isPresent()) {
if (metaValue == null && expectedVersion.get() != -1 || metaValue != null && !expectedVersion.get().equals(metaValue.getVersion())) {
throw new MetadataStoreException.BadVersionException(String.format("Version mismatch, actual=%s, expect=%s", metaValue == null ? null : metaValue.getVersion(), expectedVersion.get()));
}
}
boolean created = false;
long timestamp = System.currentTimeMillis();
if (metaValue == null) {
// create new node
metaValue = new MetaValue();
metaValue.version = 0;
metaValue.createdTimestamp = timestamp;
metaValue.ephemeral = options.contains(CreateOption.Ephemeral);
if (options.contains(CreateOption.Sequential)) {
path += sequentialIdGenerator.getAndIncrement();
pathBytes = toBytes(path);
transaction.put(SEQUENTIAL_ID_KEY, toBytes(sequentialIdGenerator.get()));
}
created = true;
} else {
// update old node
metaValue.version++;
}
metaValue.modifiedTimestamp = timestamp;
metaValue.owner = instanceId;
metaValue.data = data;
// handle Sequential
transaction.put(pathBytes, metaValue.serialize());
transaction.commit();
receivedNotification(new Notification(created ? NotificationType.Created : NotificationType.Modified, path));
if (created) {
notifyParentChildrenChanged(path);
}
return CompletableFuture.completedFuture(new Stat(path, metaValue.version, metaValue.createdTimestamp, metaValue.modifiedTimestamp, metaValue.ephemeral, true));
}
} catch (Throwable e) {
return FutureUtil.failedFuture(MetadataStoreException.wrap(e));
} finally {
dbStateLock.readLock().unlock();
}
}
use of org.apache.pulsar.metadata.api.Notification in project incubator-pulsar by apache.
the class LocalMemoryMetadataStore method storePut.
@Override
public CompletableFuture<Stat> storePut(String path, byte[] data, Optional<Long> optExpectedVersion, EnumSet<CreateOption> options) {
if (!isValidPath(path)) {
return FutureUtil.failedFuture(new MetadataStoreException.InvalidPathException(path));
}
synchronized (map) {
boolean hasVersion = optExpectedVersion.isPresent();
int expectedVersion = optExpectedVersion.orElse(-1L).intValue();
if (options.contains(CreateOption.Sequential)) {
path += Long.toString(sequentialIdGenerator.getAndIncrement());
}
long now = System.currentTimeMillis();
if (hasVersion && expectedVersion == -1) {
Value newValue = new Value(0, data, now, now, options.contains(CreateOption.Ephemeral));
Value existingValue = map.putIfAbsent(path, newValue);
if (existingValue != null) {
return FutureUtils.exception(new BadVersionException(""));
} else {
receivedNotification(new Notification(NotificationType.Created, path));
notifyParentChildrenChanged(path);
return FutureUtils.value(new Stat(path, 0, now, now, newValue.isEphemeral(), true));
}
} else {
Value existingValue = map.get(path);
long existingVersion = existingValue != null ? existingValue.version : -1;
if (hasVersion && expectedVersion != existingVersion) {
return FutureUtils.exception(new BadVersionException(""));
} else {
long newVersion = existingValue != null ? existingValue.version + 1 : 0;
long createdTimestamp = existingValue != null ? existingValue.createdTimestamp : now;
Value newValue = new Value(newVersion, data, createdTimestamp, now, options.contains(CreateOption.Ephemeral));
map.put(path, newValue);
NotificationType type = existingValue == null ? NotificationType.Created : NotificationType.Modified;
receivedNotification(new Notification(type, path));
if (type == NotificationType.Created) {
notifyParentChildrenChanged(path);
}
return FutureUtils.value(new Stat(path, newValue.version, newValue.createdTimestamp, newValue.modifiedTimestamp, false, true));
}
}
}
}
use of org.apache.pulsar.metadata.api.Notification in project incubator-pulsar by apache.
the class RocksdbMetadataStore method storeDelete.
@Override
protected CompletableFuture<Void> storeDelete(String path, Optional<Long> expectedVersion) {
if (log.isDebugEnabled()) {
log.debug("storeDelete.path={},instanceId={}", path, instanceId);
}
try {
dbStateLock.readLock().lock();
if (state == State.CLOSED) {
throw new MetadataStoreException.AlreadyClosedException("");
}
try (Transaction transaction = db.beginTransaction(optionSync)) {
byte[] pathBytes = toBytes(path);
byte[] oldValueData = transaction.getForUpdate(optionDontCache, pathBytes, false);
MetaValue metaValue = MetaValue.parse(oldValueData);
if (metaValue == null) {
throw new MetadataStoreException.NotFoundException(String.format("path %s not found.", path));
}
if (expectedVersion.isPresent() && !expectedVersion.get().equals(metaValue.getVersion())) {
throw new MetadataStoreException.BadVersionException(String.format("Version mismatch, actual=%s, expect=%s", metaValue.getVersion(), expectedVersion.get()));
}
transaction.delete(pathBytes);
transaction.commit();
receivedNotification(new Notification(NotificationType.Deleted, path));
notifyParentChildrenChanged(path);
return CompletableFuture.completedFuture(null);
}
} catch (Throwable e) {
return FutureUtil.failedFuture(MetadataStoreException.wrap(e));
} finally {
dbStateLock.readLock().unlock();
}
}
use of org.apache.pulsar.metadata.api.Notification in project incubator-pulsar by apache.
the class ZKMetadataStore method handleWatchEvent.
private void handleWatchEvent(WatchedEvent event) {
if (log.isDebugEnabled()) {
log.debug("Received ZK watch : {}", event);
}
String path = event.getPath();
if (path == null) {
// Ignore Session events
return;
}
String parent = parent(path);
Notification childrenChangedNotification = null;
NotificationType type;
switch(event.getType()) {
case NodeCreated:
type = NotificationType.Created;
if (parent != null) {
childrenChangedNotification = new Notification(NotificationType.ChildrenChanged, parent);
}
break;
case NodeDataChanged:
type = NotificationType.Modified;
break;
case NodeChildrenChanged:
type = NotificationType.ChildrenChanged;
break;
case NodeDeleted:
type = NotificationType.Deleted;
if (parent != null) {
childrenChangedNotification = new Notification(NotificationType.ChildrenChanged, parent);
}
break;
default:
return;
}
receivedNotification(new Notification(type, event.getPath()));
if (childrenChangedNotification != null) {
receivedNotification(childrenChangedNotification);
}
}
use of org.apache.pulsar.metadata.api.Notification in project incubator-pulsar by apache.
the class AbstractMetadataStore method notifyParentChildrenChanged.
protected void notifyParentChildrenChanged(String path) {
String parent = parent(path);
while (parent != null) {
receivedNotification(new Notification(NotificationType.ChildrenChanged, parent));
parent = parent(parent);
}
}
Aggregations