use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class InodeTree method lockFullInodePath.
/**
* Locks existing inodes on the path to the inode specified by an id, in the specified
* {@link LockMode}. The target inode must exist. This may require multiple traversals of the
* tree, so may be inefficient.
*
* @param id the inode id
* @param lockMode the {@link LockMode} to lock the inodes with
* @return the {@link LockedInodePath} representing the locked path of inodes
* @throws FileDoesNotExistException if the target inode does not exist
*/
public LockedInodePath lockFullInodePath(long id, LockMode lockMode) throws FileDoesNotExistException {
int count = 0;
while (true) {
Inode<?> inode = mInodes.getFirst(id);
if (inode == null) {
throw new FileDoesNotExistException(ExceptionMessage.INODE_DOES_NOT_EXIST.getMessage(id));
}
// Compute the path given the target inode.
StringBuilder builder = new StringBuilder();
computePathForInode(inode, builder);
AlluxioURI uri = new AlluxioURI(builder.toString());
boolean valid = false;
LockedInodePath inodePath = null;
try {
inodePath = lockFullInodePath(uri, lockMode);
if (inodePath.getInode().getId() == id) {
// Set to true, so the path is not unlocked before returning.
valid = true;
return inodePath;
}
// The path does not end up at the target inode id. Repeat the traversal.
} catch (InvalidPathException e) {
// ignore and repeat the loop
LOG.warn("Inode lookup id {} computed path {} mismatch id. Repeating.", id, uri);
} finally {
if (!valid && inodePath != null) {
inodePath.close();
}
}
count++;
if (count > PATH_TRAVERSAL_RETRIES) {
throw new FileDoesNotExistException(ExceptionMessage.INODE_DOES_NOT_EXIST_RETRIES.getMessage(id));
}
}
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class InodeTree method createPath.
/**
* Creates a file or directory at path.
*
* @param inodePath the path
* @param options method options
* @return a {@link CreatePathResult} representing the modified inodes and created inodes during
* path creation
* @throws FileAlreadyExistsException when there is already a file at path if we want to create a
* directory there
* @throws BlockInfoException when blockSizeBytes is invalid
* @throws InvalidPathException when path is invalid, for example, (1) when there is nonexistent
* necessary parent directories and recursive is false, (2) when one of the necessary
* parent directories is actually a file
* @throws IOException if creating the path fails
* @throws FileDoesNotExistException if the parent of the path does not exist and the recursive
* option is false
*/
public CreatePathResult createPath(LockedInodePath inodePath, CreatePathOptions<?> options) throws FileAlreadyExistsException, BlockInfoException, InvalidPathException, IOException, FileDoesNotExistException {
AlluxioURI path = inodePath.getUri();
if (path.isRoot()) {
String errorMessage = ExceptionMessage.FILE_ALREADY_EXISTS.getMessage(path);
LOG.error(errorMessage);
throw new FileAlreadyExistsException(errorMessage);
}
if (options instanceof CreateFileOptions) {
CreateFileOptions fileOptions = (CreateFileOptions) options;
if (fileOptions.getBlockSizeBytes() < 1) {
throw new BlockInfoException("Invalid block size " + fileOptions.getBlockSizeBytes());
}
}
if (!(inodePath instanceof MutableLockedInodePath)) {
throw new InvalidPathException(ExceptionMessage.NOT_MUTABLE_INODE_PATH.getMessage(inodePath.getUri()));
}
LOG.debug("createPath {}", path);
TraversalResult traversalResult = traverseToInode(inodePath, LockMode.WRITE_PARENT);
InodeLockList lockList = traversalResult.getInodeLockList();
MutableLockedInodePath extensibleInodePath = (MutableLockedInodePath) inodePath;
String[] pathComponents = extensibleInodePath.getPathComponents();
String name = path.getName();
// pathIndex is the index into pathComponents where we start filling in the path from the inode.
int pathIndex = extensibleInodePath.getInodes().size();
if (pathIndex < pathComponents.length - 1) {
// Otherwise we add the remaining path components to the list of components to create.
if (!options.isRecursive()) {
final String msg = new StringBuilder().append("File ").append(path).append(" creation failed. Component ").append(pathIndex).append("(").append(pathComponents[pathIndex]).append(") does not exist").toString();
LOG.error("FileDoesNotExistException: {}", msg);
throw new FileDoesNotExistException(msg);
}
}
// The ancestor inode (parent or ancestor) of the target path.
Inode<?> ancestorInode = extensibleInodePath.getAncestorInode();
if (!ancestorInode.isDirectory()) {
throw new InvalidPathException("Could not traverse to parent directory of path " + path + ". Component " + pathComponents[pathIndex - 1] + " is not a directory.");
}
InodeDirectory currentInodeDirectory = (InodeDirectory) ancestorInode;
List<Inode<?>> createdInodes = new ArrayList<>();
List<Inode<?>> modifiedInodes = new ArrayList<>();
// These are inodes that already exist, that should be journaled as persisted.
List<Inode<?>> existingNonPersisted = new ArrayList<>();
// These are inodes to mark as persisted at the end of this method.
List<Inode<?>> toPersistDirectories = new ArrayList<>();
if (options.isPersisted()) {
// Directory persistence will not happen until the end of this method.
toPersistDirectories.addAll(traversalResult.getNonPersisted());
existingNonPersisted.addAll(traversalResult.getNonPersisted());
}
if (pathIndex < (pathComponents.length - 1) || currentInodeDirectory.getChild(name) == null) {
// (1) There are components in parent paths that need to be created. Or
// (2) The last component of the path needs to be created.
// In these two cases, the last traversed Inode will be modified.
modifiedInodes.add(currentInodeDirectory);
}
// TODO(gpang): We may not have to lock the newly created inodes if the last inode is write
// locked. This could improve performance. Further investigation is needed.
// Fill in the ancestor directories that were missing.
// NOTE, we set the mode of missing ancestor directories to be the default value, rather
// than inheriting the option of the final file to create, because it may not have
// "execute" permission.
CreateDirectoryOptions missingDirOptions = CreateDirectoryOptions.defaults().setMountPoint(false).setPersisted(options.isPersisted()).setOwner(options.getOwner()).setGroup(options.getGroup());
for (int k = pathIndex; k < (pathComponents.length - 1); k++) {
InodeDirectory dir = InodeDirectory.create(mDirectoryIdGenerator.getNewDirectoryId(), currentInodeDirectory.getId(), pathComponents[k], missingDirOptions);
// Lock the newly created inode before subsequent operations, and add it to the lock group.
lockList.lockWriteAndCheckNameAndParent(dir, currentInodeDirectory, pathComponents[k]);
dir.setPinned(currentInodeDirectory.isPinned());
currentInodeDirectory.addChild(dir);
currentInodeDirectory.setLastModificationTimeMs(options.getOperationTimeMs());
if (options.isPersisted()) {
toPersistDirectories.add(dir);
}
createdInodes.add(dir);
mInodes.add(dir);
currentInodeDirectory = dir;
}
// Create the final path component. First we need to make sure that there isn't already a file
// here with that name. If there is an existing file that is a directory and we're creating a
// directory, update persistence property of the directories if needed, otherwise, throw
// FileAlreadyExistsException unless options.allowExists is true.
Inode<?> lastInode = currentInodeDirectory.getChild(name);
if (lastInode != null) {
// Lock the last inode before subsequent operations, and add it to the lock group.
lockList.lockWriteAndCheckNameAndParent(lastInode, currentInodeDirectory, name);
if (lastInode.isDirectory() && options instanceof CreateDirectoryOptions && !lastInode.isPersisted() && options.isPersisted()) {
// The final path component already exists and is not persisted, so it should be added
// to the non-persisted Inodes of traversalResult.
existingNonPersisted.add(lastInode);
toPersistDirectories.add(lastInode);
} else if (!lastInode.isDirectory() || !(options instanceof CreateDirectoryOptions && ((CreateDirectoryOptions) options).isAllowExists())) {
String errorMessage = ExceptionMessage.FILE_ALREADY_EXISTS.getMessage(path);
LOG.error(errorMessage);
throw new FileAlreadyExistsException(errorMessage);
}
} else {
if (options instanceof CreateDirectoryOptions) {
CreateDirectoryOptions directoryOptions = (CreateDirectoryOptions) options;
lastInode = InodeDirectory.create(mDirectoryIdGenerator.getNewDirectoryId(), currentInodeDirectory.getId(), name, directoryOptions);
// Lock the created inode before subsequent operations, and add it to the lock group.
lockList.lockWriteAndCheckNameAndParent(lastInode, currentInodeDirectory, name);
if (directoryOptions.isPersisted()) {
toPersistDirectories.add(lastInode);
}
lastInode.setPinned(currentInodeDirectory.isPinned());
} else if (options instanceof CreateFileOptions) {
CreateFileOptions fileOptions = (CreateFileOptions) options;
lastInode = InodeFile.create(mContainerIdGenerator.getNewContainerId(), currentInodeDirectory.getId(), name, System.currentTimeMillis(), fileOptions);
// Lock the created inode before subsequent operations, and add it to the lock group.
lockList.lockWriteAndCheckNameAndParent(lastInode, currentInodeDirectory, name);
if (currentInodeDirectory.isPinned()) {
// Update set of pinned file ids.
mPinnedInodeFileIds.add(lastInode.getId());
}
lastInode.setPinned(currentInodeDirectory.isPinned());
}
createdInodes.add(lastInode);
mInodes.add(lastInode);
currentInodeDirectory.addChild(lastInode);
currentInodeDirectory.setLastModificationTimeMs(options.getOperationTimeMs());
}
// we mark it as persisted.
for (Inode<?> inode : toPersistDirectories) {
MountTable.Resolution resolution = mMountTable.resolve(getPath(inode));
String ufsUri = resolution.getUri().toString();
UnderFileSystem ufs = resolution.getUfs();
MkdirsOptions mkdirsOptions = MkdirsOptions.defaults().setCreateParent(false).setOwner(inode.getOwner()).setGroup(inode.getGroup()).setMode(new Mode(inode.getMode()));
if (ufs.isDirectory(ufsUri) || ufs.mkdirs(ufsUri, mkdirsOptions)) {
inode.setPersistenceState(PersistenceState.PERSISTED);
}
}
// Extend the inodePath with the created inodes.
extensibleInodePath.getInodes().addAll(createdInodes);
LOG.debug("createFile: File Created: {} parent: {}", lastInode, currentInodeDirectory);
return new CreatePathResult(modifiedInodes, createdInodes, existingNonPersisted);
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class WebInterfaceBrowseServlet method doGet.
/**
* Populates attribute fields with data from the MasterInfo associated with this servlet. Errors
* will be displayed in an error field. Debugging can be enabled to display additional data. Will
* eventually redirect the request to a jsp.
*
* @param request the {@link HttpServletRequest} object
* @param response the {@link HttpServletResponse} object
* @throws ServletException if the target resource throws this exception
* @throws IOException if the target resource throws this exception
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (SecurityUtils.isSecurityEnabled() && AuthenticatedClientUser.get() == null) {
AuthenticatedClientUser.set(LoginUser.get().getName());
}
request.setAttribute("debug", Configuration.getBoolean(PropertyKey.DEBUG));
request.setAttribute("showPermissions", Configuration.getBoolean(PropertyKey.SECURITY_AUTHORIZATION_PERMISSION_ENABLED));
request.setAttribute("masterNodeAddress", mMaster.getRpcAddress().toString());
request.setAttribute("invalidPathError", "");
List<FileInfo> filesInfo;
String requestPath = request.getParameter("path");
if (requestPath == null || requestPath.isEmpty()) {
requestPath = AlluxioURI.SEPARATOR;
}
AlluxioURI currentPath = new AlluxioURI(requestPath);
request.setAttribute("currentPath", currentPath.toString());
request.setAttribute("viewingOffset", 0);
try {
long fileId = mMaster.getFileSystemMaster().getFileId(currentPath);
FileInfo fileInfo = mMaster.getFileSystemMaster().getFileInfo(fileId);
UIFileInfo currentFileInfo = new UIFileInfo(fileInfo);
if (currentFileInfo.getAbsolutePath() == null) {
throw new FileDoesNotExistException(currentPath.toString());
}
request.setAttribute("currentDirectory", currentFileInfo);
request.setAttribute("blockSizeBytes", currentFileInfo.getBlockSizeBytes());
if (!currentFileInfo.getIsDirectory()) {
String offsetParam = request.getParameter("offset");
long relativeOffset = 0;
long offset;
try {
if (offsetParam != null) {
relativeOffset = Long.parseLong(offsetParam);
}
} catch (NumberFormatException e) {
relativeOffset = 0;
}
String endParam = request.getParameter("end");
// relative to the end of the file.
if (endParam == null) {
offset = relativeOffset;
} else {
offset = fileInfo.getLength() - relativeOffset;
}
if (offset < 0) {
offset = 0;
} else if (offset > fileInfo.getLength()) {
offset = fileInfo.getLength();
}
try {
displayFile(new AlluxioURI(currentFileInfo.getAbsolutePath()), request, offset);
} catch (AlluxioException e) {
throw new IOException(e);
}
request.setAttribute("viewingOffset", offset);
getServletContext().getRequestDispatcher("/viewFile.jsp").forward(request, response);
return;
}
setPathDirectories(currentPath, request);
filesInfo = mMaster.getFileSystemMaster().listStatus(currentPath, ListStatusOptions.defaults().setLoadMetadataType(LoadMetadataType.Always));
} catch (FileDoesNotExistException e) {
request.setAttribute("invalidPathError", "Error: Invalid Path " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
} catch (InvalidPathException e) {
request.setAttribute("invalidPathError", "Error: Invalid Path " + e.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
} catch (IOException e) {
request.setAttribute("invalidPathError", "Error: File " + currentPath + " is not available " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
} catch (AccessControlException e) {
request.setAttribute("invalidPathError", "Error: File " + currentPath + " cannot be accessed " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
}
List<UIFileInfo> fileInfos = new ArrayList<>(filesInfo.size());
for (FileInfo fileInfo : filesInfo) {
UIFileInfo toAdd = new UIFileInfo(fileInfo);
try {
if (!toAdd.getIsDirectory() && fileInfo.getLength() > 0) {
FileBlockInfo blockInfo = mMaster.getFileSystemMaster().getFileBlockInfoList(new AlluxioURI(toAdd.getAbsolutePath())).get(0);
List<String> locations = new ArrayList<>();
// add the in-memory block locations
for (BlockLocation location : blockInfo.getBlockInfo().getLocations()) {
WorkerNetAddress address = location.getWorkerAddress();
locations.add(address.getHost() + ":" + address.getDataPort());
}
// add underFS locations
locations.addAll(blockInfo.getUfsLocations());
toAdd.setFileLocations(locations);
}
} catch (FileDoesNotExistException e) {
request.setAttribute("FileDoesNotExistException", "Error: non-existing file " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
} catch (InvalidPathException e) {
request.setAttribute("InvalidPathException", "Error: invalid path " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
} catch (AccessControlException e) {
request.setAttribute("AccessControlException", "Error: File " + currentPath + " cannot be accessed " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
}
fileInfos.add(toAdd);
}
Collections.sort(fileInfos, UIFileInfo.PATH_STRING_COMPARE);
request.setAttribute("nTotalFile", fileInfos.size());
// URL can not determine offset and limit, let javascript in jsp determine and redirect
if (request.getParameter("offset") == null && request.getParameter("limit") == null) {
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
}
try {
int offset = Integer.parseInt(request.getParameter("offset"));
int limit = Integer.parseInt(request.getParameter("limit"));
List<UIFileInfo> sub = fileInfos.subList(offset, offset + limit);
request.setAttribute("fileInfos", sub);
} catch (NumberFormatException e) {
request.setAttribute("fatalError", "Error: offset or limit parse error, " + e.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
} catch (IndexOutOfBoundsException e) {
request.setAttribute("fatalError", "Error: offset or offset + limit is out of bound, " + e.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
} catch (IllegalArgumentException e) {
request.setAttribute("fatalError", e.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
return;
}
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class WebInterfaceDownloadServlet method doGet.
/**
* Prepares for downloading a file.
*
* @param request the {@link HttpServletRequest} object
* @param response the {@link HttpServletResponse} object
* @throws ServletException if the target resource throws this exception
* @throws IOException if the target resource throws this exception
*/
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (SecurityUtils.isSecurityEnabled() && AuthenticatedClientUser.get() == null) {
AuthenticatedClientUser.set(LoginUser.get().getName());
}
String requestPath = request.getParameter("path");
if (requestPath == null || requestPath.isEmpty()) {
requestPath = AlluxioURI.SEPARATOR;
}
AlluxioURI currentPath = new AlluxioURI(requestPath);
try {
long fileId = mFsMaster.getFileId(currentPath);
FileInfo fileInfo = mFsMaster.getFileInfo(fileId);
if (fileInfo == null) {
throw new FileDoesNotExistException(currentPath.toString());
}
downloadFile(new AlluxioURI(fileInfo.getPath()), request, response);
} catch (FileDoesNotExistException e) {
request.setAttribute("invalidPathError", "Error: Invalid Path " + e.getMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
} catch (InvalidPathException e) {
request.setAttribute("invalidPathError", "Error: Invalid Path " + e.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
} catch (AlluxioException e) {
request.setAttribute("invalidPathError", "Error: " + e.getLocalizedMessage());
getServletContext().getRequestDispatcher("/browse.jsp").forward(request, response);
}
}
use of alluxio.exception.InvalidPathException in project alluxio by Alluxio.
the class FileSystemMaster method mountAndJournal.
/**
* Mounts a UFS path onto an Alluxio path.
* <p>
* Writes to the journal.
*
* @param inodePath the Alluxio path to mount to
* @param ufsPath the UFS path to mount
* @param options the mount options
* @param journalContext the journal context
* @throws InvalidPathException if an invalid path is encountered
* @throws FileAlreadyExistsException if the path to be mounted to already exists
* @throws FileDoesNotExistException if the parent of the path to be mounted to does not exist
* @throws IOException if an I/O error occurs
* @throws AccessControlException if the permission check fails
*/
private void mountAndJournal(LockedInodePath inodePath, AlluxioURI ufsPath, MountOptions options, JournalContext journalContext) throws InvalidPathException, FileAlreadyExistsException, FileDoesNotExistException, IOException, AccessControlException {
// Check that the Alluxio Path does not exist
if (inodePath.fullPathExists()) {
// TODO(calvin): Add a test to validate this (ALLUXIO-1831)
throw new InvalidPathException(ExceptionMessage.MOUNT_POINT_ALREADY_EXISTS.getMessage(inodePath.getUri()));
}
mountInternal(inodePath, ufsPath, false, /* not replayed */
options);
boolean loadMetadataSucceeded = false;
try {
// This will create the directory at alluxioPath
loadDirectoryMetadataAndJournal(inodePath, LoadMetadataOptions.defaults().setCreateAncestors(false), journalContext);
loadMetadataSucceeded = true;
} finally {
if (!loadMetadataSucceeded) {
unmountInternal(inodePath.getUri());
}
}
// For proto, build a list of String pairs representing the properties map.
Map<String, String> properties = options.getProperties();
List<StringPairEntry> protoProperties = new ArrayList<>(properties.size());
for (Map.Entry<String, String> entry : properties.entrySet()) {
protoProperties.add(StringPairEntry.newBuilder().setKey(entry.getKey()).setValue(entry.getValue()).build());
}
AddMountPointEntry addMountPoint = AddMountPointEntry.newBuilder().setAlluxioPath(inodePath.getUri().toString()).setUfsPath(ufsPath.toString()).setReadOnly(options.isReadOnly()).addAllProperties(protoProperties).setShared(options.isShared()).build();
appendJournalEntry(JournalEntry.newBuilder().setAddMountPoint(addMountPoint).build(), journalContext);
}
Aggregations