public async Task <CheckApprovalResult> BetterHandlingValidateReportLineItem([ActivityTrigger] CheckApprovalRequest checkApprovalRequest) { var validator = _expenseValidatorFactory.Create(checkApprovalRequest.ExpenseCategory); var approved = await validator.IsApproved(checkApprovalRequest.EmployeeId, checkApprovalRequest.Amount); return(new CheckApprovalResult { LineItemId = checkApprovalRequest.LineItemId, IsApproved = approved }); }
public async Task BetterHandlingOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { var report = context.GetInput <ExpenseReport>(); var lineItemTasks = new List <Task <CheckApprovalResult> >(); foreach (var lineItem in report.LineItems) { var approvalRequest = new CheckApprovalRequest { LineItemId = lineItem.Id, EmployeeId = report.EmployeeId, Amount = lineItem.Amount, ExpenseCategory = lineItem.Category }; lineItemTasks.Add(context.CallActivityAsync <CheckApprovalResult>(nameof(BetterHandlingValidateReportLineItem), approvalRequest)); } await Task.WhenAll(lineItemTasks); foreach (var lineItem in report.LineItems) { lineItem.Approved = lineItemTasks.FirstOrDefault(task => task.Result.LineItemId == lineItem.Id)?.Result.IsApproved ?? false; } try { await context.CallActivityAsync(nameof(SaveReport), report); } catch (Exception ex) { _logger.LogError(ex, "Failed to save validated report"); } var retryOptions = new RetryOptions(TimeSpan.FromSeconds(5), 3); await context.CallActivityWithRetryAsync(nameof(NotifyUserReportFinished), retryOptions, report.EmployeeId); }
public async Task AdvancedHandlingOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { try { var report = context.GetInput <ExpenseReport>(); var lineItemTasks = new List <Task <CheckApprovalResult> >(); foreach (var lineItem in report.LineItems) { var approvalRequest = new CheckApprovalRequest { LineItemId = lineItem.Id, EmployeeId = report.EmployeeId, Amount = lineItem.Amount, ExpenseCategory = lineItem.Category }; lineItemTasks.Add(context.CallActivityAsync <CheckApprovalResult>(nameof(AdvancedHandlingValidateReportLineItem), approvalRequest)); } await Task.WhenAll(lineItemTasks); foreach (var lineItem in report.LineItems) { lineItem.Approved = lineItemTasks.FirstOrDefault(task => task.Result.LineItemId == lineItem.Id)?.Result.IsApproved ?? false; } await context.CallActivityAsync(nameof(SaveExpenseReport), report); await context.CallActivityAsync(nameof(SendApprovalRequestNotification), report.Id); using (var timeoutCts = new CancellationTokenSource()) { var expiration = context.CurrentUtcDateTime.AddHours(24); var timeoutTask = context.CreateTimer(expiration, timeoutCts.Token); var approvedTask = context.WaitForExternalEvent <string>(Constants.Events.Approval); var resultTask = await Task.WhenAny(timeoutTask, approvedTask); if (resultTask == timeoutTask) { await context.CallActivityAsync(nameof(SendEscalationNotification), report.Id); } else { await context.CallActivityAsync(nameof(SendReportReceivedResponseNotification), (report.Id, approvedTask.Result)); } if (!timeoutTask.IsCompleted) { // the function wont exit unless this is complete or cancelled timeoutCts.Cancel(); } } } catch (Exception ex) { _logger.LogError(ex, $"Error occurred during orchestration {context.InstanceId}"); // In a real application we'd probably want to send some sort of notification here } }