Пример #1
0
        /// <summary>
        /// Validates the request.
        /// </summary>
        /// <returns>The validation result.</returns>
        private async Task <Tuple <bool, BlobS3HandlerResult, CloudBlockBlob> > ValidateRequestAsync()
        {
            BlobS3HandlerResult result = null;

            if (!await this.BlobRepository.GetBlobContainerReference(this.SourceBlobContainer).ExistsAsync().ConfigureAwait(false))
            {
                result = new BlobS3HandlerResult
                {
                    HasSucceeded = false,
                    Message      = ContainerNotExists
                };

                return(new Tuple <bool, BlobS3HandlerResult, CloudBlockBlob>(false, result, null));
            }

            var blobToCopy = this.BlobRepository.GetBlockBlobReference(this.SourceBlob, this.SourceBlobContainer);

            if (await blobToCopy.ExistsAsync().ConfigureAwait(false))
            {
                return(new Tuple <bool, BlobS3HandlerResult, CloudBlockBlob>(true, null, blobToCopy));
            }

            result = new BlobS3HandlerResult
            {
                HasSucceeded = false,
                Message      = BlobNotExists
            };

            return(new Tuple <bool, BlobS3HandlerResult, CloudBlockBlob>(false, result, null));
        }
Пример #2
0
        /// <summary>
        /// Processes the BLOB an copy to s3.
        /// </summary>
        /// <returns>Returns the result of copy from BLOB to S3.</returns>
        private async Task <BlobS3HandlerResult> ProcessBlobAndCopyToS3Async()
        {
            var result = new BlobS3HandlerResult();

            var validationResult = await this.ValidateRequestAsync().ConfigureAwait(false);

            if (!validationResult.Item1)
            {
                return(validationResult.Item2);
            }

            var blobToCopy = validationResult.Item3;
            await blobToCopy.FetchAttributesAsync().ConfigureAwait(false);

            var  remainingBytes = blobToCopy.Properties.Length;
            long readPosition   = 0; // To be used offset / position from where to start reading from BLOB.

            var initiateMultipartUploadRequest = new InitiateMultipartUploadRequest
            {
                BucketName = this.TargetS3Bucket,
                Key        = this.TargetS3File
            };

            // Will use UploadId from this response.
            var initiateMultipartUploadResponse = this.S3Client.InitiateMultipartUpload(initiateMultipartUploadRequest);
            var uploadPartResponses             = new List <UploadPartResponse>();

            try
            {
                var partCounter = 0; // To increment on each read of parts and use it as part number.
                var sha256      = new SHA256Managed();

                while (remainingBytes > 0)
                {
                    // Determine the size when final block reached as it might be less than Part size.
                    // Will be PartSize except final block.
                    var bytesToCopy = Math.Min(PartSize, remainingBytes);

                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        // To download part from BLOB.
                        await blobToCopy.DownloadRangeToStreamAsync(memoryStream, readPosition, bytesToCopy).ConfigureAwait(false);

                        memoryStream.Position = 0;
                        partCounter++;

                        var uploadRequest = new UploadPartRequest
                        {
                            BucketName  = this.TargetS3Bucket,
                            Key         = this.TargetS3File,
                            UploadId    = initiateMultipartUploadResponse.UploadId,
                            PartNumber  = partCounter,
                            PartSize    = bytesToCopy,
                            InputStream = memoryStream
                        };

                        var uploadPartResponse = this.S3Client.UploadPart(uploadRequest);
                        uploadPartResponses.Add(uploadPartResponse);

                        remainingBytes -= bytesToCopy;
                        readPosition   += bytesToCopy;

                        // $"Uploaded part with part number {partCounter}, size {bytesToCopy}bytes and remaining {remainingBytes}bytes to read.")

                        // Calculate the checksum value.
                        if (remainingBytes <= 0)
                        {
                            sha256.TransformFinalBlock(memoryStream.ToArray(), 0, (int)bytesToCopy);
                        }
                        else
                        {
                            var bytesToSend = memoryStream.ToArray();
                            sha256.TransformBlock(bytesToSend, 0, (int)bytesToCopy, bytesToSend, 0);
                        }
                    }
                }

                result.Sha256CheckSum = BitConverter.ToString(sha256.Hash).Replace("-", string.Empty);

                var completeMultipartUploadRequest = new CompleteMultipartUploadRequest
                {
                    BucketName = this.TargetS3Bucket,
                    Key        = this.TargetS3File,
                    UploadId   = initiateMultipartUploadResponse.UploadId
                };

                completeMultipartUploadRequest.AddPartETags(uploadPartResponses);

                var completeMultipartUploadResponse = await this.S3Client.CompleteMultipartUploadAsync(completeMultipartUploadRequest).ConfigureAwait(false);

                result.HasSucceeded = true;
                result.S3Path       = completeMultipartUploadResponse.Location;
            }
            catch (Exception exception)
            {
                result.HasSucceeded = false;
                result.Message      = exception.Message;

                var abortMultipartUploadRequest = new AbortMultipartUploadRequest
                {
                    BucketName = this.TargetS3Bucket,
                    Key        = this.TargetS3File,
                    UploadId   = initiateMultipartUploadResponse.UploadId
                };

                await this.S3Client.AbortMultipartUploadAsync(abortMultipartUploadRequest).ConfigureAwait(false);
            }

            return(result);
        }