public async Task CloudBlobContainerConditionalAccessAsync() { OperationContext operationContext = new OperationContext(); CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); await container.FetchAttributesAsync(); string currentETag = container.Properties.ETag; DateTimeOffset currentModifiedTime = container.Properties.LastModified.Value; // ETag conditional tests container.Metadata["ETagConditionalName"] = "ETagConditionalValue"; await container.SetMetadataAsync(); await container.FetchAttributesAsync(); string newETag = container.Properties.ETag; Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); // LastModifiedTime tests currentModifiedTime = container.Properties.LastModified.Value; container.Metadata["DateConditionalName"] = "DateConditionalValue"; await TestHelper.ExpectedExceptionAsync( async() => await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(currentModifiedTime), null, operationContext), operationContext, "IfModifiedSince conditional on current modified time should throw", HttpStatusCode.PreconditionFailed, "ConditionNotMet"); container.Metadata["DateConditionalName"] = "DateConditionalValue2"; currentETag = container.Properties.ETag; DateTimeOffset pastTime = currentModifiedTime.Subtract(TimeSpan.FromMinutes(5)); await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); pastTime = currentModifiedTime.Subtract(TimeSpan.FromHours(5)); await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); pastTime = currentModifiedTime.Subtract(TimeSpan.FromDays(5)); await container.SetMetadataAsync(AccessCondition.GenerateIfModifiedSinceCondition(pastTime), null, null); await container.FetchAttributesAsync(); newETag = container.Properties.ETag; Assert.AreNotEqual(newETag, currentETag, "ETage should be modified on write metadata"); } finally { container.DeleteIfExistsAsync().Wait(); } }
public async Task CloudBlobContainerSetMetadataAsync() { CloudBlobContainer container = GetRandomContainerReference(); try { await container.CreateAsync(); CloudBlobContainer container2 = container.ServiceClient.GetContainerReference(container.Name); await container2.FetchAttributesAsync(); Assert.AreEqual(0, container2.Metadata.Count); container.Metadata.Add("key1", "value1"); await container.SetMetadataAsync(); await container2.FetchAttributesAsync(); Assert.AreEqual(1, container2.Metadata.Count); Assert.AreEqual("value1", container2.Metadata["key1"]); ContainerResultSegment results = await container.ServiceClient.ListContainersSegmentedAsync(container.Name, ContainerListingDetails.Metadata, null, null, null, null); CloudBlobContainer container3 = results.Results.First(); Assert.AreEqual(1, container3.Metadata.Count); Assert.AreEqual("value1", container3.Metadata["key1"]); container.Metadata.Clear(); await container.SetMetadataAsync(); await container2.FetchAttributesAsync(); Assert.AreEqual(0, container2.Metadata.Count); } finally { container.DeleteIfExistsAsync().AsTask().Wait(); } }
/// <summary> /// Add some sample metadata to the container. /// </summary> /// <param name="container">A CloudBlobContainer object.</param> /// <returns>A Task object.</returns> private static async Task AddContainerMetadataAsync(CloudBlobContainer container) { try { // Add some metadata to the container. container.Metadata.Add("docType", "textDocuments"); container.Metadata["category"] = "guidance"; // Set the container's metadata asynchronously. await container.SetMetadataAsync(); } catch (StorageException e) { Console.WriteLine(e.Message); Console.ReadLine(); throw; } }
/// <summary> /// Test container reads and writes, expecting success. /// </summary> /// <param name="testContainer">The container.</param> /// <param name="testAccessCondition">The access condition to use.</param> private async Task ContainerReadWriteExpectLeaseSuccessAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition) { await testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, null); await testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, null); await testContainer.SetMetadataAsync(testAccessCondition, null /* options */, null); await testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, null); }
/// <summary> /// Test container reads and writes, expecting lease failure. /// </summary> /// <param name="testContainer">The container.</param> /// <param name="testAccessCondition">The failing access condition to use.</param> /// <param name="expectedErrorCode">The expected error code.</param> /// <param name="description">The reason why these calls should fail.</param> private async Task ContainerReadWriteExpectLeaseFailureAsync(CloudBlobContainer testContainer, AccessCondition testAccessCondition, HttpStatusCode expectedStatusCode, string expectedErrorCode, string description) { OperationContext operationContext = new OperationContext(); // FetchAttributes is a HEAD request with no extended error info, so it returns with the generic ConditionFailed error code. await TestHelper.ExpectedExceptionAsync( async () => await testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, operationContext), operationContext, description + "(Fetch Attributes)", HttpStatusCode.PreconditionFailed); await TestHelper.ExpectedExceptionAsync( async () => await testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, operationContext), operationContext, description + " (Get Permissions)", expectedStatusCode, expectedErrorCode); await TestHelper.ExpectedExceptionAsync( async () => await testContainer.SetMetadataAsync(testAccessCondition, null /* options */, operationContext), operationContext, description + " (Set Metadata)", expectedStatusCode, expectedErrorCode); await TestHelper.ExpectedExceptionAsync( async () => await testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, operationContext), operationContext, description + " (Set Permissions)", expectedStatusCode, expectedErrorCode); }
/// <summary> /// Verifies the behavior of a lease while the lease holds. Once the lease expires, this method confirms that write operations succeed. /// The test is cut short once the <c>testLength</c> time has elapsed. /// </summary> /// <param name="leasedContainer">The container.</param> /// <param name="duration">The duration of the lease.</param> /// <param name="testLength">The maximum length of time to run the test.</param> /// <param name="tolerance">The allowed lease time error.</param> internal async Task ContainerAcquireRenewLeaseTestAsync(CloudBlobContainer leasedContainer, TimeSpan? duration, TimeSpan testLength, TimeSpan tolerance) { OperationContext operationContext = new OperationContext(); DateTime beginTime = DateTime.UtcNow; while (true) { try { // Attempt to delete the container with no lease ID. await leasedContainer.DeleteAsync(null, null, operationContext); // The delete succeeded, which means that the lease must have expired. // If the lease was infinite then there is an error because it should not have expired. Assert.IsNotNull(duration, "An infinite lease should not expire."); // The lease should be past its expiration time. Assert.IsTrue(DateTime.UtcNow - beginTime > duration - tolerance, "Deletes should not succeed while lease is present."); // Since the lease has expired (and the container was deleted), the test is over. return; } catch (Exception) { if (operationContext.LastResult.ExtendedErrorInformation.ErrorCode == BlobErrorCodeStrings.LeaseIdMissing) { // We got this error because the lease has not expired yet. // Make sure the lease is not past its expiration time yet. DateTime currentTime = DateTime.UtcNow; if (duration.HasValue) { Assert.IsTrue(currentTime - beginTime < duration + tolerance, "Deletes should succeed after a lease expires."); } // End the test early if necessary if (currentTime - beginTime > testLength) { // The lease has not expired, but we're not waiting any longer. return; } } else { throw; } } // Attempt to write to and read from the container. This should always succeed. await leasedContainer.SetMetadataAsync(); await leasedContainer.FetchAttributesAsync(); // Wait 1 second before trying again. await Task.Delay(TimeSpan.FromSeconds(1)); } }
/// <summary> /// Test container reads and writes, expecting success. /// </summary> /// <param name="testContainer">The container.</param> /// <param name="testAccessCondition">The access condition to use.</param> private void ContainerReadWriteExpectLeaseSuccessTask(CloudBlobContainer testContainer, AccessCondition testAccessCondition) { testContainer.FetchAttributesAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); testContainer.GetPermissionsAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); testContainer.SetMetadataAsync(testAccessCondition, null /* options */, null /* operationContext */).Wait(); testContainer.SetPermissionsAsync(new BlobContainerPermissions(), testAccessCondition, null /* options */, null /* operationContext */).Wait(); }
private async Task<HttpResponseMessage> SetContainerMetadata(CloudBlobContainer container) { const string MetadataPrefix = "x-ms-meta-"; HttpRequestBase request = RequestFromContext(HttpContextFactory.Current); container.Metadata.Clear(); var metadata = Request.Headers.Where(header => header.Key.StartsWith(MetadataPrefix)); foreach (var metadatum in metadata) { container.Metadata.Add(metadatum.Key.Substring(MetadataPrefix.Length), metadatum.Value.FirstOrDefault()); } await container.SetMetadataAsync(); HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); await AddBasicContainerHeaders(response, container); return response; }
static async Task CopyContainer(CloudBlobContainer sourceContainer, CloudBlobContainer destContainer) { await sourceContainer.FetchAttributesAsync(); var access = await sourceContainer.GetPermissionsAsync(); await destContainer.CreateIfNotExistsAsync(access.PublicAccess, null, null); await destContainer.SetPermissionsAsync(access); destContainer.Metadata.Clear(); foreach (var metadatum in sourceContainer.Metadata) { destContainer.Metadata.Add(metadatum); } await destContainer.SetMetadataAsync(); }