public ConnectionFactoryWrapper(ConnectionConfiguration connectionConfiguration, IClusterHostSelectionStrategy <ConnectionFactoryInfo> clusterHostSelectionStrategy) { this.clusterHostSelectionStrategy = clusterHostSelectionStrategy; Preconditions.CheckNotNull(connectionConfiguration, "connectionConfiguration"); Preconditions.CheckAny(connectionConfiguration.Hosts, "connectionConfiguration", "At least one host must be defined in connectionConfiguration"); Configuration = connectionConfiguration; foreach (var hostConfiguration in Configuration.Hosts) { var connectionFactory = new ConnectionFactory { UseBackgroundThreadsForIO = connectionConfiguration.UseBackgroundThreads, AutomaticRecoveryEnabled = false, TopologyRecoveryEnabled = false }; if (connectionConfiguration.AMQPConnectionString != null) { connectionFactory.Uri = connectionConfiguration.AMQPConnectionString; } connectionFactory.HostName = hostConfiguration.Host; if (connectionFactory.VirtualHost == "/") { connectionFactory.VirtualHost = Configuration.VirtualHost; } if (connectionFactory.UserName == "guest") { connectionFactory.UserName = Configuration.UserName; } if (connectionFactory.Password == "guest") { connectionFactory.Password = Configuration.Password; } if (connectionFactory.Port == -1) { connectionFactory.Port = hostConfiguration.Port; } if (hostConfiguration.Ssl.Enabled) { connectionFactory.Ssl = hostConfiguration.Ssl; } //Prefer SSL configurations per each host but fall back to ConnectionConfiguration's SSL configuration for backwards compatibility else if (Configuration.Ssl.Enabled) { connectionFactory.Ssl = Configuration.Ssl; } connectionFactory.RequestedHeartbeat = TimeSpan.FromSeconds(Configuration.RequestedHeartbeat); connectionFactory.ClientProperties = Configuration.ClientProperties; connectionFactory.AuthMechanisms = Configuration.AuthMechanisms; clusterHostSelectionStrategy.Add(new ConnectionFactoryInfo(connectionFactory, hostConfiguration)); } }
/// <summary> /// Set the container creation function. This allows you to replace EasyNetQ's default internal /// IoC container. Note that all components should be registered as singletons. EasyNetQ will /// also call Dispose on components that are no longer required. /// </summary> public static void SetContainerFactory(Func <IContainer> createContainer) { Preconditions.CheckNotNull(createContainer, "createContainer"); createContainerInternal = createContainer; }
/// <summary> /// Creates a new instance of RabbitBus. /// </summary> /// <param name="connectionString"> /// The EasyNetQ connection string. Example: /// host=192.168.1.1;port=5672;virtualHost=MyVirtualHost;username=MyUsername;password=MyPassword;requestedHeartbeat=10 /// /// The following default values will be used if not specified: /// host=localhost;port=5672;virtualHost=/;username=guest;password=guest;requestedHeartbeat=0 /// </param> /// <returns> /// A new RabbitBus instance. /// </returns> public static IBus CreateBus(string connectionString) { Preconditions.CheckNotNull(connectionString, "connectionString"); return(CreateBus(connectionString, x => {})); }
public void Publish <T>(T message) where T : class { Preconditions.CheckNotNull(message, "message"); PublishAsync(message).Wait(); }
public Task PublishAsync <T>(T message) where T : class { Preconditions.CheckNotNull(message, "message"); return(PublishAsync(message, conventions.TopicNamingConvention(typeof(T)))); }
/// <summary> /// Publishes a message with a topic. /// When used with publisher confirms the task completes when the publish is confirmed. /// Task will throw an exception if the confirm is NACK'd or times out. /// </summary> /// <param name="pubSub">The pubSub instance</param> /// <param name="message">The message to publish</param> /// <param name="messageType">The message type</param> /// <param name="cancellationToken">The cancellation token</param> /// <returns></returns> public static Task PublishAsync(this IPubSub pubSub, object message, Type messageType, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(pubSub, "pubSub"); return(pubSub.PublishAsync(message, messageType, c => { }, cancellationToken)); }
public virtual void Publish <T>(T message) where T : class { Preconditions.CheckNotNull(message, "message"); Publish(message, conventions.TopicNamingConvention(typeof(T))); }
public async Task <IQueue> QueueDeclareAsync( string name, bool passive = false, bool durable = true, bool exclusive = false, bool autoDelete = false, int?perQueueMessageTtl = null, int?expires = null, int?maxPriority = null, string deadLetterExchange = null, string deadLetterRoutingKey = null, int?maxLength = null, int?maxLengthBytes = null) { Preconditions.CheckNotNull(name, "name"); if (passive) { await clientCommandDispatcher.InvokeAsync(x => x.QueueDeclarePassive(name)).ConfigureAwait(false); return(new Queue(name, exclusive)); } var arguments = new Dictionary <string, object>(); if (perQueueMessageTtl.HasValue) { arguments.Add("x-message-ttl", perQueueMessageTtl.Value); } if (expires.HasValue) { arguments.Add("x-expires", expires); } if (maxPriority.HasValue) { arguments.Add("x-max-priority", maxPriority.Value); } // Allow empty dead-letter-exchange as it represents the default rabbitmq exchange // and thus is a valid value. To dead-letter a message directly to a queue, you // would set dead-letter-exchange to empty and dead-letter-routing-key to name of the // queue since every queue has a direct binding with default exchange. if (deadLetterExchange != null) { arguments.Add("x-dead-letter-exchange", deadLetterExchange); } if (!string.IsNullOrEmpty(deadLetterRoutingKey)) { arguments.Add("x-dead-letter-routing-key", deadLetterRoutingKey); } if (maxLength.HasValue) { arguments.Add("x-max-length", maxLength.Value); } if (maxLengthBytes.HasValue) { arguments.Add("x-max-length-bytes", maxLengthBytes.Value); } await clientCommandDispatcher.InvokeAsync(x => x.QueueDeclare(name, durable, exclusive, autoDelete, arguments)).ConfigureAwait(false); logger.DebugWrite("Declared Queue: '{0}', durable:{1}, exclusive:{2}, autoDelete:{3}, args:{4}", name, durable, exclusive, autoDelete, string.Join(", ", arguments.Select(kvp => $"{kvp.Key}={kvp.Value}"))); return(new Queue(name, exclusive)); }
/// <summary> /// Publishes a message. /// </summary> /// <param name="pubSub">The pubSub instance</param> /// <param name="message">The message to publish</param> /// <param name="messageType">The message type</param> /// <param name="cancellationToken">The cancellation token</param> public static void Publish(this IPubSub pubSub, object message, Type messageType, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(pubSub, "pubSub"); pubSub.Publish(message, messageType, c => { }, cancellationToken); }
public virtual async Task PublishAsync( IExchange exchange, string routingKey, bool mandatory, MessageProperties messageProperties, byte[] body) { Preconditions.CheckNotNull(exchange, "exchange"); Preconditions.CheckShortString(routingKey, "routingKey"); Preconditions.CheckNotNull(messageProperties, "messageProperties"); Preconditions.CheckNotNull(body, "body"); // Fix me: It's very hard now to move publish logic to separate abstraction, just leave it here. var rawMessage = produceConsumeInterceptor.OnProduce(new RawMessage(messageProperties, body)); if (connectionConfiguration.PublisherConfirms) { var timeBudget = new TimeBudget(TimeSpan.FromSeconds(connectionConfiguration.Timeout)).Start(); while (!timeBudget.IsExpired()) { var confirmsWaiter = await clientCommandDispatcher.InvokeAsync(model => { var properties = model.CreateBasicProperties(); rawMessage.Properties.CopyTo(properties); var waiter = confirmationListener.GetWaiter(model); try { model.BasicPublish(exchange.Name, routingKey, mandatory, properties, rawMessage.Body); } catch (Exception) { waiter.Cancel(); throw; } return(waiter); }).ConfigureAwait(false); try { await confirmsWaiter.WaitAsync(timeBudget.GetRemainingTime()).ConfigureAwait(false); break; } catch (PublishInterruptedException) { } } } else { await clientCommandDispatcher.InvokeAsync(model => { var properties = model.CreateBasicProperties(); rawMessage.Properties.CopyTo(properties); model.BasicPublish(exchange.Name, routingKey, mandatory, properties, rawMessage.Body); }).ConfigureAwait(false); } eventBus.Publish(new PublishedMessageEvent(exchange.Name, routingKey, rawMessage.Properties, rawMessage.Body)); logger.DebugWrite("Published to exchange: '{0}', routing key: '{1}', correlationId: '{2}'", exchange.Name, routingKey, messageProperties.CorrelationId); }
public RabbitAdvancedBus( IConnectionFactory connectionFactory, IConsumerFactory consumerFactory, IEasyNetQLogger logger, IClientCommandDispatcherFactory clientCommandDispatcherFactory, IPublishConfirmationListener confirmationListener, IEventBus eventBus, IHandlerCollectionFactory handlerCollectionFactory, IContainer container, ConnectionConfiguration connectionConfiguration, IProduceConsumeInterceptor produceConsumeInterceptor, IMessageSerializationStrategy messageSerializationStrategy, IConventions conventions, AdvancedBusEventHandlers advancedBusEventHandlers, IPersistentConnectionFactory persistentConnectionFactory) { Preconditions.CheckNotNull(connectionFactory, "connectionFactory"); Preconditions.CheckNotNull(consumerFactory, "consumerFactory"); Preconditions.CheckNotNull(logger, "logger"); Preconditions.CheckNotNull(eventBus, "eventBus"); Preconditions.CheckNotNull(handlerCollectionFactory, "handlerCollectionFactory"); Preconditions.CheckNotNull(container, "container"); Preconditions.CheckNotNull(messageSerializationStrategy, "messageSerializationStrategy"); Preconditions.CheckNotNull(connectionConfiguration, "connectionConfiguration"); Preconditions.CheckNotNull(produceConsumeInterceptor, "produceConsumeInterceptor"); Preconditions.CheckNotNull(conventions, "conventions"); Preconditions.CheckNotNull(advancedBusEventHandlers, "advancedBusEventHandlers"); Preconditions.CheckNotNull(persistentConnectionFactory, "persistentConnectionFactory"); this.consumerFactory = consumerFactory; this.logger = logger; this.confirmationListener = confirmationListener; this.eventBus = eventBus; this.handlerCollectionFactory = handlerCollectionFactory; this.Container = container; this.connectionConfiguration = connectionConfiguration; this.produceConsumeInterceptor = produceConsumeInterceptor; this.messageSerializationStrategy = messageSerializationStrategy; this.Conventions = conventions; this.eventBus.Subscribe <ConnectionCreatedEvent>(e => OnConnected()); if (advancedBusEventHandlers.Connected != null) { Connected += advancedBusEventHandlers.Connected; } this.eventBus.Subscribe <ConnectionDisconnectedEvent>(e => OnDisconnected()); if (advancedBusEventHandlers.Disconnected != null) { Disconnected += advancedBusEventHandlers.Disconnected; } this.eventBus.Subscribe <ConnectionBlockedEvent>(OnBlocked); if (advancedBusEventHandlers.Blocked != null) { Blocked += advancedBusEventHandlers.Blocked; } this.eventBus.Subscribe <ConnectionUnblockedEvent>(e => OnUnblocked()); if (advancedBusEventHandlers.Unblocked != null) { Unblocked += advancedBusEventHandlers.Unblocked; } this.eventBus.Subscribe <ReturnedMessageEvent>(OnMessageReturned); if (advancedBusEventHandlers.MessageReturned != null) { MessageReturned += advancedBusEventHandlers.MessageReturned; } connection = persistentConnectionFactory.CreateConnection(); clientCommandDispatcher = clientCommandDispatcherFactory.GetClientCommandDispatcher(connection); connection.Initialize(); }
/// <summary> /// Publishes a message with a topic /// </summary> /// <typeparam name="T">The message type</typeparam> /// <param name="pubSub">The pubSub instance</param> /// <param name="message">The message to publish</param> /// <param name="topic">The topic string</param> /// <param name="cancellationToken">The cancellation token</param> public static void Publish <T>(this IPubSub pubSub, T message, string topic, CancellationToken cancellationToken = default) { Preconditions.CheckNotNull(pubSub, "pubSub"); pubSub.Publish(message, c => c.WithTopic(topic), cancellationToken); }
/// <summary> /// Creates a new instance of <see cref="RabbitBus"/>. /// </summary> /// <param name="connectionString"> /// The EasyNetQ connection string. Example: /// host=192.168.1.1;port=5672;virtualHost=MyVirtualHost;username=MyUsername;password=MyPassword;requestedHeartbeat=10 /// /// The following default values will be used if not specified: /// host=localhost;port=5672;virtualHost=/;username=guest;password=guest;requestedHeartbeat=10 /// </param> /// <returns> /// A new <see cref="RabbitBus"/> instance. /// </returns> public static IBus CreateBus(string connectionString) { Preconditions.CheckNotNull(connectionString, "connectionString"); return CreateBus(connectionString, AdvancedBusEventHandlers.Default); }
public virtual IQueue QueueDeclare( string name, bool passive = false, bool durable = true, bool exclusive = false, bool autoDelete = false, int?perQueueMessageTtl = null, int?expires = null, int?maxPriority = null, string deadLetterExchange = null, string deadLetterRoutingKey = null, int?maxLength = null, int?maxLengthBytes = null) { Preconditions.CheckNotNull(name, "name"); if (passive) { clientCommandDispatcher.Invoke(x => x.QueueDeclarePassive(name)); return(new Queue(name, exclusive)); } var arguments = new Dictionary <string, object>(); if (perQueueMessageTtl.HasValue) { arguments.Add("x-message-ttl", perQueueMessageTtl.Value); } if (expires.HasValue) { arguments.Add("x-expires", expires); } if (maxPriority.HasValue) { arguments.Add("x-max-priority", maxPriority.Value); } // Allow empty dead-letter-exchange as it represents the default rabbitmq exchange // and thus is a valid value. To dead-letter a message directly to a queue, you // would set dead-letter-exchange to empty and dead-letter-routing-key to name of the // queue since every queue has a direct binding with default exchange. if (deadLetterExchange != null) { arguments.Add("x-dead-letter-exchange", deadLetterExchange); } if (!string.IsNullOrEmpty(deadLetterRoutingKey)) { arguments.Add("x-dead-letter-routing-key", deadLetterRoutingKey); } if (maxLength.HasValue) { arguments.Add("x-max-length", maxLength.Value); } if (maxLengthBytes.HasValue) { arguments.Add("x-max-length-bytes", maxLengthBytes.Value); } var queueDeclareOk = clientCommandDispatcher.Invoke(x => x.QueueDeclare(name, durable, exclusive, autoDelete, arguments)); if (logger.IsDebugEnabled()) { logger.DebugFormat( "Declared queue {queue}: durable={durable}, exclusive={exclusive}, autoDelete={autoDelete}, arguments={arguments}", queueDeclareOk.QueueName, durable, exclusive, autoDelete, arguments.Stringify() ); } return(new Queue(queueDeclareOk.QueueName, exclusive)); }