public async Task <List <string> > RunOrchestrator( [OrchestrationTrigger] IDurableOrchestrationContext context) { using var disposable = context.PushLoggerProperties(); var phone = context.GetInput <string>(); var outputs = new List <string>(); var proxy = context.CreateEntityProxy <INotifySubscriptionEntity>(NotifySubscriptionEntity.BuildId(phone, EventNameApproved)); try { await proxy.Subscribe(context.InstanceId); await context.CallActivityWithRetryAsync(nameof(SendMessageActivity), _retryOptions, phone); // might fail, better include retry mechanism var approvalNotification = await proxy.GetLatestNotification() // get latest, maybe already approved (optional) ?? await WaitForUserAction(context, _timeToWait, EventNameApproved); // wait for user approval outputs.Add(approvalNotification != null ? $"We have approval from {phone} at {approvalNotification.Timestamp}" : $"No approval from {phone} after waiting {_timeToWait}"); } finally { await proxy.Unsubscribe(context.InstanceId); } return(outputs); }
public async Task <HttpResponseMessage> ReceiveMessage( [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "ReceiveMessage/{phone}/{message}")] HttpRequestMessage req, string phone, string message, [DurableClient] IDurableEntityClient entityClient, // need the durable entity client [DurableClient] IDurableOrchestrationClient orchestrationClient) // and the Orchestration client { if (!message.Equals("APPROVE", StringComparison.InvariantCultureIgnoreCase) && !message.Equals("REJECT", StringComparison.InvariantCultureIgnoreCase)) { return(new HttpResponseMessage(HttpStatusCode.BadRequest)); } var notifyPayload = new NotifyPayload() { Phone = phone, EventName = message.ToUpperInvariant(), Timestamp = TimeService.UtcNow }; var notifySubscriptionEntityId = NotifySubscriptionEntity.BuildId(phone, notifyPayload.EventName); var entity = await entityClient.ReadEntityStateAsync <NotifySubscriptionEntity>(notifySubscriptionEntityId); await entityClient.SignalEntityAsync(notifySubscriptionEntityId, nameof(NotifySubscriptionEntity.RegisterNotification), notifyPayload); // send a signal to the entity if (entity.EntityExists && entity.EntityState.InstancesToNotify.Length > 0) // we have live subscribers { foreach (var instanceId in entity.EntityState.InstancesToNotify) { await orchestrationClient.RaiseEventAsync(instanceId, notifyPayload.EventName, notifyPayload); // notify all subscribers } } else { _log.Trace(LogEventLevel.Verbose, message: "No subscribed instances to notify"); } return(new HttpResponseMessage(HttpStatusCode.OK)); }