mirror of https://github.com/dapr/quickstarts.git
Update .NET workflow quickstart
Signed-off-by: Marc Duiker <marcduiker@users.noreply.github.com>
This commit is contained in:
parent
0afc299ce8
commit
9334142016
|
|
@ -0,0 +1,3 @@
|
|||
* text=auto eol=lf
|
||||
*.{cmd,[cC][mM][dD]} text eol=crlf
|
||||
*.{bat,[bB][aA][tT]} text eol=crlf
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
# Dapr workflows
|
||||
|
||||
In this quickstart, you'll create a simple console application to demonstrate Dapr's workflow programming model and the workflow management API. The console app starts and manages the lifecycle of a workflow that stores and retrieves data in a state store.
|
||||
In this quickstart, you'll run a console application to demonstrate Dapr's workflow programming model and the workflow management API. The console app starts and manages the lifecycle of a workflow that stores and retrieves data in a state store.
|
||||
|
||||
This quickstart includes one project:
|
||||
|
||||
- .NET console app `order-processor`
|
||||
|
||||
The quickstart contains 1 workflow to simulate purchasing items from a store, and 4 unique activities within the workflow. These 4 activities are as follows:
|
||||
The quickstart contains 1 workflow to simulate purchasing items from a store, and 5 unique activities within the workflow. These 5 activities are as follows:
|
||||
|
||||
- NotifyActivity: This activity utilizes a logger to print out messages throughout the workflow. These messages notify the user when there is insufficient inventory, their payment couldn't be processed, and more.
|
||||
- VerifyInventoryActivity: This activity checks the state store to ensure that there is enough inventory present for purchase.
|
||||
- RequestApprovalActivity: This activity is responsible requesting approval to purchase the order items in case the total cost is above a certain threshold.
|
||||
- ProcessPaymentActivity: This activity is responsible for processing and authorizing the payment.
|
||||
- ReserveInventoryActivity: This activity checks the state store to ensure that there is enough inventory present for purchase.
|
||||
- UpdateInventoryActivity: This activity removes the requested items from the state store and updates the store with the new remaining inventory value.
|
||||
|
||||
### Run the order processor workflow
|
||||
|
|
@ -52,39 +53,156 @@ dapr run -f .
|
|||
3. Expected output
|
||||
|
||||
```
|
||||
== APP - order-processor == Starting workflow 898fd553 purchasing 10 Cars
|
||||
|
||||
== APP - order-processor == Starting workflow 571a6e25 purchasing 1 Cars
|
||||
== APP - order-processor == info: Microsoft.DurableTask.Client.Grpc.GrpcDurableTaskClient[40]
|
||||
== APP - order-processor == Scheduling new OrderProcessingWorkflow orchestration with instance ID '571a6e25' and 45 bytes of input data.
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/StartInstance
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/StartInstance
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 3045.9209ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 3046.0945ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 3016.1346ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 3016.3572ms - 200
|
||||
== APP - order-processor == info: Microsoft.DurableTask.Client.Grpc.GrpcDurableTaskClient[42]
|
||||
== APP - order-processor == Waiting for instance '571a6e25' to start.
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/WaitForInstanceStart
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/WaitForInstanceStart
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 2.9095ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 3.0445ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 99.446ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 99.5407ms - 200
|
||||
== APP - order-processor == Your workflow has started. Here is the status of the workflow: Running
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.NotifyActivity[1985924262]
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.NotifyActivity[1985924262]
|
||||
== APP - order-processor == Presenting notification Notification { Message = Received order 898fd553 for 10 Cars at $15000 }
|
||||
== APP - order-processor == info: Microsoft.DurableTask.Client.Grpc.GrpcDurableTaskClient[43]
|
||||
== APP - order-processor == Waiting for instance '898fd553' to complete, fail, or terminate.
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[2013970020]
|
||||
== APP - order-processor == Received request ID '898fd553' for 10 Cars at $15000
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.ReserveInventoryActivity[1988035937]
|
||||
== APP - order-processor == Reserving inventory for order request ID '898fd553' of 10 Cars
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.ReserveInventoryActivity[1130866279]
|
||||
== APP - order-processor == There are: 10 Cars available for purchase
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[1162731597]
|
||||
== APP - order-processor == Checked inventory for request ID 'InventoryRequest { RequestId = 898fd553, ItemName = Cars, Quantity = 10 }'
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.ProcessPaymentActivity[340284070]
|
||||
== APP - order-processor == Processing payment: request ID '898fd553' for 10 Cars at $15000
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.ProcessPaymentActivity[1851315765]
|
||||
== APP - order-processor == Payment for request ID '898fd553' processed successfully
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[340284070]
|
||||
== APP - order-processor == Processed payment request as there's sufficient inventory to proceed: PaymentRequest { RequestId = 898fd553, ItemBeingPurchased = Cars, Amount = 10, Currency = 15000 }
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.UpdateInventoryActivity[2144991393]
|
||||
== APP - order-processor == Checking inventory for request ID '898fd553' for 10 Cars
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.UpdateInventoryActivity[1901852920]
|
||||
== APP - order-processor == There are now 90 Cars left in stock
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[96138418]
|
||||
== APP - order-processor == Updating available inventory for PaymentRequest { RequestId = 898fd553, ItemBeingPurchased = Cars, Amount = 10, Currency = 15000 }
|
||||
== APP - order-processor == Waiting for instance '571a6e25' to complete, fail, or terminate.
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/WaitForInstanceCompletion
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/WaitForInstanceCompletion
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.NotifyActivity[1985924262]
|
||||
== APP - order-processor == Presenting notification Notification { Message = Order 898fd553 has completed! }
|
||||
== APP - order-processor == Presenting notification Notification { Message = Received order 571a6e25 for 1 Cars at $5000 }
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 1.6785ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 1.7869ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[2013970020]
|
||||
== APP - order-processor == Received request ID '571a6e25' for 1 Cars at $5000
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 1.1947ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 1.3293ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.VerifyInventoryActivity[1478802116]
|
||||
== APP - order-processor == Reserving inventory for order request ID '571a6e25' of 1 Cars
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.VerifyInventoryActivity[1130866279]
|
||||
== APP - order-processor == There are: 10 Cars available for purchase
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 1.8534ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 2.0077ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[1162731597]
|
||||
== APP - order-processor == Checked inventory for request ID 'InventoryRequest { RequestId = 571a6e25, ItemName = Cars, Quantity = 1 }'
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 1.1851ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 1.3742ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.ProcessPaymentActivity[340284070]
|
||||
== APP - order-processor == Processing payment: request ID '571a6e25' for 1 Cars at $5000
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.ProcessPaymentActivity[1851315765]
|
||||
== APP - order-processor == Payment for request ID '571a6e25' processed successfully
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 0.8249ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 0.9595ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[340284070]
|
||||
== APP - order-processor == Processed payment request as there's sufficient inventory to proceed: PaymentRequest { RequestId = 571a6e25, ItemBeingPurchased = Cars, Amount = 1, Currency = 5000 }
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 0.4457ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 0.5267ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.UpdateInventoryActivity[2144991393]
|
||||
== APP - order-processor == Checking inventory for request ID '571a6e25' for 1 Cars
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.UpdateInventoryActivity[1901852920]
|
||||
== APP - order-processor == There are now 9 Cars left in stock
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 0.6012ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 0.7097ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[96138418]
|
||||
== APP - order-processor == Updating available inventory for PaymentRequest { RequestId = 571a6e25, ItemBeingPurchased = Cars, Amount = 1, Currency = 5000 }
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 0.469ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 0.5431ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Activities.NotifyActivity[1985924262]
|
||||
== APP - order-processor == Presenting notification Notification { Message = Order 571a6e25 has completed! }
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteActivityTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 0.494ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 0.5685ms - 200
|
||||
== APP - order-processor == info: WorkflowConsoleApp.Workflows.OrderProcessingWorkflow[510392223]
|
||||
== APP - order-processor == Order 898fd553 has completed
|
||||
== APP - order-processor == Order 571a6e25 has completed
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[100]
|
||||
== APP - order-processor == Start processing HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[100]
|
||||
== APP - order-processor == Sending HTTP request POST http://localhost:37355/TaskHubSidecarService/CompleteOrchestratorTask
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 1.6353ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 1.7546ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.ClientHandler[101]
|
||||
== APP - order-processor == Received HTTP response headers after 15807.213ms - 200
|
||||
== APP - order-processor == info: System.Net.Http.HttpClient.Default.LogicalHandler[101]
|
||||
== APP - order-processor == End processing HTTP request after 15807.3675ms - 200
|
||||
== APP - order-processor == Workflow Status: Completed
|
||||
```
|
||||
|
||||
|
|
@ -106,12 +224,12 @@ docker run -d -p 9411:9411 openzipkin/zipkin
|
|||
|
||||
### What happened?
|
||||
|
||||
When you ran `dapr run --app-id order-processor dotnet run`
|
||||
When you ran `dapr run -f .`
|
||||
|
||||
1. A unique order ID for the workflow is generated (in the above example, `898fd553`) and the workflow is scheduled.
|
||||
2. The `NotifyActivity` workflow activity sends a notification saying an order for 10 cars has been received.
|
||||
3. The `ReserveInventoryActivity` workflow activity checks the inventory data, determines if you can supply the ordered item, and responds with the number of cars in stock.
|
||||
4. Your workflow starts and notifies you of its status.
|
||||
3. The `CheckInventoryActivity` workflow activity checks the inventory data, determines if you can supply the ordered item, and responds with the number of cars in stock. If the inventory is sufficient the workflow continues.
|
||||
4. The total cost of the order is 5000, so the workflow will not call the `RequestApprovalActivity` activity.
|
||||
5. The `ProcessPaymentActivity` workflow activity begins processing payment for order `898fd553` and confirms if successful.
|
||||
6. The `UpdateInventoryActivity` workflow activity updates the inventory with the current available cars after the order has been processed.
|
||||
7. The `NotifyActivity` workflow activity sends a notification saying that order `898fd553` has completed.
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 606 KiB After Width: | Height: | Size: 732 KiB |
|
|
@ -0,0 +1,22 @@
|
|||
namespace WorkflowConsoleApp.Activities;
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Dapr.Workflow;
|
||||
using WorkflowConsoleApp.Models;
|
||||
|
||||
internal sealed partial class RequestApprovalActivity(ILogger<RequestApprovalActivity> logger) : WorkflowActivity<ApprovalRequest, object?>
|
||||
{
|
||||
public override async Task<object?> RunAsync(WorkflowActivityContext context, ApprovalRequest approvalRequest)
|
||||
{
|
||||
LogRequestApproval(logger, approvalRequest);
|
||||
|
||||
// Simulate slow processing
|
||||
await Task.Delay(TimeSpan.FromSeconds(2));
|
||||
|
||||
return Task.FromResult<object?>(null);
|
||||
}
|
||||
|
||||
[LoggerMessage(LogLevel.Information, "Approval Request {approvalRequest}")]
|
||||
static partial void LogRequestApproval(ILogger logger, ApprovalRequest approvalRequest);
|
||||
}
|
||||
|
|
@ -7,13 +7,13 @@ using Microsoft.Extensions.Logging;
|
|||
using Models;
|
||||
using System;
|
||||
|
||||
internal sealed partial class ReserveInventoryActivity(ILogger<ReserveInventoryActivity> logger, DaprClient daprClient) : WorkflowActivity<InventoryRequest, InventoryResult>
|
||||
internal sealed partial class VerifyInventoryActivity(ILogger<VerifyInventoryActivity> logger, DaprClient daprClient) : WorkflowActivity<InventoryRequest, InventoryResult>
|
||||
{
|
||||
private const string StoreName = "statestore";
|
||||
|
||||
public override async Task<InventoryResult> RunAsync(WorkflowActivityContext context, InventoryRequest req)
|
||||
{
|
||||
LogReserveInventory(logger, req.RequestId, req.Quantity, req.ItemName);
|
||||
LogVerifyInventory(logger, req.RequestId, req.Quantity, req.ItemName);
|
||||
|
||||
// Ensure that the store has items
|
||||
var (orderResult, _) = await daprClient.GetStateAndETagAsync<OrderPayload>(StoreName, req.ItemName);
|
||||
|
|
@ -32,7 +32,7 @@ internal sealed partial class ReserveInventoryActivity(ILogger<ReserveInventoryA
|
|||
// Simulate slow processing
|
||||
await Task.Delay(TimeSpan.FromSeconds(2));
|
||||
|
||||
LogSufficientInventory(logger, req.Quantity, req.ItemName);
|
||||
LogSufficientInventory(logger, orderResult.Quantity, req.ItemName);
|
||||
return new InventoryResult(true, orderResult);
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +42,7 @@ internal sealed partial class ReserveInventoryActivity(ILogger<ReserveInventoryA
|
|||
}
|
||||
|
||||
[LoggerMessage(LogLevel.Information, "Reserving inventory for order request ID '{requestId}' of {quantity} {name}")]
|
||||
static partial void LogReserveInventory(ILogger logger, string requestId, int quantity, string name);
|
||||
static partial void LogVerifyInventory(ILogger logger, string requestId, int quantity, string name);
|
||||
|
||||
[LoggerMessage(LogLevel.Warning, "Unable to locate an order result for request ID '{requestId}' for the indicated item {itemName} in the state store")]
|
||||
static partial void LogStateNotFound(ILogger logger, string requestId, string itemName);
|
||||
|
|
@ -3,5 +3,7 @@ namespace WorkflowConsoleApp.Models;
|
|||
internal sealed record OrderPayload(string Name, double TotalCost, int Quantity = 1);
|
||||
internal sealed record InventoryRequest(string RequestId, string ItemName, int Quantity);
|
||||
internal sealed record InventoryResult(bool Success, OrderPayload? OrderPayload);
|
||||
internal sealed record ApprovalRequest(string RequestId, string ItemBeingPurchased, int Quantity, double Amount);
|
||||
internal sealed record ApprovalResponse(string RequestId, bool IsApproved);
|
||||
internal sealed record PaymentRequest(string RequestId, string ItemBeingPurchased, int Amount, double Currency);
|
||||
internal sealed record OrderResult(bool Processed);
|
||||
|
|
@ -20,7 +20,8 @@ var builder = Host.CreateDefaultBuilder(args).ConfigureServices(services =>
|
|||
|
||||
// These are the activities that get invoked by the workflow(s).
|
||||
options.RegisterActivity<NotifyActivity>();
|
||||
options.RegisterActivity<ReserveInventoryActivity>();
|
||||
options.RegisterActivity<VerifyInventoryActivity>();
|
||||
options.RegisterActivity<RequestApprovalActivity>();
|
||||
options.RegisterActivity<ProcessPaymentActivity>();
|
||||
options.RegisterActivity<UpdateInventoryActivity>();
|
||||
});
|
||||
|
|
@ -36,13 +37,13 @@ var workflowClient = host.Services.GetRequiredService<DaprWorkflowClient>();
|
|||
// Generate a unique ID for the workflow
|
||||
var orderId = Guid.NewGuid().ToString()[..8];
|
||||
const string itemToPurchase = "Cars";
|
||||
const int amountToPurchase = 10;
|
||||
const int amountToPurchase = 1;
|
||||
|
||||
// Populate the store with items
|
||||
RestockInventory(itemToPurchase);
|
||||
|
||||
// Construct the order
|
||||
var orderInfo = new OrderPayload(itemToPurchase, 15000, amountToPurchase);
|
||||
var orderInfo = new OrderPayload(itemToPurchase, 5000, amountToPurchase);
|
||||
|
||||
// Start the workflow
|
||||
Console.WriteLine($"Starting workflow {orderId} purchasing {amountToPurchase} {itemToPurchase}");
|
||||
|
|
@ -67,5 +68,5 @@ return;
|
|||
|
||||
void RestockInventory(string itemToPurchase)
|
||||
{
|
||||
daprClient.SaveStateAsync(storeName, itemToPurchase, new OrderPayload(Name: itemToPurchase, TotalCost: 15000, Quantity: 100));
|
||||
daprClient.SaveStateAsync(storeName, itemToPurchase, new OrderPayload(Name: itemToPurchase, TotalCost: 50000, Quantity: 10));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ internal sealed partial class OrderProcessingWorkflow : Workflow<OrderPayload, O
|
|||
// Determine if there is enough of the item available for purchase by checking the inventory
|
||||
var inventoryRequest = new InventoryRequest(RequestId: orderId, order.Name, order.Quantity);
|
||||
var result = await context.CallActivityAsync<InventoryResult>(
|
||||
nameof(ReserveInventoryActivity), inventoryRequest);
|
||||
nameof(VerifyInventoryActivity), inventoryRequest);
|
||||
LogCheckInventory(logger, inventoryRequest);
|
||||
|
||||
// If there is insufficient inventory, fail and let the user know
|
||||
|
|
@ -35,6 +35,23 @@ internal sealed partial class OrderProcessingWorkflow : Workflow<OrderPayload, O
|
|||
return new OrderResult(Processed: false);
|
||||
}
|
||||
|
||||
if (order.TotalCost > 5000)
|
||||
{
|
||||
await context.CallActivityAsync(nameof(RequestApprovalActivity),
|
||||
new ApprovalRequest(orderId, order.Name, order.Quantity, order.TotalCost));
|
||||
|
||||
var approvalResponse = await context.WaitForExternalEventAsync<ApprovalResponse>(
|
||||
eventName: "ApprovalResponse",
|
||||
timeout: TimeSpan.FromSeconds(30));
|
||||
if (!approvalResponse.IsApproved)
|
||||
{
|
||||
await context.CallActivityAsync(nameof(NotifyActivity),
|
||||
new Notification($"Order {orderId} was not approved"));
|
||||
LogOrderNotApproved(logger, orderId);
|
||||
return new OrderResult(Processed: false);
|
||||
}
|
||||
}
|
||||
|
||||
// There is enough inventory available so the user can purchase the item(s). Process their payment
|
||||
var processPaymentRequest = new PaymentRequest(RequestId: orderId, order.Name, order.Quantity, order.TotalCost);
|
||||
await context.CallActivityAsync(nameof(ProcessPaymentActivity),processPaymentRequest);
|
||||
|
|
@ -73,6 +90,9 @@ internal sealed partial class OrderProcessingWorkflow : Workflow<OrderPayload, O
|
|||
[LoggerMessage(LogLevel.Information, "Insufficient inventory for order {orderName}")]
|
||||
static partial void LogInsufficientInventory(ILogger logger, string orderName);
|
||||
|
||||
[LoggerMessage(LogLevel.Information, "Order {orderName} was not approved")]
|
||||
static partial void LogOrderNotApproved(ILogger logger, string orderName);
|
||||
|
||||
[LoggerMessage(LogLevel.Information, "Processed payment request as there's sufficient inventory to proceed: {request}")]
|
||||
static partial void LogPaymentProcessing(ILogger logger, PaymentRequest request);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue