private RabbitMQQueue BindSubscriptionQueue(TopicName topicName, Uri publisherUri, string subscriptionQueueName, CancellationToken cancellationToken) { var publisherTopicExchange = topicName.GetTopicExchangeName(); var attempts = 0; const int maxAttempts = 10; var retryDelay = TimeSpan.FromSeconds(5); while (!cancellationToken.IsCancellationRequested) { try { using (var connection = _connectionManager.GetConnection(publisherUri)) using (var channel = connection.CreateModel()) { attempts++; channel.ExchangeDeclarePassive(publisherTopicExchange); var subscriptionQueue = new RabbitMQQueue(connection, subscriptionQueueName, this, _encoding, _defaultQueueOptions, _diagnosticService, _securityTokenService, null); subscriptionQueue.Init(); channel.QueueBind(subscriptionQueueName, publisherTopicExchange, "", null); _diagnosticService.Emit( new RabbitMQEventBuilder(this, RabbitMQEventType.RabbitMQQueueBound) { Detail = "Subscription queue bound to topic exchange", Queue = subscriptionQueueName, Exchange = publisherTopicExchange, Topic = topicName, ChannelNumber = channel.ChannelNumber }.Build()); return(subscriptionQueue); } } catch (Exception ex) { if (attempts >= maxAttempts) { throw; } _diagnosticService.Emit( new RabbitMQEventBuilder(this, RabbitMQEventType.RabbitMQQueueBindError) { Detail = "Error binding subscription queue to topic exchange (attempt " + attempts + " of " + maxAttempts + "). Retrying in " + retryDelay, Queue = subscriptionQueueName, Exchange = publisherTopicExchange, Topic = topicName, Exception = ex }.Build()); Task.Delay(retryDelay, cancellationToken).Wait(cancellationToken); } } throw new OperationCanceledException(); }
/// <inheritdoc /> /// <summary> /// Establishes a named queue /// </summary> /// <param name="queueName">The name of the queue</param> /// <param name="listener">An object that will receive messages off of the queue for processing</param> /// <param name="options">(Optional) Options that govern how the queue behaves</param> /// <param name="cancellationToken">(Optional) A cancellation token that can be used /// by the caller to cancel queue creation if necessary</param> /// <returns>Returns a task that will complete when the queue has been created</returns> /// <exception cref="T:System.ArgumentNullException">Thrown if <paramref name="queueName" /> or /// <paramref name="listener" /> is <c>null</c></exception> /// <exception cref="T:Platibus.QueueAlreadyExistsException">Thrown if a queue with the specified /// name already exists</exception> public Task CreateQueue(QueueName queueName, IQueueListener listener, QueueOptions options = null, CancellationToken cancellationToken = default(CancellationToken)) { CheckDisposed(); var connection = _connectionManager.GetConnection(_uri); var queue = new RabbitMQQueue(connection, queueName, listener, _encoding, options ?? _defaultQueueOptions, _diagnosticService, _securityTokenService, _messageEncryptionService); if (!_queues.TryAdd(queueName, queue)) { throw new QueueAlreadyExistsException(queueName); } queue.Init(); return(Task.FromResult(true)); }
public Task CreateQueue(QueueName queueName, IQueueListener listener, QueueOptions options = default(QueueOptions), CancellationToken cancellationToken = default(CancellationToken)) { CheckDisposed(); var connection = _connectionManager.GetConnection(_uri); var queue = new RabbitMQQueue(queueName, listener, connection, _encoding, options); if (!_queues.TryAdd(queueName, queue)) { throw new QueueAlreadyExistsException(queueName); } Log.DebugFormat("Initializing RabbitMQ queue \"{0}\"", queueName); queue.Init(); Log.DebugFormat("RabbitMQ queue \"{0}\" created successfully", queueName); return Task.FromResult(true); }
/// <summary> /// Initializes a new <see cref="RabbitMQTransportService"/> /// </summary> /// <param name="options">The options that govern the configuration and behavior of the /// RabbitMQ transport</param> public RabbitMQTransportService(RabbitMQTransportServiceOptions options) { if (options == null) { throw new ArgumentNullException(nameof(options)); } _baseUri = options.BaseUri; _connectionManager = options.ConnectionManager; _diagnosticService = options.DiagnosticService ?? DiagnosticService.DefaultInstance; _messageJournal = options.MessageJournal; _securityTokenService = options.SecurityTokenService ?? new JwtSecurityTokenService(); _encoding = options.Encoding ?? Encoding.GetEncoding(RabbitMQDefaults.Encoding); _defaultQueueOptions = options.DefaultQueueOptions ?? new QueueOptions(); var connection = _connectionManager.GetConnection(_baseUri); var topics = (options.Topics ?? Enumerable.Empty <TopicName>()).Where(t => t != null); using (var channel = connection.CreateModel()) { foreach (var topicName in topics) { var exchangeName = topicName.GetTopicExchangeName(); channel.ExchangeDeclare(exchangeName, "fanout", _defaultQueueOptions.IsDurable, false, new Dictionary <string, object>()); _diagnosticService.Emit( new RabbitMQEventBuilder(this, RabbitMQEventType.RabbitMQExchangeDeclared) { Detail = "Fanout exchange declared for topic", Exchange = exchangeName, Topic = topicName, ChannelNumber = channel.ChannelNumber }.Build()); } } _inboundQueue = new RabbitMQQueue(connection, InboxQueueName, this, _encoding, _defaultQueueOptions, _diagnosticService, _securityTokenService, null); _inboundQueue.Init(); }