109 lines
3.5 KiB
C#
109 lines
3.5 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Reflection;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using RabbitMQ.Client;
|
|
using Tapeti.Annotations;
|
|
using Tapeti.Config;
|
|
using Tapeti.Default;
|
|
using Tapeti.Exceptions;
|
|
using Tapeti.Helpers;
|
|
|
|
namespace Tapeti.Connection
|
|
{
|
|
/// <inheritdoc />
|
|
public class TapetiPublisher : IInternalPublisher
|
|
{
|
|
private readonly ITapetiConfig config;
|
|
private readonly Func<ITapetiClient> clientFactory;
|
|
private readonly IExchangeStrategy exchangeStrategy;
|
|
private readonly IRoutingKeyStrategy routingKeyStrategy;
|
|
private readonly IMessageSerializer messageSerializer;
|
|
|
|
|
|
/// <inheritdoc />
|
|
public TapetiPublisher(ITapetiConfig config, Func<ITapetiClient> clientFactory)
|
|
{
|
|
this.config = config;
|
|
this.clientFactory = clientFactory;
|
|
|
|
exchangeStrategy = config.DependencyResolver.Resolve<IExchangeStrategy>();
|
|
routingKeyStrategy = config.DependencyResolver.Resolve<IRoutingKeyStrategy>();
|
|
messageSerializer = config.DependencyResolver.Resolve<IMessageSerializer>();
|
|
}
|
|
|
|
|
|
/// <inheritdoc />
|
|
public async Task Publish(object message)
|
|
{
|
|
await Publish(message, null, IsMandatory(message));
|
|
}
|
|
|
|
|
|
/// <inheritdoc />
|
|
public async Task Publish(object message, IMessageProperties properties, bool mandatory)
|
|
{
|
|
var messageClass = message.GetType();
|
|
var exchange = exchangeStrategy.GetExchange(messageClass);
|
|
var routingKey = routingKeyStrategy.GetRoutingKey(messageClass);
|
|
|
|
await Publish(message, properties, exchange, routingKey, mandatory);
|
|
}
|
|
|
|
|
|
/// <inheritdoc />
|
|
public async Task PublishDirect(object message, string queueName, IMessageProperties properties, bool mandatory)
|
|
{
|
|
await Publish(message, properties, null, queueName, mandatory);
|
|
}
|
|
|
|
|
|
private async Task Publish(object message, IMessageProperties properties, string exchange, string routingKey, bool mandatory)
|
|
{
|
|
var writableProperties = new MessageProperties(properties);
|
|
|
|
if (!writableProperties.Timestamp.HasValue)
|
|
writableProperties.Timestamp = DateTime.UtcNow;
|
|
|
|
writableProperties.Persistent = true;
|
|
|
|
|
|
var context = new PublishContext
|
|
{
|
|
Config = config,
|
|
Exchange = exchange,
|
|
RoutingKey = routingKey,
|
|
Message = message,
|
|
Properties = writableProperties
|
|
};
|
|
|
|
|
|
await MiddlewareHelper.GoAsync(
|
|
config.Middleware.Publish,
|
|
async (handler, next) => await handler.Handle(context, next),
|
|
async () =>
|
|
{
|
|
var body = messageSerializer.Serialize(message, writableProperties);
|
|
await clientFactory().Publish(body, writableProperties, exchange, routingKey, mandatory);
|
|
});
|
|
}
|
|
|
|
|
|
private static bool IsMandatory(object message)
|
|
{
|
|
return message.GetType().GetCustomAttribute<MandatoryAttribute>() != null;
|
|
}
|
|
|
|
|
|
private class PublishContext : IPublishContext
|
|
{
|
|
public ITapetiConfig Config { get; set; }
|
|
public string Exchange { get; set; }
|
|
public string RoutingKey { get; set; }
|
|
public object Message { get; set; }
|
|
public IMessageProperties Properties { get; set; }
|
|
}
|
|
}
|
|
}
|