internal async Task SetBlobTag(long taskId, IStorageBlobManagement localChannel, CloudBlobContainer container, string blobName)
        {
            if (!NameUtil.IsValidBlobName(blobName))
            {
                throw new ArgumentException(String.Format(Resources.InvalidBlobName, blobName));
            }

            ValidatePipelineCloudBlobContainer(container);

            BlobContainerClient track2container = AzureStorageContainer.GetTrack2BlobContainerClient(container, this.Channel.StorageContext, ClientOptions);

            BlobBaseClient blobClient = Util.GetTrack2BlobClient(track2container, blobName, localChannel.StorageContext, null, false, null, ClientOptions);

            await SetBlobTag(taskId, localChannel, blobClient, true).ConfigureAwait(false);
        }
        public async Task BlobTrigger_IfBoundToCloudBlob_Binds()
        {
            // Arrange
            var container = CreateContainer(blobServiceClient, ContainerName);
            var blob      = container.GetBlockBlobClient(BlobName);

            await blob.UploadTextAsync("ignore");

            // Act
            BlobBaseClient result = await RunTriggerAsync <BlobBaseClient>(typeof(BindToCloudBlobProgram),
                                                                           (s) => BindToCloudBlobProgram.TaskSource = s);

            // Assert
            Assert.AreEqual(blob.Uri, result.Uri);
        }
Example #3
0
        private void CopyBlobSync(IStorageBlobManagement destChannel, BlobBaseClient srcBlobBaseClient, string destContainerName, string destBlobName)
        {
            NameUtil.ValidateContainerName(destContainerName);
            if (string.IsNullOrEmpty(destBlobName))
            {
                destBlobName = srcBlobBaseClient.Name;
            }
            else
            {
                NameUtil.ValidateBlobName(destBlobName);
            }
            BlobBaseClient destBlob = this.GetDestBlob(destChannel, destContainerName, destBlobName, Util.GetBlobType(srcBlobBaseClient));

            this.CopyBlobSync(destChannel, srcBlobBaseClient, destBlob);
        }
Example #4
0
        public async Task HandleAsync_ShouldReturnFalseAndLogEvent_WhenSetMetadataThrows()
        {
            // Arrange
            var     blobUri          = new Uri(_expectedInboxUrl);
            var     appInsightsUri   = new Uri("https://www.appinsights.com");
            JObject operationContext = JsonHelpers.JsonToJObject("{\"something\": \"something value\"}");
            var     metadataData     = new Dictionary <string, string>
            {
                { "key1", "value1" },
                { "key2", "value2" }
            };
            var topicEndpointUri = new Uri("https://www.topichost.com");
            var testEvent        = new EventGridEvent
            {
                EventTime   = DateTime.UtcNow,
                EventType   = CustomEventTypes.RequestCreateMetadata,
                DataVersion = "1.0",
                Data        = JsonConvert.SerializeObject(new RequestBlobMetadataCreateDTO {
                    BlobUri = blobUri, BlobMetadata = JObject.FromObject(metadataData), OperationContext = JObject.FromObject(operationContext)
                })
            };
            var blobBaseClient = new BlobBaseClient(blobUri);
            var blobProperties = new BlobProperties();

            // Arrange Mocks
            Mock.Get(_settingsProvider)
            .Setup(x => x.GetAppSettingsValue(Publishing.TopicOutboundEndpointSettingName))
            .Returns(topicEndpointUri.ToString());
            Mock.Get(_storageService)
            .Setup(x => x.SetBlobMetadataAsync(blobUri, metadataData, It.IsAny <StorageClientProviderContext>()))
            .ThrowsAsync(new ArgumentException("Something's wrong"));
            Mock.Get(_logger)
            .Setup(x => x.LogExceptionObject(
                       out appInsightsUri,
                       LogEventIds.GridwichUnhandledException,
                       It.IsAny <Exception>(),
                       It.IsAny <object>()));

            // Act
            var handleAsyncResult = await _handler.HandleAsync(testEvent).ConfigureAwait(true);

            // Assert
            handleAsyncResult.ShouldBe(false);
            Mock.Get(_logger).Verify(x =>
                                     x.LogExceptionObject(out appInsightsUri, LogEventIds.GridwichUnhandledException, It.IsAny <Exception>(), It.IsAny <object>()),
                                     Times.Once,
                                     "An exception should be logged when the work fails");
        }
Example #5
0
        public PartitionedDownloader(
            BlobBaseClient client,
            StorageTransferOptions transferOptions             = default,
            DownloadTransactionalHashingOptions hashingOptions = default)
        {
            _client = client;

            // Set _maxWorkerCount
            if (transferOptions.MaximumConcurrency.HasValue &&
                transferOptions.MaximumConcurrency > 0)
            {
                _maxWorkerCount = transferOptions.MaximumConcurrency.Value;
            }
            else
            {
                _maxWorkerCount = Constants.Blob.Block.DefaultConcurrentTransfersCount;
            }

            // Set _rangeSize
            if (transferOptions.MaximumTransferSize.HasValue &&
                transferOptions.MaximumTransferSize.Value > 0)
            {
                _rangeSize = Math.Min(transferOptions.MaximumTransferSize.Value, Constants.Blob.Block.MaxDownloadBytes);
            }
            else
            {
                _rangeSize = Constants.DefaultBufferSize;
            }

            // Set _initialRangeSize
            if (transferOptions.InitialTransferSize.HasValue &&
                transferOptions.InitialTransferSize.Value > 0)
            {
                _initialRangeSize = transferOptions.InitialTransferSize.Value;
            }
            else
            {
                _initialRangeSize = Constants.Blob.Block.DefaultInitalDownloadRangeSize;
            }

            // the caller to this stream cannot defer validation, as they cannot access a returned hash
            if (!(hashingOptions?.Validate ?? true))
            {
                throw Errors.CannotDeferTransactionalHashVerification();
            }

            _hashingOptions = hashingOptions;
        }
        public T Convert(BlobBaseClient input)
        {
            if (input == null)
            {
                return(default(T));
            }

            T blob = input as T;

            if (blob == null)
            {
                throw new InvalidOperationException($"The blob is not an {typeof(T).Name}.");
            }

            return(blob);
        }
Example #7
0
        public async Task SetImmutibilityPolicyAsync_Mutable()
        {
            // Arrange
            BlobBaseClient blob = InstrumentClient(_containerClient.GetBlobClient(GetNewBlobName()));

            BlobImmutabilityPolicy immutabilityPolicy = new BlobImmutabilityPolicy
            {
                ExpiresOn  = Recording.UtcNow.AddSeconds(5),
                PolicyMode = BlobImmutabilityPolicyMode.Mutable
            };

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentException>(
                blob.SetImmutabilityPolicyAsync(immutabilityPolicy),
                e => Assert.AreEqual("PolicyMode must be Locked or Unlocked", e.Message));
        }
Example #8
0
        public async Task SetImmutibilityPolicyAsync_Error()
        {
            // Arrange
            BlobBaseClient blob = InstrumentClient(_containerClient.GetBlobClient(GetNewBlobName()));

            BlobImmutabilityPolicy immutabilityPolicy = new BlobImmutabilityPolicy
            {
                ExpiresOn  = Recording.UtcNow.AddSeconds(5),
                PolicyMode = BlobImmutabilityPolicyMode.Locked
            };

            // Act
            await TestHelper.AssertExpectedExceptionAsync <RequestFailedException>(
                blob.SetImmutabilityPolicyAsync(immutabilityPolicy),
                e => Assert.AreEqual(BlobErrorCode.BlobNotFound.ToString(), e.ErrorCode));
        }
        public async Task <ITriggerData> BindAsync(object value, ValueBindingContext context)
        {
            ConversionResult <BlobBaseClient> conversionResult = await _converter.TryConvertAsync(value, context.CancellationToken).ConfigureAwait(false);

            if (!conversionResult.Succeeded)
            {
                throw new InvalidOperationException("Unable to convert trigger to BlobBaseClient.");
            }

            BlobBaseClient blobClient     = conversionResult.Result;
            BlobProperties blobProperties = await blobClient.FetchPropertiesOrNullIfNotExistAsync(cancellationToken : context.CancellationToken).ConfigureAwait(false);

            IReadOnlyDictionary <string, object> bindingData = CreateBindingData(blobClient, blobProperties);

            return(new TriggerData(bindingData));
        }
Example #10
0
        public async Task SetImmutibilityPolicyAsync_InvalidRequestConditions(string invalidCondition)
        {
            // Arrange
            BlobBaseClient blobBaseClient = new BlobBaseClient(new Uri("https://www.doesntmatter.com"), GetOptions());

            BlobImmutabilityPolicy immutabilityPolicy = new BlobImmutabilityPolicy
            {
                ExpiresOn  = Recording.UtcNow.AddMinutes(5),
                PolicyMode = BlobImmutabilityPolicyMode.Unlocked
            };

            BlobRequestConditions conditions = new BlobRequestConditions();

            switch (invalidCondition)
            {
            case nameof(BlobRequestConditions.IfMatch):
                conditions.IfMatch = new ETag();
                break;

            case nameof(BlobRequestConditions.IfModifiedSince):
                conditions.IfModifiedSince = Recording.UtcNow.AddMinutes(5);
                break;

            case nameof(BlobRequestConditions.IfNoneMatch):
                conditions.IfNoneMatch = new ETag();
                break;

            case nameof(BlobRequestConditions.LeaseId):
                conditions.LeaseId = string.Empty;
                break;

            case nameof(BlobRequestConditions.TagConditions):
                conditions.TagConditions = string.Empty;
                break;
            }

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentException>(
                blobBaseClient.SetImmutabilityPolicyAsync(
                    immutabilityPolicy,
                    conditions),
                e =>
            {
                Assert.IsTrue(e.Message.Contains($"SetImmutabilityPolicy does not support the {invalidCondition} condition(s)."));
                Assert.IsTrue(e.Message.Contains("conditions"));
            });
        }
Example #11
0
        /// <summary>
        /// Make sure the pipeline blob is valid and already existing
        /// </summary>
        /// <param name="blob">CloudBlob object</param>
        internal void ValidatePipelineCloudBlobTrack2(BlobBaseClient blob)
        {
            if (null == blob)
            {
                throw new ArgumentException(String.Format(Resources.ObjectCannotBeNull, typeof(CloudBlob).Name));
            }

            if (!NameUtil.IsValidBlobName(blob.Name))
            {
                throw new ArgumentException(String.Format(Resources.InvalidBlobName, blob.Name));
            }

            if (!NameUtil.IsValidContainerName(blob.BlobContainerName))
            {
                throw new ArgumentException(String.Format(Resources.InvalidContainerName, blob.BlobContainerName));
            }
        }
Example #12
0
 public PartitionedDownloader(
     BlobBaseClient client,
     StorageTransferOptions transferOptions = default,
     long?initialTransferLength             = null)
 {
     _client         = client;
     _maxWorkerCount =
         transferOptions.MaximumConcurrency ??
         Constants.Blob.Block.DefaultConcurrentTransfersCount;
     _initialRangeSize =
         initialTransferLength ??
         ((long?)transferOptions.MaximumTransferLength) ??
         Constants.DefaultBufferSize;
     _rangeSize = Math.Min(
         Constants.Blob.Block.MaxDownloadBytes,
         transferOptions.MaximumTransferLength ?? Constants.DefaultBufferSize);
 }
Example #13
0
        /// <summary>
        /// Create a mock sleeve, properly set up so that the two main getter's work.
        /// </summary>
        private static IStorageBlobClientSleeve MockSleeve(BlobBaseClient client, StorageClientProviderContext context)
        {
            Mock.Get(client)
            .SetupGet(x => x.AccountName)
            .Returns(@"ut");

            var sleeve = Mock.Of <IStorageBlobClientSleeve>();

            Mock.Get(sleeve)
            .SetupGet(x => x.Client)
            .Returns(client);
            Mock.Get(sleeve)
            .SetupGet(x => x.Context)
            .Returns(context);

            return(sleeve);
        }
Example #14
0
        private void StartCopyBlob(IStorageBlobManagement destChannel, BlobBaseClient srcCloudBlob, BlobBaseClient destCloudBlob)
        {
            global::Azure.Storage.Blobs.Models.BlobType srcBlobType = Util.GetBlobType(srcCloudBlob, true).Value;
            if (srcCloudBlob is BlobClient)
            {
                srcCloudBlob = Util.GetTrack2BlobClientWithType(srcCloudBlob, Channel.StorageContext, srcBlobType);
            }
            if (destCloudBlob is BlobClient)
            {
                destCloudBlob = Util.GetTrack2BlobClientWithType(destCloudBlob, destChannel.StorageContext, srcBlobType);
            }
            ValidateBlobTier(Util.convertBlobType_Track2ToTrack1(srcBlobType), pageBlobTier, standardBlobTier, rehydratePriority);

            Func <long, Task> taskGenerator = (taskId) => StartCopyAsync(taskId, destChannel, srcCloudBlob, destCloudBlob);

            RunTask(taskGenerator);
        }
Example #15
0
        public async Task SetLegalHoldAsync()
        {
            // Arrange
            await using DisposingImmutableStorageWithVersioningContainer vlwContainer = await GetTestVersionLevelWormContainer(TestConfigOAuth);

            BlobBaseClient blob = await GetNewBlobClient(vlwContainer.Container);

            // Act
            Response <BlobLegalHoldResult> response = await blob.SetLegalHoldAsync(true);

            // Assert
            Assert.IsTrue(response.Value.HasLegalHold);

            // Validate that we are correctly deserializing Get Properties response.
            // Act
            Response <BlobProperties> propertiesResponse = await blob.GetPropertiesAsync();

            // Assert
            Assert.IsTrue(propertiesResponse.Value.HasLegalHold);

            // Validate we are correctly deserializing Blob Items.
            // Act
            List <BlobItem> blobItems = new List <BlobItem>();

            await foreach (BlobItem blobItem in vlwContainer.Container.GetBlobsAsync(traits: BlobTraits.LegalHold))
            {
                blobItems.Add(blobItem);
            }

            // Assert
            Assert.AreEqual(1, blobItems.Count);
            Assert.IsTrue(blobItems[0].Properties.HasLegalHold);

            // Validate we are correctly deserialzing Get Blob response.
            // Act
            Response <BlobDownloadInfo> downloadResponse = await blob.DownloadAsync();

            // Assert
            Assert.IsTrue(downloadResponse.Value.Details.HasLegalHold);

            // Act
            response = await blob.SetLegalHoldAsync(false);

            // Assert
            Assert.IsFalse(response.Value.HasLegalHold);
        }
        public async Task HandleAsync_ShouldReturnFalseAndLogEvents_WhenPublishingThrows()
        {
            // Arrange
            var     blobUri          = new Uri(_expectedInboxUrl);
            JObject operationContext = JObject.Parse("{\"something\": \"something value\"}");
            var     topicEndpointUri = new Uri("https://www.topichost.com");
            var     testEvent        = new EventGridEvent
            {
                EventTime   = DateTime.UtcNow,
                EventType   = CustomEventTypes.RequestBlobCopy,
                DataVersion = "1.0",
                Data        = JsonConvert.SerializeObject(new RequestBlobCopyDTO {
                    SourceUri = blobUri, DestinationUri = blobUri, OperationContext = JObject.FromObject(operationContext)
                })
            };
            var blobBaseClient = new BlobBaseClient(blobUri);
            var blobProperties = new BlobProperties();

            // Arrange Mocks
            Mock.Get(_settingsProvider)
            .Setup(x => x.GetAppSettingsValue(Publishing.TopicOutboundEndpointSettingName))
            .Returns(topicEndpointUri.ToString());
            Mock.Get(_storageService)
            .Setup(x => x.GetBlobMetadataAsync(blobUri, It.IsAny <StorageClientProviderContext>()))
            .ReturnsAsync(new JObject());
            Mock.Get(_eventGridPublisher)
            .Setup(x => x.PublishEventToTopic(It.IsAny <EventGridEvent>()))
            .ThrowsAsync(new InvalidOperationException());

            // Act
            var handleAsyncResult = await _handler.HandleAsync(testEvent).ConfigureAwait(true);

            // Assert
            handleAsyncResult.ShouldBe(false);
            Mock.Get(_logger).Verify(x =>
                                     x.LogExceptionObject(LogEventIds.FailedCriticallyToPublishEvent,
                                                          It.IsAny <Exception>(), It.IsAny <object>()),
                                     Times.AtLeastOnce,
                                     "An exception should be logged when the publishing fails");
            Mock.Get(_logger).Verify(x =>
                                     x.LogEventObject(LogEventIds.FailedToAcknowledge,
                                                      It.IsAny <object>()),
                                     Times.Once,
                                     "An exception should be logged when the acknowledgement fails");
        }
Example #17
0
        public async Task SetImmutibilityPolicyAsync_Mutable()
        {
            // Arrange
            await using DisposingImmutableStorageWithVersioningContainer vlwContainer = await GetTestVersionLevelWormContainer(TestConfigOAuth);

            BlobBaseClient blob = InstrumentClient(vlwContainer.Container.GetBlobClient(GetNewBlobName()));

            BlobImmutabilityPolicy immutabilityPolicy = new BlobImmutabilityPolicy
            {
                ExpiresOn  = Recording.UtcNow.AddSeconds(5),
                PolicyMode = BlobImmutabilityPolicyMode.Mutable
            };

            // Act
            await TestHelper.AssertExpectedExceptionAsync <ArgumentException>(
                blob.SetImmutabilityPolicyAsync(immutabilityPolicy),
                e => Assert.AreEqual("PolicyMode must be Locked or Unlocked", e.Message));
        }
Example #18
0
        public async Task SetImmutibilityPolicyAsync_Error()
        {
            // Arrange
            await using DisposingImmutableStorageWithVersioningContainer vlwContainer = await GetTestVersionLevelWormContainer(TestConfigOAuth);

            BlobBaseClient blob = InstrumentClient(vlwContainer.Container.GetBlobClient(GetNewBlobName()));

            BlobImmutabilityPolicy immutabilityPolicy = new BlobImmutabilityPolicy
            {
                ExpiresOn  = Recording.UtcNow.AddSeconds(5),
                PolicyMode = BlobImmutabilityPolicyMode.Locked
            };

            // Act
            await TestHelper.AssertExpectedExceptionAsync <RequestFailedException>(
                blob.SetImmutabilityPolicyAsync(immutabilityPolicy),
                e => Assert.AreEqual(BlobErrorCode.BlobNotFound.ToString(), e.ErrorCode));
        }
Example #19
0
        public async Task SetLegalHoldAsync()
        {
            // Arrange
            BlobBaseClient blob = await GetNewBlobClient(_containerClient);

            // Act
            Response <BlobLegalHoldResult> response = await blob.SetLegalHoldAsync(true);

            // Assert
            Assert.IsTrue(response.Value.HasLegalHold);

            // Validate that we are correctly deserializing Get Properties response.
            // Act
            Response <BlobProperties> propertiesResponse = await blob.GetPropertiesAsync();

            // Assert
            Assert.IsTrue(propertiesResponse.Value.HasLegalHold);

            // Validate we are correctly deserializing Blob Items.
            // Act
            List <BlobItem> blobItems = new List <BlobItem>();

            await foreach (BlobItem blobItem in _containerClient.GetBlobsAsync(traits: BlobTraits.LegalHold, prefix: blob.Name))
            {
                blobItems.Add(blobItem);
            }

            // Assert
            Assert.AreEqual(1, blobItems.Count);
            Assert.IsTrue(blobItems[0].Properties.HasLegalHold);

            // Validate we are correctly deserialzing Get Blob response.
            // Act
            Response <BlobDownloadInfo> downloadResponse = await blob.DownloadAsync();

            // Assert
            Assert.IsTrue(downloadResponse.Value.Details.HasLegalHold);

            // Act
            response = await blob.SetLegalHoldAsync(false);

            // Assert
            Assert.IsFalse(response.Value.HasLegalHold);
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
            ILogger log)
        {
            // Try to get the blobUri from the request parameters:
            string blobUri = req?.Query["blobUri"];

            blobUri ??= HttpUtility.UrlDecode(blobUri);

            // Replace with the blobUri from the body, if it exists:
            using (var sr = new StreamReader(req?.Body))
            {
                string requestBody = await sr.ReadToEndAsync().ConfigureAwait(false);

                dynamic data = JsonConvert.DeserializeObject(requestBody);
                blobUri ??= data?.blobUri;
            }

            // If we have a blobUri, try to get the ContentLength:
            long contentLength = -1;

            try
            {
                if (Uri.TryCreate(blobUri, UriKind.Absolute, out Uri requestedUri))
                {
                    var blobBaseClient = new BlobBaseClient(requestedUri, _tokenCredential);
                    var props          = await blobBaseClient.GetPropertiesAsync().ConfigureAwait(false);

                    contentLength = props.Value.ContentLength;
                }
            }
            catch (Azure.RequestFailedException e) when(e.ErrorCode == "AuthorizationPermissionMismatch")
            {
                return(new BadRequestObjectResult(new { error = $"BlobBaseClient.GetPropertiesAsync requires the identity principal to have role 'Storage Blob Data Reader' on resource (file, container, resource-group, or subscription).\n\n\nException.Message:\n\n{e.Message}" }));
            }
            catch (Exception e)
            {
                return(new BadRequestObjectResult(new { error = $"Exception.Message:\n{e.Message}\n\nInnerException.Message:\n{e.InnerException?.Message}" }));
            }

            log.LogInformation($"BlobUri: {blobUri}, ContentLength: {contentLength}");

            return(new OkObjectResult(contentLength));
        }
Example #21
0
        /// <summary>
        /// Create a mock sleeve, properly set up so that the two main getter's work.
        /// </summary>
        private static IStorageBlobClientSleeve MockSleeve(BlobBaseClient client, StorageClientProviderContext context)
        {
            Mock.Get(client)
            .SetupGet(x => x.AccountName)
            .Returns(@"ut");

            var serviceClient = new BlobServiceClient(new Uri($@"https://{client.AccountName}.blob.core.windows.net"));

            var sleeve = Mock.Of <IStorageBlobClientSleeve>();

            Mock.Get(sleeve)
            .SetupGet(x => x.Client)
            .Returns(client);
            Mock.Get(sleeve)
            .SetupGet(x => x.Context)
            .Returns(context);

            return(sleeve);
        }
        /// <summary>
        /// Creates a BlobClientSleeve (BlobBaseClient + Context).  Called when one does not exist yet.
        /// </summary>
        /// <param name="blobUri">The target Uri.</param>
        /// <param name="ctx">The context.</param>
        /// <returns>
        /// A BlobBaseClient object.
        /// </returns>
        internal StorageBlobClientSleeve CreateBlobClientSleeveForUri(Uri blobUri, StorageClientProviderContext ctx)
        {
            BlobBaseClient blobBaseClient;
            BlobUriBuilder blobUriBuilder;

            var contextCopy       = new StorageClientProviderContext(ctx);
            var blobClientOptions = new BlobClientOptions();

            try
            {
                blobUriBuilder = new BlobUriBuilder(blobUri);
                var clientRequestIdPolicy = new BlobClientPipelinePolicy(contextCopy);
                blobClientOptions.AddPolicy(clientRequestIdPolicy, HttpPipelinePosition.PerCall);
                blobBaseClient = new BlobBaseClient(blobUri, _identity, blobClientOptions);
            }
            catch (Exception e)
            {
                _log.LogExceptionObject(LogEventIds.BlobBaseClientProviderFailedToCreateBlobBaseClient, e, blobUri);
                throw;
            }

            try
            {
                // BlobUriBuilder SDK class will just give null for Accountname if URL is malformed, so let flow upwards
                _ = StringHelpers.NullIfNullOrWhiteSpace(blobUriBuilder.AccountName) ?? throw new UriFormatException($@"Malformed Azure Storage URL: {blobUri}");

                var accountUri = StorageHelpers.BuildStorageAccountUri(blobUriBuilder.AccountName, buildForBlobService: true);
                var newSleeve  = new StorageBlobClientSleeve(blobBaseClient,
                                                             new BlobServiceClient(accountUri, _identity, blobClientOptions),
                                                             contextCopy);
                return(newSleeve);
            }
            catch (UriFormatException uriex)
            {
                _log.LogExceptionObject(LogEventIds.BlobBaseClientProviderUriMissingAccountName, uriex, blobUri);
                throw new ArgumentException(LogEventIds.BlobBaseClientProviderUriMissingAccountName.Name, nameof(blobUri), uriex);
            }
            catch (ArgumentException aex)
            {
                _log.LogExceptionObject(LogEventIds.BlobBaseClientProviderUriMissingAccountName, aex, blobUri);
                throw;
            }
        }
            private async Task <IEnumerable <T> > ConvertBlobs(IAsyncEnumerable <BlobItem> blobItems, BlobContainerClient blobContainerClient)
            {
                var list = new List <T>();

                await foreach (var blobItem in blobItems.ConfigureAwait(false))
                {
                    BlobBaseClient src = null;
                    switch (blobItem.Properties.BlobType)
                    {
                    case BlobType.Block:
                        if (typeof(T) == typeof(BlobClient))
                        {
                            // BlobClient is simplified version of BlockBlobClient, i.e. upload results in creation of block blob.
                            src = blobContainerClient.GetBlobClient(blobItem.Name);
                        }
                        else
                        {
                            src = blobContainerClient.GetBlockBlobClient(blobItem.Name);
                        }
                        break;

                    case BlobType.Append:
                        src = blobContainerClient.GetAppendBlobClient(blobItem.Name);
                        break;

                    case BlobType.Page:
                        src = blobContainerClient.GetPageBlobClient(blobItem.Name);
                        break;

                    default:
                        throw new InvalidOperationException($"Unexpected blob type {blobItem.Properties.BlobType}");
                    }

                    var funcCtx  = new FunctionBindingContext(Guid.Empty, CancellationToken.None);
                    var valueCtx = new ValueBindingContext(funcCtx, CancellationToken.None);

                    var converted = await _converter(src, null, valueCtx).ConfigureAwait(false);

                    list.Add(converted);
                }

                return(list);
            }
Example #24
0
        public void TestUploadToWrongBlobType([Values("block", "page", "append")] string actualType)
        {
            var blobName = Guid.NewGuid().ToString();

            var createFunctions = new Dictionary <string, Action>
            {
                ["block"]  = () => new BlockBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName).Upload(Stream.Null),
                ["page"]   = () => new PageBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName).CreateIfNotExists(size: 0),
                ["append"] = () => new AppendBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName).CreateIfNotExists()
            };

            // right now append blobs aren't fully supported, so we can't fully test this
            if (actualType == "append")
            {
                Assert.Throws <RequestFailedException>(() => createFunctions[actualType]())
                .ErrorCode.ShouldEqual("FeatureNotSupportedByEmulator");
                return;
            }
            else
            {
                createFunctions.Remove("append"); // to prevent it from failing below
            }

            var baseClient = new BlobBaseClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName);

            Assert.IsFalse(baseClient.Exists());
            createFunctions[actualType]();
            Assert.IsTrue(baseClient.Exists());

            foreach (var kvp in createFunctions)
            {
                if (kvp.Key == actualType)
                {
                    Assert.DoesNotThrow(() => kvp.Value());
                }
                else
                {
                    Assert.Throws <RequestFailedException>(() => kvp.Value())
                    .ErrorCode.ShouldEqual("InvalidBlobType");
                }
            }
        }
Example #25
0
        /// <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;
            }
        }
Example #26
0
        /// <summary>
        /// get blob content
        /// </summary>
        /// <param name="blob">source BlobBaseClient object</param>
        /// <param name="fileName">destination file path</param>
        /// <param name="isValidBlob">whether the source container validated</param>
        /// <returns>the downloaded AzureStorageBlob object</returns>
        internal void GetBlobContent(BlobBaseClient blob, string fileName, bool isValidBlob = false)
        {
            if (null == blob)
            {
                throw new ArgumentNullException(typeof(CloudBlob).Name, String.Format(Resources.ObjectCannotBeNull, typeof(CloudBlob).Name));
            }

            if (!isValidBlob)
            {
                ValidatePipelineCloudBlobTrack2(blob);
            }

            //skip download the snapshot except the CloudBlob pipeline
            DateTimeOffset?snapshotTime = Util.GetSnapshotTimeFromBlobUri(blob.Uri);

            if (snapshotTime != null && ParameterSetName != BlobParameterSet)
            {
                WriteWarning(String.Format(Resources.SkipDownloadSnapshot, blob.Name, snapshotTime));
                return;
            }

            string filePath = GetFullReceiveFilePath(fileName, blob.Name, snapshotTime);

            if (!isValidBlob)
            {
                ValidatePipelineCloudBlobTrack2(blob);
            }

            //create the destination directory if not exists.
            String dirPath = Path.GetDirectoryName(filePath);

            if (!Directory.Exists(dirPath))
            {
                Directory.CreateDirectory(dirPath);
            }

            IStorageBlobManagement localChannel  = Channel;
            Func <long, Task>      taskGenerator = (taskId) => DownloadBlob(taskId, localChannel, blob, filePath);

            RunTask(taskGenerator);
        }
        private IReadOnlyDictionary <string, object> CreateBindingData(BlobBaseClient value, BlobProperties blobProperties)
        {
            var bindingData = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase);

            bindingData.Add("BlobTrigger", value.GetBlobPath());
            bindingData.Add("Uri", value.Uri);
            bindingData.Add("Properties", blobProperties);
            bindingData.Add("Metadata", blobProperties.Metadata);

            IReadOnlyDictionary <string, object> bindingDataFromPath = _path.CreateBindingData(value.ToBlobPath());

            if (bindingDataFromPath != null)
            {
                foreach (KeyValuePair <string, object> item in bindingDataFromPath)
                {
                    // In case of conflict, binding data from the value type overrides the built-in binding data above.
                    bindingData[item.Key] = item.Value;
                }
            }
            return(bindingData);
        }
Example #28
0
        /// <inheritdoc/>
        public async Task <BlobDownloadInfo> DownloadHttpRangeAsync(Uri blobUri, HttpRange httpRange = default)
        {
            _ = blobUri ?? throw new ArgumentNullException(nameof(blobUri));
            var blobBaseClient = new BlobBaseClient(blobUri, _tokenCredential);

            // Note: when the httpRange struct is omitted it defaults to 'default' which downloads the entire blob.
            BlobDownloadInfo blobDownloadInfo;

            try
            {
                blobDownloadInfo = (await blobBaseClient.DownloadAsync(httpRange).ConfigureAwait(false)).Value;
            }
            catch (Exception e)
            {
                var message = $"Could not download the HTTP range for {blobUri}.";
                _log.LogError(message, e);
                throw new Exception(message, e);
            }

            return(blobDownloadInfo);
        }
Example #29
0
        private void CopyBlobSync(IStorageBlobManagement destChannel, BlobBaseClient srcCloudBlob, BlobBaseClient destCloudBlob)
        {
            Track2Models.BlobType srcBlobType = Util.GetBlobType(srcCloudBlob, true).Value;
            if (srcBlobType != Track2Models.BlobType.Block)
            {
                throw new ArgumentException(string.Format("The cmdlet currently only support souce blob and destination blob are both block blob. The source blob type is {0}.", srcBlobType));
            }

            if (srcCloudBlob is BlobClient)
            {
                srcCloudBlob = Util.GetTrack2BlobClientWithType(srcCloudBlob, Channel.StorageContext, srcBlobType, ClientOptions);
            }
            if (destCloudBlob is BlobClient)
            {
                destCloudBlob = Util.GetTrack2BlobClientWithType(destCloudBlob, destChannel.StorageContext, srcBlobType, ClientOptions);
            }

            Func <long, Task> taskGenerator = (taskId) => CopyFromUri(taskId, destChannel, srcCloudBlob.GenerateUriWithCredentials(Channel.StorageContext), destCloudBlob);

            RunTask(taskGenerator);
        }
Example #30
0
        public async Task SetImmutibilityPolicyAsync_SetLegalHold_AccoutnSas(AccountSasPermissions sasPermissions)
        {
            // Arrange
            await using DisposingImmutableStorageWithVersioningContainer vlwContainer = await GetTestVersionLevelWormContainer(TestConfigOAuth);

            BlobBaseClient blob = await GetNewBlobClient(vlwContainer.Container, GetNewBlobName());

            BlobServiceClient sharedKeyServiceClient = InstrumentClient(
                GetServiceClient_OAuthAccount_SharedKey());
            Uri serviceSasUri = sharedKeyServiceClient.GenerateAccountSasUri(
                sasPermissions,
                Recording.UtcNow.AddDays(1),
                AccountSasResourceTypes.All);
            BlobBaseClient sasBlobClient = InstrumentClient(new BlobServiceClient(serviceSasUri, GetOptions())
                                                            .GetBlobContainerClient(vlwContainer.Container.Name)
                                                            .GetBlobBaseClient(blob.Name));

            BlobImmutabilityPolicy immutabilityPolicy = new BlobImmutabilityPolicy
            {
                ExpiresOn  = Recording.UtcNow.AddMinutes(5),
                PolicyMode = BlobImmutabilityPolicyMode.Unlocked
            };

            // The service rounds Immutability Policy Expiry to the nearest second.
            DateTimeOffset expectedImmutabilityPolicyExpiry = RoundToNearestSecond(immutabilityPolicy.ExpiresOn.Value);

            // Act
            Response <BlobImmutabilityPolicy> response = await sasBlobClient.SetImmutabilityPolicyAsync(
                immutabilityPolicy : immutabilityPolicy);

            // Assert
            Assert.AreEqual(expectedImmutabilityPolicyExpiry, response.Value.ExpiresOn);
            Assert.AreEqual(immutabilityPolicy.PolicyMode, response.Value.PolicyMode);

            // Act
            Response <BlobLegalHoldResult> legalHoldResponse = await sasBlobClient.SetLegalHoldAsync(hasLegalHold : false);

            // Assert
            Assert.IsFalse(legalHoldResponse.Value.HasLegalHold);
        }