internal static async Task <ICommandResult> GetCommandResultAsync(this IDurableClient durableClient, Guid commandId)
        {
            if (durableClient is null)
            {
                throw new ArgumentNullException(nameof(durableClient));
            }

            var commandStatus = await durableClient
                                .GetStatusAsync(OrchestratorCommandOrchestrationHandler.GetCommandOrchestrationInstanceId(commandId))
                                .ConfigureAwait(false);

            if (commandStatus?.RuntimeStatus.IsFinal() ?? true)
            {
                // we use the command wrapper status as a fallback if there is no orchstration status available
                // for the command itself, but also if the command orchestration reached a final state and we
                // need to return the overall processing status (incl. all tasks managed by the wrapper)

                commandStatus = await durableClient
                                .GetStatusAsync(OrchestratorCommandOrchestrationHandler.GetCommandOrchestrationWrapperInstanceId(commandId))
                                .ConfigureAwait(false) ?? commandStatus; // final fallback if there is no wrapper orchstration
            }

            if (commandStatus != null)
            {
                var commandResult = commandStatus.Output.HasValues
                    ? commandStatus.Output.ToObject <ICommandResult>()
                    : commandStatus.Input.ToObject <ICommand>().CreateResult(); // fallback to the default command result

                return(commandResult.ApplyStatus(commandStatus));
            }

            return(null);
        }
        public async Task <DurableOrchestrationStatus> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "status/{id}")] HttpRequestMessage request,
            [DurableClient] IDurableClient orchestratorClient,
            string id,
            ILogger log)
        {
            DurableOrchestrationStatus status;

            var parameters = GetQueryStringParameters(request);

            if (parameters.hasParameters)
            {
                status = await orchestratorClient.GetStatusAsync(
                    id,
                    parameters.showHistory,
                    parameters.showHistoryOutput,
                    parameters.showInput);
            }
            else
            {
                status = await orchestratorClient.GetStatusAsync(id);
            }

            return(status);
        }
Пример #3
0
        public async Task SingleInstanceQuery()
        {
            object input = 42;

            DurableOrchestrationStatus status = await this.RunOrchestrationAsync(nameof(Functions.Sequence), input);

            Assert.Equal(OrchestrationRuntimeStatus.Completed, status.RuntimeStatus);
            Assert.Equal(10, (int)status.Output);

            IDurableClient client = await this.GetDurableClientAsync();

            status = await client.GetStatusAsync(status.InstanceId);

            Assert.NotNull(status.Input);
            Assert.Equal(JTokenType.Integer, status.Input.Type);
            Assert.Equal(42, status.Input);
            Assert.Null(status.History);

            status = await client.GetStatusAsync(status.InstanceId, showHistory : true);

            Assert.NotNull(status.Input);
            Assert.Equal(JTokenType.Integer, status.Input.Type);
            Assert.Equal(42, status.Input);
            Assert.NotNull(status.History);
            Assert.NotEmpty(status.History);
            Assert.True(status.History.Count >= 12);

            // TODO: Check the content of the history for input/output fields
        }
Пример #4
0
        public static async Task <ICommandResult> GetCommandResultAsync(this IDurableClient durableClient, ICommand command)
        {
            if (durableClient is null)
            {
                throw new ArgumentNullException(nameof(durableClient));
            }

            if (command is null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            var commandStatus = await durableClient
                                .GetStatusAsync(CommandHandler.GetCommandOrchestrationInstanceId(command))
                                .ConfigureAwait(false);

            if (commandStatus is null)
            {
                // the command orchestration wasn't created yet
                // there is no way to return a command result

                return(null);
            }
            else if (commandStatus.RuntimeStatus.IsFinal())
            {
                // the command orchestration reached a final state
                // but the message orchestration is responsible to
                // send the result and there could modify the overall
                // command result (e.g. if a send operation fails).

                var commandMessageStatus = await durableClient
                                           .GetStatusAsync(CommandHandler.GetCommandMessageOrchestrationInstanceId(command))
                                           .ConfigureAwait(false);

                if (commandMessageStatus?.Output.HasValues ?? false)
                {
                    return(commandMessageStatus.Output
                           .ToObject <ICommandResult>()
                           .ApplyStatus(commandMessageStatus));
                }
            }

            // the command orchestration is in-flight
            // get the current command result from its
            // output or fallback to the default result

            var commandResult = commandStatus.Output.HasValues
                ? commandStatus.Output.ToObject <ICommandResult>()
                : command.CreateResult(); // fallback to the default command result

            return(commandResult.ApplyStatus(commandStatus));
        }
Пример #5
0
        public static async Task <IActionResult> DfmGetOrchestrationFunction(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = Globals.ApiRoutePrefix + "/orchestrations('{instanceId}')")] HttpRequest req,
            string instanceId,
            [DurableClient(TaskHub = Globals.TaskHubRouteParamName)] IDurableClient durableClient,
            ILogger log)
        {
            // Checking that the call is authenticated properly
            try
            {
                await Auth.ValidateIdentityAsync(req.HttpContext.User, req.Headers, durableClient.TaskHubName);
            }
            catch (Exception ex)
            {
                log.LogError(ex, "Failed to authenticate request");
                return(new UnauthorizedResult());
            }

            var status = await durableClient.GetStatusAsync(instanceId, false, false, true);

            if (status == null)
            {
                return(new NotFoundObjectResult($"Instance {instanceId} doesn't exist"));
            }

            return(new DetailedOrchestrationStatus(status).ToJsonContentResult(Globals.FixUndefinedsInJson));
        }
Пример #6
0
        private async Task <IActionResult> HandleGetAsync(IDurableClient durableClient, Guid commandId)
        {
            var wrapperInstanceId = GetCommandWrapperOrchestrationInstanceId(commandId);

            var wrapperInstanceStatus = await durableClient
                                        .GetStatusAsync(wrapperInstanceId)
                                        .ConfigureAwait(false);

            var command = wrapperInstanceStatus?.Input
                          .ToObject <IOrchestratorCommand>();

            if (command is null)
            {
                return(new NotFoundResult());
            }

            var commandResult = await durableClient
                                .GetCommandResultAsync(command)
                                .ConfigureAwait(false);

            if (commandResult is null)
            {
                commandResult = command.CreateResult(wrapperInstanceStatus);
            }

            if (commandResult.RuntimeStatus.IsFinal())
            {
                return(new OkObjectResult(commandResult));
            }

            var location = UriHelper.GetDisplayUrl(httpContextAccessor.HttpContext.Request)
                           .AppendPathSegment(commandResult.CommandId);

            return(new AcceptedResult(location, commandResult));
        }
        public static async Task RunEntity(
            [EntityTrigger] IDurableEntityContext functionContext,
            [DurableClient] IDurableClient durableClient)
        {
            if (functionContext is null)
            {
                throw new ArgumentNullException(nameof(functionContext));
            }

            var activeCommand  = functionContext.GetState <ICommand>();
            var pendingCommand = functionContext.GetInput <ICommand>();

            functionContext.SetState(pendingCommand);

            var activeCommandId = activeCommand?.CommandId;

            if (activeCommandId.HasValue)
            {
                var status = await durableClient
                             .GetStatusAsync(activeCommandId.Value.ToString())
                             .ConfigureAwait(false);

                if (status?.RuntimeStatus.IsFinal() ?? true)
                {
                    activeCommandId = null;
                }
            }

            functionContext.Return(activeCommandId?.ToString());
        }
Пример #8
0
        private static async Task <ICommandResult> StartCommandOrchestration(IDurableClient durableClient, IOrchestratorCommand orchestratorCommand)
        {
            var orchestratorCommandMessage = new OrchestratorCommandMessage(orchestratorCommand);
            var orchestratorCommandResult  = orchestratorCommand.CreateResult();

            var orchestratorCommandOrchestration = orchestratorCommand switch
            {
                _ => $"{orchestratorCommand.GetType().Name}Orchestration"
            };

            try
            {
                var instanceId = await durableClient
                                 .StartNewAsync <object>(orchestratorCommandOrchestration, orchestratorCommand.CommandId.ToString(), orchestratorCommandMessage)
                                 .ConfigureAwait(false);

                var status = await durableClient
                             .GetStatusAsync(instanceId)
                             .ConfigureAwait(false);

                orchestratorCommandResult.ApplyStatus(status);
            }
            catch (FunctionFailedException exc)
            {
                orchestratorCommandResult.Errors.Add(exc);
            }

            return(orchestratorCommandResult);
        }
    }
        public static async Task ProjectCommandSerializationEntity(
            [EntityTrigger] IDurableEntityContext context,
            [DurableClient] IDurableClient durableClient)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var oldCommand = context.GetState <ICommand>();
            var newCommand = context.GetInput <ICommand>();

            context.SetState(newCommand);

            var correlationId = oldCommand?.CommandId;

            if (correlationId.HasValue)
            {
                var status = await durableClient
                             .GetStatusAsync(correlationId.Value.ToString())
                             .ConfigureAwait(false);

                if (status?.IsFinalRuntimeStatus() ?? true)
                {
                    correlationId = null;
                }
            }

            context.Return(correlationId?.ToString());
        }
Пример #10
0
        public static async Task <ICommandResult> RunActivity(
            [ActivityTrigger] IDurableActivityContext activityContext,
            [DurableClient] IDurableClient durableClient,
            ILogger log)
        {
            if (activityContext is null)
            {
                throw new ArgumentNullException(nameof(activityContext));
            }

            if (durableClient is null)
            {
                throw new ArgumentNullException(nameof(durableClient));
            }

            var commandResult = activityContext.GetInput <ICommandResult>();

            try
            {
                var commandStatus = await durableClient
                                    .GetStatusAsync(commandResult.CommandId.ToString())
                                    .ConfigureAwait(false);

                if (commandStatus != null)
                {
                    commandResult.ApplyStatus(commandStatus);
                }
            }
            catch (Exception exc)
            {
                log?.LogWarning(exc, $"Failed to augment command result with orchestration status {commandResult.CommandId}: {exc.Message}");
            }

            return(commandResult);
        }
Пример #11
0
        public async Task SingleInstancePurge()
        {
            DurableOrchestrationStatus status = await this.RunOrchestrationAsync(nameof(Functions.NoOp));

            Assert.Equal(OrchestrationRuntimeStatus.Completed, status.RuntimeStatus);

            IDurableClient client = await this.GetDurableClientAsync();

            PurgeHistoryResult result;

            // First purge gets the active instance
            result = await client.PurgeInstanceHistoryAsync(status.InstanceId);

            Assert.NotNull(result);
            Assert.Equal(1, result.InstancesDeleted);

            // Verify that it's gone
            DurableOrchestrationStatus statusAfterPurge = await client.GetStatusAsync(status.InstanceId);

            Assert.Null(statusAfterPurge);

            // Second purge should be a no-op
            result = await client.PurgeInstanceHistoryAsync(status.InstanceId);

            Assert.NotNull(result);
            Assert.Equal(0, result.InstancesDeleted);
        }
Пример #12
0
        public static async Task <ICommandResult> RunActivity(
            [ActivityTrigger] IDurableActivityContext functionContext,
            [DurableClient] IDurableClient durableClient)
        {
            if (functionContext is null)
            {
                throw new ArgumentNullException(nameof(functionContext));
            }

            if (durableClient is null)
            {
                throw new ArgumentNullException(nameof(durableClient));
            }

            var(commandResult, instanceId) = functionContext.GetInput <(ICommandResult, string)>();

            try
            {
                var commandStatus = await durableClient
                                    .GetStatusAsync(instanceId)
                                    .ConfigureAwait(false);

                return(commandResult
                       .ApplyStatus(commandStatus));
            }
            catch (Exception exc) when(!exc.IsSerializable(out var serializableExc))
            {
                throw serializableExc;
            }
        }
    }
Пример #13
0
        public static async Task <IActionResult> Finish(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Finish/{id}")] HttpRequest req,
            string id,
            [DurableClient] IDurableClient client,
            ILogger log)
        {
            log.LogInformation("Request to close to registry {id}.", id);

            // id is required on route Finish/{id}
            if (string.IsNullOrWhiteSpace(id))
            {
                return(new BadRequestObjectResult("Id is required after Finish/ on the route."));
            }

            // confirm a workflow exists
            var instance = await client.GetStatusAsync(id);

            // not there
            if (instance == null)
            {
                return(new BadRequestObjectResult($"Unable to find workflow with id {id}"));
            }

            // not running
            if (instance.RuntimeStatus != OrchestrationRuntimeStatus.Running)
            {
                return(new BadRequestObjectResult($"Instance {id} is not active."));
            }

            // signal to close
            await client.RaiseEventAsync(id, CLOSE_TASK, true);

            return(new OkResult());
        }
        public async Task <IActionResult> AddCertificate_HttpPoll(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "add-certificate/{instanceId}")] HttpRequest req,
            string instanceId,
            [DurableClient] IDurableClient starter)
        {
            if (!User.Identity.IsAuthenticated)
            {
                return(Unauthorized());
            }

            var status = await starter.GetStatusAsync(instanceId);

            if (status == null)
            {
                return(BadRequest());
            }

            if (status.RuntimeStatus == OrchestrationRuntimeStatus.Failed)
            {
                return(Problem(status.Output.ToString()));
            }

            if (status.RuntimeStatus == OrchestrationRuntimeStatus.Running ||
                status.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
                status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew)
            {
                return(AcceptedAtFunction(nameof(AddCertificate_HttpPoll), new { instanceId }, null));
            }

            return(Ok());
        }
Пример #15
0
        private async Task <IActionResult> HandleGetAsync(IDurableClient durableClient, Guid commandId)
        {
            var wrapperInstanceId = GetCommandWrapperOrchestrationInstanceId(commandId);

            var wrapperInstanceStatus = await durableClient
                                        .GetStatusAsync(wrapperInstanceId)
                                        .ConfigureAwait(false);

            var command = wrapperInstanceStatus?.Input
                          .ToObject <IOrchestratorCommand>();

            if (command is null)
            {
                return(new NotFoundResult());
            }

            var commandResult = await durableClient
                                .GetCommandResultAsync(command)
                                .ConfigureAwait(false);

            if (commandResult is null)
            {
                commandResult = command.CreateResult(wrapperInstanceStatus);
            }

            return(CreateCommandResultResponse(commandResult));
        }
Пример #16
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "command/{commandId:guid}")] HttpRequest httpRequest,
            [DurableClient] IDurableClient durableClient,
            string commandId
            /* ILogger log */)
        {
            if (httpRequest is null)
            {
                throw new ArgumentNullException(nameof(httpRequest));
            }

            if (durableClient is null)
            {
                throw new ArgumentNullException(nameof(durableClient));
            }

            if (commandId is null)
            {
                throw new ArgumentNullException(nameof(commandId));
            }


            var status = await durableClient
                         .GetStatusAsync(commandId, showHistory : false, showHistoryOutput : false, showInput : true)
                         .ConfigureAwait(false);

            var commandResult = status?.GetCommandResult();

            if (commandResult is null)
            {
                return(new NotFoundResult());
            }

            return(new OkObjectResult(commandResult));
        }
Пример #17
0
        public static async Task <bool> RunActivity(
            [ActivityTrigger] ProjectCommandNotification notification,
            [DurableClient] IDurableClient durableClient)
        {
            if (notification is null)
            {
                throw new ArgumentNullException(nameof(notification));
            }

            var status = await durableClient
                         .GetStatusAsync(notification.ActiveCommandId.ToString())
                         .ConfigureAwait(false);

            if (status?.RuntimeStatus.IsFinal() ?? true)
            {
                // no status available or final status reached

                await durableClient
                .RaiseEventAsync(notification.PendingInstanceId, notification.ActiveCommandId.ToString())
                .ConfigureAwait(true);

                return(false); // orchestration is not active
            }

            return(true); // orchstration is active (has not reached final state)
        }
Пример #18
0
    public Task <DurableOrchestrationStatus> RunActivity(
        [ActivityTrigger] IDurableActivityContext activityContext,
        [DurableClient] IDurableClient orchestrationClient,
        ILogger log)
    {
        if (activityContext is null)
        {
            throw new ArgumentNullException(nameof(activityContext));
        }

        if (orchestrationClient is null)
        {
            throw new ArgumentNullException(nameof(orchestrationClient));
        }

        if (log is null)
        {
            throw new ArgumentNullException(nameof(log));
        }

        try
        {
            var input = activityContext.GetInput <Input>();

            return(orchestrationClient
                   .GetStatusAsync(input.CommandId.ToString(), showHistory: input.ShowHistory, showHistoryOutput: input.ShowHistoryOutput, showInput: input.ShowInput));
        }
        catch (Exception exc)
        {
            log.LogError(exc, $"Failed to enqeueu command: {exc.Message}");

            throw exc.AsSerializable();
        }
    }
        public static async Task <bool> ProjectCommandSerializationActivity(
            [ActivityTrigger] ProjectCommandNotification notification,
            [DurableClient] IDurableClient durableClient)
        {
            if (notification is null)
            {
                throw new ArgumentNullException(nameof(notification));
            }

            if (durableClient is null)
            {
                throw new ArgumentNullException(nameof(durableClient));
            }

            var status = await durableClient
                         .GetStatusAsync(notification.CorrelationId.ToString())
                         .ConfigureAwait(false);

            if (!status.IsFinalRuntimeStatus())
            {
                _ = await durableClient
                    .StartNewAsync(nameof(ProjectCommandMonitoring.ProjectCommandMonitoringOrchestrator), notification)
                    .ConfigureAwait(false);

                return(true); // command monitoring started
            }

            return(false); // no command monitoring started
        }
        public async Task <IActionResult> HttpGetJobs(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "jobs")] HttpRequestMessage req,
            [DurableClient] IDurableClient durableClient,
            ILogger log)
        {
            var durableTasks = await durableClient.GetStatusAsync();

            return(new OkObjectResult(durableTasks));
        }
Пример #21
0
        public static async Task CancelTimeoutAsync(this IDurableClient client, EntityId instanceId)
        {
            var status = await client.GetStatusAsync(instanceId.EntityKey);

            if (status != null && status.RuntimeStatus == OrchestrationRuntimeStatus.Running)
            {
                await client.TerminateAsync(instanceId.EntityKey, "Entity deleted");
            }
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "genericHttp")] HttpRequest req,
            [DurableClient] IDurableClient client,
            ILogger log)
        {
            string        requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            Arguments     arguments   = JsonConvert.DeserializeObject <Arguments>(requestBody);
            IActionResult response;

            try
            {
                DateTime starttime = DateTime.UtcNow;

                if (arguments.InstanceId == null)
                {
                    // start the orchestration, and wait for the persistence confirmation
                    arguments.InstanceId = await client.StartNewAsync <JToken>(arguments.Name, null, arguments.Input);

                    // then wait for completion
                    response = await client.WaitForCompletionOrCreateCheckStatusResponseAsync(req, arguments.InstanceId, TimeSpan.FromSeconds(arguments.Timeout));
                }
                else
                {
                    // issue start and wait together. This can be a bit faster for orchestrations that complete very quickly.
                    Task start = client.StartNewAsync <JToken>(arguments.Name, arguments.InstanceId, arguments.Input);
                    Task <IActionResult> completion = client.WaitForCompletionOrCreateCheckStatusResponseAsync(req, arguments.InstanceId, TimeSpan.FromSeconds(arguments.Timeout));
                    await start;
                    response = await completion;
                }

                DateTime endtime = DateTime.UtcNow;

                if (response is ObjectResult objectResult &&
                    objectResult.Value is HttpResponseMessage responseMessage &&
                    responseMessage.StatusCode == System.Net.HttpStatusCode.OK &&
                    responseMessage.Content is StringContent stringContent)
                {
                    if (arguments.UseReportedLatency)
                    {
                        var state = await client.GetStatusAsync(arguments.InstanceId, false, false, false);

                        starttime = state.CreatedTime;
                        endtime   = state.LastUpdatedTime;
                    }
                    response = new OkObjectResult(new Response {
                        Result   = await stringContent.ReadAsStringAsync(),
                        Time     = endtime,
                        Duration = (endtime - starttime).TotalMilliseconds
                    });
                }
                else
                {
                    return(response); // it is a 202 response that will be interpreted as a timeout
                }
            }
Пример #23
0
        public static async Task <IActionResult> Run(
            // Using /a/p/i route prefix, to let Functions Host distinguish api methods from statics
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "a/p/i/orchestrations")] HttpRequest req,
            [DurableClient(TaskHub = "%DFM_HUB_NAME%")] IDurableClient durableClient,
            ILogger log)
        {
            // Checking that the call is authenticated properly
            try
            {
                Globals.ValidateIdentity(req.HttpContext.User, req.Headers);
            }
            catch (UnauthorizedAccessException ex)
            {
                return(new OkObjectResult(ex.Message)
                {
                    StatusCode = 401
                });
            }

            DateTime?timeFrom, timeTill;
            string   filterString = ExtractTimeRange(req.Query["$filter"], out timeFrom, out timeTill);

            string entityType;

            filterString = ExtractEntityType(filterString, out entityType);

            var filterClause = new FilterClause(filterString);

            var orchestrations = (await(
                                      (timeFrom.HasValue && timeTill.HasValue) ?
                                      durableClient.GetStatusAsync(timeFrom.Value, timeTill, new OrchestrationRuntimeStatus[0]) :
                                      durableClient.GetStatusAsync()
                                      ))
                                 .ExpandStatusIfNeeded(durableClient, filterClause)
                                 .ApplyEntityTypeFilter(entityType)
                                 .ApplyFilter(filterClause)
                                 .ApplyOrderBy(req.Query)
                                 .ApplySkip(req.Query)
                                 .ApplyTop(req.Query);

            return(orchestrations.ToJsonContentResult(Globals.FixUndefinedsInJson));
        }
Пример #24
0
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "command/{commandId:guid}")] HttpRequest httpRequest,
            [DurableClient] IDurableClient durableClient,
            string commandId,
            ILogger logger)
        {
            var status = await durableClient
                         .GetStatusAsync(commandId, showHistory : false, showHistoryOutput : false, showInput : false)
                         .ConfigureAwait(false);

            return(status is null ? (IActionResult) new NotFoundResult() : new OkObjectResult(status.GetResult()));
        }
        public async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string instanceId = await _client.StartNewAsync("E1_HelloSequence");

            DurableOrchestrationStatus status = await _client.GetStatusAsync(instanceId);

            while (status.RuntimeStatus == OrchestrationRuntimeStatus.Pending ||
                   status.RuntimeStatus == OrchestrationRuntimeStatus.Running ||
                   status.RuntimeStatus == OrchestrationRuntimeStatus.ContinuedAsNew)
            {
                await Task.Delay(10000);

                status = await _client.GetStatusAsync(instanceId);
            }

            return(new ObjectResult(status));
        }
Пример #26
0
        public static async Task ResetTimeoutAsync(this IDurableClient client, EntityId instanceId)
        {
            var status = await client.GetStatusAsync(instanceId.EntityKey);

            if (status != null && status.RuntimeStatus == OrchestrationRuntimeStatus.Running)
            {
                await client.RaiseEventAsync(instanceId.EntityKey, "TimeoutReset");
            }
            else
            {
                await client.StartNewAsync(nameof(StartTimeoutAsync), instanceId.EntityKey);
            }
        }
        public async Task GivenNotFound_WhenGettingStatus_ThenReturnNull()
        {
            Guid id = Guid.NewGuid();

            using var source = new CancellationTokenSource();

            _durableClient.GetStatusAsync(OperationId.ToString(id), showInput: true).Returns(Task.FromResult <DurableOrchestrationStatus>(null));

            Assert.Null(await _client.GetStatusAsync(id, source.Token));

            await _durableClient.Received(1).GetStatusAsync(OperationId.ToString(id), showInput: true);

            await _extendedQueryTagStore.DidNotReceiveWithAnyArgs().GetExtendedQueryTagsAsync((IReadOnlyList <int>) default);
        private static async Task <DetailedOrchestrationStatus> GetInstanceStatusWithHistory(string connName, string instanceId, IDurableClient durableClient, ILogger log)
        {
            var status = await durableClient.GetStatusAsync(instanceId, true, true, true);

            if (status == null)
            {
                return(null);
            }

            ConvertScheduledTime(status.History);

            return(new DetailedOrchestrationStatus(status, connName));
        }
Пример #29
0
        public static async Task <IActionResult> Add(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "Add/{id}")]
            HttpRequest req,
            string id,
            [DurableClient] IDurableClient client,
            ILogger log)
        {
            log.LogInformation("Request to add to registry {id}.", id);

            // id is required on route like Add/{id}
            if (string.IsNullOrWhiteSpace(id))
            {
                return(new BadRequestObjectResult("Id is required after Add/ on the route."));
            }

            // item is required like Add/{id}?item={item}
            if (!req.Query.ContainsKey("item"))
            {
                return(new BadRequestObjectResult("Item is required as a querystring parameter"));
            }

            // grab the item
            var item = req.Query["item"];

            // confirm a workflow exists
            var instance = await client.GetStatusAsync(id);

            // doesn't exist
            if (instance == null)
            {
                return(new BadRequestObjectResult($"Unable to find workflow with id {id}"));
            }

            // no longer open/running
            if (instance.RuntimeStatus != OrchestrationRuntimeStatus.Running)
            {
                return(new BadRequestObjectResult($"Instance {id} is not active."));
            }

            // add item to list
            await client.SignalEntityAsync <IRegistryList>(
                id.AsRegistryId(),
                list => list.AddItem(item));

            // update total item count
            await client.SignalEntityAsync <IRegistryStats>(
                StatsId,
                stats => stats.NewItem());

            return(new OkResult());
        }
Пример #30
0
        private async Task <IActionResult> HandlePostAsync(IDurableClient durableClient, HttpRequestMessage requestMessage, ILogger log)
        {
            IOrchestratorCommand command;

            try
            {
                command = await requestMessage.Content
                          .ReadAsJsonAsync <IOrchestratorCommand>()
                          .ConfigureAwait(false);

                command?.Validate(throwOnValidationError: true);
            }
            catch (ValidationException)
            {
                return(new BadRequestResult());
            }

            if (command is null)
            {
                return(new BadRequestResult());
            }

            var instanceId = GetCommandWrapperOrchestrationInstanceId(command.CommandId);

            try
            {
                _ = await durableClient
                    .StartNewAsync(nameof(OrchestratorCommandOrchestration), instanceId, command)
                    .ConfigureAwait(false);
            }
            catch (InvalidOperationException)
            {
                // check if there is an orchestration for the given
                // orchstrator command message is already in-flight

                var commandWarpperStatus = await durableClient
                                           .GetStatusAsync(instanceId)
                                           .ConfigureAwait(false);

                if (commandWarpperStatus is null)
                {
                    throw; // bubble exception
                }
                return(new System.Web.Http.ConflictResult());
            }

            var commandResult = await WaitForCommandResultAsync(durableClient, command, log)
                                .ConfigureAwait(false);

            return(CreateCommandResultResponse(command, commandResult));
        }