using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Tapeti.Config; namespace Tapeti.Connection { /// /// /// Defines a queue binding to an exchange using a routing key /// public readonly struct QueueBinding : IEquatable { /// public readonly string Exchange; /// public readonly string RoutingKey; /// /// Initializes a new QueueBinding /// /// /// public QueueBinding(string exchange, string routingKey) { Exchange = exchange; RoutingKey = routingKey; } /// public bool Equals(QueueBinding other) { return string.Equals(Exchange, other.Exchange) && string.Equals(RoutingKey, other.RoutingKey); } /// public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) return false; return obj is QueueBinding other && Equals(other); } /// public override int GetHashCode() { unchecked { return ((Exchange != null ? Exchange.GetHashCode() : 0) * 397) ^ (RoutingKey != null ? RoutingKey.GetHashCode() : 0); } } } /// /// Provides a bridge between Tapeti and the actual RabbitMQ client /// public interface ITapetiClient { /// /// Publishes a message. The exchange and routing key are determined by the registered strategies. /// /// The raw message data to publish /// Metadata to include in the message /// The exchange to publish the message to, or empty to send it directly to a queue /// The routing key for the message, or queue name if exchange is empty /// If true, an exception will be raised if the message can not be delivered to at least one queue Task Publish(byte[] body, IMessageProperties properties, string exchange, string routingKey, bool mandatory); /// /// Starts a consumer for the specified queue, using the provided bindings to handle messages. /// /// Cancelled when the connection is lost /// /// The consumer implementation which will receive the messages from the queue /// The consumer tag as returned by BasicConsume. Task Consume(CancellationToken cancellationToken, string queueName, IConsumer consumer); /// /// Stops the consumer with the specified tag. /// /// The consumer tag as returned by Consume. Task Cancel(string consumerTag); /// /// Creates a durable queue if it does not already exist, and updates the bindings. /// /// Cancelled when the connection is lost /// The name of the queue to create /// A list of bindings. Any bindings already on the queue which are not in this list will be removed Task DurableQueueDeclare(CancellationToken cancellationToken, string queueName, IEnumerable bindings); /// /// Verifies a durable queue exists. Will raise an exception if it does not. /// /// Cancelled when the connection is lost /// The name of the queue to verify Task DurableQueueVerify(CancellationToken cancellationToken, string queueName); /// /// Deletes a durable queue. /// /// Cancelled when the connection is lost /// The name of the queue to delete /// If true, the queue will only be deleted if it is empty otherwise all bindings will be removed. If false, the queue is deleted even if there are queued messages. Task DurableQueueDelete(CancellationToken cancellationToken, string queueName, bool onlyIfEmpty = true); /// /// Creates a dynamic queue. /// /// Cancelled when the connection is lost /// An optional prefix for the dynamic queue's name. If not provided, RabbitMQ's default logic will be used to create an amq.gen queue. Task DynamicQueueDeclare(CancellationToken cancellationToken, string queuePrefix = null); /// /// Add a binding to a dynamic queue. /// /// Cancelled when the connection is lost /// The name of the dynamic queue previously created using DynamicQueueDeclare /// The binding to add to the dynamic queue Task DynamicQueueBind(CancellationToken cancellationToken, string queueName, QueueBinding binding); /// /// Closes the connection to RabbitMQ gracefully. /// Task Close(); } }