in apis/filesystem/src/main/java/org/jclouds/filesystem/strategy/internal/FilesystemStorageStrategyImpl.java [552:630]
public String putBlob(final String containerName, final Blob blob, BlobAccess access) throws IOException {
String blobKey = blob.getMetadata().getName();
Payload payload = blob.getPayload();
filesystemContainerNameValidator.validate(containerName);
filesystemBlobKeyValidator.validate(blobKey);
if (getDirectoryBlobSuffix(blobKey) != null) {
return putDirectoryBlob(containerName, blob);
}
File outputFile = getFileForBlobKey(containerName, blobKey);
// TODO: should we use a known suffix to filter these out during list?
String tmpBlobName = blobKey + "-" + UUID.randomUUID();
File tmpFile = getFileForBlobKey(containerName, tmpBlobName);
Path tmpPath = tmpFile.toPath();
boolean isMpu = false;
if (blob.getMetadata() != null && blob.getMetadata().getETag() != null)
isMpu = MPU_ETAG_FORMAT.matcher(blob.getMetadata().getETag()).matches();
InputStream inputStream = null;
byte[] eTag = null;
try {
Files.createParentDirs(tmpFile);
if (isMpu) {
inputStream = payload.openStream();
eTag = blob.getMetadata().getETag().getBytes();
} else {
inputStream = new HashingInputStream(Hashing.md5(), payload.openStream());
}
long actualSize = Files.asByteSink(tmpFile).writeFrom(inputStream);
Long expectedSize = blob.getMetadata().getContentMetadata().getContentLength();
if (expectedSize != null && actualSize != expectedSize) {
throw new IOException("Content-Length mismatch, actual: " + actualSize +
" expected: " + expectedSize);
}
if (!isMpu) {
HashCode actualHashCode = ((HashingInputStream) inputStream).hash();
HashCode expectedHashCode = payload.getContentMetadata().getContentMD5AsHashCode();
if (expectedHashCode != null && !actualHashCode.equals(expectedHashCode)) {
throw new IOException("MD5 hash code mismatch, actual: " + actualHashCode +
" expected: " + expectedHashCode);
}
payload.getContentMetadata().setContentMD5(actualHashCode);
eTag = actualHashCode.asBytes();
}
// TODO: is this necessary?
if (isWindows() && outputFile.exists()) {
delete(outputFile);
}
UserDefinedFileAttributeView view = getUserDefinedFileAttributeView(tmpPath);
if (view != null) {
try {
view.write(XATTR_CONTENT_MD5, ByteBuffer.wrap(eTag));
writeCommonMetadataAttr(view, blob);
} catch (IOException e) {
logger.debug("xattrs not supported on %s", tmpPath);
}
}
setBlobAccess(containerName, tmpBlobName, access);
move(tmpPath, outputFile.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
tmpFile = null;
return base16().lowerCase().encode(eTag);
} finally {
if (tmpFile != null) {
try {
delete(tmpFile);
} catch (IOException e) {
logger.debug("Could not delete %s: %s", tmpFile, e);
}
}
closeQuietly(inputStream);
if (payload != null) {
payload.release();
}
}
}