use of org.dcache.pool.repository.RepositoryChannel in project dcache by dCache.
the class EDSOperationWRITE method process.
@Override
public void process(CompoundContext context, nfs_resop4 result) {
final WRITE4res res = result.opwrite;
try {
NfsMover mover = nfsTransferService.getMoverByStateId(context, _args.opwrite.stateid);
if (!mover.getIoMode().contains(StandardOpenOption.WRITE)) {
throw new PermException("an attempt to write without IO mode enabled");
}
long offset = _args.opwrite.offset.value;
RepositoryChannel fc = mover.getMoverChannel();
_args.opwrite.data.rewind();
int bytesWritten = fc.write(_args.opwrite.data, offset);
res.status = nfsstat.NFS_OK;
res.resok4 = new WRITE4resok();
res.resok4.count = new count4(bytesWritten);
res.resok4.writeverf = context.getRebootVerifier();
/*
* The pool holds only the data. If client wants to sync metadata
* as well (FILE_SYNC-like behavior), the it must send an explicit
* LAYOUT_COMMIT to the door.
*/
res.resok4.committed = stable_how4.DATA_SYNC4;
_log.debug("MOVER: {}@{} written, {} requested.", bytesWritten, offset, bytesWritten);
} catch (ChimeraNFSException he) {
_log.debug(he.getMessage());
res.status = he.getStatus();
} catch (OutOfDiskException e) {
_log.error("DSWRITE: no allocatable space left on the pool");
res.status = nfsstat.NFSERR_NOSPC;
} catch (IOException ioe) {
_log.error("DSWRITE: ", ioe);
res.status = nfsstat.NFSERR_IO;
} catch (Exception e) {
_log.error("DSWRITE: ", e);
res.status = nfsstat.NFSERR_SERVERFAULT;
}
}
use of org.dcache.pool.repository.RepositoryChannel in project dcache by dCache.
the class EDSOperationCOMMIT method process.
@Override
public void process(CompoundContext cc, nfs_resop4 result) throws ChimeraNFSException, IOException {
final COMMIT4res res = result.opcommit;
Inode inode = cc.currentInode();
/**
* The nfs commit operation comes without a stateid. The assumption, is
* that for now we have only one writer and, as a result, pnfsid will
* point only to a single mover.
*/
NfsMover mover = nfsTransferService.getPnfsIdByHandle(inode.toNfsHandle());
RepositoryChannel fc = mover.getMoverChannel();
fc.sync();
mover.commitFileSize(fc.size());
res.status = nfsstat.NFS_OK;
res.resok4 = new COMMIT4resok();
res.resok4.writeverf = cc.getRebootVerifier();
}
use of org.dcache.pool.repository.RepositoryChannel in project dcache by dCache.
the class Companion method copy.
private Set<Checksum> copy(String uri, ReplicaDescriptor handle) throws IOException, InterruptedException {
RepositoryChannel channel = handle.createChannel();
try {
HttpGet get = new HttpGet(uri);
get.addHeader(HttpHeaders.CONNECTION, HTTP.CONN_CLOSE);
get.setConfig(RequestConfig.custom().setConnectTimeout((int) CONNECT_TIMEOUT).setSocketTimeout((int) READ_TIMEOUT).build());
setRequest(get);
try (CloseableHttpClient client = HttpClients.custom().setSSLContext(_sslContext).setUserAgent(USER_AGENT).build();
CloseableHttpResponse response = client.execute(get)) {
StatusLine statusLine = response.getStatusLine();
if (statusLine.getStatusCode() >= 300) {
throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase());
}
HttpEntity entity = response.getEntity();
if (entity == null) {
throw new ClientProtocolException("Response contains no content");
}
long contentLength = entity.getContentLength();
if (contentLength >= 0 && contentLength != _fileAttributes.getSize()) {
/* Fail fast if the response is incomplete.
*/
throw new EOFException("Received file does not match expected file size.");
}
entity.getContent().transferTo(Channels.newOutputStream(channel));
try {
channel.sync();
} catch (SyncFailedException e) {
/* Data is not guaranteed to be on disk. Not a fatal
* problem, but better generate a warning.
*/
LOGGER.warn("Failed to synchronize file with storage device: {}", e.getMessage());
}
} finally {
setRequest(null);
}
return channel.optionallyAs(ChecksumChannel.class).map(ChecksumChannel::getChecksums).orElseThrow(() -> new IllegalStateException("Missing ChecksumChannel"));
} catch (ClosedChannelException | InterruptedIOException e) {
// clear interrupted status
Thread.interrupted();
throw new InterruptedException();
} finally {
channel.close();
}
}
use of org.dcache.pool.repository.RepositoryChannel in project dcache by dCache.
the class ChecksumChannelTest method shouldNotUpdateChecksumForIncompleteWritesWithZeroBytesWritesToChannelWithMultipleBuffers.
@Test
public void shouldNotUpdateChecksumForIncompleteWritesWithZeroBytesWritesToChannelWithMultipleBuffers() throws IOException, NoSuchAlgorithmException {
RepositoryChannel mockRepositoryChannel = mock(RepositoryChannel.class);
when(mockRepositoryChannel.write(any(), anyInt())).thenReturn(0);
ChecksumChannel csc = new ChecksumChannel(mockRepositoryChannel, EnumSet.of(ChecksumType.MD5_TYPE));
csc.write(buffers);
}
use of org.dcache.pool.repository.RepositoryChannel in project dcache by dCache.
the class ChecksumChannelTest method shouldNotUpdateChecksumForIncompleteWritesWithZeroByteWritesToChannelWithMultipleBuffersAndOffset.
@Test
public void shouldNotUpdateChecksumForIncompleteWritesWithZeroByteWritesToChannelWithMultipleBuffersAndOffset() throws IOException, NoSuchAlgorithmException {
RepositoryChannel mockRepositoryChannel = mock(RepositoryChannel.class);
when(mockRepositoryChannel.write(any(), anyInt())).thenReturn(0);
ChecksumChannel csc = new ChecksumChannel(mockRepositoryChannel, EnumSet.of(ChecksumType.MD5_TYPE));
csc.write(buffers, 0, blockcount);
}
Aggregations