From e214f59af42dc6a376736106bb193b19402aedb5 Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Wed, 21 Apr 2021 21:42:13 +0700 Subject: [PATCH 1/2] Fix BlobContainerClient.CreateIfNotExists returns null if container already exists (#160) * Fix BlobContainerClient.CreateIfNotExists returns null if container already exists * Make spec connection string configurable --- .../Issue159Spec.cs | 86 +++++++++++++++++++ .../Snapshot/AzureBlobSnapshotStore.cs | 25 ++++-- 2 files changed, 103 insertions(+), 8 deletions(-) create mode 100644 src/Akka.Persistence.Azure.Tests/Issue159Spec.cs diff --git a/src/Akka.Persistence.Azure.Tests/Issue159Spec.cs b/src/Akka.Persistence.Azure.Tests/Issue159Spec.cs new file mode 100644 index 0000000..1fbe926 --- /dev/null +++ b/src/Akka.Persistence.Azure.Tests/Issue159Spec.cs @@ -0,0 +1,86 @@ +using System; +using Akka.Configuration; +using Akka.Persistence.Azure.TestHelpers; +using Akka.Persistence.TCK.Snapshot; +using Azure.Storage.Blobs; +using Xunit.Abstractions; + +namespace Akka.Persistence.Azure.Tests +{ + public class Issue159Spec: SnapshotStoreSpec + { + private static Config Config() + { + var connectionString = Environment.GetEnvironmentVariable("AZURE_CONNECTION_STR"); + if(string.IsNullOrEmpty(connectionString)) + connectionString = WindowsAzureStorageEmulatorFixture.GenerateConnStr(); + + return ConfigurationFactory.ParseString(@" +akka { + loglevel = DEBUG + log-config-on-start = off + test.single-expect-default = 30s + + persistence { + publish-plugin-commands = on + + journal { + plugin = ""akka.persistence.journal.azure-table"" + + azure-table { + connection-string = """ + connectionString + @""" + connect-timeout = 3s + request-timeout = 3s + verbose-logging = on + } + } + + query { + journal { + azure-table { + write-plugin = ""akka.persistence.journal.azure-table"" + refresh-interval = 1s + max-buffer-size = 150 + } + } + } + + snapshot-store { + plugin = ""akka.persistence.snapshot-store.azure-blob-store"" + } + } +} + +akka.persistence.snapshot-store.azure-blob-store { + class = ""Akka.Persistence.Azure.Snapshot.AzureBlobSnapshotStore, Akka.Persistence.Azure"" + connection-string = """ + connectionString + @""" + container-name = ""default"" + connect-timeout = 3s + request-timeout = 3s + verbose-logging = on + plugin-dispatcher = ""akka.actor.default-dispatcher"" +}"); + } + + public Issue159Spec(ITestOutputHelper output) + : base(Config(), nameof(Issue159Spec), output) + { + var extension = AzurePersistence.Get(Sys); + + var service = new BlobServiceClient(extension.BlobSettings.ConnectionString); + var containerClient = service.GetBlobContainerClient(extension.BlobSettings.ContainerName); + + // The thing we're testing, the container already exist on the account + if (!containerClient.Exists()) + containerClient.Create(extension.BlobSettings.ContainerPublicAccessType); + + // empty the container, possible junk from previous tests + foreach (var blob in containerClient.GetBlobs()) + { + containerClient.GetBlobClient(blob.Name).Delete(); + } + + Initialize(); + } + } +} diff --git a/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs b/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs index a18c295..2afe505 100644 --- a/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs +++ b/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs @@ -102,15 +102,24 @@ private async Task InitCloudStorage(int remainingTries) return blobClient; } - - var response = await blobClient.CreateIfNotExistsAsync( - _settings.ContainerPublicAccessType, - cancellationToken: cts.Token); - - if (response.GetRawResponse().Status == (int)HttpStatusCode.Created) - _log.Info("Created Azure Blob Container {0}", _settings.ContainerName); - else + + if (await blobClient.ExistsAsync(cts.Token)) + { _log.Info("Successfully connected to existing container {0}", _settings.ContainerName); + } + else + { + try + { + await blobClient.CreateAsync(_settings.ContainerPublicAccessType, + cancellationToken: cts.Token); + _log.Info("Created Azure Blob Container {0}", _settings.ContainerName); + } + catch (Exception e) + { + throw new Exception($"Failed to create Azure Blob Container {_settings.ContainerName}", e); + } + } return blobClient; } From adfe0b27bebf00674778d90afcf80fe610eecded Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Wed, 21 Apr 2021 21:59:56 +0700 Subject: [PATCH 2/2] Update RELEASE_NOTES.md for 0.8.1 release (#161) Co-authored-by: Aaron Stannard --- RELEASE_NOTES.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 068bc7f..29193b8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,13 +1,4 @@ -#### 0.8.0 April 16 2021 #### +#### 0.8.1 April 20 2021 #### **Release of Akka.Persistence.Azure** -- [Problem with implimentation of akka persistence contract](https://github.com/petabridge/Akka.Persistence.Azure/pull/143) -- [Limiting batch size for table storage](https://github.com/petabridge/Akka.Persistence.Azure/pull/145) -- [Bump AkkaVersion from 1.4.14 to 1.4.18](https://github.com/petabridge/Akka.Persistence.Azure/pull/148) -- [Added settings for auto-initialize](https://github.com/petabridge/Akka.Persistence.Azure/pull/150) -- [Upgrade WindowsAzure.Storage to Microsoft.Azure.Cosmos.Table and Azure.Storage.Blobs](https://github.com/petabridge/Akka.Persistence.Azure/pull/151) -- [Added support to configure blob container public access level](https://github.com/petabridge/Akka.Persistence.Azure/pull/152) -- [Change the default public access type of auto-init containers to None](https://github.com/petabridge/Akka.Persistence.Azure/pull/154) -- [Add DefaultAzureIdentity support for snapshot Azure Blob Storage](https://github.com/petabridge/Akka.Persistence.Azure/pull/155) - -See the README for documentation on how to use the latest features in Akka.Persistence.Azure: https://github.com/petabridge/Akka.Persistence.Azure#akkapersistenceazure +- [Fix BlobContainerClient.CreateIfNotExists() returns null if container already exists](https://github.com/petabridge/Akka.Persistence.Azure/pull/160)