private async Task StartCopyFromUri(long taskId, IStorageBlobManagement destChannel, Uri srcUri, BlobBaseClient destBlob) { bool destExist = true; Track2Models.BlobType? destBlobType = Util.GetBlobType(destBlob); Track2Models.BlobProperties properties = null; try { properties = (await destBlob.GetPropertiesAsync(this.BlobRequestConditions, cancellationToken: this.CmdletCancellationToken).ConfigureAwait(false)).Value; destBlobType = properties.BlobType; } catch (global::Azure.RequestFailedException e) when(e.Status == 404) { destExist = false; } if (destBlobType != null) { ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(destBlobType), pageBlobTier, standardBlobTier, rehydratePriority); } if (!destExist || this.ConfirmOverwrite(srcUri.AbsoluteUri.ToString(), destBlob.Uri.ToString())) { Track2Models.BlobCopyFromUriOptions options = new global::Azure.Storage.Blobs.Models.BlobCopyFromUriOptions(); // The Blob Type and Blob Tier must match, since already checked they are match at the begin of ExecuteCmdlet(). if (pageBlobTier != null) { options.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(pageBlobTier); } else if (standardBlobTier != null || rehydratePriority != null) { options.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier); options.RehydratePriority = Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority); } if (this.BlobTag != null) { options.Tags = this.BlobTag.Cast <DictionaryEntry>().ToDictionary(d => (string)d.Key, d => (string)d.Value); } options.SourceConditions = this.BlobRequestConditions; if (this.DestTagCondition != null) { options.DestinationConditions = new Track2Models.BlobRequestConditions(); options.DestinationConditions.TagConditions = DestTagCondition; } Track2Models.CopyFromUriOperation copyId = await destBlob.StartCopyFromUriAsync(srcUri, options, this.CmdletCancellationToken).ConfigureAwait(false); this.OutputStream.WriteVerbose(taskId, String.Format(Resources.CopyDestinationBlobPending, destBlob.Name, destBlob.BlobContainerName, copyId)); OutputStream.WriteObject(taskId, new AzureStorageBlob(destBlob, destChannel.StorageContext, properties, options: ClientOptions)); } }
private async Task CopyFromUri(long taskId, IStorageBlobManagement destChannel, Uri srcUri, BlobBaseClient destBlob) { bool destExist = true; Track2Models.BlobType? destBlobType = Util.GetBlobType(destBlob); Track2Models.BlobProperties properties = null; try { properties = (await destBlob.GetPropertiesAsync(this.BlobRequestConditions, cancellationToken: this.CmdletCancellationToken).ConfigureAwait(false)).Value; destBlobType = properties.BlobType; } catch (global::Azure.RequestFailedException e) when(e.Status == 404) { destExist = false; } if (destBlobType != null) { ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(destBlobType), null, standardBlobTier, rehydratePriority); } if (!destExist || this.ConfirmOverwrite(srcUri.AbsoluteUri.ToString(), destBlob.Uri.ToString())) { Track2Models.BlobCopyFromUriOptions options = new Track2Models.BlobCopyFromUriOptions(); // The Blob Type and Blob Tier must match, since already checked before if (standardBlobTier != null || rehydratePriority != null) { options.AccessTier = Util.ConvertAccessTier_Track1ToTrack2(standardBlobTier); options.RehydratePriority = Util.ConvertRehydratePriority_Track1ToTrack2(rehydratePriority); } options.SourceConditions = this.BlobRequestConditions; BlockBlobClient srcBlockblob = new BlockBlobClient(srcUri, ClientOptions); Track2Models.BlobProperties srcProperties = srcBlockblob.GetProperties(cancellationToken: this.CmdletCancellationToken).Value; //Prepare progress handler string activity = String.Format("Copy Blob {0} to {1}", srcBlockblob.Name, destBlob.Name); string status = "Prepare to Copy Blob"; ProgressRecord pr = new ProgressRecord(OutputStream.GetProgressId(taskId), activity, status); IProgress <long> progressHandler = new Progress <long>((finishedBytes) => { if (pr != null) { // Size of the source file might be 0, when it is, directly treat the progress as 100 percent. pr.PercentComplete = 0 == srcProperties.ContentLength ? 100 : (int)(finishedBytes * 100 / srcProperties.ContentLength); pr.StatusDescription = string.Format("Percent: {0}%.", pr.PercentComplete); Console.WriteLine(finishedBytes); this.OutputStream.WriteProgress(pr); } }); switch (destBlobType) { case Track2Models.BlobType.Block: BlockBlobClient destBlockBlob = (BlockBlobClient)Util.GetTrack2BlobClientWithType(destBlob, Channel.StorageContext, Track2Models.BlobType.Block, ClientOptions); Track2Models.CommitBlockListOptions commitBlockListOptions = new Track2Models.CommitBlockListOptions(); commitBlockListOptions.HttpHeaders = new Track2Models.BlobHttpHeaders(); commitBlockListOptions.HttpHeaders.ContentType = srcProperties.ContentType; commitBlockListOptions.HttpHeaders.ContentHash = srcProperties.ContentHash; commitBlockListOptions.HttpHeaders.ContentEncoding = srcProperties.ContentEncoding; commitBlockListOptions.HttpHeaders.ContentLanguage = srcProperties.ContentLanguage; commitBlockListOptions.HttpHeaders.ContentDisposition = srcProperties.ContentDisposition; commitBlockListOptions.Metadata = srcProperties.Metadata; try { commitBlockListOptions.Tags = srcBlockblob.GetTags(cancellationToken: this.CmdletCancellationToken).Value.Tags; } catch (global::Azure.RequestFailedException e) when(e.Status == 403 || e.Status == 404 || e.Status == 401) { if (!this.Force && !OutputStream.ConfirmAsync("Can't get source blob Tags, so source blob tags won't be copied to dest blob. Do you want to continue the blob copy?").Result) { return; } } long blockLength = GetBlockLength(srcProperties.ContentLength); string[] blockIDs = GetBlockIDs(srcProperties.ContentLength, blockLength, destBlockBlob.Name); long copyoffset = 0; progressHandler.Report(copyoffset); foreach (string id in blockIDs) { long blocksize = blockLength; if (copyoffset + blocksize > srcProperties.ContentLength) { blocksize = srcProperties.ContentLength - copyoffset; } destBlockBlob.StageBlockFromUri(srcUri, id, new global::Azure.HttpRange(copyoffset, blocksize), null, null, null, cancellationToken: this.CmdletCancellationToken); copyoffset += blocksize; progressHandler.Report(copyoffset); } destBlockBlob.CommitBlockList(blockIDs, commitBlockListOptions, this.CmdletCancellationToken); break; case Track2Models.BlobType.Page: case Track2Models.BlobType.Append: default: throw new ArgumentException(string.Format("The cmdlet currently only support souce blob and destination blob are both block blob. The dest blob type is {0}.", destBlobType)); } OutputStream.WriteObject(taskId, new AzureStorageBlob(destBlob, destChannel.StorageContext, null, options: ClientOptions)); } }