Exemple #1
0
        /// <inheritdoc />
        public async Task Start(RequestDelegate requestDelegate, CancellationToken cancellationToken)
        {
            await _communication.Init();

            _communication.CreateBasicConsumer(async(_, args) =>
            {
                try
                {
                    _log.LogTrace($"Incoming request");

                    if (cancellationToken.IsCancellationRequested)
                    {
                        _log.LogTrace("Cancellation token call. {queueName}", args.RoutingKey);
                        _communication.Dispose();
                        return;
                    }

                    _log.LogTrace("Parsing request");
                    var features = new FeatureCollection();
                    features.Set(new ItemsFeature());
                    var context = await _converter.Parse(args, features);

                    if (context != null)
                    {
                        await requestDelegate(context);
                        await _responseProcessed.Handle(args, context);
                    }
                    else
                    {
                        await _communication.Ack(args);
                        await _communication.SendError(new BasicDeliverEventArgs
                        {
                            BasicProperties = args.BasicProperties,
                            Exchange        = args.Exchange,
                            Body            = args.Body
                        });
                    }
                }
                catch (Exception e)
                {
                    _log.LogError(e, "Error processing message");
                    args.BasicProperties.Headers.TryAddToLowerCase("exception", e.ToString());
                    await _communication.SendException(args);
                }
            });
        }
        public async Task Handle(BasicDeliverEventArgs requestArgs, HttpContext context)
        {
            var request  = context.Request;
            var response = context.Response;

            var requestProps = requestArgs.BasicProperties;

            _log.LogInformation("{route} response status {status}", requestArgs.RoutingKey, response.StatusCode);

            if (response.StatusCode >= 500)
            {
                _log.LogInformation("Response Status {status}. Retry", response.StatusCode);

                var config = response.Headers.ParseRepeat() ?? request.Headers.ParseRepeat();

                if (config != null)
                {
                    if (await _communication.Retry(requestArgs, config))
                    {
                        return;
                    }
                }
            }

            var basicProperties = _communication.CreateBasicProperties()
                                  .CreateBasicPropertiesResponse(requestArgs.BasicProperties, context.Request, response);

            if (requestProps.ReplyTo == null)
            {
                if (response.StatusCode >= 400)
                {
                    var bodyTask = new StreamReader(response.Body).ReadToEndAsync();

                    var errorArgs = new BasicDeliverEventArgs
                    {
                        Body            = requestArgs.Body,
                        BasicProperties = basicProperties
                    };
                    errorArgs.BasicProperties.Expiration = _errorExpiration.ToString();
                    errorArgs.BasicProperties.Headers.Add("responseUid", context.TraceIdentifier);
                    _log.LogTrace("Response {uid}:{response}", context.TraceIdentifier, await bodyTask);
                    await _communication.SendError(errorArgs);
                }

                await _communication.Ack(requestArgs);

                return;
            }

            var address = requestProps.ReplyToAddress;

            var args = new BasicDeliverEventArgs
            {
                RoutingKey      = address.RoutingKey,
                Body            = await response.Body.ReadAllBytesAsync(),
                BasicProperties = basicProperties,
                Exchange        = address.ExchangeName
            };

            _log.LogTrace("Response. exchange: {exchange} route: {queue}", address.ExchangeName, args.RoutingKey);

            try
            {
                await _communication.Send(args)
                .ContinueWith(task =>
                {
                    if (task.Exception != null)
                    {
                        _log.LogError(task.Exception, $"Error send message exchange: {address.ExchangeName}, routing {args.RoutingKey}");

                        _communication.SendError(args);
                    }
                    else
                    {
                        _communication.Ack(requestArgs);
                    }
                });
            }
            catch (Exception e)
            {
                _log.LogError(e, "Error send response message");
            }
            _log.LogTrace("Response. exchange: {exchange} route: {queue} sended", address.ExchangeName, args.RoutingKey);
        }