コード例 #1
0
        public void CalculateExecutionTimeoutDateTimeUtc_GivenExecutionRequestWithoutTimeoutDuration_ShouldReturnDateTimeBasedOnDefaultTimeoutDuration()
        {
            var execRequest = new ExecutionRequest {
                ExecutionId = Guid.NewGuid().ToString()
            };

            execRequest.CalculateExecutionTimeoutDateTimeUtc(TimeSpan.FromHours(2));

            execRequest.ExecutionTimeoutDateTimeUtc.Should().BeAfter(DateTime.UtcNow.AddHours(2).AddSeconds(-5)).And
            .BeBefore(DateTime.UtcNow.AddHours(2).AddSeconds(5));
        }
コード例 #2
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);
        }