Beispiel #1
0
        public virtual async Task <ServiceResponse <TResponse> > Execute(TRequest request, CancellationToken cancellationToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }
            StartTime = ServiceClock.CurrentTime();
            _chainedServiceResolver?.AddCallToChain(this);
            _correlationId        = CalculateCorrelationId(request);
            _sessionId            = request.SessionId;
            _serviceHop           = CalculateServiceHop();
            request.CorrelationId = _correlationId;
            request.SyncCorrelationIds();
            ServiceResponse <TResponse> response = null;

            // ON REQUEST PIPELINE

            _logger.LogTrace($"Start request pipeline for {request.CorrelationId}");
            foreach (var middleware in _pipeline)
            {
                try
                {
                    if (_serviceHop > 0 &&
                        middleware.SkipOnInternalCall)
                    {
                        continue;
                    }
                    var middlewareResult = await middleware.OnRequest(this, request, cancellationToken);

                    if (middlewareResult != null)
                    {
                        response = new ServiceResponse <TResponse>(default(TResponse), middlewareResult.MetaData);
                        break;
                    }
                }
                catch (Exception ex)
                {
                    if (!middleware.IgnoreExceptions)
                    {
                        var errorResponse = PermanentError(ex);
                        StoredResponse = errorResponse;
                        return(errorResponse);
                    }
                }
            }
            _logger.LogTrace($"End request pipeline for {request.CorrelationId}");

            // EXECUTE THE SERVICE
            _logger.LogTrace($"Start execute for {request.CorrelationId}");
            try
            {
                if (!cancellationToken.IsCancellationRequested)
                {
                    if (response == null)
                    {
                        response = await BeforeImplementation(request, cancellationToken);
                    }
                }
                else
                {
                    response = TemporaryException("Cancellation Request:BeforeImplementation");
                }

                if (!cancellationToken.IsCancellationRequested)
                {
                    if (response == null)
                    {
                        response = await Implementation(request, cancellationToken);
                    }
                }
                else
                {
                    response = TemporaryException("Cancellation Requested:Implementation");
                }
            }
            catch (NotImplementedException ex)
            {
                _logger.LogInformation(ex, $"Call path is not implemented: {request.CorrelationId}");
                response = new ServiceResponse <TResponse>(
                    default(TResponse),
                    new ResponseMetaData(this, ServiceResult.NotImplemented));
            }
            catch (BusinessLogicException ex)
            {
                response = new ServiceResponse <TResponse>(
                    default(TResponse),
                    new ResponseMetaData(this, ex.Result, publicMessage: ex.PublicMessage, exceptionMessage: ex.ToString()));
            }
            catch (ValidationErrorException ex)
            {
                response = ValidationError(ex.Error, ex.Member);
            }
            catch (Exception ex)
            {
                response = PermanentError(ex);
            }

            _logger.LogTrace($"End execute for {request.CorrelationId}");


            _logger.LogTrace($"Start response pipeline for {request.CorrelationId}");
            // ON RESPONSE PIPELINE
            for (var i = _pipeline.Count - 1; i >= 0; i--)
            {
                var middleware = _pipeline[i];

                if (_serviceHop > 0 && middleware.SkipOnInternalCall)
                {
                    continue;
                }

                try
                {
                    await middleware.OnResponse(this, request, response, cancellationToken);
                }
                catch (Exception ex)
                {
                    if (!middleware.IgnoreExceptions)
                    {
                        var errorResponse = PermanentError(ex);
                        StoredResponse = errorResponse;
                        return(errorResponse);
                    }
                }
            }
            _logger.LogTrace($"End response pipeline for {request.CorrelationId}");

            await BeforeResponse(response, cancellationToken);

            StoredResponse = response;
            return(response);
        }
Beispiel #2
0
 protected virtual Task BeforeResponse(ServiceResponse <TResponse> response, CancellationToken cancellationToken)
 {
     return(Task.CompletedTask);
 }