Skip to content
Open
7 changes: 7 additions & 0 deletions Dapr.PluggableComponents.Complete.sln
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DiscordBindingSample", "sam
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dapr.PluggableComponents.Tests", "src\Dapr.PluggableComponents.Tests\Dapr.PluggableComponents.Tests.csproj", "{C9027B0B-A589-4E92-AB32-34B8961C479B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalEnvSecretStoreSample", "samples\LocalEnvSecretStoreSample\LocalEnvSecretStoreSample.csproj", "{FB79E8DE-3AA9-47E0-9EA6-627DCAFC6068}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -60,6 +62,10 @@ Global
{C9027B0B-A589-4E92-AB32-34B8961C479B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9027B0B-A589-4E92-AB32-34B8961C479B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9027B0B-A589-4E92-AB32-34B8961C479B}.Release|Any CPU.Build.0 = Release|Any CPU
{FB79E8DE-3AA9-47E0-9EA6-627DCAFC6068}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB79E8DE-3AA9-47E0-9EA6-627DCAFC6068}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB79E8DE-3AA9-47E0-9EA6-627DCAFC6068}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB79E8DE-3AA9-47E0-9EA6-627DCAFC6068}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{E54270BE-EF83-47BE-B29C-29BC89701099} = {8E8203A7-A0B9-4F48-9CD4-DE9A0D3B73FB}
Expand All @@ -69,5 +75,6 @@ Global
{A6565BA8-E05C-4B4E-A908-C4B86232F9AB} = {6F4E950F-E4CD-4FA4-BA3D-528F0022C03B}
{BCE0E3E4-60D9-4947-9E1A-300640BE5FBF} = {6F4E950F-E4CD-4FA4-BA3D-528F0022C03B}
{C9027B0B-A589-4E92-AB32-34B8961C479B} = {8E8203A7-A0B9-4F48-9CD4-DE9A0D3B73FB}
{FB79E8DE-3AA9-47E0-9EA6-627DCAFC6068} = {6F4E950F-E4CD-4FA4-BA3D-528F0022C03B}
EndGlobalSection
EndGlobal
20 changes: 20 additions & 0 deletions samples/LocalEnvSecretStoreSample/LocalEnvSecretStoreSample.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Dapr.PluggableComponents.AspNetCore\Dapr.PluggableComponents.AspNetCore.csproj">
<GlobalPropertiesToRemove></GlobalPropertiesToRemove>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Remove="Services\" />
</ItemGroup>
<ItemGroup>
<Folder Include="Services\" />
</ItemGroup>
</Project>
18 changes: 18 additions & 0 deletions samples/LocalEnvSecretStoreSample/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Dapr.PluggableComponents;
using LocalEnvSecretStoreSample.Services;

var app = DaprPluggableComponentsApplication.Create();

app.RegisterService(
"local.env-pluggable",
serviceBuilder =>
{
serviceBuilder.RegisterSecretStore(
context =>
{
Console.WriteLine("Creating secret store for instance '{0}' on socket '{1}'...", context.InstanceId, context.SocketPath);
return new LocalEnvSecretStore(context.ServiceProvider.GetRequiredService<ILogger<LocalEnvSecretStore>>());
});
});

app.Run();
74 changes: 74 additions & 0 deletions samples/LocalEnvSecretStoreSample/Services/LocalEnvSecretStore.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Collections;
using Dapr.PluggableComponents.Components;
using Dapr.PluggableComponents.Components.SecretStore;

namespace LocalEnvSecretStoreSample.Services;

internal sealed class LocalEnvSecretStore : ISecretStore
{
private readonly ILogger<LocalEnvSecretStore> logger;

public LocalEnvSecretStore(ILogger<LocalEnvSecretStore> logger)
{
this.logger = logger;
}

#region ISecretStore Members

public Task<SecretStoreGetResponse> GetAsync(SecretStoreGetRequest request, CancellationToken cancellationToken = default)
{
this.logger.LogInformation("Get request for secret {key}", request.Key);

return Task.FromResult(
new SecretStoreGetResponse
{
Secrets = new Dictionary<string, string>
{
{ request.Key, Environment.GetEnvironmentVariable(request.Key) ?? String.Empty }
}
});
}

public Task<SecretStoreBulkGetResponse> BulkGetAsync(SecretStoreBulkGetRequest request, CancellationToken cancellationToken = default)
{
this.logger.LogInformation("Get request for all secrets");

return Task.FromResult(
new SecretStoreBulkGetResponse
{
Keys =
Environment
.GetEnvironmentVariables()
.ToDictionary<string, string>()
.ToDictionary(
kvp => kvp.Key,
kvp => new SecretStoreGetResponse
{
Secrets = new Dictionary<string, string>
{
{ kvp.Key, kvp.Value ?? String.Empty }
}
})
});
}

public Task InitAsync(MetadataRequest request, CancellationToken cancellationToken = default)
{
return Task.CompletedTask;
}

#endregion
}

internal static class DictionaryExtensions
{
public static IEnumerable<KeyValuePair<TKey, TValue?>> ToDictionary<TKey, TValue>(this IDictionary dictionary)
{
var enumerator = dictionary.GetEnumerator();

while (enumerator.MoveNext())
{
yield return new KeyValuePair<TKey, TValue?>((TKey)enumerator.Key, (TValue?)enumerator.Value);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
9 changes: 9 additions & 0 deletions samples/LocalEnvSecretStoreSample/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Dapr.PluggableComponents.Adaptors;
using Dapr.PluggableComponents.Components.Bindings;
using Dapr.PluggableComponents.Components.PubSub;
using Dapr.PluggableComponents.Components.SecretStore;
using Dapr.PluggableComponents.Components.StateStore;

namespace Dapr.PluggableComponents;
Expand Down Expand Up @@ -181,6 +182,45 @@ public DaprPluggableComponentsServiceBuilder RegisterStateStore<TStateStore>(Com

#endregion

#region Secret Store Registration

/// <summary>
/// Registers a singleton secret store with this service.
/// </summary>
/// <typeparam name="TSecretStore">The type of secret store to register.</typeparam>
/// <returns>The current <see cref="DaprPluggableComponentsServiceBuilder"/> instance.</returns>
/// <remarks>
/// A single instance of the secret store will be created to service all configured Dapr components.
///
/// Only a single secret store type can be associated with a given service.
/// </remarks>
public DaprPluggableComponentsServiceBuilder RegisterSecretStore<TSecretStore>() where TSecretStore : class, ISecretStore
{
this.AddComponent<ISecretStore, TSecretStore, SecretStoreAdaptor>();
return this;
}

/// <summary>
/// Registers a secret store with this service.
/// </summary>
/// <typeparam name="TSecretStore">The type of secret store to register.</typeparam>
/// <param name="secretStoreFactory">A factory method called when creating new secret store instances.</param>
/// <returns>The current <see cref="DaprPluggableComponentsServiceBuilder"/> instance.</returns>
/// <remarks>
/// The factory method will be called once for each configured Dapr component; the returned instance will be
/// associated with that Dapr component and methods invoked when the component receives requests.
///
/// Only a single secret store type can be associated with a given service.
/// </remarks>
public DaprPluggableComponentsServiceBuilder RegisterSecretStore<TSecretStore>(ComponentProviderDelegate<TSecretStore> secretStoreFactory)
where TSecretStore : class, ISecretStore
{
this.AddComponent<ISecretStore, TSecretStore, SecretStoreAdaptor>(secretStoreFactory);
return this;
}

#endregion

private void AddComponent<TComponentType, TComponentImpl, TAdaptor>()
where TComponentType : class
where TComponentImpl : class, TComponentType
Expand Down Expand Up @@ -236,4 +276,9 @@ private void AddRelatedStateStoreServices<TStateStore>() where TStateStore : cla
this.AddRelatedService<IQueryableStateStore, TStateStore, QueryableStateStoreAdaptor>();
}
}

private void AddRelatedSecretStoreServices<TSecretStore>() where TSecretStore : class
{
this.AddRelatedService<ISecretStore, TSecretStore, SecretStoreAdaptor>();
}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<ProtosVersion>v1</ProtosVersion>
<ProtosTag>v1.11.0</ProtosTag>
<ProtosTag>v1.14.4</ProtosTag>
<ProtosBaseUrl>https://raw.githubusercontent.com/dapr/dapr/$(ProtosTag)/dapr/proto/components/$(ProtosVersion)</ProtosBaseUrl>
<ProtosRootDir>$(BaseIntermediateOutputPath)$(Configuration)\$(TargetFramework)\Protos</ProtosRootDir>
<ProtosComponentsDir>$(ProtosRootDir)\dapr\proto\components\$(ProtosVersion)</ProtosComponentsDir>
Expand All @@ -13,6 +13,7 @@
<Protos Include="common.proto" Visible="false" />
<Protos Include="pubsub.proto" Visible="false" />
<Protos Include="state.proto" Visible="false" />
<Protos Include="secretstore.proto" Visible="false" />
</ItemGroup>

<!-- Additional Nuget package properties. -->
Expand All @@ -36,12 +37,8 @@
</ItemGroup>

<Target Name="DownloadComponentProtos" BeforeTargets="Protobuf_BeforeCompile">
<MakeDir
Directories="$(ProtosComponentsDir)" />
<DownloadFile
Condition="!Exists('$(ProtosComponentsDir)/%(Protos.Identity)')"
SourceUrl="$(ProtosBaseUrl)/%(Protos.Identity)"
DestinationFolder="$(ProtosComponentsDir)" />
<MakeDir Directories="$(ProtosComponentsDir)" />
<DownloadFile Condition="!Exists('$(ProtosComponentsDir)/%(Protos.Identity)')" SourceUrl="$(ProtosBaseUrl)/%(Protos.Identity)" DestinationFolder="$(ProtosComponentsDir)" />
</Target>

</Project>
</Project>
6 changes: 6 additions & 0 deletions src/Dapr.PluggableComponents.Tests/Adaptors/AdaptorFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Dapr.PluggableComponents.Components;
using Dapr.PluggableComponents.Components.Bindings;
using Dapr.PluggableComponents.Components.PubSub;
using Dapr.PluggableComponents.Components.SecretStore;
using Dapr.PluggableComponents.Components.StateStore;
using Grpc.Core;
using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -75,6 +76,11 @@ public static AdaptorFixture<StateStoreAdaptor, IStateStore> CreateStateStore(IS
return new AdaptorFixture<StateStoreAdaptor, IStateStore>((logger, componentProvider) => new StateStoreAdaptor(logger, componentProvider), mockComponent);
}

public static AdaptorFixture<SecretStoreAdaptor, ISecretStore> CreateSecretStore(ISecretStore? mockComponent = null)
{
return new AdaptorFixture<SecretStoreAdaptor, ISecretStore>((logger, componentProvider) => new SecretStoreAdaptor(logger, componentProvider), mockComponent);
}

public static async Task TestInitAsync<TAdaptor, TInterface>(
Func<AdaptorFixture<TAdaptor, TInterface>> adaptorFactory,
Func<AdaptorFixture<TAdaptor, TInterface>, Client.Autogen.Grpc.v1.MetadataRequest, Task> initCall)
Expand Down
Loading
Loading