public String putBlob()

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();
         }
      }
   }