From e0f14d084b855a01cb3d6a65d76760e8fb46ca49 Mon Sep 17 00:00:00 2001 From: Gregorius Soedharmo Date: Thu, 15 Apr 2021 19:52:21 +0700 Subject: [PATCH] Add DefaultAzureIdentity support (#155) * Add DefaultAzureIdentity support for blob snapshot * Add documentation. --- README.md | 16 ++++++ .../Akka.Persistence.Azure.csproj | 1 + .../Snapshot/AzureBlobSnapshotSetup.cs | 49 +++++++++++++++++++ .../Snapshot/AzureBlobSnapshotStore.cs | 22 +++++++-- 4 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotSetup.cs diff --git a/README.md b/README.md index d1df18a..31b93ed 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,22 @@ akka.persistence.snapshot-store.azure-blob-store.connection-string = "Your Azure akka.persistence.snapshot-store.azure-blob-store.container-name = "Your container name" ``` +### Configuring snapshots Blob Storage using DefaultAzureCredential + +You can use `Azure.Identity` `DefaultAzureCredential` to configure the resource by using `AzureBlobSnapshotSetup`. When using `DefaultAzureCredential`, the HOCON 'connection-string' setting is ignored. + +Example: +``` +var blobStorageSetup = AzureBlobSnapshotSetup.Create( + new Uri("https://{account_name}.blob.core.windows.net"), // This is the blob service URI + new DefaultAzureCredential() // You can pass a DefaultAzureCredentialOption here. + // https://docs.microsoft.com/en-us/dotnet/api/azure.identity.defaultazurecredential?view=azure-dotnet +); + +var bootstrap = BootstrapSetup.Create().And(blobStorageSetup); +var system = ActorSystem.Create("actorSystem", bootstrap); +``` + ## Using the plugin in local development environment You can use this plugin with Azure Storage Emulator in a local development environment by setting the development flag in the configuration file: diff --git a/src/Akka.Persistence.Azure/Akka.Persistence.Azure.csproj b/src/Akka.Persistence.Azure/Akka.Persistence.Azure.csproj index fa75f96..461da09 100644 --- a/src/Akka.Persistence.Azure/Akka.Persistence.Azure.csproj +++ b/src/Akka.Persistence.Azure/Akka.Persistence.Azure.csproj @@ -15,6 +15,7 @@ + diff --git a/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotSetup.cs b/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotSetup.cs new file mode 100644 index 0000000..c7c26a9 --- /dev/null +++ b/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotSetup.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Akka.Actor.Setup; +using Azure.Identity; +using Azure.Storage.Blobs; + +namespace Akka.Persistence.Azure.Snapshot +{ + public class AzureBlobSnapshotSetup : Setup + { + /// + /// Create a new + /// + /// + /// A referencing the blob service. + /// This is likely to be similar to "https://{account_name}.blob.core.windows.net". + /// + /// + /// The used to sign requests. + /// + /// + /// Optional client options that define the transport pipeline policies for authentication, + /// retries, etc., that are applied to every request. + /// + /// A new instance + public static AzureBlobSnapshotSetup Create( + Uri serviceUri, + DefaultAzureCredential defaultAzureCredential, + BlobClientOptions blobClientOptions = default) + => new AzureBlobSnapshotSetup(serviceUri, defaultAzureCredential, blobClientOptions); + + private AzureBlobSnapshotSetup( + Uri serviceUri, + DefaultAzureCredential azureCredential, + BlobClientOptions blobClientOptions) + { + ServiceUri = serviceUri; + DefaultAzureCredential = azureCredential; + BlobClientOptions = blobClientOptions; + } + + public Uri ServiceUri { get; } + + public DefaultAzureCredential DefaultAzureCredential { get; } + + public BlobClientOptions BlobClientOptions { get; } + } +} diff --git a/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs b/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs index 17f07fb..a18c295 100644 --- a/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs +++ b/src/Akka.Persistence.Azure/Snapshot/AzureBlobSnapshotStore.cs @@ -54,9 +54,25 @@ public AzureBlobSnapshotStore(Config config = null) ? AzurePersistence.Get(Context.System).BlobSettings : AzureBlobSnapshotStoreSettings.Create(config); - _serviceClient = _settings.Development ? - new BlobServiceClient("UseDevelopmentStorage=true") : - new BlobServiceClient(_settings.ConnectionString); + if (_settings.Development) + { + _serviceClient = new BlobServiceClient("UseDevelopmentStorage=true"); + } + else + { + var credentialSetup = Context.System.Settings.Setup.Get(); + if (credentialSetup.HasValue) + { + _serviceClient = new BlobServiceClient( + credentialSetup.Value.ServiceUri, + credentialSetup.Value.DefaultAzureCredential, + credentialSetup.Value.BlobClientOptions); + } + else + { + _serviceClient = new BlobServiceClient(_settings.ConnectionString); + } + } _containerClient = new Lazy(() => InitCloudStorage(5).Result); }