use of diskCacheV111.vehicles.DoorTransferFinishedMessage in project dcache by dCache.
the class P2PClient method messageArrived.
public synchronized void messageArrived(DoorTransferFinishedMessage message) {
HttpProtocolInfo pinfo = (HttpProtocolInfo) message.getProtocolInfo();
int sessionId = pinfo.getSessionId();
Companion companion = _companions.get(sessionId);
if (companion != null) {
companion.messageArrived(message);
}
}
use of diskCacheV111.vehicles.DoorTransferFinishedMessage in project dcache by dCache.
the class HttpPoolRequestHandler method doOnGet.
/**
* Single GET operation.
* <p>
* Finds the correct mover channel using the UUID in the GET. Range queries are supported. The
* file will be sent to the remote peer in chunks to avoid server side memory issues.
*/
@Override
protected ChannelFuture doOnGet(ChannelHandlerContext context, HttpRequest request) {
NettyTransferService<HttpProtocolInfo>.NettyMoverChannel file;
List<HttpByteRange> ranges;
long fileSize;
if (isBadRequest(request)) {
return context.newSucceededFuture();
}
try {
file = open(request, false);
if (file.getIoMode().contains(StandardOpenOption.WRITE)) {
throw new HttpException(METHOD_NOT_ALLOWED.code(), "Resource is not open for reading");
}
fileSize = file.size();
ranges = parseHttpRange(request, 0, fileSize - 1);
} catch (Redirect e) {
return context.writeAndFlush(e.createResponse());
} catch (HttpException e) {
return context.writeAndFlush(createErrorResponse(e.getErrorCode(), e.getMessage()));
} catch (URISyntaxException e) {
return context.writeAndFlush(createErrorResponse(BAD_REQUEST, "URI not valid: " + e.getMessage()));
} catch (IllegalArgumentException e) {
return context.writeAndFlush(createErrorResponse(BAD_REQUEST, e.getMessage()));
} catch (IOException e) {
return context.writeAndFlush(createErrorResponse(INTERNAL_SERVER_ERROR, e.getMessage()));
}
Optional<String> digest = wantDigest(request).flatMap(h -> Checksums.digestHeader(h, file.getFileAttributes()));
if (ranges == null || ranges.isEmpty()) {
/*
* GET for a whole file
*/
context.write(new HttpGetResponse(fileSize, file, digest)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
context.write(read(file, 0, fileSize - 1)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
ChannelFuture writeAndFlush = context.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
// Release the file immediately after supplying all of the file's content. We're
// assuming that the client will not make further requests against this URL. This is
// done to send the DoorTransferFinishedMessage in a timely fashion.
writeAndFlush.addListener(f -> file.release());
return writeAndFlush;
} else if (ranges.size() == 1) {
/* RFC 2616: 14.16. A response to a request for a single range
* MUST NOT be sent using the multipart/byteranges media type.
*/
HttpByteRange range = ranges.get(0);
context.write(new HttpPartialContentResponse(range.getLower(), range.getUpper(), fileSize, digest)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
context.write(read(file, range.getLower(), range.getUpper())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
// client will not make further requests against this URL.
return context.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
} else {
/*
* GET for multiple ranges
*/
long totalLen = 0;
ByteBuf[] fragmentMarkers = new ByteBuf[ranges.size()];
for (int i = 0; i < ranges.size(); i++) {
HttpByteRange range = ranges.get(i);
long upper = range.getUpper();
long lower = range.getLower();
totalLen += upper - lower + 1;
ByteBuf buffer = fragmentMarkers[i] = createMultipartFragmentMarker(lower, upper, fileSize);
totalLen += buffer.readableBytes();
}
ByteBuf endMarker = createMultipartEnd();
totalLen += endMarker.readableBytes();
context.write(new HttpMultipartResponse(digest, totalLen)).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
for (int i = 0; i < ranges.size(); i++) {
HttpByteRange range = ranges.get(i);
context.write(fragmentMarkers[i]).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
context.write(read(file, range.getLower(), range.getUpper())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
// client will not make further requests against this URL.
return context.writeAndFlush(new DefaultLastHttpContent(endMarker));
}
}
use of diskCacheV111.vehicles.DoorTransferFinishedMessage in project dcache by dCache.
the class DefaultPostTransferService method sendFinished.
public void sendFinished(Mover<?> mover, MoverInfoMessage moverInfoMessage) {
DoorTransferFinishedMessage finished = new DoorTransferFinishedMessage(mover.getClientId(), mover.getFileAttributes().getPnfsId(), mover.getProtocolInfo(), mover.getFileAttributes(), _poolName, mover.getQueueName());
finished.setMoverInfo(moverInfoMessage);
if (mover.getErrorCode() == 0) {
finished.setSucceeded();
} else {
finished.setReply(mover.getErrorCode(), mover.getErrorMessage());
}
_door.notify(mover.getPathToDoor(), finished);
}
use of diskCacheV111.vehicles.DoorTransferFinishedMessage in project dcache by dCache.
the class ChecksumCalculatingTransfer method calculateChecksum.
public Checksum calculateChecksum() throws CacheException, InterruptedException, IOException, NoSuchAlgorithmException {
boolean success = false;
setAdditionalAttributes(EnumSet.of(FileAttribute.CHECKSUM));
readNameSpaceEntry(false);
if (getFileAttributes().getChecksums().isEmpty()) {
throw new CacheException("No checksums found.");
}
Checksum existingChecksum = Checksums.preferredOrder().max(getFileAttributes().getChecksums());
MessageDigest verifyingDigest = existingChecksum.getType().createMessageDigest();
MessageDigest desiredDigest = desiredType.createMessageDigest();
try (ServerSocketChannel ssc = ServerSocketChannel.open()) {
portRange.bind(ssc.socket(), localAddress);
LOGGER.debug("calculating checksum using port {}", ssc.getLocalAddress());
setProtocolInfo(new GFtpProtocolInfo("GFtp", 1, 0, (InetSocketAddress) ssc.getLocalAddress(), 1, 1, 1, MiB.toBytes(1), 0, getFileAttributes().getSize()));
try {
selectPoolAndStartMover(tryOnce().doNotTimeout());
try (SocketChannel s = ssc.accept()) {
ByteBuffer buffer = ByteBuffer.allocate(MiB.toBytes(1));
while (s.read(buffer) > -1) {
advanceCalculated(buffer.position());
buffer.flip();
desiredDigest.update(buffer);
buffer.rewind();
verifyingDigest.update(buffer);
buffer.clear();
}
}
if (!waitForMover(30_000)) {
throw new TimeoutCacheException("copy: wait for DoorTransferFinishedMessage expired");
}
success = true;
if (getCalculated() != getFileAttributes().getSize()) {
throw new CacheException("File size mismatch: " + getCalculated() + " != " + getFileAttributes().getSize());
}
Checksum verifyingChecksum = new Checksum(verifyingDigest);
if (!existingChecksum.equals(verifyingChecksum)) {
throw new CacheException("Corrupt data: " + verifyingChecksum + " != " + existingChecksum);
}
return new Checksum(desiredDigest);
} finally {
if (!success) {
killMover(0, "killed by failure");
}
}
}
}
Aggregations