Skip to content

Commit

Permalink
Add support in dotnet client sdk to support multi state store support (
Browse files Browse the repository at this point in the history
…#207)

* Including state Store name in the APIs to support multi state store scenario in SDK

* correcting the typo in the comment.

* Respective Changes to the tests

* Changes in StateAttribute and Binder classes to support state store name

* Changes in StateEntryModelBinderTests

* StoreName changes in the Integration test app

* fixing build issues

* Fixing integration tests

* Addressing review comments.

* Addressing review comments

* Updating samples to use correct state store name as generated by dapr cli.

Co-authored-by: Aman Bhardwaj <amanbha@users.noreply.github.com>
  • Loading branch information
shalabhms and amanbha committed Feb 6, 2020
1 parent a5078a6 commit 5b8a426
Show file tree
Hide file tree
Showing 21 changed files with 398 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,18 @@ namespace ControllerSample.Controllers
[ApiController]
public class SampleController : ControllerBase
{
/// <summary>
/// State store name.
/// </summary>
public const string StoreName = "statestore";

/// <summary>
/// Gets the account information as specified by the id.
/// </summary>
/// <param name="account">Account information for the id from Dapr state store.</param>
/// <returns>Account information.</returns>
[HttpGet("{account}")]
public ActionResult<Account> Get(StateEntry<Account> account)
public ActionResult<Account> Get([FromState(StoreName)]StateEntry<Account> account)
{
if (account.Value is null)
{
Expand All @@ -32,7 +37,7 @@ public ActionResult<Account> Get(StateEntry<Account> account)
}

/// <summary>
/// Method for depositing to account as psecified in transaction.
/// Method for depositing to account as specified in transaction.
/// </summary>
/// <param name="transaction">Transaction info.</param>
/// <param name="stateClient">State client to interact with Dapr runtime.</param>
Expand All @@ -41,7 +46,7 @@ public ActionResult<Account> Get(StateEntry<Account> account)
[HttpPost("deposit")]
public async Task<ActionResult<Account>> Deposit(Transaction transaction, [FromServices] StateClient stateClient)
{
var state = await stateClient.GetStateEntryAsync<Account>(transaction.Id);
var state = await stateClient.GetStateEntryAsync<Account>(StoreName, transaction.Id);
state.Value ??= new Account() { Id = transaction.Id, };
state.Value.Balance += transaction.Amount;
await state.SaveAsync();
Expand All @@ -58,7 +63,7 @@ public async Task<ActionResult<Account>> Deposit(Transaction transaction, [FromS
[HttpPost("withdraw")]
public async Task<ActionResult<Account>> Withdraw(Transaction transaction, [FromServices] StateClient stateClient)
{
var state = await stateClient.GetStateEntryAsync<Account>(transaction.Id);
var state = await stateClient.GetStateEntryAsync<Account>(StoreName, transaction.Id);

if (state.Value == null)
{
Expand Down
15 changes: 10 additions & 5 deletions samples/AspNetCore/RoutingSample/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ namespace RoutingSample
/// </summary>
public class Startup
{
/// <summary>
/// State store name.
/// </summary>
public const string StoreName = "statestore";

/// <summary>
/// Initializes a new instance of the <see cref="Startup"/> class.
/// </summary>
Expand Down Expand Up @@ -80,7 +85,7 @@ async Task Balance(HttpContext context)
var client = context.RequestServices.GetRequiredService<StateClient>();

var id = (string)context.Request.RouteValues["id"];
var account = await client.GetStateAsync<Account>(id);
var account = await client.GetStateAsync<Account>(StoreName, id);
if (account == null)
{
context.Response.StatusCode = 404;
Expand All @@ -96,7 +101,7 @@ async Task Deposit(HttpContext context)
var client = context.RequestServices.GetRequiredService<StateClient>();

var transaction = await JsonSerializer.DeserializeAsync<Transaction>(context.Request.Body, serializerOptions);
var account = await client.GetStateAsync<Account>(transaction.Id);
var account = await client.GetStateAsync<Account>(StoreName, transaction.Id);
if (account == null)
{
account = new Account() { Id = transaction.Id, };
Expand All @@ -109,7 +114,7 @@ async Task Deposit(HttpContext context)
}

account.Balance += transaction.Amount;
await client.SaveStateAsync(transaction.Id, account);
await client.SaveStateAsync(StoreName, transaction.Id, account);

context.Response.ContentType = "application/json";
await JsonSerializer.SerializeAsync(context.Response.Body, account, serializerOptions);
Expand All @@ -120,7 +125,7 @@ async Task Withdraw(HttpContext context)
var client = context.RequestServices.GetRequiredService<StateClient>();

var transaction = await JsonSerializer.DeserializeAsync<Transaction>(context.Request.Body, serializerOptions);
var account = await client.GetStateAsync<Account>(transaction.Id);
var account = await client.GetStateAsync<Account>(StoreName, transaction.Id);
if (account == null)
{
context.Response.StatusCode = 404;
Expand All @@ -134,7 +139,7 @@ async Task Withdraw(HttpContext context)
}

account.Balance -= transaction.Amount;
await client.SaveStateAsync(transaction.Id, account);
await client.SaveStateAsync(StoreName, transaction.Id, account);

context.Response.ContentType = "application/json";
await JsonSerializer.SerializeAsync(context.Response.Body, account, serializerOptions);
Expand Down
8 changes: 4 additions & 4 deletions samples/Grpc/GrpcClient/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace GrpcClient
public class Program
{
private static string stateKeyName = "mykey";
private static string stateStoreName = "statestore";
private static string storeName = "statestore";

/// <summary>
/// Main entry point.
Expand Down Expand Up @@ -77,7 +77,7 @@ private static async Task SaveStateAsync(Dapr.DaprClient client)
};

var saveStateEnvelope = new SaveStateEnvelope();
saveStateEnvelope.StoreName = stateStoreName;
saveStateEnvelope.StoreName = storeName;
saveStateEnvelope.Requests.Add(req);
_ = await client.SaveStateAsync(saveStateEnvelope);
Console.WriteLine("Saved State!");
Expand All @@ -87,7 +87,7 @@ private static async Task GetStateAsync(Dapr.DaprClient client)
{
var getStateEnvelope = new GetStateEnvelope()
{
StoreName = stateStoreName,
StoreName = storeName,
Key = stateKeyName,
};

Expand All @@ -99,7 +99,7 @@ private static async Task DeleteStateAsync(Dapr.DaprClient client)
{
var deleteStateEnvelope = new DeleteStateEnvelope()
{
StoreName = stateStoreName,
StoreName = storeName,
Key = stateKeyName,
};

Expand Down
15 changes: 15 additions & 0 deletions src/Dapr.AspNetCore/Dapr.AspNetCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,19 @@
<ProjectReference Include="..\Dapr.Client\Dapr.Client.csproj" />
</ItemGroup>

<ItemGroup>
<Compile Update="Resources\SR.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>SR.resx</DependentUpon>
</Compile>
</ItemGroup>

<ItemGroup>
<EmbeddedResource Update="Resources\SR.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>SR.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

</Project>
21 changes: 18 additions & 3 deletions src/Dapr.AspNetCore/FromStateAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
namespace Microsoft.AspNetCore.Mvc
{
using System;
using System.ComponentModel;
using Dapr;
using Microsoft.AspNetCore.Mvc.ModelBinding;

Expand All @@ -18,19 +19,33 @@ public class FromStateAttribute : Attribute, IBindingSourceMetadata
/// <summary>
/// Initializes a new instance of the <see cref="FromStateAttribute"/> class.
/// </summary>
public FromStateAttribute()
/// <param name="storeName">The state store name.</param>
public FromStateAttribute(string storeName)
{
if (string.IsNullOrEmpty(storeName))
{
throw new ArgumentException("The value cannot be null or empty.", nameof(storeName));
}

this.StoreName = storeName;
}

/// <summary>
/// Initializes a new instance of the <see cref="FromStateAttribute"/> class.
/// </summary>
/// <param name="storeName">The state store name.</param>
/// <param name="key">The state key.</param>
public FromStateAttribute(string key)
public FromStateAttribute(string storeName, string key)
{
this.StoreName = storeName;
this.Key = key;
}

/// <summary>
/// Gets the state store name.
/// </summary>
public string StoreName { get; }

/// <summary>
/// Gets the state store key.
/// </summary>
Expand All @@ -43,7 +58,7 @@ public BindingSource BindingSource
{
get
{
return new FromStateBindingSource(this.Key);
return new FromStateBindingSource(this.StoreName, this.Key);
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion src/Dapr.AspNetCore/FromStateBindingSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ namespace Dapr

internal class FromStateBindingSource : BindingSource
{
public FromStateBindingSource(string key)
public FromStateBindingSource(string storeName, string key)
: base("state", "Dapr state store", isGreedy: true, isFromRequest: false)
{
this.StoreName = storeName;
this.Key = key;
}

public string StoreName { get; }

public string Key { get; }
}
}
72 changes: 72 additions & 0 deletions src/Dapr.AspNetCore/Resources/SR.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 5b8a426

Please sign in to comment.