Beispiel #1
0
        public static async Task <IActionResult> PostOrchestrationFunction(
            // Using /a/p/i route prefix, to let Functions Host distinguish api methods from statics
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "a/p/i/orchestrations('{instanceId}')/{action?}")] HttpRequest req,
            string instanceId,
            string action,
            [DurableClient(TaskHub = "%DFM_HUB_NAME%")] IDurableClient durableClient,
            ILogger log)
        {
            // Checking that the call is authenticated properly
            try
            {
                await Auth.ValidateIdentityAsync(req.HttpContext.User, req.Headers);
            }
            catch (Exception ex)
            {
                log.LogError(ex, "Failed to authenticate request");
                return(new UnauthorizedResult());
            }

            string bodyString = await req.ReadAsStringAsync();

            switch (action)
            {
            case "purge":
                await durableClient.PurgeInstanceHistoryAsync(instanceId);

                break;

            case "rewind":
                await durableClient.RewindAsync(instanceId, bodyString);

                break;

            case "terminate":
                await durableClient.TerminateAsync(instanceId, bodyString);

                break;

            case "raise-event":
                dynamic bodyObject = JObject.Parse(bodyString);
                string  eventName  = bodyObject.name;
                JObject eventData  = bodyObject.data;

                await durableClient.RaiseEventAsync(instanceId, eventName, eventData);

                break;

            case "set-custom-status":

                string connectionString = Environment.GetEnvironmentVariable(EnvVariableNames.AzureWebJobsStorage);
                string hubName          = Environment.GetEnvironmentVariable(EnvVariableNames.DFM_HUB_NAME);

                // Updating the table directly, as there is no other known way
                var tableClient = CloudStorageAccount.Parse(connectionString).CreateCloudTableClient();
                var table       = tableClient.GetTableReference($"{hubName}Instances");

                var orcEntity = (await table.ExecuteAsync(TableOperation.Retrieve(instanceId, string.Empty))).Result as DynamicTableEntity;

                if (string.IsNullOrEmpty(bodyString))
                {
                    orcEntity.Properties.Remove("CustomStatus");
                }
                else
                {
                    // Ensuring that it is at least a valid JSON
                    string customStatus = JObject.Parse(bodyString).ToString();
                    orcEntity.Properties["CustomStatus"] = new EntityProperty(customStatus);
                }

                await table.ExecuteAsync(TableOperation.Replace(orcEntity));

                break;

            case "restart":
                bool restartWithNewInstanceId = ((dynamic)JObject.Parse(bodyString)).restartWithNewInstanceId;

                await durableClient.RestartAsync(instanceId, restartWithNewInstanceId);

                break;

            default:
                return(new NotFoundResult());
            }

            return(new OkResult());
        }
        public static async Task <IActionResult> DfmPostOrchestrationFunction(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = Globals.ApiRoutePrefix + "/orchestrations('{instanceId}')/{action?}")] HttpRequest req,
            string instanceId,
            string action,
            [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());
            }

            // Checking that we're not in ReadOnly mode
            if (DfmEndpoint.Settings.Mode == DfmMode.ReadOnly)
            {
                log.LogError("Endpoint is in ReadOnly mode");
                return(new StatusCodeResult(403));
            }

            string bodyString = await req.ReadAsStringAsync();

            switch (action)
            {
            case "purge":
                await durableClient.PurgeInstanceHistoryAsync(instanceId);

                break;

            case "rewind":
                await durableClient.RewindAsync(instanceId, bodyString);

                break;

            case "terminate":
                await durableClient.TerminateAsync(instanceId, bodyString);

                break;

            case "raise-event":

                dynamic bodyObject = JObject.Parse(bodyString);
                string  eventName  = bodyObject.name;
                JObject eventData  = bodyObject.data;

                var match = ExpandedOrchestrationStatus.EntityIdRegex.Match(instanceId);
                // if this looks like an Entity
                if (match.Success)
                {
                    // then sending signal
                    var entityId = new EntityId(match.Groups[1].Value, match.Groups[2].Value);

                    await durableClient.SignalEntityAsync(entityId, eventName, eventData);
                }
                else
                {
                    // otherwise raising event
                    await durableClient.RaiseEventAsync(instanceId, eventName, eventData);
                }

                break;

            case "set-custom-status":

                // Updating the table directly, as there is no other known way
                var table = TableClient.GetTableClient().GetTableReference($"{durableClient.TaskHubName}Instances");

                var orcEntity = (await table.ExecuteAsync(TableOperation.Retrieve(instanceId, string.Empty))).Result as DynamicTableEntity;

                if (string.IsNullOrEmpty(bodyString))
                {
                    orcEntity.Properties.Remove("CustomStatus");
                }
                else
                {
                    // Ensuring that it is at least a valid JSON
                    string customStatus = JObject.Parse(bodyString).ToString();
                    orcEntity.Properties["CustomStatus"] = new EntityProperty(customStatus);
                }

                await table.ExecuteAsync(TableOperation.Replace(orcEntity));

                break;

            case "restart":
                bool restartWithNewInstanceId = ((dynamic)JObject.Parse(bodyString)).restartWithNewInstanceId;

                await durableClient.RestartAsync(instanceId, restartWithNewInstanceId);

                break;

            default:
                return(new NotFoundResult());
            }

            return(new OkResult());
        }