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> /// Check for the latest status of the copy operation. /// </summary> /// <param name="cancellationToken"> /// Optional <see cref="CancellationToken"/> to propagate /// notifications that the operation should be cancelled. /// </param> /// <param name="async" /> /// <returns>The <see cref="Response"/> with the status update.</returns> private async Task <Response> UpdateStatusAsync(bool async, CancellationToken cancellationToken) { // Short-circuit when already completed (which improves mocking // scenarios that won't have a client). if (HasCompleted) { return(GetRawResponse()); } // Use our original CancellationToken if the user didn't provide one if (cancellationToken == default) { cancellationToken = _cancellationToken; } // Get the latest status Response <BlobProperties> update = async ? await _client.GetPropertiesAsync(cancellationToken : cancellationToken).ConfigureAwait(false) : _client.GetProperties(cancellationToken: cancellationToken); // Check if the operation is no longer running if (Id != update.Value.CopyId || update.Value.CopyStatus != CopyStatus.Pending) { _hasCompleted = true; } // Check if the operation succeeded if (Id == update.Value.CopyId && update.Value.CopyStatus == CopyStatus.Success) { _value = update.Value.ContentLength; } // Check if the operation aborted or failed if (Id == update.Value.CopyId && (update.Value.CopyStatus == CopyStatus.Aborted || update.Value.CopyStatus == CopyStatus.Failed)) { _value = 0; } // Save this update as the latest raw response indicating the state // of the copy operation Response response = update.GetRawResponse(); _rawResponse = response; return(response); }
/// <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)); } }
/// <summary> /// Azure storage blob constructor /// </summary> /// <param name="blob">ICloud blob object</param> public AzureStorageBlob(BlobBaseClient track2BlobClient, AzureStorageContext storageContext, BlobClientOptions options = null, BlobItem listBlobItem = null) { if (listBlobItem == null) { SetProperties(track2BlobClient, storageContext, track2BlobClient.GetProperties().Value, options); return; } this.privateBlobBaseClient = track2BlobClient; Name = track2BlobClient.Name; this.Context = storageContext; privateClientOptions = options; ICloudBlob = GetTrack1Blob(track2BlobClient, storageContext.StorageAccount.Credentials, listBlobItem.Properties.BlobType); if (!(ICloudBlob is InvalidCloudBlob)) { BlobType = ICloudBlob.BlobType; SnapshotTime = ICloudBlob.SnapshotTime; } else { BlobType = Util.convertBlobType_Track2ToTrack1(listBlobItem.Properties.BlobType); if (listBlobItem.Snapshot != null) { SnapshotTime = DateTimeOffset.Parse(listBlobItem.Snapshot); } } // Set the AzureStorageBlob Properties Length = listBlobItem.Properties.ContentLength is null ? 0 : listBlobItem.Properties.ContentLength.Value; IsDeleted = listBlobItem.Deleted; RemainingDaysBeforePermanentDelete = listBlobItem.Properties.RemainingRetentionDays; ContentType = listBlobItem.Properties.ContentType; LastModified = listBlobItem.Properties.LastModified; VersionId = listBlobItem.VersionId; IsLatestVersion = listBlobItem.IsLatestVersion; AccessTier = listBlobItem.Properties.AccessTier is null? null: listBlobItem.Properties.AccessTier.ToString(); if (listBlobItem.Tags != null) { Tags = listBlobItem.Tags.ToHashtable(); TagCount = listBlobItem.Tags.Count; } }
/// <summary> /// Get the Blob Type of the Track2 Blob client type /// </summary> /// <param name="blob"></param> /// <param name="CheckOnServer"> If Track2 blob Client don't contain blob type inforamtion, try to get it on server</param> public static global::Azure.Storage.Blobs.Models.BlobType?GetBlobType(BlobBaseClient blob, bool CheckOnServer = false) { if (blob is BlockBlobClient) { return(global::Azure.Storage.Blobs.Models.BlobType.Block); } if (blob is PageBlobClient) { return(global::Azure.Storage.Blobs.Models.BlobType.Page); } if (blob is AppendBlobClient) { return(global::Azure.Storage.Blobs.Models.BlobType.Append); } if (!CheckOnServer) { return(null); } else { return(blob.GetProperties().Value.BlobType); } }
/// <summary> /// list blobs by blob name and container name /// </summary> /// <param name="containerName">container name</param> /// <param name="blobName">blob name pattern</param> /// <returns>An enumerable collection of IListBlobItem</returns> internal async Task ListBlobsByName(long taskId, IStorageBlobManagement localChannel, string containerName, string blobName, bool includeDeleted = false, bool includeVersion = false) { CloudBlobContainer container = null; BlobRequestOptions requestOptions = RequestOptions; AccessCondition accessCondition = null; string prefix = string.Empty; if (String.IsNullOrEmpty(blobName) || WildcardPattern.ContainsWildcardCharacters(blobName) || includeDeleted) { container = await GetCloudBlobContainerByName(localChannel, containerName).ConfigureAwait(false); prefix = NameUtil.GetNonWildcardPrefix(blobName); WildcardOptions options = WildcardOptions.IgnoreCase | WildcardOptions.Compiled; WildcardPattern wildcard = null; if (!String.IsNullOrEmpty(blobName)) { wildcard = new WildcardPattern(blobName, options); } Func <string, bool> blobFilter = (blobNameToFilte) => wildcard == null || wildcard.IsMatch(blobNameToFilte); await ListBlobsByPrefix(taskId, localChannel, containerName, prefix, blobFilter, includeDeleted, IncludeVersion).ConfigureAwait(false); } else { container = await GetCloudBlobContainerByName(localChannel, containerName, true).ConfigureAwait(false); BlobContainerClient track2container = AzureStorageContainer.GetTrack2BlobContainerClient(container, localChannel.StorageContext, ClientOptions); if (!NameUtil.IsValidBlobName(blobName)) { throw new ArgumentException(String.Format(Resources.InvalidBlobName, blobName)); } BlobBaseClient blobClient = null; if (UseTrack2Sdk()) // User Track2 SDK { blobClient = Util.GetTrack2BlobClient(track2container, blobName, localChannel.StorageContext, this.VersionId, false, this.SnapshotTime is null ? null : this.SnapshotTime.Value.ToString("o"), ClientOptions); global::Azure.Storage.Blobs.Models.BlobProperties blobProperties; try { blobProperties = blobClient.GetProperties(BlobRequestConditions, cancellationToken: CmdletCancellationToken); } catch (global::Azure.RequestFailedException e) when(e.Status == 404) { throw new ResourceNotFoundException(String.Format(Resources.BlobNotFound, blobName, containerName)); } blobClient = Util.GetTrack2BlobClient(track2container, blobName, localChannel.StorageContext, this.VersionId, blobProperties.IsLatestVersion, this.SnapshotTime is null ? null : this.SnapshotTime.Value.ToString("o"), ClientOptions, blobProperties.BlobType); AzureStorageBlob outputBlob = new AzureStorageBlob(blobClient, localChannel.StorageContext, blobProperties, ClientOptions); OutputStream.WriteObject(taskId, outputBlob); } else // Use Track1 SDK { CloudBlob blob = await localChannel.GetBlobReferenceFromServerAsync(container, blobName, this.SnapshotTime, accessCondition, requestOptions, OperationContext, CmdletCancellationToken).ConfigureAwait(false); if (null == blob) { throw new ResourceNotFoundException(String.Format(Resources.BlobNotFound, blobName, containerName)); } else { OutputStream.WriteObject(taskId, new AzureStorageBlob(blob, localChannel.StorageContext, ClientOptions)); } } } }
//refresh XSCL track2 blob properties object from server public void FetchAttributes() { privateBlobProperties = BlobBaseClient.GetProperties().Value; }
/// <summary> /// Stop copy operation by CloudBlob object /// </summary> /// <param name="blob">CloudBlob object</param> /// <param name="copyId">Copy id</param> private async Task StopCopyBlob(long taskId, IStorageBlobManagement localChannel, CloudBlob blob, string copyId, bool fetchCopyIdFromBlob = false) { ValidateBlobType(blob); if (UseTrack2SDK()) // Use Track2 { if (null == blob) { throw new ArgumentException(String.Format(Resources.ObjectCannotBeNull, typeof(CloudBlob).Name)); } BlobBaseClient blobBaseClient = AzureStorageBlob.GetTrack2BlobClient(blob, Channel.StorageContext, this.ClientOptions); string specifiedCopyId = copyId; if (string.IsNullOrEmpty(specifiedCopyId) && fetchCopyIdFromBlob) { if (blob.CopyState != null) { specifiedCopyId = blob.CopyState.CopyId; } } string abortCopyId = string.Empty; if (string.IsNullOrEmpty(specifiedCopyId) || Force) { //Make sure we use the correct copy id to abort //Use default retry policy for FetchBlobAttributes Track2Models.BlobProperties blobProperties = blobBaseClient.GetProperties(this.BlobRequestConditions, this.CmdletCancellationToken).Value; if (String.IsNullOrEmpty(blobProperties.CopyId)) { ArgumentException e = new ArgumentException(String.Format(Resources.CopyTaskNotFound, blobBaseClient.Name, blobBaseClient.BlobContainerName)); OutputStream.WriteError(taskId, e); } else { abortCopyId = blobProperties.CopyId; } if (!Force) { string confirmation = String.Format(Resources.ConfirmAbortCopyOperation, blobBaseClient.Name, blobBaseClient.BlobContainerName, abortCopyId); if (!await OutputStream.ConfirmAsync(confirmation).ConfigureAwait(false)) { string cancelMessage = String.Format(Resources.StopCopyOperationCancelled, blobBaseClient.Name, blobBaseClient.BlobContainerName); OutputStream.WriteVerbose(taskId, cancelMessage); } } } else { abortCopyId = specifiedCopyId; } await blobBaseClient.AbortCopyFromUriAsync(abortCopyId, this.BlobRequestConditions, this.CmdletCancellationToken).ConfigureAwait(false); //localChannel.AbortCopyAsync(blob, abortCopyId, accessCondition, abortRequestOption, OperationContext, CmdletCancellationToken).ConfigureAwait(false); string message = String.Format(Resources.StopCopyBlobSuccessfully, blobBaseClient.Name, blobBaseClient.BlobContainerName); OutputStream.WriteObject(taskId, message); } else // use Track1 { AccessCondition accessCondition = null; BlobRequestOptions abortRequestOption = RequestOptions ?? new BlobRequestOptions(); //Set no retry to resolve the 409 conflict exception abortRequestOption.RetryPolicy = new NoRetry(); if (null == blob) { throw new ArgumentException(String.Format(Resources.ObjectCannotBeNull, typeof(CloudBlob).Name)); } string specifiedCopyId = copyId; if (string.IsNullOrEmpty(specifiedCopyId) && fetchCopyIdFromBlob) { if (blob.CopyState != null) { specifiedCopyId = blob.CopyState.CopyId; } } string abortCopyId = string.Empty; if (string.IsNullOrEmpty(specifiedCopyId) || Force) { //Make sure we use the correct copy id to abort //Use default retry policy for FetchBlobAttributes BlobRequestOptions options = RequestOptions; await localChannel.FetchBlobAttributesAsync(blob, accessCondition, options, OperationContext, CmdletCancellationToken).ConfigureAwait(false); if (blob.CopyState == null || String.IsNullOrEmpty(blob.CopyState.CopyId)) { ArgumentException e = new ArgumentException(String.Format(Resources.CopyTaskNotFound, blob.Name, blob.Container.Name)); OutputStream.WriteError(taskId, e); } else { abortCopyId = blob.CopyState.CopyId; } if (!Force) { string confirmation = String.Format(Resources.ConfirmAbortCopyOperation, blob.Name, blob.Container.Name, abortCopyId); if (!await OutputStream.ConfirmAsync(confirmation).ConfigureAwait(false)) { string cancelMessage = String.Format(Resources.StopCopyOperationCancelled, blob.Name, blob.Container.Name); OutputStream.WriteVerbose(taskId, cancelMessage); } } } else { abortCopyId = specifiedCopyId; } await localChannel.AbortCopyAsync(blob, abortCopyId, accessCondition, abortRequestOption, OperationContext, CmdletCancellationToken).ConfigureAwait(false); string message = String.Format(Resources.StopCopyBlobSuccessfully, blob.Name, blob.Container.Name); OutputStream.WriteObject(taskId, message); } }