private void validateBounds(final RPCBlockReadRequest req, final long fileLength) { Preconditions.checkArgument( req.getOffset() <= fileLength, "Offset(%s) is larger than file length(%s)", req.getOffset(), fileLength); Preconditions.checkArgument( req.getLength() == -1 || req.getOffset() + req.getLength() <= fileLength, "Offset(%s) plus length(%s) is larger than file length(%s)", req.getOffset(), req.getLength(), fileLength); }
private void handleBlockReadRequest( final ChannelHandlerContext ctx, final RPCBlockReadRequest req) throws IOException { final long blockId = req.getBlockId(); final long offset = req.getOffset(); final long len = req.getLength(); final long lockId = req.getLockId(); final long sessionId = req.getSessionId(); BlockReader reader; try { reader = mBlockWorker.readBlockRemote(sessionId, blockId, lockId); } catch (BlockDoesNotExistException e) { throw new IOException(e); } catch (InvalidWorkerStateException e) { throw new IOException(e); } try { req.validate(); final long fileLength = reader.getLength(); validateBounds(req, fileLength); final long readLength = returnLength(offset, len, fileLength); RPCBlockReadResponse resp = new RPCBlockReadResponse( blockId, offset, readLength, getDataBuffer(req, reader, readLength), RPCResponse.Status.SUCCESS); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); future.addListener(new ClosableResourceChannelListener(reader)); mBlockWorker.accessBlock(sessionId, blockId); LOG.info("Preparation for responding to remote block request for: {} done.", blockId); } catch (Exception e) { LOG.error("The file is not here : {}", e.getMessage(), e); RPCBlockReadResponse resp = RPCBlockReadResponse.createErrorResponse(req, RPCResponse.Status.FILE_DNE); ChannelFuture future = ctx.writeAndFlush(resp); future.addListener(ChannelFutureListener.CLOSE); if (reader != null) { reader.close(); } } }