Search in sources :

Example 1 with TpcWriteDescriptor

use of org.dcache.xrootd.tpc.TpcWriteDescriptor in project dcache by dCache.

the class XrootdPoolRequestHandler method doOnOpen.

/**
 * Obtains the right mover channel using an opaque token in the request. The mover channel is
 * wrapped by a file descriptor. The file descriptor is stored for subsequent access.
 * <p>
 * In the case that this is a write request as destination in a third party copy, a third-party
 * client is started.  The client issues login, open and read requests to the source server, and
 * writes the responses to the file descriptor.
 * <p>
 * The third-party client also sends a sync response back to the client when the transfer has
 * completed.
 */
@Override
protected XrootdResponse<OpenRequest> doOnOpen(ChannelHandlerContext ctx, OpenRequest msg) throws XrootdException {
    try {
        Map<String, String> opaqueMap = getOpaqueMap(msg.getOpaque());
        UUID uuid = getUuid(opaqueMap);
        if (uuid == null) {
            _log.info("Request to open {} contains no UUID.", msg.getPath());
            throw new XrootdException(kXR_NotAuthorized, "Request lacks the " + UUID_PREFIX + " property.");
        }
        enforceClientTlsIfDestinationRequiresItForTpc(opaqueMap);
        NettyTransferService<XrootdProtocolInfo>.NettyMoverChannel file = _server.openFile(uuid, false);
        if (file == null) {
            _log.info("No mover found for {} with UUID {}.", msg.getPath(), uuid);
            return redirectToDoor(ctx, msg, () -> {
                throw new XrootdException(kXR_NotAuthorized, UUID_PREFIX + " is no longer valid.");
            });
        }
        /*
             *  Stop any timer in case this is a reconnect.
             */
        _server.cancelReconnectTimeoutForMover(uuid);
        _log.debug("doOnOpen, called cancel on reconnect timers for {}", uuid);
        XrootdProtocolInfo protocolInfo = file.getProtocolInfo();
        try {
            FileDescriptor descriptor;
            boolean isWrite = file.getIoMode().contains(StandardOpenOption.WRITE);
            if (msg.isNew() && !isWrite) {
                throw new XrootdException(kXR_FileNotOpen, "File exists.");
            } else if (msg.isDelete() && !isWrite) {
                throw new XrootdException(kXR_Unsupported, "File exists.");
            /*
                     *  Some clients express only kXR_delete when then intend to write
                     *  so we need to consider delete as a write request here.
                     */
            } else if ((msg.isNew() || msg.isReadWrite() || msg.isDelete()) && isWrite) {
                boolean posc = (msg.getOptions() & kXR_posc) == kXR_posc || protocolInfo.getFlags().contains(XrootdProtocolInfo.Flags.POSC);
                if (opaqueMap.containsKey("tpc.src")) {
                    _log.debug("Request to open {} is as third-party destination.", msg);
                    XrootdTpcInfo tpcInfo = new XrootdTpcInfo(opaqueMap);
                    tpcInfo.setDelegatedProxy(protocolInfo.getDelegatedCredential());
                    tpcInfo.setUid(protocolInfo.getTpcUid());
                    tpcInfo.setGid(protocolInfo.getTpcGid());
                    descriptor = new TpcWriteDescriptor(file, posc, ctx, _server, opaqueMap.get("org.dcache.xrootd.client"), tpcInfo, tlsSessionInfo);
                } else {
                    descriptor = new WriteDescriptor(file, posc);
                }
            } else {
                descriptor = new ReadDescriptor(file);
            }
            FileStatus stat = msg.isRetStat() ? stat(file) : null;
            int fd = addDescriptor(descriptor);
            _redirectingDoor = protocolInfo.getDoorAddress();
            file = null;
            _hasOpenedFiles = true;
            return new OpenResponse(msg, fd, null, null, stat);
        } finally {
            if (file != null) {
                file.release();
            }
        }
    } catch (ParseException e) {
        throw new XrootdException(kXR_ArgInvalid, e.getMessage());
    } catch (IOException e) {
        throw new XrootdException(kXR_IOError, e.getMessage());
    }
}
Also used : NettyTransferService(org.dcache.pool.movers.NettyTransferService) FileStatus(org.dcache.xrootd.util.FileStatus) XrootdProtocolInfo(org.dcache.vehicles.XrootdProtocolInfo) IOException(java.io.IOException) TpcWriteDescriptor(org.dcache.xrootd.tpc.TpcWriteDescriptor) XrootdTpcInfo(org.dcache.xrootd.tpc.XrootdTpcInfo) OpenResponse(org.dcache.xrootd.protocol.messages.OpenResponse) ParseException(org.dcache.xrootd.util.ParseException) UUID(java.util.UUID) XrootdException(org.dcache.xrootd.core.XrootdException) TpcWriteDescriptor(org.dcache.xrootd.tpc.TpcWriteDescriptor)

Example 2 with TpcWriteDescriptor

use of org.dcache.xrootd.tpc.TpcWriteDescriptor in project dcache by dCache.

the class XrootdPoolRequestHandler method doOnStat.

/**
 * In third-party requests where dCache is the destination, the client may ask for a size
 * update.  This can be provided by checking channel size.
 * <p>
 * Otherwise, stat is not supported on the pool and should be issued to the door.
 *
 * @param ctx Received from the netty pipeline
 * @param msg The actual request
 */
@Override
protected XrootdResponse<StatRequest> doOnStat(ChannelHandlerContext ctx, StatRequest msg) throws XrootdException {
    switch(msg.getTarget()) {
        case PATH:
            _log.debug("Request to stat {}; redirecting to door.", msg);
            return redirectToDoor(ctx, msg);
        case FHANDLE:
            int fd = msg.getFhandle();
            FileDescriptor descriptor = getDescriptor(fd);
            if (descriptor instanceof TpcWriteDescriptor) {
                _log.debug("Request to stat {} is for third-party transfer.", msg);
                return ((TpcWriteDescriptor) descriptor).handleStat(msg);
            } else {
                try {
                    _log.debug("Request to stat open file fhandle={}", fd);
                    return new StatResponse(msg, stat(descriptor.getChannel()));
                } catch (IOException e) {
                    throw new XrootdException(kXR_IOError, e.getMessage());
                }
            }
        default:
            throw new XrootdException(kXR_NotFile, "Unexpected stat target");
    }
}
Also used : StatResponse(org.dcache.xrootd.protocol.messages.StatResponse) IOException(java.io.IOException) XrootdException(org.dcache.xrootd.core.XrootdException) TpcWriteDescriptor(org.dcache.xrootd.tpc.TpcWriteDescriptor)

Aggregations

IOException (java.io.IOException)2 XrootdException (org.dcache.xrootd.core.XrootdException)2 TpcWriteDescriptor (org.dcache.xrootd.tpc.TpcWriteDescriptor)2 UUID (java.util.UUID)1 NettyTransferService (org.dcache.pool.movers.NettyTransferService)1 XrootdProtocolInfo (org.dcache.vehicles.XrootdProtocolInfo)1 OpenResponse (org.dcache.xrootd.protocol.messages.OpenResponse)1 StatResponse (org.dcache.xrootd.protocol.messages.StatResponse)1 XrootdTpcInfo (org.dcache.xrootd.tpc.XrootdTpcInfo)1 FileStatus (org.dcache.xrootd.util.FileStatus)1 ParseException (org.dcache.xrootd.util.ParseException)1