use of org.apache.ignite.events.IgfsEvent in project ignite by apache.
the class IgfsEventsAbstractSelfTest method testNestedEmptyDirs.
/**
* Checks events on CRUD operations with multiple
* empty directories.
*
* @throws Exception If failed.
*/
public void testNestedEmptyDirs() throws Exception {
final List<Event> evtList = new ArrayList<>();
final int evtsCnt = 2 + 1;
final CountDownLatch latch = new CountDownLatch(evtsCnt);
grid(1).events().localListen(lsnr = new IgnitePredicate<Event>() {
@Override
public boolean apply(Event evt) {
log.info("Received event [evt=" + evt + ']');
evtList.add(evt);
latch.countDown();
return true;
}
}, EVTS_IGFS);
IgfsPath dir = new IgfsPath("/dir1/dir2");
assertFalse(igfs.exists(dir.parent()));
// Will generate 2 EVT_IGFS_DIR_RENAMED events.
igfs.mkdirs(dir);
// Will generate EVT_IGFS_DIR_DELETED event.
assertTrue(igfs.delete(dir.parent(), true));
assertTrue(latch.await(10, TimeUnit.SECONDS));
assertEquals(evtsCnt, evtList.size());
IgfsEvent evt = (IgfsEvent) evtList.get(0);
assertEquals(EVT_IGFS_DIR_CREATED, evt.type());
assertEquals(new IgfsPath("/dir1"), evt.path());
evt = (IgfsEvent) evtList.get(1);
assertEquals(EVT_IGFS_DIR_CREATED, evt.type());
assertEquals(new IgfsPath("/dir1/dir2"), evt.path());
evt = (IgfsEvent) evtList.get(2);
assertEquals(EVT_IGFS_DIR_DELETED, evt.type());
assertEquals(new IgfsPath("/dir1"), evt.path());
}
use of org.apache.ignite.events.IgfsEvent in project ignite by apache.
the class IgfsImpl method update.
/**
* {@inheritDoc}
*/
@Override
public IgfsFile update(final IgfsPath path, final Map<String, String> props) {
A.notNull(path, "path");
A.notNull(props, "props");
A.ensure(!props.isEmpty(), "!props.isEmpty()");
if (meta.isClient())
return meta.runClientTask(new IgfsClientUpdateCallable(cfg.getName(), IgfsUserContext.currentUser(), path, props));
return safeOp(new Callable<IgfsFile>() {
@Override
public IgfsFile call() throws Exception {
if (log.isDebugEnabled())
log.debug("Set file properties [path=" + path + ", props=" + props + ']');
IgfsMode mode = resolveMode(path);
switch(mode) {
case PRIMARY:
{
List<IgniteUuid> fileIds = meta.idsForPath(path);
IgniteUuid fileId = fileIds.get(fileIds.size() - 1);
if (fileId != null) {
IgfsEntryInfo info = meta.updateProperties(fileId, props);
if (info != null) {
if (evts.isRecordable(EVT_IGFS_META_UPDATED))
evts.record(new IgfsEvent(path, igfsCtx.localNode(), EVT_IGFS_META_UPDATED, props));
return new IgfsFileImpl(path, info, data.groupBlockSize());
}
}
break;
}
case DUAL_ASYNC:
case DUAL_SYNC:
{
await(path);
IgfsEntryInfo info = meta.updateDual(secondaryFs, path, props);
if (info != null)
return new IgfsFileImpl(path, info, data.groupBlockSize());
break;
}
default:
assert mode == PROXY : "Unknown mode: " + mode;
IgfsFile status = secondaryFs.update(path, props);
return status != null ? new IgfsFileImpl(status, data.groupBlockSize()) : null;
}
return null;
}
});
}
use of org.apache.ignite.events.IgfsEvent in project ignite by apache.
the class IgfsMetaManager method mkdirsDual.
/**
* Create directory in DUAL mode.
*
* @param fs Secondary file system.
* @param path Path to create.
* @param props Properties to be applied.
* @return {@code True} in case rename was successful.
* @throws IgniteCheckedException If directory creation failed.
*/
public boolean mkdirsDual(final IgfsSecondaryFileSystem fs, final IgfsPath path, final Map<String, String> props) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
assert fs != null;
assert path != null;
if (path.parent() == null)
// No additional handling for root directory is needed.
return true;
// Events to fire (can be done outside of a transaction).
final Deque<IgfsEvent> pendingEvts = new LinkedList<>();
SynchronizationTask<Boolean> task = new SynchronizationTask<Boolean>() {
@Override
public Boolean onSuccess(Map<IgfsPath, IgfsEntryInfo> infos) throws Exception {
fs.mkdirs(path, props);
assert !infos.isEmpty();
// Now perform synchronization again starting with the last created parent.
IgfsPath parentPath = null;
for (IgfsPath curPath : infos.keySet()) {
if (parentPath == null || curPath.isSubDirectoryOf(parentPath))
parentPath = curPath;
}
assert parentPath != null;
IgfsEntryInfo parentPathInfo = infos.get(parentPath);
synchronize(fs, parentPath, parentPathInfo, path, true, null);
if (evts.isRecordable(EventType.EVT_IGFS_DIR_CREATED)) {
IgfsPath evtPath = path;
while (!parentPath.equals(evtPath)) {
pendingEvts.addFirst(new IgfsEvent(evtPath, locNode, EventType.EVT_IGFS_DIR_CREATED));
evtPath = evtPath.parent();
// If this fails, then ROOT does not exist.
assert evtPath != null;
}
}
return true;
}
@Override
public Boolean onFailure(@Nullable Exception err) throws IgniteCheckedException {
U.error(log, "Directory creation in DUAL mode failed [path=" + path + ", properties=" + props + ']', err);
throw new IgniteCheckedException("Failed to create the path due to secondary file system " + "exception: " + path, err);
}
};
try {
return synchronizeAndExecute(task, fs, false, path.parent());
} finally {
for (IgfsEvent evt : pendingEvts) evts.record(evt);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to create directory in DUAL mode because Grid is stopping: " + path);
}
use of org.apache.ignite.events.IgfsEvent in project ignite by apache.
the class IgfsMetaManager method renameDual.
/**
* Rename path in DUAL mode.
*
* @param fs Secondary file system.
* @param src Source path.
* @param dest Destination path.
* @return Operation result.
* @throws IgniteCheckedException If failed.
*/
public boolean renameDual(final IgfsSecondaryFileSystem fs, final IgfsPath src, final IgfsPath dest) throws IgniteCheckedException {
if (busyLock.enterBusy()) {
try {
assert fs != null;
assert src != null;
assert dest != null;
if (src.parent() == null)
// Root directory cannot be renamed.
return false;
// Events to fire (can be done outside of a transaction).
final Collection<IgfsEvent> pendingEvts = new LinkedList<>();
SynchronizationTask<Boolean> task = new SynchronizationTask<Boolean>() {
@Override
public Boolean onSuccess(Map<IgfsPath, IgfsEntryInfo> infos) throws Exception {
IgfsEntryInfo srcInfo = infos.get(src);
IgfsEntryInfo srcParentInfo = infos.get(src.parent());
IgfsEntryInfo destInfo = infos.get(dest);
IgfsEntryInfo destParentInfo = dest.parent() != null ? infos.get(dest.parent()) : null;
// Source path and destination (or destination parent) must exist.
if (srcInfo == null)
throw fsException(new IgfsPathNotFoundException("Failed to rename " + "(source path not found): " + src));
if (destInfo == null && destParentInfo == null)
throw fsException(new IgfsPathNotFoundException("Failed to rename " + "(destination path not found): " + dest));
// Delegate to the secondary file system.
fs.rename(src, dest);
// Rename was successful, perform compensation in the local file system.
if (destInfo == null)
moveNonTx(srcInfo.id(), src.name(), srcParentInfo.id(), dest.name(), destParentInfo.id());
else {
// Move.
if (destInfo.isFile())
throw fsException("Failed to rename the path in the local file system " + "because destination path already exists and it is a file: " + dest);
else
moveNonTx(srcInfo.id(), src.name(), srcParentInfo.id(), src.name(), destInfo.id());
}
// Record event if needed.
if (srcInfo.isFile()) {
if (evts.isRecordable(EventType.EVT_IGFS_FILE_RENAMED))
pendingEvts.add(new IgfsEvent(src, destInfo == null ? dest : new IgfsPath(dest, src.name()), locNode, EventType.EVT_IGFS_FILE_RENAMED));
} else if (evts.isRecordable(EventType.EVT_IGFS_DIR_RENAMED))
pendingEvts.add(new IgfsEvent(src, dest, locNode, EventType.EVT_IGFS_DIR_RENAMED));
return true;
}
@Override
public Boolean onFailure(@Nullable Exception err) throws IgniteCheckedException {
U.error(log, "Path rename in DUAL mode failed [source=" + src + ", destination=" + dest + ']', err);
throw new IgniteCheckedException("Failed to rename the path due to secondary file system " + "exception: " + src, err);
}
};
try {
return synchronizeAndExecute(task, fs, false, src, dest);
} finally {
for (IgfsEvent evt : pendingEvts) evts.record(evt);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to rename in DUAL mode because Grid is stopping [src=" + src + ", dest=" + dest + ']');
}
use of org.apache.ignite.events.IgfsEvent in project ignite by apache.
the class IgfsMetaManager method onSuccessCreate.
/**
* A delegate method that performs file creation in the synchronization task.
*
* @param fs File system.
* @param path Path.
* @param simpleCreate "Simple create" flag.
* @param props Properties..
* @param overwrite Overwrite flag.
* @param bufSize Buffer size.
* @param replication Replication factor.
* @param blockSize Block size.
* @param affKey Affinity key.
* @param infos Map from paths to corresponding infos.
* @param pendingEvts A non-null collection the events are to be accumulated in.
* @param t1 A signle-object tuple to hold the created output stream.
* @return Output stream descriptor.
* @throws Exception On error.
*/
IgfsCreateResult onSuccessCreate(IgfsSecondaryFileSystem fs, IgfsPath path, boolean simpleCreate, @Nullable final Map<String, String> props, boolean overwrite, int bufSize, short replication, long blockSize, IgniteUuid affKey, Map<IgfsPath, IgfsEntryInfo> infos, final Deque<IgfsEvent> pendingEvts, final T1<OutputStream> t1) throws Exception {
validTxState(true);
assert !infos.isEmpty();
// Determine the first existing parent.
IgfsPath parentPath = null;
for (IgfsPath curPath : infos.keySet()) {
if (parentPath == null || curPath.isSubDirectoryOf(parentPath))
parentPath = curPath;
}
assert parentPath != null;
IgfsEntryInfo parentInfo = infos.get(parentPath);
// Delegate to the secondary file system.
OutputStream out = simpleCreate ? fs.create(path, overwrite) : fs.create(path, bufSize, overwrite, replication, blockSize, props);
t1.set(out);
IgfsPath parent0 = path.parent();
assert parent0 != null : "path.parent() is null (are we creating ROOT?): " + path;
// If some of the parent directories were missing, synchronize again.
if (!parentPath.equals(parent0)) {
parentInfo = synchronize(fs, parentPath, parentInfo, parent0, true, null);
// Fire notification about missing directories creation.
if (evts.isRecordable(EventType.EVT_IGFS_DIR_CREATED)) {
IgfsPath evtPath = parent0;
while (!parentPath.equals(evtPath)) {
pendingEvts.addFirst(new IgfsEvent(evtPath, locNode, EventType.EVT_IGFS_DIR_CREATED));
evtPath = evtPath.parent();
// If this fails, then ROOT does not exist.
assert evtPath != null;
}
}
}
// Get created file info.
IgfsFile status = fs.info(path);
if (status == null)
throw fsException("Failed to open output stream to the file created in " + "the secondary file system because it no longer exists: " + path);
else if (status.isDirectory())
throw fsException("Failed to open output stream to the file created in " + "the secondary file system because the path points to a directory: " + path);
IgfsEntryInfo newInfo = IgfsUtils.createFile(IgniteUuid.randomUuid(), igfsCtx.configuration().getBlockSize(), status.length(), affKey, createFileLockId(false), igfsCtx.igfs().evictExclude(path, false), status.properties(), status.accessTime(), status.modificationTime());
// Add new file info to the listing optionally removing the previous one.
assert parentInfo != null;
IgniteUuid oldId = putIfAbsentNonTx(parentInfo.id(), path.name(), newInfo);
if (oldId != null) {
IgfsEntryInfo oldInfo = info(oldId);
// Otherwise cache is in inconsistent state.
assert oldInfo != null;
// The contact is that we cannot overwrite a file locked for writing:
if (oldInfo.lockId() != null)
throw fsException("Failed to overwrite file (file is opened for writing) [path=" + path + ", fileId=" + oldId + ", lockId=" + oldInfo.lockId() + ']');
// Remove the old one.
id2InfoPrj.remove(oldId);
id2InfoPrj.invoke(parentInfo.id(), new IgfsMetaDirectoryListingRemoveProcessor(path.name(), parentInfo.listing().get(path.name()).fileId()));
// Put new one.
createNewEntry(newInfo, parentInfo.id(), path.name());
igfsCtx.data().delete(oldInfo);
}
// Record CREATE event if needed.
if (oldId == null && evts.isRecordable(EventType.EVT_IGFS_FILE_CREATED))
pendingEvts.add(new IgfsEvent(path, locNode, EventType.EVT_IGFS_FILE_CREATED));
return new IgfsCreateResult(newInfo, out);
}
Aggregations