use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsDataManager method processAckMessage.
/**
* @param nodeId Node ID.
* @param ackMsg Write acknowledgement message.
*/
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
private void processAckMessage(UUID nodeId, IgfsAckMessage ackMsg) {
try {
ackMsg.finishUnmarshal(igfsCtx.kernalContext().config().getMarshaller(), null);
} catch (IgniteCheckedException e) {
U.error(log, "Failed to unmarshal message (will ignore): " + ackMsg, e);
return;
}
IgniteUuid fileId = ackMsg.fileId();
WriteCompletionFuture fut = pendingWrites.get(fileId);
if (fut != null) {
if (ackMsg.error() != null)
fut.onError(nodeId, ackMsg.error());
else
fut.onWriteAck(nodeId, ackMsg.id());
} else {
if (log.isDebugEnabled())
log.debug("Received write acknowledgement for non-existent write future (most likely future was " + "failed) [nodeId=" + nodeId + ", fileId=" + fileId + ']');
}
}
use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method softDelete.
/**
* Move path to the trash directory.
*
* @param path Path.
* @param recursive Recursive flag.
* @param secondaryFs Secondary file system (optional).
* @return ID of an entry located directly under the trash directory.
* @throws IgniteCheckedException If failed.
*/
IgfsDeleteResult softDelete(final IgfsPath path, final boolean recursive, @Nullable IgfsSecondaryFileSystem secondaryFs) throws IgniteCheckedException {
while (true) {
if (busyLock.enterBusy()) {
try {
validTxState(false);
IgfsPathIds pathIds = pathIds(path);
if (!pathIds.allExists() && secondaryFs == null)
return new IgfsDeleteResult(false, null);
IgniteUuid victimId = pathIds.lastId();
String victimName = pathIds.lastPart();
if (IgfsUtils.isRootId(victimId))
throw new IgfsException("Cannot remove root directory");
// Prepare IDs to lock.
SortedSet<IgniteUuid> allIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
pathIds.addExistingIds(allIds, relaxed);
IgniteUuid trashId = IgfsUtils.randomTrashId();
allIds.add(trashId);
try (GridNearTxLocal tx = startTx()) {
// Lock participants.
Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(allIds);
if (secondaryFs != null && isRetryForSecondary(pathIds, lockInfos))
continue;
// Ensure that all participants are still in place.
if (!pathIds.allExists() || !pathIds.verifyIntegrity(lockInfos, relaxed)) {
// For DUAL mode we will try to update the underlying FS still. Note we do that inside TX.
if (secondaryFs != null) {
boolean res = secondaryFs.delete(path, recursive);
return new IgfsDeleteResult(res, null);
} else
return new IgfsDeleteResult(false, null);
}
IgfsEntryInfo victimInfo = lockInfos.get(victimId);
// Cannot delete non-empty directory if recursive flag is not set.
if (!recursive && victimInfo.hasChildren())
throw new IgfsDirectoryNotEmptyException("Failed to remove directory (directory is not " + "empty and recursive flag is not set).");
// Prepare trash data.
IgfsEntryInfo trashInfo = lockInfos.get(trashId);
final String trashName = IgfsUtils.composeNameForTrash(path, victimId);
assert !trashInfo.hasChild(trashName) : "Failed to add file name into the " + "destination directory (file already exists) [destName=" + trashName + ']';
IgniteUuid parentId = pathIds.lastParentId();
IgfsEntryInfo parentInfo = lockInfos.get(parentId);
// Propagate call to the secondary file system.
if (secondaryFs != null && !secondaryFs.delete(path, recursive))
return new IgfsDeleteResult(false, null);
transferEntry(parentInfo.listing().get(victimName), parentId, victimName, trashId, trashName);
tx.commit();
signalDeleteWorker();
return new IgfsDeleteResult(true, victimInfo);
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to perform soft delete because Grid is " + "stopping [path=" + path + ']');
}
}
use of org.apache.ignite.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method create.
/**
* Create a file.
*
* @param path Path.
* @param dirProps Directory properties.
* @param overwrite Overwrite flag.
* @param blockSize Block size.
* @param affKey Affinity key.
* @param evictExclude Evict exclude flag.
* @param fileProps File properties.
* @param secondaryCtx Secondary file system create context.
* @return @return Operation result.
* @throws IgniteCheckedException If failed.
*/
IgfsCreateResult create(final IgfsPath path, Map<String, String> dirProps, final boolean overwrite, final int blockSize, @Nullable final IgniteUuid affKey, final boolean evictExclude, @Nullable Map<String, String> fileProps, @Nullable IgfsSecondaryFileSystemCreateContext secondaryCtx) throws IgniteCheckedException {
validTxState(false);
while (true) {
if (busyLock.enterBusy()) {
OutputStream secondaryOut = null;
try {
// Prepare path IDs.
IgfsPathIds pathIds = pathIds(path);
// Prepare lock IDs.
Set<IgniteUuid> lockIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
pathIds.addExistingIds(lockIds, relaxed);
pathIds.addSurrogateIds(lockIds);
// In overwrite mode we also lock ID of potential replacement as well as trash ID.
IgniteUuid overwriteId = IgniteUuid.randomUuid();
IgniteUuid trashId = IgfsUtils.randomTrashId();
if (overwrite) {
lockIds.add(overwriteId);
// Trash ID is only added if we suspect conflict.
if (pathIds.allExists())
lockIds.add(trashId);
}
// Start TX.
try (GridNearTxLocal tx = startTx()) {
Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(lockIds);
if (secondaryCtx != null && isRetryForSecondary(pathIds, lockInfos))
continue;
if (!pathIds.verifyIntegrity(lockInfos, relaxed))
// Directory structure changed concurrently. So we simply re-try.
continue;
if (pathIds.allExists()) {
// All participants found.
IgfsEntryInfo oldInfo = lockInfos.get(pathIds.lastId());
// Check: is it a file?
if (!oldInfo.isFile())
throw new IgfsPathIsDirectoryException("Failed to create a file: " + path);
// Check: can we overwrite it?
if (!overwrite)
throw new IgfsPathAlreadyExistsException("Failed to create a file: " + path);
// Check if file already opened for write.
if (oldInfo.lockId() != null)
throw new IgfsException("File is already opened for write: " + path);
// At this point file can be re-created safely.
// Add existing to trash listing.
IgniteUuid oldId = pathIds.lastId();
id2InfoPrj.invoke(trashId, new IgfsMetaDirectoryListingAddProcessor(IgfsUtils.composeNameForTrash(path, oldId), new IgfsListingEntry(oldInfo)));
// Replace ID in parent directory.
String name = pathIds.lastPart();
IgniteUuid parentId = pathIds.lastParentId();
id2InfoPrj.invoke(parentId, new IgfsMetaDirectoryListingReplaceProcessor(name, overwriteId));
// Create the file.
IgniteUuid newLockId = createFileLockId(false);
long newAccessTime;
long newModificationTime;
Map<String, String> newProps;
long newLen;
int newBlockSize;
if (secondaryCtx != null) {
secondaryOut = secondaryCtx.create();
newAccessTime = 0L;
newModificationTime = 0L;
newProps = null;
} else {
newAccessTime = System.currentTimeMillis();
newModificationTime = newAccessTime;
newProps = fileProps;
}
newLen = 0L;
newBlockSize = blockSize;
IgfsEntryInfo newInfo = invokeAndGet(overwriteId, new IgfsMetaFileCreateProcessor(newAccessTime, newModificationTime, newProps, newBlockSize, affKey, newLockId, evictExclude, newLen));
// Prepare result and commit.
tx.commit();
IgfsUtils.sendEvents(igfsCtx.kernalContext(), path, EventType.EVT_IGFS_FILE_OPENED_WRITE);
return new IgfsCreateResult(newInfo, secondaryOut);
} else {
// Create file and parent folders.
T1<OutputStream> secondaryOutHolder = null;
if (secondaryCtx != null)
secondaryOutHolder = new T1<>();
IgfsPathsCreateResult res;
try {
res = createFile(pathIds, lockInfos, dirProps, fileProps, blockSize, affKey, evictExclude, secondaryCtx, secondaryOutHolder);
} finally {
if (secondaryOutHolder != null)
secondaryOut = secondaryOutHolder.get();
}
if (res == null)
continue;
// Commit.
tx.commit();
// Generate events.
generateCreateEvents(res.createdPaths(), true);
return new IgfsCreateResult(res.info(), secondaryOut);
}
}
} catch (IgniteException | IgniteCheckedException e) {
U.closeQuiet(secondaryOut);
throw e;
} catch (Exception e) {
U.closeQuiet(secondaryOut);
throw new IgniteCheckedException("Create failed due to unexpected exception: " + path, e);
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to mkdir because Grid is stopping. [path=" + path + ']');
}
}
use of org.apache.ignite.lang.IgniteUuid 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.lang.IgniteUuid in project ignite by apache.
the class IgfsMetaManager method mkdirs.
/**
* Mkdirs implementation.
*
* @param path The path to create.
* @param props The properties to use for created directories.
* @return True if a directory was created during the operation.
* @throws IgniteCheckedException If a non-directory file exists on the requested path, and in case of other errors.
*/
boolean mkdirs(final IgfsPath path, final Map<String, String> props) throws IgniteCheckedException {
validTxState(false);
while (true) {
if (busyLock.enterBusy()) {
try {
// Prepare path IDs.
IgfsPathIds pathIds = pathIds(path);
// Prepare lock IDs. Essentially, they consist of two parts: existing IDs and potential new IDs.
Set<IgniteUuid> lockIds = new TreeSet<>(PATH_ID_SORTING_COMPARATOR);
pathIds.addExistingIds(lockIds, relaxed);
pathIds.addSurrogateIds(lockIds);
// Start TX.
try (GridNearTxLocal tx = startTx()) {
final Map<IgniteUuid, IgfsEntryInfo> lockInfos = lockIds(lockIds);
if (!pathIds.verifyIntegrity(lockInfos, relaxed))
// Directory structure changed concurrently. So we simply re-try.
continue;
// Check if the whole structure is already in place.
if (pathIds.allExists()) {
if (lockInfos.get(pathIds.lastExistingId()).isDirectory())
return false;
else
throw new IgfsParentNotDirectoryException("Failed to create directory (parent " + "element is not a directory)");
}
IgfsPathsCreateResult res = createDirectory(pathIds, lockInfos, props);
if (res == null)
continue;
// Commit TX.
tx.commit();
generateCreateEvents(res.createdPaths(), false);
// We are done.
return true;
}
} finally {
busyLock.leaveBusy();
}
} else
throw new IllegalStateException("Failed to mkdir because Grid is stopping. [path=" + path + ']');
}
}
Aggregations