Пример #1
0
        public async Task <Core.Models.ExecutionContext> ProcessRequestAsync(ExecutionRequest execRequest, CancellationToken cancelToken)
        {
            if (execRequest == null)
            {
                throw new ArgumentNullException(nameof(execRequest));
            }

            // We're about to execute the extension. Update the execution status to [Processing].

            var execContext = execRequest.ToExecutionContext().UpdateStatus(ExecutionStatus.Processing);

            logger.LogInformation($"Updating execution [{execRequest.ExecutionId}] status: [{execContext.Status}]...");

            await UpdateExecutionStatusAsync(execRequest.UpdateExecutionStatusUrl, execContext.ToExecutionUpdate());

            logger.LogInformation($"Processing execution request [{execRequest.ExecutionId}]...");

            // Invoke the execution adapter and execute the extension.

            execContext = await this.execAdapter.ExecuteAsync(execRequest, cancelToken);

            logger.LogInformation($"Updating execution [{execRequest.ExecutionId}] status: [{execContext.Status}]...");

            // All done! Update the execution status based on the response from the execution adapter.

            await UpdateExecutionStatusAsync(execRequest.UpdateExecutionStatusUrl, execContext.ToExecutionUpdate());

            return(execContext);
        }
Пример #2
0
        public void ToExecutionContext_GivenExecutionRequest_ShouldReturnEquivalentExecutionContext()
        {
            var execRequest = new ExecutionRequest
            {
                CreatedDateTimeUtc     = DateTime.UtcNow.AddMinutes(-10),
                ExecutionProfileName   = "DefaultExecutionProfile",
                ExecutionId            = Guid.NewGuid().ToString(),
                ExtensionId            = Guid.NewGuid().ToString(),
                ExtensionVersionId     = Guid.NewGuid().ToString(),
                LastUpdatedDateTimeUtc = DateTime.UtcNow.AddMinutes(-5),
                Priority                    = ExecutionPriority.High,
                StatusUpdateKey             = Guid.NewGuid().ToString(),
                ExecutionTimeoutDateTimeUtc = DateTime.UtcNow.AddHours(1),
                ExecutionModelName          = "DefaultExecutionModel",
                ObjectProviderName          = "DefaultObjectProvider",
                SupportedServices           = new Dictionary <string, JObject> {
                    ["ServiceA"] = null
                },
                ProvidedInputObjects = new List <string> {
                    "InputObjectA"
                },
                InputObjects = new Dictionary <string, ExtensionInputObject> {
                    ["InputObjectA"] = null
                },
                OutputObjects = new Dictionary <string, ExtensionOutputObject> {
                    ["OutputObjectA"] = null
                }
            };

            var execContext = execRequest.ToExecutionContext();

            execContext.Should().NotBeNull();
            execContext.CreatedDateTimeUtc.Should().Be(execRequest.CreatedDateTimeUtc);
            execContext.ExecutionProfileName.Should().Be(execRequest.ExecutionProfileName);
            execContext.ExecutionId.Should().Be(execRequest.ExecutionId);
            execContext.ExtensionId.Should().Be(execRequest.ExtensionId);
            execContext.ExtensionVersionId.Should().Be(execRequest.ExtensionVersionId);
            execContext.LastUpdatedDateTimeUtc.Should().Be(execRequest.LastUpdatedDateTimeUtc);
            execContext.Priority.Should().Be(execRequest.Priority);
            execContext.StatusUpdateKey.Should().Be(execRequest.StatusUpdateKey);
            execContext.ExecutionTimeoutDateTimeUtc.Should().Be(execRequest.ExecutionTimeoutDateTimeUtc);
            execContext.ExecutionModelName.Should().Be(execRequest.ExecutionModelName);
            execContext.ObjectProviderName.Should().Be(execRequest.ObjectProviderName);
            execContext.SupportedServices.Should().BeEquivalentTo(execRequest.SupportedServices);
            execContext.ProvidedInputObjects.Should().BeEquivalentTo(execRequest.ProvidedInputObjects);
            execContext.InputObjects.Should().BeEquivalentTo(execRequest.InputObjects);
            execContext.OutputObjects.Should().BeEquivalentTo(execRequest.OutputObjects);
        }
Пример #3
0
        public Task <Draco.Core.Models.ExecutionContext> ExecuteAsync(ExecutionRequest request, CancellationToken cancelToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            if (cancelToken == null)
            {
                throw new ArgumentNullException(nameof(cancelToken));
            }

            // We're not actually doing anything. Mark the execution as [Succeeded] and move on...

            return(Task.FromResult(request.ToExecutionContext().UpdateStatus(ExecutionStatus.Succeeded)));
        }
Пример #4
0
        public async Task <Core.Models.ExecutionContext> ExecuteAsync(ExecutionRequest request, CancellationToken cancelToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            var requestJson    = JsonConvert.SerializeObject(request);
            var requestMessage = new Message(Encoding.UTF8.GetBytes(requestJson));

            requestMessage.UserProperties.Add(nameof(ExecutionRequest.ExecutionModelName), request.ExecutionModelName);
            requestMessage.UserProperties.Add(nameof(ExecutionRequest.ExecutionProfileName), request.ExecutionProfileName);
            requestMessage.UserProperties.Add(nameof(ExecutionRequest.Priority), request.Priority.ToString());

            await topicClient.SendAsync(requestMessage);

            return(request.ToExecutionContext().UpdateStatus(ExecutionStatus.Queued));
        }
Пример #5
0
        public async Task <Core.Models.ExecutionContext> ExecuteAsync(ExecutionRequest execRequest, CancellationToken cancelToken)
        {
            if (execRequest == null)
            {
                throw new ArgumentNullException(nameof(execRequest));
            }

            logger.LogInformation($"Processing execution request [{execRequest.ExecutionId}]...");

            // Give all the applicable extension services a chance to do any synchronous pre-work ahead of the actual execution...
            // For more information on extension services, see /doc/architecture/extension-services.md.

            await(execRequest.ValidateOnly ?
                  this.execServiceProvider.OnValidatingAsync(execRequest) :
                  this.execServiceProvider.OnExecutingAsync(execRequest));

            // UTC now + the execution timeout on the execution request if it was provided.
            // If no execution timeout was defined, default to an hour [defaultTimeoutPeriod].

            execRequest.CalculateExecutionTimeoutDateTimeUtc(defaultTimeoutPeriod);

            logger.LogDebug($"Execution [{execRequest.ExecutionId}] timeout set to [{execRequest.ExecutionTimeoutDateTimeUtc}] UTC.");

            // We're about to execution the extension. Create an execution context to capture the results...

            var execContext = execRequest.ToExecutionContext();

            try
            {
                // Deserialize the execution model-specific settings, provided in the [execRequest.extensionSettings] JSON object property,
                // to get the execution and/or validation URLs that we need to handle the request.

                var httpSettings = GetHttpExtensionSettings(execRequest);

                // Create the execution request that we'll POST to the extension...

                var httpExecRequest = await ToHttpExecutionRequestAsync(execRequest);

                logger.LogDebug($"Execution [{execRequest.ExecutionId}] URL is [{httpSettings.ExecutionUrl}].");

                logger.LogDebug(string.IsNullOrEmpty(httpSettings.ValidationUrl) ?
                                $"Execution [{execRequest.ExecutionId}] validation URL is [{httpSettings.ValidationUrl}]." :
                                $"Execution [{execRequest.ExecutionId}] validation URL not provided.");

                // If there was a valid RSA public/private key pair provided along with the request,
                // sign the request before we send it along to the extension...

                if (!string.IsNullOrEmpty(execRequest.SignatureRsaKeyXml))
                {
                    logger.LogDebug($"Signing execution request [{execRequest.ExecutionId}]...");

                    httpExecRequest.Signature = await httpExecRequestSigner.GenerateSignatureAsync(execRequest.SignatureRsaKeyXml, httpExecRequest);
                }

                if (execRequest.ValidateOnly)
                {
                    // If it's a validation only request, make sure that the extension actually supports validation.
                    // Under normal circumstances, this should have been caught way further upstream at the execution API.

                    if (execRequest.IsValidationSupported == false)
                    {
                        throw new NotSupportedException($"Extension [{execRequest.ExtensionId}:{execRequest.ExtensionVersionId}] " +
                                                        "does not support validation.");
                    }

                    // Validate the request...

                    execContext = await ValidateAsync(execContext, httpExecRequest, httpSettings);
                }
                else
                {
                    // Execute the request...

                    execContext = await ExecuteAsync(execContext, httpExecRequest, httpSettings);
                }
            }
            catch (Exception ex)
            {
                logger.LogError($"An error occurred while processing execution request [{execRequest.ExecutionId}]: [{ex.Message}].");

                execContext.UpdateStatus(ExecutionStatus.Failed);
            }
            finally
            {
                // Give all the applicable extension services a chance to do any synchronous post-work after the execution
                // regardless of whether or not it succeeded. For more information on extension services, see /doc/architecture/extension-services.md.

                await(execRequest.ValidateOnly ?
                      this.execServiceProvider.OnValidatedAsync(execContext) :
                      this.execServiceProvider.OnExecutedAsync(execContext));

                logger.LogInformation($"Execution request [{execRequest.ExecutionId}] processing complete.");
            }

            return(execContext);
        }