private void SetProperties(BlobBaseClient track2BlobClient, AzureStorageContext storageContext, global::Azure.Storage.Blobs.Models.BlobProperties blobProperties = null, BlobClientOptions options = null) { if (blobProperties == null) { try { privateBlobProperties = track2BlobClient.GetProperties().Value; } catch (global::Azure.RequestFailedException e) when(e.Status == 403 || e.Status == 404) { // privateBlobProperties will be null when there are no permission to get blob proeprties, or blob is already deleted. } } else { privateBlobProperties = blobProperties; } this.privateBlobBaseClient = track2BlobClient; Name = track2BlobClient.Name; this.Context = storageContext; privateClientOptions = options; if (privateBlobProperties is null) { ICloudBlob = GetTrack1Blob(track2BlobClient, storageContext.StorageAccount.Credentials, null); } else { ICloudBlob = GetTrack1Blob(track2BlobClient, storageContext.StorageAccount.Credentials, privateBlobProperties.BlobType); } if (!(ICloudBlob is InvalidCloudBlob)) { BlobType = ICloudBlob.BlobType; SnapshotTime = ICloudBlob.SnapshotTime; } else // This code might should not be necessary, since currently only blob version will has Track1 Blob as null, and blob veresion won't have snapshot time { SnapshotTime = Util.GetSnapshotTimeFromBlobUri(track2BlobClient.Uri); } // Set the AzureStorageBlob Properties if (privateBlobProperties != null) { Length = privateBlobProperties.ContentLength; ContentType = privateBlobProperties.ContentType; LastModified = privateBlobProperties.LastModified; VersionId = privateBlobProperties.VersionId; IsLatestVersion = privateBlobProperties.IsLatestVersion; if (ICloudBlob is InvalidCloudBlob) { BlobType = Util.convertBlobType_Track2ToTrack1(privateBlobProperties.BlobType); } AccessTier = privateBlobProperties.AccessTier is null ? null : privateBlobProperties.AccessTier.ToString(); TagCount = privateBlobProperties.TagCount; } }
/// <summary> /// Download blob to local file /// </summary> /// <param name="blob">Source blob object</param> /// <param name="filePath">Destination file path</param> internal virtual async Task DownloadBlob(long taskId, IStorageBlobManagement localChannel, BlobBaseClient blob, string filePath) { Track2Models.BlobProperties blobProperties = blob.GetProperties(cancellationToken: CmdletCancellationToken); if (this.Force.IsPresent || !System.IO.File.Exists(filePath) || ShouldContinue(string.Format(Resources.OverwriteConfirmation, filePath), null)) { StorageTransferOptions trasnferOption = new StorageTransferOptions() { MaximumConcurrency = this.GetCmdletConcurrency(), MaximumTransferSize = size4MB, InitialTransferSize = size4MB }; await blob.DownloadToAsync(filePath, BlobRequestConditions, trasnferOption, CmdletCancellationToken).ConfigureAwait(false); OutputStream.WriteObject(taskId, new AzureStorageBlob(blob, localChannel.StorageContext, blobProperties, options: ClientOptions)); } }
//refresh XSCL track2 blob properties object from server public void FetchAttributes() { privateBlobProperties = BlobBaseClient.GetProperties().Value; }
public AzureStorageBlob(BlobBaseClient track2BlobClient, AzureStorageContext storageContext, global::Azure.Storage.Blobs.Models.BlobProperties blobProperties, BlobClientOptions options = null) { SetProperties(track2BlobClient, storageContext, blobProperties, options); }
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)); } }