-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathOrderProcessingOrchestration.cs
More file actions
85 lines (72 loc) · 3.85 KB
/
OrderProcessingOrchestration.cs
File metadata and controls
85 lines (72 loc) · 3.85 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.DurableTask;
using Microsoft.DurableTask.Client;
using Microsoft.Extensions.Logging;
using Company.Function.Models;
using Company.Function.Activities;
using System.Collections.Concurrent;
using System.Diagnostics;
namespace Company.Function
{
public static partial class OrderProcessingOrchestration
{
[Function(nameof(OrderProcessingOrchestration))]
public static async Task<OrderResult> RunOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context, OrderPayload order)
{
ILogger logger = context.CreateReplaySafeLogger(nameof(OrderProcessingOrchestration));
// Determine if there is enough of the item available for purchase by checking the inventory
string orderId = context.InstanceId;
logger.LogInformation("Started processing order {orderId}", orderId);
InventoryResult result = await context.CallActivityAsync<InventoryResult>(
nameof(Activities.ReserveInventory),
new InventoryRequest(RequestId: orderId, order.Name, order.Quantity));
// If there is insufficient inventory, fail and let the customer know
if (!result.Success)
{
await context.CallActivityAsync(
nameof(Activities.NotifyCustomer),
new Notification($"Insufficient inventory for {order.Name}"));
return new OrderResult(Processed: false);
}
// There is enough inventory available so the user can purchase the item(s). Process their payment
await context.CallActivityAsync(
nameof(Activities.ProcessPayment),
new PaymentRequest(RequestId: orderId, order.Name, order.Quantity, order.TotalCost));
try
{
// Update inventory
await context.CallActivityAsync(
nameof(Activities.UpdateInventory),
new PaymentRequest(RequestId: orderId, order.Name, order.Quantity, order.TotalCost));
}
catch (TaskFailedException)
{
// Failed to place order. Let customer know they are getting a refund
await context.CallActivityAsync(
nameof(Activities.NotifyCustomer),
new Notification($"Order {orderId} Failed! You are now getting a refund"));
return new OrderResult(Processed: false);
}
// Order has been placed successfully. Notify the customer.
await context.CallActivityAsync(
nameof(Activities.NotifyCustomer),
new Notification($"Order {orderId} has completed!"));
return new OrderResult(Processed: true);
}
[Function("OrderProcessingOrchestration_HttpStart")]
public static async Task<HttpResponseData> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
[DurableClient] DurableTaskClient client,
FunctionContext executionContext)
{
ILogger logger = executionContext.GetLogger("OrderProcessingOrchestration_HttpStart");
// Mimic a new order being placed to start order processing orchestration
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync(
nameof(OrderProcessingOrchestration), new OrderPayload("milk", TotalCost: 5, Quantity: 1));
logger.LogInformation("Started orchestration with ID = '{instanceId}'.", instanceId);
return await client.CreateCheckStatusResponseAsync(req, instanceId);
}
}
}