Search in sources :

Example 1 with RemoteHttpDataTransferProtocolInfo

use of diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo in project dcache by dCache.

the class RemoteHttpDataTransferProtocol method verifyRemoteFile.

private void verifyRemoteFile(RemoteHttpDataTransferProtocolInfo info) throws ThirdPartyTransferFailedCacheException {
    FileAttributes attributes = _channel.getFileAttributes();
    boolean isFirstAttempt = true;
    long t_max = maxRetryDuration(attributes.getSize());
    long deadline = System.currentTimeMillis() + t_max;
    try {
        while (System.currentTimeMillis() < deadline) {
            long sleepFor = Math.min(deadline - System.currentTimeMillis(), DELAY_BETWEEN_REQUESTS);
            if (!isFirstAttempt && sleepFor > 0) {
                Thread.sleep(sleepFor);
            }
            isFirstAttempt = false;
            HttpClientContext context = storeContext(new HttpClientContext());
            HttpHead head = buildHeadRequest(info, deadline);
            buildWantDigest().ifPresent(v -> head.addHeader("Want-Digest", v));
            try {
                try (CloseableHttpResponse response = _client.execute(head, context)) {
                    StatusLine status = response.getStatusLine();
                    if (status.getStatusCode() >= 300) {
                        checkThirdPartyTransferSuccessful(!info.isVerificationRequired(), "rejected HEAD: %d %s", status.getStatusCode(), status.getReasonPhrase());
                        return;
                    }
                    if (shouldRetry(response)) {
                        continue;
                    }
                    OptionalLong contentLengthHeader = contentLength(response);
                    if (contentLengthHeader.isPresent()) {
                        long contentLength = contentLengthHeader.getAsLong();
                        long fileSize = attributes.getSize();
                        checkThirdPartyTransferSuccessful(contentLength == fileSize, "HEAD Content-Length (%d) does not match file size (%d)", contentLength, fileSize);
                    } else {
                        LOGGER.debug("HEAD response did not contain Content-Length");
                    }
                    String rfc3230 = headerValue(response, "Digest");
                    checkChecksums(info, rfc3230, attributes.getChecksumsIfPresent());
                    return;
                } catch (IOException e) {
                    throw new ThirdPartyTransferFailedCacheException("failed to " + "connect to server: " + e.toString(), e);
                }
            } catch (ThirdPartyTransferFailedCacheException e) {
                List<URI> redirections = context.getRedirectLocations();
                if (redirections != null && !redirections.isEmpty()) {
                    throw new ThirdPartyTransferFailedCacheException(e.getMessage() + "; redirections " + redirections, e.getCause());
                } else {
                    throw e;
                }
            }
        }
    } catch (InterruptedException e) {
        throw new ThirdPartyTransferFailedCacheException("pool is shutting down", e);
    }
    throw new ThirdPartyTransferFailedCacheException("remote server failed " + "to provide length after " + describeDuration(GET_RETRY_DURATION, MILLISECONDS));
}
Also used : HttpClientContext(org.apache.http.client.protocol.HttpClientContext) IOException(java.io.IOException) HttpHead(org.apache.http.client.methods.HttpHead) ThirdPartyTransferFailedCacheException(diskCacheV111.util.ThirdPartyTransferFailedCacheException) StatusLine(org.apache.http.StatusLine) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) OptionalLong(java.util.OptionalLong) List(java.util.List) ArrayList(java.util.ArrayList) FileAttributes(org.dcache.vehicles.FileAttributes)

Example 2 with RemoteHttpDataTransferProtocolInfo

use of diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo in project dcache by dCache.

the class RemoteHttpDataTransferProtocol method runIO.

@Override
public void runIO(FileAttributes attributes, RepositoryChannel channel, ProtocolInfo genericInfo, Set<? extends OpenOption> access) throws CacheException, IOException, InterruptedException {
    LOGGER.debug("info={}, attributes={},  access={}", genericInfo, attributes, access);
    RemoteHttpDataTransferProtocolInfo info = (RemoteHttpDataTransferProtocolInfo) genericInfo;
    _channel = new MoverChannel<>(access, attributes, info, channel);
    channel.optionallyAs(ChecksumChannel.class).ifPresent(c -> {
        info.getDesiredChecksum().ifPresent(t -> {
            try {
                c.addType(t);
            } catch (IOException e) {
                LOGGER.warn("Unable to calculate checksum {}: {}", t, messageOrClassName(e));
            }
        });
    });
    try {
        if (access.contains(StandardOpenOption.WRITE)) {
            receiveFile(info);
        } else {
            checkThat(!info.isVerificationRequired() || attributes.isDefined(CHECKSUM), "checksum verification failed: file has no checksum");
            sendAndCheckFile(info);
        }
    } finally {
        afterTransfer();
    }
}
Also used : IOException(java.io.IOException) RemoteHttpDataTransferProtocolInfo(diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo)

Example 3 with RemoteHttpDataTransferProtocolInfo

use of diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo in project dcache by dCache.

the class RemoteHttpDataTransferProtocol method receiveFile.

private void receiveFile(final RemoteHttpDataTransferProtocolInfo info) throws ThirdPartyTransferFailedCacheException {
    Set<Checksum> checksums;
    long deadline = System.currentTimeMillis() + GET_RETRY_DURATION;
    HttpClientContext context = storeContext(new HttpClientContext());
    try {
        try (CloseableHttpResponse response = doGet(info, context, deadline)) {
            String rfc3230 = headerValue(response, "Digest");
            checksums = Checksums.decodeRfc3230(rfc3230);
            checksums.forEach(_integrityChecker);
            HttpEntity entity = response.getEntity();
            if (entity == null) {
                throw new ThirdPartyTransferFailedCacheException("GET response contains no content");
            }
            long length = entity.getContentLength();
            if (length > 0) {
                _channel.truncate(length);
            }
            if (response.getStatusLine() != null && response.getStatusLine().getStatusCode() < 300 && length > -1) {
                _expectedTransferSize = length;
            }
            entity.writeTo(Channels.newOutputStream(_channel));
        } catch (SocketTimeoutException e) {
            String message = "socket timeout on GET (received " + describeSize(_channel.getBytesTransferred()) + " of data; " + describeSize(e.bytesTransferred) + " pending)";
            if (e.getMessage() != null) {
                message += ": " + e.getMessage();
            }
            throw new ThirdPartyTransferFailedCacheException(message, e);
        } catch (IOException e) {
            throw new ThirdPartyTransferFailedCacheException(messageOrClassName(e), e);
        } catch (InterruptedException e) {
            throw new ThirdPartyTransferFailedCacheException("pool is shutting down", e);
        }
    } catch (ThirdPartyTransferFailedCacheException e) {
        List<URI> redirections = context.getRedirectLocations();
        if (redirections != null && !redirections.isEmpty()) {
            StringBuilder message = new StringBuilder(e.getMessage());
            message.append("; redirects ").append(redirections);
            throw new ThirdPartyTransferFailedCacheException(message.toString(), e.getCause());
        } else {
            throw e;
        }
    }
    // HEAD requests.
    if (checksums.isEmpty() && info.isVerificationRequired()) {
        HttpHead head = buildHeadRequest(info, deadline);
        head.addHeader("Want-Digest", WANT_DIGEST_VALUE);
        try {
            try (CloseableHttpResponse response = _client.execute(head)) {
                String rfc3230 = headerValue(response, "Digest");
                checkThirdPartyTransferSuccessful(rfc3230 != null, "no checksums in HEAD response");
                checksums = Checksums.decodeRfc3230(rfc3230);
                checkThirdPartyTransferSuccessful(!checksums.isEmpty(), "no useful checksums in HEAD response: %s", rfc3230);
                // Ensure integrety.  If we're lucky, this won't trigger
                // rescanning the uploaded file.
                checksums.forEach(_integrityChecker);
            }
        } catch (IOException e) {
            throw new ThirdPartyTransferFailedCacheException("HEAD request failed: " + messageOrClassName(e), e);
        }
    }
}
Also used : HttpEntity(org.apache.http.HttpEntity) HttpClientContext(org.apache.http.client.protocol.HttpClientContext) IOException(java.io.IOException) HttpHead(org.apache.http.client.methods.HttpHead) ThirdPartyTransferFailedCacheException(diskCacheV111.util.ThirdPartyTransferFailedCacheException) SocketTimeoutException(java.net.SocketTimeoutException) Checksum(org.dcache.util.Checksum) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) List(java.util.List) ArrayList(java.util.ArrayList)

Example 4 with RemoteHttpDataTransferProtocolInfo

use of diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo in project dcache by dCache.

the class RemoteHttpTransferService method createMoverProtocol.

@Override
protected MoverProtocol createMoverProtocol(ProtocolInfo info) throws Exception {
    if (!(info instanceof RemoteHttpDataTransferProtocolInfo)) {
        throw new CacheException(CacheException.CANNOT_CREATE_MOVER, "Could not create third-party HTTP mover for " + info);
    }
    if (info instanceof RemoteHttpsDataTransferProtocolInfo) {
        RemoteHttpsDataTransferProtocolInfo tlsInfo = (RemoteHttpsDataTransferProtocolInfo) info;
        // connection reuse even with X.509 credentials.
        if (tlsInfo.hasCredential()) {
            X509Credential credential = tlsInfo.getCredential();
            SSLContext context = buildSSLContext(credential.getKeyManager());
            CloseableHttpClient client = createClient(context);
            return new RemoteHttpDataTransferProtocol(client) {

                @Override
                protected void afterTransfer() {
                    super.afterTransfer();
                    try {
                        client.close();
                    } catch (IOException e) {
                        LOGGER.warn("Failed to shutdown client cleanly: {}", meaningfulMessage(e));
                    }
                }
            };
        }
    }
    return new RemoteHttpDataTransferProtocol(sharedClient);
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) X509Credential(eu.emi.security.authn.x509.X509Credential) CacheException(diskCacheV111.util.CacheException) RemoteHttpsDataTransferProtocolInfo(diskCacheV111.vehicles.RemoteHttpsDataTransferProtocolInfo) SSLContext(javax.net.ssl.SSLContext) RemoteHttpDataTransferProtocol(org.dcache.pool.movers.RemoteHttpDataTransferProtocol) IOException(java.io.IOException) RemoteHttpDataTransferProtocolInfo(diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo)

Example 5 with RemoteHttpDataTransferProtocolInfo

use of diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo in project dcache by dCache.

the class Storage method performRemoteTransfer.

private String performRemoteTransfer(SRMUser srmUser, URI remoteTURL, FsPath actualFilePath, boolean store, Map<String, String> extraInfo, Long remoteCredentialId, CopyCallbacks callbacks) throws SRMException {
    DcacheUser user = asDcacheUser(srmUser);
    _log.debug("performRemoteTransfer performing {}", (store ? "store" : "restore"));
    IpProtocolInfo protocolInfo;
    InetSocketAddress remoteAddr = new InetSocketAddress(remoteTURL.getHost(), URIs.optionalPortWithDefault(remoteTURL).orElseThrow(() -> new SRMException("Unknown port number for TURL " + remoteTURL)));
    X509Credential credential = null;
    RequestCredential result = RequestCredential.getRequestCredential(remoteCredentialId);
    if (result != null) {
        credential = result.getDelegatedCredential();
    }
    switch(remoteTURL.getScheme().toLowerCase()) {
        case "gsiftp":
            if (credential == null) {
                throw new SRMAuthorizationException("Cannot authenticate " + "with remote gsiftp service; credential " + "delegation required.");
            }
            RemoteGsiftpTransferProtocolInfo gsiftpProtocolInfo = new RemoteGsiftpTransferProtocolInfo("RemoteGsiftpTransfer", 1, 1, remoteAddr, remoteTURL.toString(), getCellName(), getCellDomainName(), config.getBuffer_size(), config.getTcp_buffer_size(), credential, Optional.empty());
            gsiftpProtocolInfo.setEmode(true);
            gsiftpProtocolInfo.setNumberOfStreams(config.getParallel_streams());
            protocolInfo = gsiftpProtocolInfo;
            break;
        case "https":
            protocolInfo = new RemoteHttpsDataTransferProtocolInfo("RemoteHttpsDataTransfer", 1, 1, remoteAddr, remoteTURL.toString(), isVerifyRequired(extraInfo), httpHeaders(extraInfo), credential, Optional.empty());
            break;
        case "http":
            protocolInfo = new RemoteHttpDataTransferProtocolInfo("RemoteHttpDataTransfer", 1, 1, remoteAddr, remoteTURL.toString(), isVerifyRequired(extraInfo), httpHeaders(extraInfo), Optional.empty());
            break;
        default:
            throw new SRMException("protocol " + remoteTURL.getScheme() + " is not supported");
    }
    RemoteTransferManagerMessage request = new RemoteTransferManagerMessage(remoteTURL, actualFilePath, store, remoteCredentialId, protocolInfo);
    request.setSubject(user.getSubject());
    request.setRestriction(user.getRestriction());
    try {
        RemoteTransferManagerMessage reply = _transferManagerStub.sendAndWait(request);
        long id = reply.getId();
        _log.debug("received first RemoteGsiftpTransferManagerMessage " + "reply from transfer manager, id ={}", id);
        TransferInfo info = new TransferInfo(id, callbacks);
        _log.debug("storing info for callerId = {}", id);
        callerIdToHandler.put(id, info);
        return String.valueOf(id);
    } catch (NoRouteToCellException | TimeoutCacheException e) {
        throw new SRMInternalErrorException("Transfer manager is unavailable: " + e.getMessage(), e);
    } catch (CacheException e) {
        throw new SRMException("TransferManager error: " + e.getMessage(), e);
    } catch (InterruptedException e) {
        throw new SRMException("Request to transfer manager got interruptd", e);
    }
}
Also used : SRMAuthorizationException(org.dcache.srm.SRMAuthorizationException) RequestCredential(org.dcache.srm.request.RequestCredential) FileIsNewCacheException(diskCacheV111.util.FileIsNewCacheException) FileExistsCacheException(diskCacheV111.util.FileExistsCacheException) NotDirCacheException(diskCacheV111.util.NotDirCacheException) FileNotFoundCacheException(diskCacheV111.util.FileNotFoundCacheException) TimeoutCacheException(diskCacheV111.util.TimeoutCacheException) CacheException(diskCacheV111.util.CacheException) FileCorruptedCacheException(diskCacheV111.util.FileCorruptedCacheException) PermissionDeniedCacheException(diskCacheV111.util.PermissionDeniedCacheException) InetSocketAddress(java.net.InetSocketAddress) RemoteGsiftpTransferProtocolInfo(diskCacheV111.vehicles.transferManager.RemoteGsiftpTransferProtocolInfo) SRMInternalErrorException(org.dcache.srm.SRMInternalErrorException) SRMException(org.dcache.srm.SRMException) X509Credential(eu.emi.security.authn.x509.X509Credential) RemoteHttpsDataTransferProtocolInfo(diskCacheV111.vehicles.RemoteHttpsDataTransferProtocolInfo) RemoteTransferManagerMessage(diskCacheV111.vehicles.transferManager.RemoteTransferManagerMessage) NoRouteToCellException(dmg.cells.nucleus.NoRouteToCellException) IpProtocolInfo(diskCacheV111.vehicles.IpProtocolInfo) RemoteHttpDataTransferProtocolInfo(diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo) TimeoutCacheException(diskCacheV111.util.TimeoutCacheException)

Aggregations

IOException (java.io.IOException)5 ThirdPartyTransferFailedCacheException (diskCacheV111.util.ThirdPartyTransferFailedCacheException)4 RemoteHttpDataTransferProtocolInfo (diskCacheV111.vehicles.RemoteHttpDataTransferProtocolInfo)3 CloseableHttpResponse (org.apache.http.client.methods.CloseableHttpResponse)3 HttpClientContext (org.apache.http.client.protocol.HttpClientContext)3 CacheException (diskCacheV111.util.CacheException)2 RemoteHttpsDataTransferProtocolInfo (diskCacheV111.vehicles.RemoteHttpsDataTransferProtocolInfo)2 X509Credential (eu.emi.security.authn.x509.X509Credential)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 StatusLine (org.apache.http.StatusLine)2 HttpHead (org.apache.http.client.methods.HttpHead)2 Checksum (org.dcache.util.Checksum)2 FileCorruptedCacheException (diskCacheV111.util.FileCorruptedCacheException)1 FileExistsCacheException (diskCacheV111.util.FileExistsCacheException)1 FileIsNewCacheException (diskCacheV111.util.FileIsNewCacheException)1 FileNotFoundCacheException (diskCacheV111.util.FileNotFoundCacheException)1 NotDirCacheException (diskCacheV111.util.NotDirCacheException)1 PermissionDeniedCacheException (diskCacheV111.util.PermissionDeniedCacheException)1 TimeoutCacheException (diskCacheV111.util.TimeoutCacheException)1