public async Task<UploadResult> UploadAsync(UploadRequest request) { // validate input _pathBuilder.Validate(request.PathFormat); // initialize request.Trace.Write("Initializing..."); var context = new CloudContext(request.ConnectionString, request.Container); await context.BlobContainer.CreateIfNotExistsAsync( BlobContainerPublicAccessType.Blob, new BlobRequestOptions(), null); request.Trace.WriteLine(" done."); // set the direct var result = new UploadResult(); CloudBlockBlob directBlob = null; if (request.UploadDirect) { if (request.Type == UploadRequestType.Number) { directBlob = await UploadDirectNumberAsync(request, context, result); } else { directBlob = await UploadDirectTimestampAsync(request, context); } } // set the latest CloudBlockBlob latestBlob = null; if (request.UploadLatest) { var latestPath = _pathBuilder.GetLatest(request.PathFormat); if (directBlob == null) { latestBlob = await UploadBlobAsync(context, request, latestPath, direct: false); } else { request.Trace.Write($"Copying the direct blob to the latest blob at '{latestPath}'..."); latestBlob = context.BlobContainer.GetBlockBlobReference(latestPath); var sourceAccessCondition = new AccessCondition {IfMatchETag = directBlob.Properties.ETag}; var destAccessCondition = new AccessCondition {IfMatchETag = request.ETag}; await latestBlob.StartCopyAsync(directBlob, sourceAccessCondition, destAccessCondition, null, null); while (latestBlob.CopyState.Status == CopyStatus.Pending) { await Task.Delay(100); await latestBlob.ExistsAsync(); } request.Trace.WriteLine(" done."); } } request.Trace.WriteLine(); if (directBlob != null) { result.DirectUri = directBlob.Uri; result.DirectETag = directBlob.Properties.ETag; request.Trace.WriteLine($"Direct: {directBlob.Uri}"); } if (latestBlob != null) { result.LatestUri = latestBlob.Uri; result.LatestETag = latestBlob.Properties.ETag; request.Trace.WriteLine($"Latest: {latestBlob.Uri}"); } return result; }
private async Task<CloudBlockBlob> UploadDirectNumberAsync(UploadRequest request, CloudContext context, UploadResult result) { var latestNumberPath = _pathBuilder.GetDirect(request.PathFormat, 0); var latestNumberBlob = context.BlobContainer.GetBlockBlobReference(latestNumberPath); string latestNumberEtag = null; var latestNumber = 0; if (request.LatestNumber.HasValue) { // Use the provided version number latestNumberEtag = request.LatestNumberETag; latestNumber = request.LatestNumber.Value; } else { // Determine what version number what last used try { await latestNumberBlob.FetchAttributesAsync(); latestNumberEtag = latestNumberBlob.Properties.ETag; var latestNumberString = latestNumberBlob.Metadata[LatestNumberMetadataKey]; latestNumber = int.Parse(latestNumberString); } catch (StorageException e) { if (e.RequestInformation.HttpStatusCode != 404) { throw; } } latestNumber++; } // Upload the stream var latestPath = _pathBuilder.GetDirect(request.PathFormat, latestNumber); var directBlob = await UploadBlobAsync(context, request, latestPath, direct: true); // Update the latest version record AccessCondition accessCondition; if (!request.UseETags) { accessCondition = null; } else if (latestNumberEtag != null) { accessCondition = AccessCondition.GenerateIfMatchCondition(latestNumberEtag); } else { accessCondition = AccessCondition.GenerateIfNoneMatchCondition("*"); } latestNumberBlob.Metadata[LatestNumberMetadataKey] = latestNumber.ToString(); await latestNumberBlob.UploadFromByteArrayAsync(new byte[0], 0, 0, accessCondition, options: null, operationContext: null); // Set the latest etag and number on the result result.LatestNumberETag = latestNumberBlob.Properties.ETag; result.LatestNumber = latestNumber; return directBlob; }