Search in sources :

Example 6 with FsPath

use of diskCacheV111.util.FsPath in project dcache by dCache.

the class XrootdDoor method listPath.

/**
 * List the contents of a path, usually a directory. In order to make fragmented responses, as
 * supported by the xroot protocol, possible and not block the processing thread in the door,
 * this will register the passed callback along with the UUID of the message that is sent to
 * PNFS-manager.
 * <p>
 * Once PNFS-manager replies to the message, that callback is retrieved and the response is
 * processed by the callback.
 *
 * @param path        The path that is listed
 * @param restriction The Restriction in effect
 * @param subject     Representation of user that request listing
 * @param callback    The callback that will process the response
 */
public void listPath(FsPath path, Subject subject, Restriction restriction, MessageCallback<PnfsListDirectoryMessage> callback, EnumSet<FileAttribute> attributes) {
    PnfsHandler pnfsHandler = new PnfsHandler(_pnfs, subject, restriction);
    PnfsListDirectoryMessage msg = new PnfsListDirectoryMessage(path.toString(), null, Range.<Integer>all(), attributes);
    UUID uuid = msg.getUUID();
    try {
        DirlistRequestHandler requestHandler = new DirlistRequestHandler(uuid, pnfsHandler.getPnfsTimeout(), callback);
        _requestHandlers.put(uuid, requestHandler);
        pnfsHandler.send(msg);
        requestHandler.resetTimeout();
    } catch (RejectedExecutionException ree) {
        _requestHandlers.remove(uuid);
        callback.failure(CacheException.UNEXPECTED_SYSTEM_EXCEPTION, ree.getMessage());
    }
}
Also used : PnfsListDirectoryMessage(org.dcache.vehicles.PnfsListDirectoryMessage) PnfsHandler(diskCacheV111.util.PnfsHandler) UUID(java.util.UUID) RejectedExecutionException(java.util.concurrent.RejectedExecutionException)

Example 7 with FsPath

use of diskCacheV111.util.FsPath in project dcache by dCache.

the class XrootdDoor method write.

public XrootdTransfer write(InetSocketAddress client, FsPath path, Set<String> tried, String ioQueue, UUID uuid, boolean createDir, boolean overwrite, Long size, OptionalLong maxUploadSize, InetSocketAddress local, Subject subject, Restriction restriction, boolean persistOnSuccessfulClose, FsPath rootPath, Serializable delegatedProxy, Map<String, String> opaque) throws CacheException, InterruptedException, ParseException {
    if (!isWriteAllowed(path)) {
        throw new PermissionDeniedCacheException("Write permission denied");
    }
    FsPath transferPath = persistOnSuccessfulClose ? getUploadPath(subject, restriction, createDir, overwrite, size, path, rootPath) : path;
    XrootdTransfer transfer = createTransfer(client, transferPath, tried, ioQueue, uuid, local, subject, restriction, opaque);
    transfer.setOverwriteAllowed(overwrite);
    /*
         *  If this is a destination door/server and the session
         *  does not contain a proxy, eventually fail downstream.
         */
    transfer.setDelegatedCredential(delegatedProxy);
    int handle = transfer.getFileHandle();
    InetSocketAddress address = null;
    _transfers.put(handle, transfer);
    String explanation = "problem within door";
    try {
        try {
            if (createDir) {
                transfer.createNameSpaceEntryWithParents();
            } else {
                transfer.createNameSpaceEntry();
            }
        } catch (FileExistsCacheException e) {
            transfer.readNameSpaceEntry(true);
            if (transfer.getFileAttributes().getStorageInfo().isCreatedOnly()) {
                transfer.setOverwriteAllowed(true);
                transfer.createNameSpaceEntry();
            } else {
                throw e;
            }
        }
        maxUploadSize.ifPresent(transfer::setMaximumLength);
        if (size != null) {
            checkResourceNotMissing(!maxUploadSize.isPresent() || size <= maxUploadSize.getAsLong(), "File exceeds maximum upload size");
            transfer.setLength(size);
        }
        try {
            transfer.selectPoolAndStartMover(RETRY_POLICY);
            address = transfer.waitForRedirect(_moverTimeout, _moverTimeoutUnit);
            if (address == null) {
                throw new CacheException(transfer.getPool() + " failed to open TCP socket");
            }
            transfer.setStatus("Mover " + transfer.getPool() + "/" + transfer.getMoverId() + ": Receiving");
        } finally {
            if (address == null) {
                transfer.deleteNameSpaceEntry();
            }
        }
    } catch (CacheException e) {
        explanation = e.getMessage();
        transfer.notifyBilling(e.getRc(), e.getMessage());
        throw e;
    } catch (InterruptedException e) {
        explanation = "transfer interrupted";
        transfer.notifyBilling(CacheException.UNEXPECTED_SYSTEM_EXCEPTION, "Transfer interrupted");
        throw e;
    } catch (RuntimeException e) {
        explanation = "bug found: " + e.toString();
        transfer.notifyBilling(CacheException.UNEXPECTED_SYSTEM_EXCEPTION, e.toString());
        throw e;
    } finally {
        if (address == null) {
            transfer.killMover(0, "killed by door: " + explanation);
            _transfers.remove(handle);
        }
    }
    return transfer;
}
Also used : PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) FileExistsCacheException(diskCacheV111.util.FileExistsCacheException) CacheException(diskCacheV111.util.CacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) InetSocketAddress(java.net.InetSocketAddress) FileExistsCacheException(diskCacheV111.util.FileExistsCacheException) FsPath(diskCacheV111.util.FsPath)

Example 8 with FsPath

use of diskCacheV111.util.FsPath in project dcache by dCache.

the class XrootdDoor method getMultipleFileStatuses.

public int[] getMultipleFileStatuses(FsPath[] allPaths, Subject subject, Restriction restriction) throws CacheException {
    PnfsHandler pnfsHandler = new PnfsHandler(_pnfs, subject, restriction);
    int[] flags = new int[allPaths.length];
    // TODO: Use SpreadAndWait
    for (int i = 0; i < allPaths.length; i++) {
        try {
            Set<FileAttribute> requestedAttributes = EnumSet.of(TYPE);
            requestedAttributes.addAll(_pdp.getRequiredAttributes());
            FileAttributes attributes = pnfsHandler.getFileAttributes(allPaths[i].toString(), requestedAttributes);
            flags[i] = getFileStatusFlags(subject, restriction, allPaths[i], attributes);
        } catch (CacheException e) {
            if (e.getRc() != CacheException.FILE_NOT_FOUND) {
                throw e;
            }
            flags[i] = kXR_other;
        }
    }
    return flags;
}
Also used : FileExistsCacheException(diskCacheV111.util.FileExistsCacheException) CacheException(diskCacheV111.util.CacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) PnfsHandler(diskCacheV111.util.PnfsHandler) FileAttributes(org.dcache.vehicles.FileAttributes) FileAttribute(org.dcache.namespace.FileAttribute)

Example 9 with FsPath

use of diskCacheV111.util.FsPath in project dcache by dCache.

the class XrootdDoor method getUploadPath.

private FsPath getUploadPath(Subject subject, Restriction restriction, boolean createDir, boolean overwrite, Long size, FsPath path, FsPath rootPath) throws CacheException, InterruptedException {
    try {
        EnumSet<CreateOption> options = EnumSet.noneOf(CreateOption.class);
        if (overwrite) {
            options.add(CreateOption.OVERWRITE_EXISTING);
        }
        if (createDir) {
            options.add(CreateOption.CREATE_PARENTS);
        }
        PnfsCreateUploadPath msg = new PnfsCreateUploadPath(subject, restriction, path, rootPath, size, null, null, null, options);
        msg = _pnfsStub.sendAndWait(msg);
        return msg.getUploadPath();
    } catch (NoRouteToCellException ex) {
        throw new CacheException("Internal communication failure", ex);
    }
}
Also used : PnfsCreateUploadPath(diskCacheV111.vehicles.PnfsCreateUploadPath) FileExistsCacheException(diskCacheV111.util.FileExistsCacheException) CacheException(diskCacheV111.util.CacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) NoRouteToCellException(dmg.cells.nucleus.NoRouteToCellException) CreateOption(org.dcache.namespace.CreateOption)

Example 10 with FsPath

use of diskCacheV111.util.FsPath in project dcache by dCache.

the class XrootdRedirectHandler method conditionallyHandleThirdPartyRequest.

/**
 * <p>Special handling of third-party requests. Distinguishes among
 * several different cases for the open and either returns a response directly to the caller or
 * proceeds with the usual mover open and redirect to the pool by returning <code>null</code>.
 * Also verifies the rendezvous information in the case of the destination server contacting
 * dCache as source.</p>
 *
 * <p>With the modified TPC lite (delegation) protocol, there is no
 * need to wait for the rendezvous destination check by comparing the open from the source.</p>
 *
 * <p>There is also the case where no delegated proxy exists but
 * a different authentication protocol (like ZTN/scitokens) is being used.  It seems that even
 * with delegation in this case the initiating client does not call open. A check for authz in
 * the opaque data has been added (03/21/2021).</p>
 */
private XrootdResponse<OpenRequest> conditionallyHandleThirdPartyRequest(OpenRequest req, LoginSessionInfo loginSessionInfo, Map<String, String> opaque, FsPath fsPath, String remoteHost) throws CacheException, XrootdException, ParseException {
    if (!_door.isReadAllowed(fsPath)) {
        throw new PermissionDeniedCacheException("Read permission denied");
    }
    Subject subject = loginSessionInfo.getSubject();
    Restriction restriction = loginSessionInfo.getRestriction();
    if ("placement".equals(opaque.get("tpc.stage"))) {
        FileStatus status = _door.getFileStatus(fsPath, subject, restriction, remoteHost);
        int fd = _door.nextTpcPlaceholder();
        _log.debug("placement response to {} sent to {} with fhandle {}.", req, remoteHost, fd);
        return new OpenResponse(req, fd, null, null, status);
    }
    String tpcKey = opaque.get("tpc.key");
    if (tpcKey == null) {
        _log.debug("{} –– not a third-party request.", req);
        // proceed as usual with mover + redirect
        return null;
    }
    if (opaque.containsKey(Cgi.AUTHZ.key())) {
        _log.debug("{} –– request contains authorization token.", req);
        // proceed as usual with mover + redirect
        return null;
    }
    enforceClientTlsIfDestinationRequiresItForTpc(opaque);
    /*
         * Check the session for the delegated credential to avoid hanging
         * in the case that tpc cgi have been passed by the destination
         * server even with TPC with delegation.
         */
    if (req.getSession().getDelegatedCredential() != null) {
        _log.debug("{} –– third-party request with delegation.", req);
        // proceed as usual with mover + redirect
        return null;
    }
    String slfn = req.getPath();
    XrootdTpcInfo info = _door.createOrGetRendezvousInfo(tpcKey);
    /*
         *  The request originated from the TPC destination server.
         *  If the client has not yet opened the file here,
         *  tells the destination to wait.  If the verification, including
         *  time to live, fails, the request is cancelled.  Otherwise,
         *  the destination is allowed to open the mover and get the
         *  normal redirect response.
         *
         *  Note that the tpc info is created by either the client or the
         *  server, whichever gets here first.  Verification of the key
         *  itself is implicit (it has been found in the map); correctness is
         *  further satisfied by matching org, host and file name.
         */
    if (opaque.containsKey("tpc.org")) {
        info.addInfoFromOpaque(slfn, opaque);
        switch(info.verify(remoteHost, slfn, opaque.get("tpc.org"))) {
            case READY:
                _log.debug("Open request {} from destination server, info {}: " + "OK to proceed.", req, info);
                /*
                     *  This means that the destination server open arrived
                     *  second, the client server open succeeded with
                     *  the correct permissions; proceed as usual
                     *  with mover + redirect.
                     */
                return null;
            case PENDING:
                _log.debug("Open request {} from destination server, info {}: " + "PENDING client open.", req, info);
                /*
                     *  This means that the destination server open arrived
                     *  first; return a wait-retry reply.
                     */
                return new AwaitAsyncResponse<>(req, 3);
            case CANCELLED:
                String error = info.isExpired() ? "ttl expired" : "dst, path or org" + " did not match";
                _log.warn("Open request {} from destination server, info {}: " + "CANCELLED: {}.", req, info, error);
                _door.removeTpcPlaceholder(info.getFd());
                return withError(req, kXR_InvalidRequest, "tpc rendezvous for " + tpcKey + ": " + error);
            case ERROR:
                /*
                     *  This means that the destination server requested open
                     *  before the client did, and the client did not have
                     *  read permissions on this file.
                     */
                error = "invalid open request (file permissions).";
                _log.warn("Open request {} from destination server, info {}: " + "ERROR: {}.", req, info, error);
                _door.removeTpcPlaceholder(info.getFd());
                return withError(req, kXR_InvalidRequest, "tpc rendezvous for " + tpcKey + ": " + error);
        }
    }
    /*
         *  The request originated from the TPC client, indicating door
         *  is the source.
         */
    if (opaque.containsKey("tpc.dst")) {
        _log.debug("Open request {} from client to door as source, " + "info {}: OK.", req, info);
        FileStatus status = _door.getFileStatus(fsPath, subject, restriction, remoteHost);
        int flags = status.getFlags();
        if ((flags & kXR_readable) != kXR_readable) {
            /*
                 * Update the info with ERROR, so when the destination checks
                 * it, an error can be returned.
                 */
            info.setStatus(Status.ERROR);
            return withError(req, kXR_InvalidRequest, "not allowed to read file.");
        }
        info.addInfoFromOpaque(slfn, opaque);
        return new OpenResponse(req, info.getFd(), null, null, status);
    }
    /*
         *  The request originated from the TPC client, indicating door
         *  is the destination.
         *
         *  First check for TLS capability if this is required.
         *
         *  Remove the rendezvous info (not needed),
         *  allow mover to start and redirect the client to the pool.
         *
         *  It is not necessary to delegate the tpc information through the
         *  protocol, particularly the rendezvous key, because it is part of
         *  the opaque data, and if any of the opaque tpc info is missing
         *  from redirected call to the pool, the transfer will fail.
         *
         *  However, the calling method will need to fetch a delegated
         *  proxy credential and add that to the protocol.
         */
    if (opaque.containsKey("tpc.src")) {
        _log.debug("Open request {} from client to door as destination: OK;" + "removing info {}.", req, info);
        _door.removeTpcPlaceholder(info.getFd());
        // proceed as usual with mover + redirect
        return null;
    }
    /*
         *  Something went wrong.
         */
    String error = String.format("Request metadata is invalid: %s: %s, %s.", req, fsPath, remoteHost);
    throw new CacheException(CacheException.THIRD_PARTY_TRANSFER_FAILED, error);
}
Also used : Restriction(org.dcache.auth.attributes.Restriction) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) AwaitAsyncResponse(org.dcache.xrootd.protocol.messages.AwaitAsyncResponse) FileStatus(org.dcache.xrootd.util.FileStatus) XrootdTpcInfo(org.dcache.xrootd.tpc.XrootdTpcInfo) FileIsNewCacheException(diskCacheV111.util.FileIsNewCacheException) FileExistsCacheException(diskCacheV111.util.FileExistsCacheException) FileNotFoundCacheException(diskCacheV111.util.FileNotFoundCacheException) NotFileCacheException(diskCacheV111.util.NotFileCacheException) TimeoutCacheException(diskCacheV111.util.TimeoutCacheException) CacheException(diskCacheV111.util.CacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) OpenResponse(org.dcache.xrootd.protocol.messages.OpenResponse) Subject(javax.security.auth.Subject)

Aggregations

FsPath (diskCacheV111.util.FsPath)98 PermissionDeniedCacheException (diskCacheV111.util.PermissionDeniedCacheException)66 CacheException (diskCacheV111.util.CacheException)63 FileNotFoundCacheException (diskCacheV111.util.FileNotFoundCacheException)56 FileExistsCacheException (diskCacheV111.util.FileExistsCacheException)43 NotDirCacheException (diskCacheV111.util.NotDirCacheException)42 TimeoutCacheException (diskCacheV111.util.TimeoutCacheException)39 FileAttributes (org.dcache.vehicles.FileAttributes)32 PnfsHandler (diskCacheV111.util.PnfsHandler)26 NotFileCacheException (diskCacheV111.util.NotFileCacheException)25 FileIsNewCacheException (diskCacheV111.util.FileIsNewCacheException)23 FileAttribute (org.dcache.namespace.FileAttribute)22 MissingResourceCacheException (diskCacheV111.util.MissingResourceCacheException)21 FileCorruptedCacheException (diskCacheV111.util.FileCorruptedCacheException)20 Subject (javax.security.auth.Subject)17 Restriction (org.dcache.auth.attributes.Restriction)17 Test (org.junit.Test)17 SRMInternalErrorException (org.dcache.srm.SRMInternalErrorException)15 SRMAuthorizationException (org.dcache.srm.SRMAuthorizationException)14 SRMException (org.dcache.srm.SRMException)14