/** * Ensures that the provided virtual space is mounted (at least one VFS file system is mounted) * * @param spaceURI uri of the virtual space * @param info dataspace info * @throws SpaceNotFoundException * @throws FileSystemException */ private void ensureVirtualSpaceIsMounted(final DataSpacesURI spaceURI, SpaceInstanceInfo info) throws SpaceNotFoundException, FileSystemException { final boolean mounted; DataSpacesURI spacePart = spaceURI.getSpacePartOnly(); try { readLock.lock(); mounted = mountedSpaces.containsKey(spacePart); } finally { readLock.unlock(); } if (!mounted) { if (info == null) { info = directory.lookupOne(spaceURI); } if (info == null) { logger.warn( "[VFSMountManager] Could not find data space in spaces directory: " + spacePart); throw new SpaceNotFoundException( "Requested data space is not registered in spaces directory."); } try { readLock.lock(); if (mountedSpaces.containsKey(spacePart) && (mountedSpaces.get(spacePart).size() > 0)) return; } finally { readLock.unlock(); } mountFirstAvailableFileSystem(info); } }
/** * Unmount all file systems for the given dataspace * * @param spaceUri dataspace uri */ private void unmountAllFileSystems(final DataSpacesURI spaceUri) { DataSpacesURI spacePart = spaceUri.getSpacePartOnly(); final ConcurrentHashMap<String, FileObject> spaceRoots = mountedSpaces.remove(spacePart); VFSMountManagerHelper.closeFileSystems(spaceRoots.keySet()); }
/** * resolves the given virtual uri into a DataSpaceFileObject. The VFS root is forced to the * spaceRootFOUri parameter. Mount the space if necessary * * @param queryUri Data Spaces URI to get access to * @param ownerActiveObjectId Id of active object requesting this file, that will become owner of * returned {@link DataSpacesFileObject} instance. May be <code>null</code>, which corresponds * to anonymous (unimportant) owner. * @param spaceRootFOUri forces the use of the provided VFS space root (in case there are several * roots) * @return * @throws FileSystemException * @throws SpaceNotFoundException */ public DataSpacesFileObject resolveFile( final DataSpacesURI queryUri, final String ownerActiveObjectId, String spaceRootFOUri) throws FileSystemException, SpaceNotFoundException { if (logger.isDebugEnabled()) logger.debug("[VFSMountManager] File access request: " + queryUri); if (!queryUri.isSuitableForUserPath()) { logger.error( "[VFSMountManager] Requested URI " + queryUri + " is not suitable for user path"); throw new IllegalArgumentException( "Requested URI " + queryUri + " is not suitable for user path"); } final DataSpacesURI spaceURI = queryUri.getSpacePartOnly(); ensureVirtualSpaceIsMounted(spaceURI, null); return doResolveFile(queryUri, ownerActiveObjectId, spaceRootFOUri); }
/** * Makes sure that the provided file system is mounted for the given dataspace (identified by its * root url) * * @param mountingPoint dataspace uri * @param spaceRootFOUri file system root * @return true if the file system is mounted * @throws FileSystemException */ private boolean ensureFileSystemIsMounted( final DataSpacesURI mountingPoint, final String spaceRootFOUri) throws FileSystemException { ConcurrentHashMap<String, FileObject> fileSystems = null; DataSpacesURI spacePart = mountingPoint.getSpacePartOnly(); try { readLock.lock(); fileSystems = mountedSpaces.get(spacePart); // already mounted if (fileSystems.get(spaceRootFOUri) != null) { return true; } } finally { readLock.unlock(); } logger.debug("[VFSMountManager] Request mounting VFS root = " + spaceRootFOUri); FileObject mountedRoot; try { mountedRoot = VFSMountManagerHelper.mount(spaceRootFOUri); // the fs is accessible try { writeLock.lock(); fileSystems.put(spaceRootFOUri, mountedRoot); mountedSpaces.put(spacePart, fileSystems); } finally { writeLock.unlock(); } if (logger.isDebugEnabled()) logger.debug( String.format( "[VFSMountManager] Mounted space: %s (access URL: %s)", spacePart, spaceRootFOUri)); return true; } catch (org.apache.commons.vfs.FileSystemException x) { String err = String.format( "[VFSMountManager] Could not access URL %s to mount %s", spaceRootFOUri, spacePart); logger.info(err); removeSpaceRootUri(spacePart, spaceRootFOUri); throw new FileSystemException(err, x); } }
/** * Internal method for resolving a file, will mount the file system if it is not mounted yet * * @param uri virtual uri of the file * @param ownerActiveObjectId Id of active object requesting this file * @param spaceRootFOUri root file system to use * @return * @throws FileSystemException */ private DataSpacesFileObject doResolveFile( final DataSpacesURI uri, final String ownerActiveObjectId, String spaceRootFOUri) throws FileSystemException { DataSpacesURI spacePart = uri.getSpacePartOnly(); if (spaceRootFOUri != null) { ensureFileSystemIsMounted(spacePart, spaceRootFOUri); } else { try { readLock.lock(); LinkedHashSet<String> los = accessibleFileObjectUris.get(spacePart); spaceRootFOUri = los.iterator().next(); } finally { readLock.unlock(); } ensureFileSystemIsMounted(spacePart, spaceRootFOUri); } final String relativeToSpace = uri.getRelativeToSpace(); try { readLock.lock(); if (!mountedSpaces.containsKey(spacePart)) { throw new FileSystemException("Could not access file that should exist (be mounted)"); } final ConcurrentHashMap<String, FileObject> spaceRoots = mountedSpaces.get(spacePart); FileObject spaceRoot = spaceRoots.get(spaceRootFOUri); FileName dataSpaceVFSFileName = null; final FileObject file; // the dataspace "File name" (it is actually a File Path) is computed using the Virtual Space // root if (dataSpaceVFSFileName == null) { dataSpaceVFSFileName = spaceRoot.getName(); } try { if (relativeToSpace == null) file = spaceRoot; else file = spaceRoot.resolveFile(relativeToSpace); final DataSpacesLimitingFileObject limitingFile = new DataSpacesLimitingFileObject( file, spacePart, spaceRoot.getName(), ownerActiveObjectId); return new VFSFileObjectAdapter( limitingFile, spacePart, dataSpaceVFSFileName, new ArrayList<String>(accessibleFileObjectUris.get(spacePart)), spaceRootFOUri, this, ownerActiveObjectId); } catch (org.apache.commons.vfs.FileSystemException x) { logger.error("[VFSMountManager] Could not access file within a space: " + uri); throw new FileSystemException(x); } catch (FileSystemException e) { ProActiveLogger.logImpossibleException(logger, e); throw new ProActiveRuntimeException(e); } } finally { readLock.unlock(); } }
/** * Mounts the first available VFS file system on the given dataspace * * @param spaceInfo space information * @throws FileSystemException if no file system could be mounted */ private void mountFirstAvailableFileSystem(final SpaceInstanceInfo spaceInfo) throws FileSystemException { final DataSpacesURI mountingPoint = spaceInfo.getMountingPoint(); try { writeLock.lock(); if (!mountedSpaces.containsKey(mountingPoint)) { mountedSpaces.put(mountingPoint, new ConcurrentHashMap<String, FileObject>()); } ConcurrentHashMap<String, FileObject> fileSystems = mountedSpaces.get(mountingPoint); if (spaceInfo.getUrls().size() == 0) { throw new IllegalStateException("Empty Space configuration"); } DataSpacesURI spacePart = mountingPoint.getSpacePartOnly(); ArrayList<String> urls = new ArrayList<String>(spaceInfo.getUrls()); if (urls.size() == 1) { urls.add( 0, Utils.getLocalAccessURL(urls.get(0), spaceInfo.getPath(), spaceInfo.getHostname())); } logger.debug("[VFSMountManager] Request mounting VFS root list : " + urls); try { VFSMountManagerHelper.mountAny(urls, fileSystems); if (!accessibleFileObjectUris.containsKey(mountingPoint)) { LinkedHashSet<String> srl = new LinkedHashSet<String>(); accessibleFileObjectUris.put(mountingPoint, srl); } LinkedHashSet<String> srl = accessibleFileObjectUris.get(mountingPoint); for (String uri : urls) { if (fileSystems.containsKey(uri)) { srl.add(uri); } } if (srl.isEmpty()) { throw new IllegalStateException( "Invalid empty size list when trying to mount " + urls + " mounted map content is " + fileSystems); } accessibleFileObjectUris.put(mountingPoint, srl); if (logger.isDebugEnabled()) logger.debug( String.format( "[VFSMountManager] Mounted space: %s (access URL: %s)", spacePart, srl)); mountedSpaces.put(mountingPoint, fileSystems); } catch (org.apache.commons.vfs.FileSystemException e) { mountedSpaces.remove(mountingPoint); throw new FileSystemException( "An error occurred while trying to mount " + spaceInfo.getName(), e); } } finally { writeLock.unlock(); } }