use of org.apache.ignite.igfs.IgfsPath 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.igfs.IgfsPath 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.igfs.IgfsPath in project ignite by apache.
the class IgfsMetaManager method generateCreateEvents.
/**
* Generate events for created file or directory.
*
* @param createdPaths Created paths.
* @param file Whether file was created.
*/
private void generateCreateEvents(List<IgfsPath> createdPaths, boolean file) {
if (evts.isRecordable(EventType.EVT_IGFS_DIR_CREATED)) {
for (int i = 0; i < createdPaths.size() - 1; i++) IgfsUtils.sendEvents(igfsCtx.kernalContext(), createdPaths.get(i), EventType.EVT_IGFS_DIR_CREATED);
}
IgfsPath leafPath = createdPaths.get(createdPaths.size() - 1);
if (file) {
IgfsUtils.sendEvents(igfsCtx.kernalContext(), leafPath, EventType.EVT_IGFS_FILE_CREATED);
IgfsUtils.sendEvents(igfsCtx.kernalContext(), leafPath, EventType.EVT_IGFS_FILE_OPENED_WRITE);
} else
IgfsUtils.sendEvents(igfsCtx.kernalContext(), leafPath, EventType.EVT_IGFS_DIR_CREATED);
}
use of org.apache.ignite.igfs.IgfsPath 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);
}
use of org.apache.ignite.igfs.IgfsPath in project ignite by apache.
the class IgfsModeResolver method readExternal.
/**
* {@inheritDoc}
*/
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
dfltMode = IgfsMode.fromOrdinal(in.readByte());
if (in.readBoolean()) {
int size = in.readInt();
modes = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
IgfsPath path = IgfsUtils.readPath(in);
modes.add(new T2<>(path, IgfsMode.fromOrdinal(in.readByte())));
}
modesCache = new GridBoundedConcurrentLinkedHashMap<>(MAX_PATH_CACHE);
}
dualParentsWithPrimaryChildren = new HashSet<>();
if (in.readBoolean()) {
int size = in.readInt();
for (int i = 0; i < size; i++) dualParentsWithPrimaryChildren.add(IgfsUtils.readPath(in));
}
}
Aggregations