async Task ISendTransport.Send <T>(T message, IPipe <SendContext <T> > pipe, CancellationToken cancelSend)
        {
            IPipe <ModelContext> modelPipe = Pipe.New <ModelContext>(p =>
            {
                p.UseFilter(_filter);

                p.UseExecuteAsync(async modelContext =>
                {
                    IBasicProperties properties = modelContext.Model.CreateBasicProperties();

                    var context = new RabbitMqSendContextImpl <T>(properties, message, _sendSettings, cancelSend);

                    try
                    {
                        await pipe.Send(context).ConfigureAwait(false);

                        properties.ContentType = context.ContentType.MediaType;

                        properties.Headers = (properties.Headers ?? Enumerable.Empty <KeyValuePair <string, object> >())
                                             .Concat(context.Headers.GetAll())
                                             .Where(x => x.Value != null && (x.Value is string || x.Value.GetType().IsValueType))
                                             .Distinct()
                                             .ToDictionary(entry => entry.Key, entry => entry.Value);
                        properties.Headers["Content-Type"] = context.ContentType.MediaType;

                        properties.Persistent = context.Durable;

                        if (context.MessageId.HasValue)
                        {
                            properties.MessageId = context.MessageId.ToString();
                        }

                        if (context.CorrelationId.HasValue)
                        {
                            properties.CorrelationId = context.CorrelationId.ToString();
                        }

                        if (context.TimeToLive.HasValue)
                        {
                            properties.Expiration = context.TimeToLive.Value.TotalMilliseconds.ToString("F0", CultureInfo.InvariantCulture);
                        }

                        await _observers.PreSend(context).ConfigureAwait(false);

                        await modelContext.BasicPublishAsync(context.Exchange, context.RoutingKey, context.Mandatory,
                                                             context.BasicProperties, context.Body).ConfigureAwait(false);

                        context.DestinationAddress.LogSent(context.MessageId?.ToString("N") ?? "", TypeMetadataCache <T> .ShortName);

                        await _observers.PostSend(context).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        await _observers.SendFault(context, ex).ConfigureAwait(false);

                        if (_log.IsErrorEnabled)
                        {
                            _log.Error("Send Fault: " + context.DestinationAddress, ex);
                        }

                        throw;
                    }
                });
            });

            await _modelCache.Send(modelPipe, cancelSend).ConfigureAwait(false);
        }
Exemple #2
0
        async Task ISendTransport.Send <T>(T message, IPipe <SendContext <T> > pipe, CancellationToken cancelSend)
        {
            IPipe <ModelContext> modelPipe = Pipe.New <ModelContext>(p =>
            {
                p.UseFilter(_filter);

                p.UseExecuteAsync(async modelContext =>
                {
                    var properties = modelContext.Model.CreateBasicProperties();

                    var context = new RabbitMqSendContextImpl <T>(properties, message, _sendSettings, cancelSend);

                    try
                    {
                        await pipe.Send(context).ConfigureAwait(false);

                        PublishContext publishContext;
                        if (context.TryGetPayload(out publishContext))
                        {
                            context.Mandatory = context.Mandatory || publishContext.Mandatory;
                        }

                        properties.ContentType = context.ContentType.MediaType;

                        KeyValuePair <string, object>[] headers = context.Headers.GetAll()
                                                                  .Where(x => x.Value != null && (x.Value is string || x.Value.GetType().IsValueType))
                                                                  .ToArray();

                        if (properties.Headers == null)
                        {
                            properties.Headers = new Dictionary <string, object>(headers.Length);
                        }

                        foreach (KeyValuePair <string, object> header in headers)
                        {
                            if (properties.Headers.ContainsKey(header.Key))
                            {
                                continue;
                            }

                            properties.SetHeader(header.Key, header.Value);
                        }

                        properties.Headers["Content-Type"] = context.ContentType.MediaType;

                        properties.Persistent = context.Durable;

                        if (context.MessageId.HasValue)
                        {
                            properties.MessageId = context.MessageId.ToString();
                        }

                        if (context.CorrelationId.HasValue)
                        {
                            properties.CorrelationId = context.CorrelationId.ToString();
                        }

                        if (context.TimeToLive.HasValue)
                        {
                            properties.Expiration = context.TimeToLive.Value.TotalMilliseconds.ToString("F0", CultureInfo.InvariantCulture);
                        }

                        await _observers.PreSend(context).ConfigureAwait(false);

                        await modelContext.BasicPublishAsync(context.Exchange, context.RoutingKey, context.Mandatory,
                                                             context.BasicProperties, context.Body, context.AwaitAck).ConfigureAwait(false);

                        context.LogSent();

                        await _observers.PostSend(context).ConfigureAwait(false);
                    }
                    catch (Exception ex)
                    {
                        await _observers.SendFault(context, ex).ConfigureAwait(false);

                        if (_log.IsErrorEnabled)
                        {
                            _log.Error("Send Fault: " + context.DestinationAddress, ex);
                        }

                        throw;
                    }
                });
            });

            await _modelCache.Send(modelPipe, cancelSend).ConfigureAwait(false);
        }