Author: mattryan
Date: Tue Aug 27 07:30:21 2019
New Revision: 1865972

URL: http://svn.apache.org/viewvc?rev=1865972&view=rev
Log:
OAK-8574: Reduce cloud service API calls in completeHttpUpload()

Modified:
    
jackrabbit/oak/trunk/oak-blob-cloud-azure/src/main/java/org/apache/jackrabbit/oak/blob/cloud/azure/blobstorage/AzureBlobStoreBackend.java
    
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/s3/S3Backend.java

Modified: 
jackrabbit/oak/trunk/oak-blob-cloud-azure/src/main/java/org/apache/jackrabbit/oak/blob/cloud/azure/blobstorage/AzureBlobStoreBackend.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-cloud-azure/src/main/java/org/apache/jackrabbit/oak/blob/cloud/azure/blobstorage/AzureBlobStoreBackend.java?rev=1865972&r1=1865971&r2=1865972&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob-cloud-azure/src/main/java/org/apache/jackrabbit/oak/blob/cloud/azure/blobstorage/AzureBlobStoreBackend.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob-cloud-azure/src/main/java/org/apache/jackrabbit/oak/blob/cloud/azure/blobstorage/AzureBlobStoreBackend.java
 Tue Aug 27 07:30:21 2019
@@ -365,12 +365,12 @@ public class AzureBlobStoreBackend exten
             CloudBlockBlob blob = 
getAzureContainer().getBlockBlobReference(key);
             blob.downloadAttributes();
             AzureBlobStoreDataRecord record = new AzureBlobStoreDataRecord(
-                this,
-                connectionString,
-                containerName,
-                new DataIdentifier(getIdentifierName(blob.getName())),
-                blob.getProperties().getLastModified().getTime(),
-                blob.getProperties().getLength());
+                    this,
+                    connectionString,
+                    containerName,
+                    new DataIdentifier(getIdentifierName(blob.getName())),
+                    blob.getProperties().getLastModified().getTime(),
+                    blob.getProperties().getLength());
             LOG.debug("Data record read for blob. identifier={} duration={} 
record={}",
                       key, (System.currentTimeMillis() - start), record);
             return record;
@@ -945,34 +945,54 @@ public class AzureBlobStoreBackend exten
         String key = uploadToken.getBlobId();
         DataIdentifier blobId = new DataIdentifier(getIdentifierName(key));
 
-        if (! exists(blobId)) {
+        DataRecord record = null;
+        try {
+            record = getRecord(blobId);
+            // If this succeeds this means either it was a "single put" upload
+            // (we don't need to do anything in this case - blob is already 
uploaded)
+            // or it was completed before with the same token.
+        }
+        catch (DataStoreException e) {
+            // record doesn't exist - so this means we are safe to do the 
complete request
             try {
                 if (uploadToken.getUploadId().isPresent()) {
-                    // An existing upload ID means this is a multi-part upload
                     CloudBlockBlob blob = 
getAzureContainer().getBlockBlobReference(key);
+                    // An existing upload ID means this is a multi-part upload
                     List<BlockEntry> blocks = blob.downloadBlockList(
                             BlockListingFilter.UNCOMMITTED,
                             AccessCondition.generateEmptyCondition(),
                             null,
                             null);
                     blob.commitBlockList(blocks);
-                }
-                // else do nothing - single put is already complete
-
-                if (!exists(blobId)) {
+                    long size = 0L;
+                    for (BlockEntry block : blocks) {
+                        size += block.getSize();
+                    }
+                    record = new AzureBlobStoreDataRecord(
+                            this,
+                            connectionString,
+                            containerName,
+                            blobId,
+                            blob.getProperties().getLastModified().getTime(),
+                            size);
+                }
+                else {
+                    // Something is wrong - upload ID missing from upload token
+                    // but record doesn't exist already, so this is invalid
                     throw new DataRecordUploadException(
-                            String.format("Unable to finalize direct write of 
binary %s", blobId));
+                            String.format("Unable to finalize direct write of 
binary %s - upload ID missing from upload token",
+                                    blobId)
+                    );
                 }
-            } catch (URISyntaxException | StorageException e) {
+            } catch (URISyntaxException | StorageException e2) {
                 throw new DataRecordUploadException(
                         String.format("Unable to finalize direct write of 
binary %s", blobId),
                         e
                 );
             }
         }
-        // else return the already existing record for this blob ID
 
-        return getRecord(blobId);
+        return record;
     }
 
     private URI createPresignedURI(String key,

Modified: 
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/s3/S3Backend.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/s3/S3Backend.java?rev=1865972&r1=1865971&r2=1865972&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/s3/S3Backend.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-blob-cloud/src/main/java/org/apache/jackrabbit/oak/blob/cloud/s3/S3Backend.java
 Tue Aug 27 07:30:21 2019
@@ -905,41 +905,64 @@ public class S3Backend extends AbstractS
         }
 
         DataRecordUploadToken uploadToken = 
DataRecordUploadToken.fromEncodedToken(uploadTokenStr, 
getOrCreateReferenceKey());
-        String blobId = uploadToken.getBlobId();
-        DataIdentifier dataIdentifier = new 
DataIdentifier(getIdentifierName(blobId));
+        String key = uploadToken.getBlobId();
+        DataIdentifier blobId = new DataIdentifier(getIdentifierName(key));
 
-        if (! exists(dataIdentifier)) {
+        DataRecord record = null;
+        try {
+            record = getRecord(blobId);
+            // If this succeeds this means either it was a "single put" upload
+            // (we don't need to do anything in this case - blob is already 
uploaded)
+            // or it was completed before with the same token.
+        }
+        catch (DataStoreException e) {
+            // record doesn't exist - so this means we are safe to do the 
complete request
             if (uploadToken.getUploadId().isPresent()) {
                 // An existing upload ID means this is a multi-part upload
                 String uploadId = uploadToken.getUploadId().get();
-                ListPartsRequest listPartsRequest = new 
ListPartsRequest(bucket, blobId, uploadId);
+                ListPartsRequest listPartsRequest = new 
ListPartsRequest(bucket, key, uploadId);
                 PartListing listing = s3service.listParts(listPartsRequest);
                 List<PartETag> eTags = Lists.newArrayList();
+                long size = 0L;
+                Date lastModified = null;
                 for (PartSummary partSummary : listing.getParts()) {
                     PartETag eTag = new PartETag(partSummary.getPartNumber(), 
partSummary.getETag());
                     eTags.add(eTag);
+                    size += partSummary.getSize();
+                    if (null == lastModified || 
partSummary.getLastModified().after(lastModified)) {
+                        lastModified = partSummary.getLastModified();
+                    }
                 }
 
                 CompleteMultipartUploadRequest completeReq = new 
CompleteMultipartUploadRequest(
                         bucket,
-                        blobId,
+                        key,
                         uploadId,
                         eTags
                 );
 
                 s3service.completeMultipartUpload(completeReq);
-            }
-            // else do nothing - single-put upload is already complete
-
 
-            if (!s3service.doesObjectExist(bucket, blobId)) {
+                record = new S3DataRecord(
+                        this,
+                        s3service,
+                        bucket,
+                        blobId,
+                        lastModified.getTime(),
+                        size
+                );
+            }
+            else {
+                // Something is wrong - upload ID missing from upload token
+                // but record doesn't exist already, so this is invalid
                 throw new DataRecordUploadException(
-                        String.format("Unable to finalize direct write of 
binary %s", blobId)
+                        String.format("Unable to finalize direct write of 
binary %s - upload ID missing from upload token",
+                                blobId)
                 );
             }
         }
 
-        return getRecord(new DataIdentifier(getIdentifierName(blobId)));
+        return record;
     }
 
     private URI createPresignedURI(DataIdentifier identifier,


Reply via email to