コード例 #1
0
        private Core.Models.Execution ApplyExecutionContext(Core.Models.ExecutionContext execContext, Core.Models.Execution execution)
        {
            execution.LastUpdatedDateTimeUtc = DateTime.UtcNow;
            execution.PercentComplete        = execContext.PercentComplete;

            if (execContext.ProvidedOutputObjects != null)
            {
                execution.ProvidedInputObjects.AddRange(
                    execContext.ProvidedInputObjects.Except(execution.ProvidedInputObjects));
            }

            if (execContext.ProvidedOutputObjects != null)
            {
                execution.ProvidedOutputObjects.AddRange(
                    execContext.ProvidedOutputObjects.Except(execution.ProvidedOutputObjects));
            }

            execution.ResultData    = (execContext.ResultData ?? execution.ResultData);
            execution.Status        = execContext.Status;
            execution.StatusMessage = execContext.StatusMessage;
            execution.ExecutionTimeoutDateTimeUtc = execContext.ExecutionTimeoutDateTimeUtc.GetValueOrDefault();

            if (execContext.ValidationErrors != null)
            {
                execution.ValidationErrors.AddRange(execContext.ValidationErrors);
            }

            return(execution);
        }
コード例 #2
0
        public async Task RouteRequestAsync_ServiceWithGivenExecutionModelName_ShouldRouteSuccessfully()
        {
            const string modelName = "expected-model/v1";

            var mockProcessor = new Mock<IExecutionProcessor>();
            var mockServiceProvider = new Mock<IServiceProvider>();

            var processorFactory = new NamedServiceFactory<IExecutionProcessor>(
                new Dictionary<string, Func<IServiceProvider, IExecutionProcessor>>
                {
                    [modelName] = sp => mockProcessor.Object
                });

            var execRequest = new ExecutionRequest
            {
                ExecutionId = Guid.NewGuid().ToString(),
                ExecutionModelName = modelName
            };

            var execContext = new Core.Models.ExecutionContext
            {
                ExecutionId = execRequest.ExecutionId,
                Status = ExecutionStatus.Succeeded
            };

            mockProcessor.Setup(ep => ep.ProcessRequestAsync(execRequest, CancellationToken.None))
                         .Returns(Task.FromResult(execContext));

            var execRequestRouter = new ExecutionRequestRouter(processorFactory, mockServiceProvider.Object);
            var actualExecContext = await execRequestRouter.RouteRequestAsync(execRequest, CancellationToken.None);

            actualExecContext.Should().NotBeNull();
            actualExecContext.Should().Be(execContext);
        }
コード例 #3
0
        private async Task <Core.Models.ExecutionContext> ExecuteAsync <T>(Core.Models.ExecutionContext execContext, T httpExecRequest,
                                                                           HttpExtensionSettings httpSettings)
        {
            logger.LogInformation($"Posting execution request [{execContext.ExecutionId}] to [{httpSettings.ExecutionUrl}]...");

            // POST the request to the extension...

            var httpExecResponse = await this.jsonHttpClient.PostAsync <HttpExecutionResponse>(
                httpSettings.ExecutionUrl, httpExecRequest);

            // Gather all the appropriate information returned from the extension...

            execContext.ResultData            = httpExecResponse.Content?.ResponseData;
            execContext.ProvidedOutputObjects = httpExecResponse.Content?.ProvidedOutputObjects;
            execContext.ValidationErrors      = httpExecResponse.Content?.ValidationErrors?.Select(ve => ve.ToCoreModel()).ToList();

            switch (httpExecResponse.StatusCode)
            {
            // If the extension responded with a [202 Accepted], the execution is long-running. Mark the execution as [Processing].
            // The extension is expected to call back to the execution API with status updates.

            case HttpStatusCode.Accepted:
                logger.LogInformation($"Execution [{execContext.ExecutionId}] is long-running.");
                execContext.UpdateStatus(ExecutionStatus.Processing);
                break;

            // If the extension responded with a [200 OK], execution was succesful. Mark the execution as such.

            case HttpStatusCode.OK:
                logger.LogInformation($"Execution [{execContext.ExecutionId}] complete.");
                execContext.UpdateStatus(ExecutionStatus.Succeeded);
                break;

            // If the extension responded with a [400 Bad Request], either we called the extension wrong OR the client
            // called the extension wrong. The extension may have provided further information as [validationErrors].
            // If [validationErrors] were provided, mark the execution as [ValidationFailed].
            // If [validationErrors] were not provided, something else went wrong, so mark the execution as [Failed].

            case HttpStatusCode.BadRequest:
                logger.LogWarning($"Execution request [{execContext.ExecutionId}] is invalid.");
                ProcessBadRequest(execContext, httpExecResponse.Content);
                break;

            // The extension responded with a status code that we didn't expect. Throw an exception...

            default:
                throw new HttpRequestException($"Extension returned an unexpected status code: [{httpExecResponse.StatusCode}].");
            }

            return(execContext);
        }
コード例 #4
0
        private Core.Models.ExecutionContext ProcessBadRequest(Core.Models.ExecutionContext execContext,
                                                               HttpExecutionResponse httpExecResponse)
        {
            execContext.ValidationErrors = httpExecResponse?.ValidationErrors.Select(e => e.ToCoreModel()).ToList();

            if (execContext.ValidationErrors.Any())
            {
                return(execContext.UpdateStatus(ExecutionStatus.ValidationFailed));
            }
            else
            {
                throw new HttpRequestException($"Extension returned an unexpected status code: [{HttpStatusCode.BadRequest}].");
            }
        }
コード例 #5
0
        private async Task <Core.Models.ExecutionContext> ValidateAsync <T>(Core.Models.ExecutionContext execContext, T httpExecRequest,
                                                                            HttpExtensionSettings httpSettings)

        {
            logger.LogInformation($"Posting execution validation request [{execContext.ExecutionId}] to [{httpSettings.ValidationUrl}]...");

            // POST the validation request to the extension...

            var httpExecResponse = await this.jsonHttpClient.PostAsync <HttpExecutionResponse>(
                httpSettings.ValidationUrl, httpExecRequest);

            // Grab any validation errors...

            execContext.ValidationErrors = httpExecResponse.Content?.ValidationErrors?.Select(ve => ve.ToCoreModel()).ToList();

            switch (httpExecResponse.StatusCode)
            {
            // If the extension responded with a [200 OK], mark the execution [ValidationSucceeded].

            case HttpStatusCode.OK:
                logger.LogInformation($"Execution request [{execContext.ExecutionId}] is valid.");
                execContext.UpdateStatus(ExecutionStatus.ValidationSucceeded);
                break;

            // If the extension responded with a [400 Bad Request], either we called the extension wrong OR the client
            // called the extension wrong. The extension may have provided further information as [validationErrors].
            // If [validationErrors] were provided, mark the execution as [ValidationFailed].
            // If [validationErrors] were not provided, something else went wrong, so mark the execution as [Failed].

            case HttpStatusCode.BadRequest:
                logger.LogInformation($"Execution request [{execContext.ExecutionId}] is invalid.");
                ProcessBadRequest(execContext, httpExecResponse.Content);
                break;

            // The extension responded with a status code that we didn't expect. Throw an exception...

            default:
                throw new HttpRequestException($"Extension returned an unexpected status code: [{httpExecResponse.StatusCode}].");
            }

            return(execContext);
        }