public static PublicationAddress ToPublicationAddress(this Uri uri, RabbitChannelGroupConfiguration config) { if (uri == ChannelEnvelope.LoopbackAddress) { return(new PublicationAddress(ExchangeType.Direct, string.Empty, config.InputQueue)); } if (uri == ChannelEnvelope.DeadLetterAddress) { return(config.DeadLetterExchange); } if (uri == ChannelEnvelope.UnhandledMessageAddress) { return(config.UnhandledMessageExchange); } if (uri == ChannelEnvelope.UnroutableMessageAddress) { return(config.UnroutableMessageExchange); } var address = PublicationAddress.Parse(uri.ToString()); return(address.ExchangeName.NormalizeName() == "default" ? new PublicationAddress(ExchangeType.Direct, string.Empty, address.RoutingKey) : address); }
public void ShouldDeserializeWithoutExchange() { //Act var addr = PublicationAddress.Parse(":///routing-key"); //Assert Assert.Null(addr); }
public void Copying() { const String appId = "app-id"; const String clusterId = "cluster-id"; const String type = "type"; const String contentEncoding = "UTF-8"; const String contentType = "application/xml"; const String correlationId = "123"; const Byte deliveryMode = 2; const String expiration = "60000"; const String messageId = "456"; const Byte priority = 3; const String userId = "me"; const String replyTo = "amqp://my.host"; var timestamp = new AmqpTimestamp(1445843868L); var properties = new BasicProperties { AppId = appId, ClusterId = clusterId, Type = type, ContentEncoding = contentEncoding, ContentType = contentType, CorrelationId = correlationId, DeliveryMode = deliveryMode, Expiration = expiration, MessageId = messageId, Priority = priority, UserId = userId, ReplyTo = replyTo, Headers = new Dictionary <String, Object> { { "h", "a" } }, Timestamp = timestamp }; var copy = properties.Copy(); Assert.Equal(appId, copy.AppId); Assert.Equal(clusterId, copy.ClusterId); Assert.Equal(type, copy.Type); Assert.Equal(contentEncoding, copy.ContentEncoding); Assert.Equal(contentType, copy.ContentType); Assert.Equal(correlationId, copy.CorrelationId); Assert.Equal(deliveryMode, copy.DeliveryMode); Assert.Equal(expiration, copy.Expiration); Assert.Equal(messageId, copy.MessageId); Assert.Equal(priority, copy.Priority); Assert.Equal(userId, copy.UserId); Assert.Equal(replyTo, copy.ReplyTo); Assert.Equal(PublicationAddress.Parse(replyTo), copy.ReplyToAddress); Assert.Equal(1, copy.Headers.Count); Assert.True(copy.Headers.ContainsKey("h")); Assert.Equal("a", copy.Headers["h"]); Assert.Equal(timestamp, copy.Timestamp); }
public void TestParseOk() { string uriLike = "fanout://name/key"; PublicationAddress addr = PublicationAddress.Parse(uriLike); Assert.AreEqual(ExchangeType.Fanout, addr.ExchangeType); Assert.AreEqual("name", addr.ExchangeName); Assert.AreEqual("key", addr.RoutingKey); Assert.AreEqual(uriLike, addr.ToString()); }
public void TestEmptyRoutingKey() { string uriLike = "direct://exch/"; PublicationAddress addr = PublicationAddress.Parse(uriLike); Assert.AreEqual(ExchangeType.Direct, addr.ExchangeType); Assert.AreEqual("exch", addr.ExchangeName); Assert.AreEqual("", addr.RoutingKey); Assert.AreEqual(uriLike, addr.ToString()); }
public void ShouldDeserializeWithExchange() { //Act var addr = PublicationAddress.Parse("exchange-type://exchange-name/routing-key"); //Assert Assert.Equal("exchange-type", addr.ExchangeType); Assert.Equal("exchange-name", addr.ExchangeName); Assert.Equal("routing-key", addr.RoutingKey); }
public void Reply <TReplyMessage>(TReplyMessage responseMessage) { if (_basicProperties.ReplyTo != null) { PublicationAddress publicationAddress = PublicationAddress.Parse(_basicProperties.ReplyTo); var replyProperties = new BasicProperties(); replyProperties.CorrelationId = _basicProperties.CorrelationId; _messagePublisher.PublishReply <TMessage, TReplyMessage>(publicationAddress, responseMessage, replyProperties); } }
public void ShouldDeserializeWithoutExchangeName() { //Act var addr = PublicationAddress.Parse("default:///routing-key"); //Assert Assert.Equal("default", addr.ExchangeType); Assert.Equal("", addr.ExchangeName); Assert.Equal("routing-key", addr.RoutingKey); }
public bool VerifyDestination(Destination destination, EndpointUsage usage, bool configureIfRequired, out string error) { try { var publish = PublicationAddress.Parse(destination.Publish) ?? new PublicationAddress("topic", destination.Publish, "");; using (IConnection connection = m_Factory.CreateConnection()) { using (IModel channel = connection.CreateModel()) { if ((usage & EndpointUsage.Publish) == EndpointUsage.Publish) { if (configureIfRequired) { channel.ExchangeDeclare(publish.ExchangeName, publish.ExchangeType, true); } else { channel.ExchangeDeclarePassive(publish.ExchangeName); } } if ((usage & EndpointUsage.Subscribe) == EndpointUsage.Subscribe) { if (configureIfRequired) { channel.QueueDeclare(destination.Subscribe, true, false, false, null); } else { channel.QueueDeclarePassive(destination.Subscribe); } if (configureIfRequired) { channel.QueueBind(destination.Subscribe, publish.ExchangeName, publish.RoutingKey == "" ? "#" : publish.RoutingKey); } } } } } catch (Exception e) { if (!e.GetType().Namespace.StartsWith("RabbitMQ") || e.GetType().Assembly != typeof(OperationInterruptedException).Assembly) { throw; } error = e.Message; return(false); } error = null; return(true); }
public Task <Message <U> > SendCommand <T, U>(string commandQueueName, Message <T> command) where U : new() { var n = PublicationAddress.Parse(commandQueueName); lock (_channel) { _channel.ExchangeDeclare(exchange: n.ExchangeName, n.ExchangeType, false, true, null); var replyQueueName = _channel.QueueDeclare().QueueName; _channel.QueueDeclare(n.ExchangeName, durable: false, exclusive: false, autoDelete: true, arguments: null); TaskCompletionSource <Message <U> > result = new TaskCompletionSource <Message <U> >(); var corrId = Guid.NewGuid().ToString(); var consumer = new EventingBasicConsumer(_channel); consumer.Received += (s, e) => { if (e.BasicProperties.CorrelationId == corrId) { try { _channel.BasicCancel(_consumerTag); var ser = _payloadSerializer.GetSerializer(e.BasicProperties.ContentType); var answer = new Message <U>(ser.Deserialize <U>(e.Body)); result.SetResult(answer); } catch (Exception exception) { result.SetException(exception); } } }; _consumerTag = _channel.BasicConsume(queue: replyQueueName, autoAck: true, consumer: consumer); var props = _channel.CreateBasicProperties(); props.ContentType = Serializer.ContentType; props.ReplyTo = replyQueueName; props.CorrelationId = corrId; props.Persistent = command.Persistent; _channel.BasicPublish(exchange: "", n.ExchangeName, basicProperties: props, body: Serializer.Serialize(command.Payload)); return(result.Task); } }
public void TestExchangeTypeValidation() { string uriLike = "direct:///"; PublicationAddress addr = PublicationAddress.Parse(uriLike); int found = 0; foreach (string exchangeType in ExchangeType.All()) { if (exchangeType.Equals(addr.ExchangeType)) { found++; } } Assert.AreEqual(1, found); }
public void Start <T, U>(string queueName, Func <Message <T>, Message <U> > commandReceived) where T : new() { var n = PublicationAddress.Parse(queueName); _channel.QueueDeclare(n.ExchangeName, durable: false, exclusive: false, autoDelete: true, arguments: null); _channel.BasicQos(0, 1, false); var consumer = new EventingBasicConsumer(_channel); consumer.Received += (s, e) => { try { try { var ser = _payloadSerializer.GetSerializer(e.BasicProperties.ContentType); var command = new Message <T>(ser.Deserialize <T>(e.Body)) { Persistent = e.BasicProperties.Persistent, CorrelationId = e.BasicProperties.CorrelationId, ReplyTo = e.BasicProperties.ReplyTo }; var response = commandReceived(command); var replyProps = _channel.CreateBasicProperties(); replyProps.ContentType = Serializer.ContentType; replyProps.CorrelationId = e.BasicProperties.CorrelationId; replyProps.Persistent = response.Persistent; _channel.BasicPublish(exchange: "", routingKey: e.BasicProperties.ReplyTo, basicProperties: replyProps, body: Serializer.Serialize(response.Payload)); _channel.BasicAck(deliveryTag: e.DeliveryTag, multiple: false); } catch (Exception) { _channel.BasicNack(e.DeliveryTag, false, false); } } catch (Exception) { _channel.BasicNack(e.DeliveryTag, false, true); } }; _consumerToken = _channel.BasicConsume(queue: n.ExchangeName, autoAck: false, consumer: consumer); }
public IDisposable RegisterHandler(string destination, Func <BinaryMessage, BinaryMessage> handler, string messageType) { var subscription = subscribe(destination, (properties, bytes, acknowledge) => { var correlationId = properties.CorrelationId; var responseBytes = handler(toBinaryMessage(properties, bytes)); //If replyTo is not parsable we treat it as queue name and message is sent via default exchange (http://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-default) var publicationAddress = PublicationAddress.Parse(properties.ReplyTo) ?? new PublicationAddress("direct", "", properties.ReplyTo); send(publicationAddress, responseBytes, p => { if (correlationId != null) { p.CorrelationId = correlationId; } }); acknowledge(true); }, messageType); return(subscription); }
///<summary>Process a single request received from our ///subscription.</summary> ///<remarks> ///<para> /// If the request's properties contain a non-null, non-empty /// CorrelationId string (see IBasicProperties), it is assumed /// to be a two-way call, requiring a response. The ReplyTo /// header property is used as the reply address (via /// PublicationAddress.Parse, unless that fails, in which case it /// is treated as a simple queue name), and the request is /// passed to HandleCall(). ///</para> ///<para> /// If the CorrelationId is absent or empty, the request is /// treated as one-way asynchronous event, and is passed to /// HandleCast(). ///</para> ///<para> /// Usually, overriding HandleCall(), HandleCast(), or one of /// their delegates is sufficient to implement a service, but /// in some cases overriding ProcessRequest() is /// required. Overriding ProcessRequest() gives the /// opportunity to implement schemes for detecting interaction /// patterns other than simple request/response or one-way /// communication. ///</para> ///</remarks> public virtual void ProcessRequest(BasicDeliverEventArgs evt) { IBasicProperties properties = evt.BasicProperties; if (properties.ReplyTo != null && properties.ReplyTo != "") { // It's a request. PublicationAddress replyAddress = PublicationAddress.Parse(properties.ReplyTo); if (replyAddress == null) { replyAddress = new PublicationAddress(ExchangeType.Direct, "", properties.ReplyTo); } IBasicProperties replyProperties; byte[] reply = HandleCall(evt.Redelivered, properties, evt.Body, out replyProperties); if (replyProperties == null) { replyProperties = m_subscription.Model.CreateBasicProperties(); } replyProperties.CorrelationId = properties.CorrelationId; m_subscription.Model.BasicPublish(replyAddress, replyProperties, reply); } else { // It's an asynchronous message. HandleCast(evt.Redelivered, properties, evt.Body); } }
public void TestMissingExchangeType() { Assert.IsNull(PublicationAddress.Parse("://exch/key")); }
public bool VerifyDestination( Destination destination, EndpointUsage usage, bool configureIfRequired, out string error) { try { var publish = PublicationAddress.Parse(destination.Publish) ?? new PublicationAddress("topic", destination.Publish, "");; using (IConnection connection = CreateConnection(false)) { using (IModel channel = connection.CreateModel()) { if (publish.ExchangeName == "" && publish.ExchangeType.ToLower() == "direct") { //default exchange should not be verified since it always exists and publication to it is always possible } else { if (configureIfRequired) { channel.ExchangeDeclare(publish.ExchangeName, publish.ExchangeType, true); } else { channel.ExchangeDeclarePassive(publish.ExchangeName); } } //temporary queue should not be verified since it is not supported by rmq client if ((usage & EndpointUsage.Subscribe) == EndpointUsage.Subscribe && !destination.Subscribe.ToLower().StartsWith("amq.")) { if (configureIfRequired) { channel.QueueDeclare(destination.Subscribe, true, false, false, null); } else { channel.QueueDeclarePassive(destination.Subscribe); } if (configureIfRequired) { channel.QueueBind(destination.Subscribe, publish.ExchangeName, publish.RoutingKey == "" ? "#" : publish.RoutingKey); } } } } } catch (Exception e) { if (!e.GetType().Namespace.StartsWith("RabbitMQ") || e.GetType().Assembly != typeof(OperationInterruptedException).Assembly) { throw; } error = e.Message; return(false); } error = null; return(true); }
private void send(string destination, BinaryMessage message, Action <IBasicProperties> tuneMessage = null) { var publicationAddress = PublicationAddress.Parse(destination) ?? new PublicationAddress("direct", destination, ""); send(publicationAddress, message, tuneMessage); }
public void Start <T>(string address, string queueName, Action <Message <T> > messageReceived) where T : new() { var n = PublicationAddress.Parse(address); Start(n.ExchangeType, n.ExchangeName, n.RoutingKey, queueName, messageReceived); }
public void TestParseFailWithUnparseableInput() { Assert.IsNull(PublicationAddress.Parse("not a valid URI")); }
public void TestParseFailWithANE() { Assert.That(() => PublicationAddress.Parse(null), Throws.ArgumentNullException); }
public void Send <T>(string queueName, Message <T> message) { var n = PublicationAddress.Parse(queueName); Send(n.ExchangeType, n.ExchangeName, n.RoutingKey, PayloadSerializerFactory.DefaultContentType, message); }
public void TestParseFail() { Assert.IsNull(PublicationAddress.Parse("not a valid uri")); }