public Task PublishAsync <T>(T message) where T : class { Preconditions.CheckNotNull(message, "message"); return(PublishAsync(message, conventions.TopicNamingConvention(typeof(T)))); }
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)); } }
public virtual IAdvancedPublishChannel OpenPublishChannel(Action <IChannelConfiguration> configure) { Preconditions.CheckNotNull(configure, "configure"); return(new RabbitAdvancedPublishChannel(this, configure)); }
public void Publish <T>(T message) where T : class { Preconditions.CheckNotNull(message, "message"); PublishAsync(message).Wait(); }
/// <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> /// <param name="registerServices"> /// Override default services. For example, to override the default <see cref="ISerializer"/>: /// RabbitHutch.CreateBus("host=localhost", x => x.Register{ISerializer}(mySerializer)); /// </param> /// <returns> /// A new <see cref="RabbitBus"/> instance. /// </returns> public static IBus CreateBus(string connectionString, Action <IServiceRegister> registerServices) { Preconditions.CheckNotNull(connectionString, "connectionString"); return(CreateBus(x => x.Resolve <IConnectionStringParser>().Parse(connectionString), registerServices)); }
/// <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=10 /// </param> /// <returns> /// A new RabbitBus instance. /// </returns> public static IBus CreateBus(string connectionString) { Preconditions.CheckNotNull(connectionString, "connectionString"); return(CreateBus(connectionString, x => {})); }
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 void CopyTo(IBasicProperties basicProperties) { Preconditions.CheckNotNull(basicProperties, "basicProperties"); if (contentTypePresent) { basicProperties.ContentType = ContentType; } if (contentEncodingPresent) { basicProperties.ContentEncoding = ContentEncoding; } if (deliveryModePresent) { basicProperties.DeliveryMode = DeliveryMode; } if (priorityPresent) { basicProperties.Priority = Priority; } if (correlationIdPresent) { basicProperties.CorrelationId = CorrelationId; } if (replyToPresent) { basicProperties.ReplyTo = ReplyTo; } if (expirationPresent) { basicProperties.Expiration = Expiration; } if (messageIdPresent) { basicProperties.MessageId = MessageId; } if (timestampPresent) { basicProperties.Timestamp = new AmqpTimestamp(Timestamp); } if (typePresent) { basicProperties.Type = Type; } if (userIdPresent) { basicProperties.UserId = UserId; } if (appIdPresent) { basicProperties.AppId = AppId; } if (clusterIdPresent) { basicProperties.ClusterId = ClusterId; } if (headersPresent) { basicProperties.Headers = new Dictionary <string, object>(Headers); } }
/// <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); }
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(); }
public virtual void Consume(IQueue queue, Func <Byte[], MessageProperties, MessageReceivedInfo, Task> onMessage) { Preconditions.CheckNotNull(queue, "queue"); Preconditions.CheckNotNull(onMessage, "onMessage"); if (disposed) { throw new EasyNetQException("This bus has been disposed"); } var newConsumerTag = conventions.ConsumerTagConvention(); var subscriptionAction = new SubscriptionAction(newConsumerTag, logger, queue.IsSingleUse, queue.IsExclusive); subscriptionAction.Action = (isNewConnection) => { // recreate channel if current channel is no longer open or connection was dropped and reconnected (to survive server restart) if (subscriptionAction.Channel == null || subscriptionAction.Channel.IsOpen == false || isNewConnection) { subscriptionAction.Channel = CreateChannel(queue); } var channel = subscriptionAction.Channel; channel.BasicQos(0, connectionConfiguration.PrefetchCount, false); var consumer = consumerFactory.CreateConsumer(subscriptionAction, channel, queue.IsSingleUse, (consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body) => { var messageRecievedInfo = new MessageReceivedInfo { ConsumerTag = consumerTag, DeliverTag = deliveryTag, Redelivered = redelivered, Exchange = exchange, RoutingKey = routingKey }; var messsageProperties = new MessageProperties(properties); return(onMessage(body, messsageProperties, messageRecievedInfo)); }); var cancelNotifications = consumer as IConsumerCancelNotifications; if (cancelNotifications != null) { cancelNotifications.BasicCancel += OnBasicCancel; } channel.BasicConsume( queue.Name, // queue NoAck, // noAck consumer.ConsumerTag, // consumerTag consumer); // consumer logger.DebugWrite("Declared Consumer. queue='{0}', consumer tag='{1}' prefetchcount={2}", queue.Name, consumer.ConsumerTag, connectionConfiguration.PrefetchCount); }; AddSubscriptionAction(subscriptionAction); }
public void Add(T item) { Preconditions.CheckNotNull(item, "item"); items.Add(item); items.Shuffle(); }
/// <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 TimeoutStrategy(ConnectionConfiguration connectionConfiguration) { Preconditions.CheckNotNull(connectionConfiguration, "connectionConfiguration"); this.connectionConfiguration = connectionConfiguration; }
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)); }
public void CopyFrom(IBasicProperties basicProperties) { Preconditions.CheckNotNull(basicProperties, "basicProperties"); if (basicProperties.IsContentTypePresent()) { ContentType = basicProperties.ContentType; } if (basicProperties.IsContentEncodingPresent()) { ContentEncoding = basicProperties.ContentEncoding; } if (basicProperties.IsDeliveryModePresent()) { DeliveryMode = basicProperties.DeliveryMode; } if (basicProperties.IsPriorityPresent()) { Priority = basicProperties.Priority; } if (basicProperties.IsCorrelationIdPresent()) { CorrelationId = basicProperties.CorrelationId; } if (basicProperties.IsReplyToPresent()) { ReplyTo = basicProperties.ReplyTo; } if (basicProperties.IsExpirationPresent()) { Expiration = basicProperties.Expiration; } if (basicProperties.IsMessageIdPresent()) { MessageId = basicProperties.MessageId; } if (basicProperties.IsTimestampPresent()) { Timestamp = basicProperties.Timestamp.UnixTime; } if (basicProperties.IsTypePresent()) { Type = basicProperties.Type; } if (basicProperties.IsUserIdPresent()) { UserId = basicProperties.UserId; } if (basicProperties.IsAppIdPresent()) { AppId = basicProperties.AppId; } if (basicProperties.IsClusterIdPresent()) { ClusterId = basicProperties.ClusterId; } if (basicProperties.IsHeadersPresent()) { foreach (var header in basicProperties.Headers) { Headers.Add(header.Key, header.Value); } } }
/// <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); }
/// <summary> /// Creates a new instance of <see cref="RabbitBus"/>. /// </summary> /// <param name="connectionConfiguration"> /// An <see cref="ConnectionConfiguration"/> instance. /// </param> /// <param name="registerServices"> /// Override default services. For example, to override the default <see cref="ISerializer"/>: /// RabbitHutch.CreateBus("host=localhost", x => x.Register{ISerializer}(mySerializer)); /// </param> /// <returns> /// A new <see cref="RabbitBus"/> instance. /// </returns> public static IBus CreateBus(ConnectionConfiguration connectionConfiguration, Action <IServiceRegister> registerServices) { Preconditions.CheckNotNull(connectionConfiguration, "connectionConfiguration"); return(CreateBus(_ => connectionConfiguration, registerServices)); }
/// <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)); }
/// <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; }
public virtual void Publish <T>(T message) where T : class { Preconditions.CheckNotNull(message, "message"); Publish(message, conventions.TopicNamingConvention(typeof(T))); }
public static string Serialize(Type type) { Preconditions.CheckNotNull(type, "type"); return(type.FullName.Replace('.', '_') + ":" + type.Assembly.GetName().Name.Replace('.', '_')); }
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)); }