Skip to content

Commit 7a47300

Browse files
authored
Respect DAPR_GRPC_PORT environment variable if set externally, allow app-port to be suppressed (#68)
* #66 : Workflow sample, respect external Environment Variables on startup, allow AppPort to be ignored * #66 : Always initialize DaprOptions to ensure valid fluent builder initalization * #66 : Unit test for HasAppPort, other cleanup * #66 : Additional unit tests
1 parent f739fd5 commit 7a47300

32 files changed

+804
-30
lines changed

all.sln

+24
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ EndProject
2626
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Man.Dapr.Sidekick.AspNetCore.Tests", "tests\Man.Dapr.Sidekick.AspNetCore.Tests\Man.Dapr.Sidekick.AspNetCore.Tests.csproj", "{F513F641-20E2-4C47-8F57-95664383004E}"
2727
EndProject
2828
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{6481CB38-F5E9-4CB4-8E5D-AB3114186E7D}"
29+
ProjectSection(SolutionItems) = preProject
30+
samples\Directory.Build.props = samples\Directory.Build.props
31+
EndProjectSection
2932
EndProject
3033
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AspNetCore", "AspNetCore", "{DA3D8137-F2DD-465D-81AA-3CA5C75087D2}"
3134
EndProject
@@ -108,6 +111,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SchedulerSample", "Schedule
108111
EndProject
109112
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SchedulerSample", "samples\AspNetCore\SchedulerSample\SchedulerSample\SchedulerSample.csproj", "{C0B2943F-3EA8-43A9-8714-7D6B84AD788E}"
110113
EndProject
114+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflow", "Workflow", "{2D362BDC-794A-4B1B-B20A-3E4A7214CADC}"
115+
EndProject
116+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ConsoleSample", "ConsoleSample", "{E20CFEC4-3F3F-4BA6-B796-363B76FA5B53}"
117+
EndProject
118+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WorkflowConsoleApp", "samples\Workflow\ConsoleSample\WorkflowConsoleApp\WorkflowConsoleApp.csproj", "{56EFBE8B-485A-48A7-8239-24709774E4FE}"
119+
EndProject
111120
Global
112121
GlobalSection(SolutionConfigurationPlatforms) = preSolution
113122
Debug|Any CPU = Debug|Any CPU
@@ -334,6 +343,18 @@ Global
334343
{C0B2943F-3EA8-43A9-8714-7D6B84AD788E}.Release|x64.Build.0 = Release|Any CPU
335344
{C0B2943F-3EA8-43A9-8714-7D6B84AD788E}.Release|x86.ActiveCfg = Release|Any CPU
336345
{C0B2943F-3EA8-43A9-8714-7D6B84AD788E}.Release|x86.Build.0 = Release|Any CPU
346+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
347+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Debug|Any CPU.Build.0 = Debug|Any CPU
348+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Debug|x64.ActiveCfg = Debug|Any CPU
349+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Debug|x64.Build.0 = Debug|Any CPU
350+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Debug|x86.ActiveCfg = Debug|Any CPU
351+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Debug|x86.Build.0 = Debug|Any CPU
352+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Release|Any CPU.ActiveCfg = Release|Any CPU
353+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Release|Any CPU.Build.0 = Release|Any CPU
354+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Release|x64.ActiveCfg = Release|Any CPU
355+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Release|x64.Build.0 = Release|Any CPU
356+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Release|x86.ActiveCfg = Release|Any CPU
357+
{56EFBE8B-485A-48A7-8239-24709774E4FE}.Release|x86.Build.0 = Release|Any CPU
337358
EndGlobalSection
338359
GlobalSection(SolutionProperties) = preSolution
339360
HideSolutionNode = FALSE
@@ -369,6 +390,9 @@ Global
369390
{2FC86574-6A81-4E2B-A0D4-78D46528A917} = {AE430C04-78BD-4CAE-86D7-EBC599774D9C}
370391
{8FD8AFF0-A56A-4BDC-B40E-F498AA147790} = {DA3D8137-F2DD-465D-81AA-3CA5C75087D2}
371392
{C0B2943F-3EA8-43A9-8714-7D6B84AD788E} = {8FD8AFF0-A56A-4BDC-B40E-F498AA147790}
393+
{2D362BDC-794A-4B1B-B20A-3E4A7214CADC} = {6481CB38-F5E9-4CB4-8E5D-AB3114186E7D}
394+
{E20CFEC4-3F3F-4BA6-B796-363B76FA5B53} = {2D362BDC-794A-4B1B-B20A-3E4A7214CADC}
395+
{56EFBE8B-485A-48A7-8239-24709774E4FE} = {E20CFEC4-3F3F-4BA6-B796-363B76FA5B53}
372396
EndGlobalSection
373397
GlobalSection(ExtensibilityGlobals) = postSolution
374398
SolutionGuid = {E906E97D-7D56-4E02-A13F-1C48AEB47A88}

properties/dapr_sidekick_csharp.props

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@
4040
<Authors>Man Group</Authors>
4141
</PropertyGroup>
4242

43+
<PropertyGroup>
44+
<!-- Disable package vulnerability warnings - not much choice as many packages required for legacy builds are old -->
45+
<NuGetAudit>false</NuGetAudit>
46+
<WarningsNotAsErrors>NU1901;NU1902;NU1903;NU1904</WarningsNotAsErrors>
47+
</PropertyGroup>
48+
4349
<!-- Asset Packages -->
4450
<ItemGroup>
4551
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="8.0.0">

samples/Actor/ActorSample/ActorSample.ActorClient/ActorSample.ActorClient.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Dapr.Actors" Version="1.13.0" />
9+
<PackageReference Include="Dapr.Actors" Version="1.14.0" />
1010
</ItemGroup>
1111

1212
<ItemGroup>

samples/Actor/ActorSample/ActorSample.DemoActor/ActorSample.DemoActor.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Dapr.Actors" Version="1.13.0" />
9-
<PackageReference Include="Dapr.Actors.AspNetCore" Version="1.13.0" />
8+
<PackageReference Include="Dapr.Actors" Version="1.14.0" />
9+
<PackageReference Include="Dapr.Actors.AspNetCore" Version="1.14.0" />
1010
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
1111
</ItemGroup>
1212

samples/Actor/ActorSample/ActorSample.IDemoActor/ActorSample.IDemoActor.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Dapr.Actors" Version="1.13.0" />
8+
<PackageReference Include="Dapr.Actors" Version="1.14.0" />
99
</ItemGroup>
1010

1111
</Project>

samples/AspNetCore/AppConfigurationSample/AppConfigurationSample/AppConfigurationSample.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="Dapr.Extensions.Configuration" Version="1.13.0" />
11+
<PackageReference Include="Dapr.Extensions.Configuration" Version="1.14.0" />
1212
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.11" />
1313
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
14-
<PackageReference Include="Dapr.AspNetCore" Version="1.13.0" />
14+
<PackageReference Include="Dapr.AspNetCore" Version="1.14.0" />
1515
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
1616
</ItemGroup>
1717

samples/AspNetCore/ControllerSample/ControllerSample/ControllerSample.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
</PropertyGroup>
66

77
<ItemGroup>
8-
<PackageReference Include="Dapr.AspNetCore" Version="1.13.0" />
8+
<PackageReference Include="Dapr.AspNetCore" Version="1.14.0" />
99
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
1010
</ItemGroup>
1111

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Dapr.Workflow;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace WorkflowConsoleApp.Activities
5+
{
6+
public class NotifyActivity(ILoggerFactory loggerFactory) : WorkflowActivity<Notification, object>
7+
{
8+
private readonly ILogger _logger = loggerFactory.CreateLogger<NotifyActivity>();
9+
10+
public override Task<object> RunAsync(WorkflowActivityContext context, Notification notification)
11+
{
12+
_logger.LogInformation(notification.Message);
13+
14+
return Task.FromResult<object>(null);
15+
}
16+
}
17+
18+
public record Notification(string Message);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Dapr.Workflow;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace WorkflowConsoleApp.Activities
5+
{
6+
public class ProcessPaymentActivity(ILoggerFactory loggerFactory) : WorkflowActivity<PaymentRequest, object>
7+
{
8+
private readonly ILogger _logger = loggerFactory.CreateLogger<ProcessPaymentActivity>();
9+
10+
public override async Task<object> RunAsync(WorkflowActivityContext context, PaymentRequest req)
11+
{
12+
_logger.LogInformation(
13+
"Processing payment: {requestId} for {amount} {item} at ${currency}",
14+
req.RequestId,
15+
req.Amount,
16+
req.ItemName,
17+
req.Currency);
18+
19+
// Simulate slow processing
20+
await Task.Delay(TimeSpan.FromSeconds(7));
21+
22+
_logger.LogInformation(
23+
"Payment for request ID '{requestId}' processed successfully",
24+
req.RequestId);
25+
26+
return null;
27+
}
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using Dapr.Workflow;
2+
using Microsoft.Extensions.Logging;
3+
4+
namespace WorkflowConsoleApp.Activities
5+
{
6+
public class RequestApprovalActivity(ILoggerFactory loggerFactory) : WorkflowActivity<OrderPayload, object>
7+
{
8+
private readonly ILogger _logger = loggerFactory.CreateLogger<RequestApprovalActivity>();
9+
10+
public override Task<object> RunAsync(WorkflowActivityContext context, OrderPayload input)
11+
{
12+
var orderId = context.InstanceId;
13+
_logger.LogInformation("Requesting approval for order {orderId}", orderId);
14+
15+
return Task.FromResult<object>(null);
16+
}
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using Dapr.Client;
2+
using Dapr.Workflow;
3+
using Microsoft.Extensions.Logging;
4+
5+
namespace WorkflowConsoleApp.Activities
6+
{
7+
public class ReserveInventoryActivity(ILoggerFactory loggerFactory, DaprClient client) : WorkflowActivity<InventoryRequest, InventoryResult>
8+
{
9+
private const string StoreName = "statestore";
10+
11+
private readonly ILogger _logger = loggerFactory.CreateLogger<ReserveInventoryActivity>();
12+
13+
public override async Task<InventoryResult> RunAsync(WorkflowActivityContext context, InventoryRequest req)
14+
{
15+
_logger.LogInformation(
16+
"Reserving inventory for order '{requestId}' of {quantity} {name}",
17+
req.RequestId,
18+
req.Quantity,
19+
req.ItemName);
20+
21+
// Ensure that the store has items
22+
var item = await client.GetStateAsync<InventoryItem>(
23+
StoreName,
24+
req.ItemName.ToLowerInvariant());
25+
26+
// Catch for the case where the statestore isn't setup
27+
if (item == null)
28+
{
29+
// Not enough items.
30+
return new InventoryResult(false, item);
31+
}
32+
33+
_logger.LogInformation(
34+
"There are {quantity} {name} available for purchase",
35+
item.Quantity,
36+
item.Name);
37+
38+
// See if there're enough items to purchase
39+
if (item.Quantity >= req.Quantity)
40+
{
41+
// Simulate slow processing
42+
await Task.Delay(TimeSpan.FromSeconds(2));
43+
44+
return new InventoryResult(true, item);
45+
}
46+
47+
// Not enough items.
48+
return new InventoryResult(false, item);
49+
}
50+
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using Dapr.Client;
2+
using Dapr.Workflow;
3+
using Microsoft.Extensions.Logging;
4+
5+
namespace WorkflowConsoleApp.Activities
6+
{
7+
public class UpdateInventoryActivity(ILoggerFactory loggerFactory, DaprClient client) : WorkflowActivity<PaymentRequest, object>
8+
{
9+
private const string StoreName = "statestore";
10+
private readonly ILogger _logger = loggerFactory.CreateLogger<UpdateInventoryActivity>();
11+
12+
public override async Task<object> RunAsync(WorkflowActivityContext context, PaymentRequest req)
13+
{
14+
_logger.LogInformation(
15+
"Checking inventory for order '{requestId}' for {amount} {name}",
16+
req.RequestId,
17+
req.Amount,
18+
req.ItemName);
19+
20+
// Simulate slow processing
21+
await Task.Delay(TimeSpan.FromSeconds(5));
22+
23+
// Determine if there are enough Items for purchase
24+
var item = await client.GetStateAsync<InventoryItem>(
25+
StoreName,
26+
req.ItemName.ToLowerInvariant());
27+
var newQuantity = item.Quantity - req.Amount;
28+
if (newQuantity < 0)
29+
{
30+
_logger.LogInformation(
31+
"Payment for request ID '{requestId}' could not be processed. Insufficient inventory.",
32+
req.RequestId);
33+
throw new InvalidOperationException($"Not enough '{req.ItemName}' inventory! Requested {req.Amount} but only {item.Quantity} available.");
34+
}
35+
36+
// Update the statestore with the new amount of the item
37+
await client.SaveStateAsync(
38+
StoreName,
39+
req.ItemName.ToLowerInvariant(),
40+
new InventoryItem(Name: req.ItemName, PerItemCost: item.PerItemCost, Quantity: newQuantity));
41+
42+
_logger.LogInformation(
43+
"There are now {quantity} {name} left in stock",
44+
newQuantity,
45+
item.Name);
46+
47+
return null;
48+
}
49+
}
50+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma warning disable SA1649 // File name should match first type name
2+
namespace WorkflowConsoleApp
3+
{
4+
public record OrderPayload(string Name, double TotalCost, int Quantity = 1);
5+
6+
public record InventoryRequest(string RequestId, string ItemName, int Quantity);
7+
8+
public record InventoryResult(bool Success, InventoryItem OrderPayload);
9+
10+
public record PaymentRequest(string RequestId, string ItemName, int Amount, double Currency);
11+
12+
public record OrderResult(bool Processed);
13+
14+
public record InventoryItem(string Name, double PerItemCost, int Quantity);
15+
16+
public enum ApprovalResult
17+
{
18+
Unspecified = 0,
19+
Approved = 1,
20+
Rejected = 2,
21+
}
22+
}
23+
#pragma warning restore SA1649 // File name should match first type name

0 commit comments

Comments
 (0)