add csharp example

Signed-off-by: Sarthak Sharma <sartsharma@microsoft.com>
This commit is contained in:
Sarthak Sharma 2022-11-10 00:49:21 +05:30
parent 8988169b9a
commit 00c9073f2b
11 changed files with 284 additions and 0 deletions

View File

@ -0,0 +1,60 @@
# Dapr Configuration API
In this quickstart, you'll create a microservice which makes use of Dapr's Configuration API. Configuration items are key/value pairs containing configuration data such as app ids, partition keys, database names etc. The service gets configuration items from the configuration store and subscribes for configuration updates.
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/configuration/) link for more information about Dapr and Configuration API.
> **Note:** This example leverages HTTP `requests` only. If you are looking for the example using the Dapr Client SDK (recommended) [click here](../sdk/).
This quickstart includes one service:
- Dotnet service `order-processor`
## Run order-updater app
> **Note:** `order-updater` app adds configuration items to the configuration store and keeps updating their value to simulate dynamic changes to configuration data. You need to start and keep it running before running `order-processor` service.
1. Navigate to [`order-updater`](./../../order-updater/) directory.
2. Check the [`Readme`](./../../order-updater/README.md) to start the app and keep it running in the terminal.
<!-- STEP
name: Run order-updater service
background: true
timeout: 90
-->
```bash
cd ./../../order-updater
go run .
```
<!-- END_STEP -->
1. This will add configuration items to redis config store and keep updating their values.
## Run order-processor
1. Open a new terminal and navigate to `order-processor` directory.
2. Run the service app with Dapr.
<!-- STEP
name: Run order-processor service
expected_stdout_lines:
- '== APP == Configuration for orderId1: {"orderId1":{"value":'
- '== APP == Configuration for orderId2: {"orderId2":{"value":'
- '== APP == App subscribed to config changes with subscription id:'
- '== APP == Configuration update {"orderId1":{"value":'
- '== APP == Configuration update {"orderId2":{"value":'
- "Exited App successfully"
expected_stderr_lines:
output_match_mode: substring
match_order: none
timeout: 30
-->
```bash
cd ./order-processor
dapr run --app-id order-processor-http --components-path ../../../components/ --app-port 7001 -- dotnet run --project .
```
<!-- END_STEP -->

View File

@ -0,0 +1,2 @@
include ../../../docker.mk
include ../../../validate.mk

View File

@ -0,0 +1,61 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var baseURL = (Environment.GetEnvironmentVariable("BASE_URL") ?? "http://localhost") + ":"
+ (Environment.GetEnvironmentVariable("DAPR_HTTP_PORT") ?? "3500");
const string DAPR_CONFIGURATION_STORE = "configstore";
var CONFIGURATION_ITEMS = new List<string> { "orderId1", "orderId2" };
var httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
foreach (var item in CONFIGURATION_ITEMS)
{
// Get config items from the config store
try
{
var response = await httpClient.GetStringAsync($"{baseURL}/v1.0-alpha1/configuration/{DAPR_CONFIGURATION_STORE}?key={item.ToString()}");
Console.WriteLine("Configuration for " + item + ": " + response);
}
catch (Exception ex)
{
Console.WriteLine("Could not get config item, err:" + ex.Message);
}
}
async Task subscribeToConfigUpdates()
{
// Add delay to allow app channel to be ready
Thread.Sleep(3000);
var subscription = await httpClient.GetStringAsync($"{baseURL}/v1.0-alpha1/configuration/{DAPR_CONFIGURATION_STORE}/subscribe");
// subscription.EnsureSuccessStatusCode();
Console.WriteLine("App subscribed to config changes with subscription id: " + subscription);
}
async Task readConfigurationChanges()
{
// Create POST endpoint to receive config updates
app.MapPost("/configuration/configstore/{item}", async (HttpRequest request) =>
{
using var sr = new StreamReader(request.Body);
var config = await sr.ReadToEndAsync();
dynamic update = JObject.Parse(config);
Console.WriteLine("Configuration update "+ update.items.ToString(Formatting.None));
});
await app.StartAsync();
}
await readConfigurationChanges();
await subscribeToConfigUpdates();
// Exit the app after 20 seconds
await Task.Delay(20000);

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,15 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"CheckoutService": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:7001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}

View File

@ -0,0 +1,58 @@
# Dapr Configuration API
In this quickstart, you'll create a microservice which makes use of Dapr's Configuration API. Configuration items are key/value pairs containing configuration data such as app ids, partition keys, database names etc. The service gets configuration items from the configuration store and subscribes for configuration updates.
Visit [this](https://docs.dapr.io/developing-applications/building-blocks/configuration/) link for more information about Dapr and Configuration API.
This quickstart includes one service:
- Dotnet service `order-processor`
## Run order-updater app
> **Note:** `order-updater` app adds configuration items to the configuration store and keeps updating their value to simulate dynamic changes to configuration data. You need to start and keep it running before running `order-processor` service.
1. Navigate to [`order-updater`](./../../order-updater/) directory.
2. Check the [`Readme`](./../../order-updater/README.md) to start the app and keep it running in the terminal.
<!-- STEP
name: Run order-updater service
background: true
timeout: 90
-->
```bash
cd ./../../order-updater
go run .
```
<!-- END_STEP -->
3. This will add configuration items to redis config store and keep updating their values.
## Run order-processor
1. Open a new terminal and navigate to `order-processor` directory.
2. Run the service app with Dapr.
<!-- STEP
name: Run order-processor service
expected_stdout_lines:
- '== APP == Configuration for orderId1: {"Value":'
- '== APP == Configuration for orderId2: {"Value":'
- '== APP == App subscribed to config changes with subscription id:'
- '== APP == Configuration update {"orderId1":{"Value":'
- '== APP == Configuration update {"orderId2":{"Value":'
- "Exited App successfully"
expected_stderr_lines:
output_match_mode: substring
match_order: none
timeout: 30
-->
```bash
cd ./order-processor
dapr run --app-id order-processor-http --components-path ../../../components/ --app-port 7001 -- dotnet run --project .
```
<!-- END_STEP -->

View File

@ -0,0 +1,2 @@
include ../../../docker.mk
include ../../../validate.mk

View File

@ -0,0 +1,40 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Dapr.Client;
const string DAPR_CONFIGURATION_STORE = "configstore";
var CONFIGURATION_ITEMS = new List<string> { "orderId1", "orderId2" };
var client = new DaprClientBuilder().Build();
// Get config from configuration store
GetConfigurationResponse config = await client.GetConfiguration(DAPR_CONFIGURATION_STORE, CONFIGURATION_ITEMS );
foreach (var item in config.Items)
{
var cfg = System.Text.Json.JsonSerializer.Serialize(item.Value);
Console.WriteLine("Configuration for " + item.Key + ": " + cfg);
}
// Exit the app after 20 seconds
var shutdownTimer = new System.Timers.Timer();
shutdownTimer.Interval = 20000;
shutdownTimer.Elapsed += (o, e) => Environment.Exit(0);
shutdownTimer.Start();
// Subscribe for configuration changes
SubscribeConfigurationResponse subscribe = await client.SubscribeConfiguration(DAPR_CONFIGURATION_STORE, CONFIGURATION_ITEMS );
// Print configuration changes
await foreach (var configItem in subscribe.Source)
{
// First invocation when app subscribes to config changes only returns subscription id
if (configItem.Keys.Count == 0)
{
Console.WriteLine("App subscribed to config changes with subscription id: " + subscribe.Id);
continue;
}
var cfg = System.Text.Json.JsonSerializer.Serialize(configItem);
Console.WriteLine("Configuration update " + cfg);
}

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapr.AspNetCore" Version="1.9.0" />
</ItemGroup>
</Project>