private void OldSendMessages(RabbitTemplate template) { IBasicProperties basicProperties = template.Execute<IBasicProperties>(delegate(IModel model) { return model.CreateBasicProperties(); }); /* * System.ArgumentNullException: String reference not set to an instance of a String. Parameter name: s at System.Text.Encoding.GetBytes(String s) at RabbitMQ.Client.Impl.WireFormatting.WriteShortstr(NetworkBinaryWriter writer, String val) */ IMessageProperties messageProperties = new MessageProperties(basicProperties); //write all short props messageProperties.ContentType = "text/plain"; messageProperties.ContentEncoding = "UTF-8"; messageProperties.CorrelationId = Encoding.UTF8.GetBytes("corr1"); messageProperties.DeliveryMode = MessageDeliveryMode.PERSISTENT; messageProperties.Priority = 0; byte[] byteMessage = Encoding.UTF8.GetBytes("testing"); template.Send("amq.direct", "foo", delegate { Message msg = new Message(byteMessage, messageProperties); Console.WriteLine("sending..."); return msg; }); //template.Send("amq.direct", "foo", channel => new Message(Encoding.UTF8.GetBytes("testing"), messageProperties)); }
public object FromMessage(Message message) { object content = null; IMessageProperties properties = message.MessageProperties; if (properties != null) { string contentType = properties.ContentType; if (contentType != null && contentType.StartsWith("text")) { string encoding = properties.ContentEncoding; if (encoding == null) { encoding = this.defaultCharset; } try { content = ConvertToString(message.Body, encoding); } catch (Exception e) { throw new MessageConversionException("Failed to convert text-based Message content", e); } } } if (content == null) { content = message.Body; } return content; }
public void ToStringForSerializableMessageBody() { var messageProperties = new MessageProperties(); messageProperties.ContentType = MessageProperties.CONTENT_TYPE_SERIALIZED_OBJECT; var message = new Message(SerializationUtils.SerializeObject(DateTime.Now), messageProperties); Assert.NotNull(message.ToString()); }
/// <summary> /// Convert from a Message to an object. /// </summary> /// <param name="message"> /// The message. /// </param> /// <returns> /// The object. /// </returns> /// <exception cref="MessageConversionException"> /// </exception> public override object FromMessage(Message message) { object content = null; var properties = message.MessageProperties; if (properties != null) { var contentType = properties.ContentType; if (!string.IsNullOrEmpty(contentType) && contentType.Contains("json")) { var encoding = properties.ContentEncoding ?? this.defaultCharset; try { var targetType = this.typeMapper.ToType(message.MessageProperties); content = SerializationUtils.DeserializeJsonAsObject(message.Body, encoding, targetType); } catch (Exception e) { throw new MessageConversionException("Failed to convert json-based Message content", e); } } } return content ?? (content = message.Body); }
public void ToStringForNonSerializableMessageBody() { var messageProperties = new MessageProperties(); messageProperties.ContentType = MessageProperties.CONTENT_TYPE_SERIALIZED_OBJECT; var message = new Message(Encoding.UTF8.GetBytes("foo"), messageProperties); // System.err.println(message); Assert.NotNull(message.ToString()); }
public void BytesAsDefaultMessageBodyType() { var converter = new SimpleMessageConverter(); var message = new Message("test".ToByteArrayWithEncoding("UTF-8"), new MessageProperties()); var result = converter.FromMessage(message); Assert.AreEqual(typeof(byte[]), result.GetType()); Assert.AreEqual("test", ((byte[])result).ToStringWithEncoding("UTF-8")); }
public void MessageToString() { var converter = new SimpleMessageConverter(); var message = new Message("test".ToByteArrayWithEncoding("UTF-8"), new MessageProperties()); message.MessageProperties.ContentType = MessageProperties.CONTENT_TYPE_TEXT_PLAIN; var result = converter.FromMessage(message); Assert.AreEqual(typeof(string), result.GetType()); Assert.AreEqual("test", result); }
public void BytesAsDefaultMessageBodyType() { SimpleMessageConverter converter = new SimpleMessageConverter(); //template.CreateMessageProperties contains the default of using application/octet-stream as content-type Message message = new Message(Encoding.UTF8.GetBytes("test"), template.CreateMessageProperties()); object result = converter.FromMessage(message); Assert.AreEqual(typeof (byte[]), result.GetType()); Assert.AreEqual("test", ConvertToString((byte[]) result, SimpleMessageConverter.DEFAULT_CHARSET)); }
/// <summary>Sends the messages.</summary> /// <param name="template">The template.</param> /// <param name="exchange">The exchange.</param> /// <param name="routingKey">The routing key.</param> /// <param name="numMessages">The num messages.</param> private static void SendMessages(RabbitTemplate template, string exchange, string routingKey, int numMessages) { for (int i = 1; i <= numMessages; i++) { byte[] bytes = Encoding.UTF8.GetBytes("testing"); var properties = new MessageProperties(); properties.Headers.Add("float", 3.14); var message = new Message(bytes, properties); template.Send(exchange, routingKey, message); Console.WriteLine("sending " + i + "..."); } }
public void MessageToBytes() { var converter = new SimpleMessageConverter(); var message = new Message(new byte[] { 1, 2, 3 }, new MessageProperties()); message.MessageProperties.ContentType = MessageProperties.CONTENT_TYPE_BYTES; var result = converter.FromMessage(message); Assert.AreEqual(typeof(byte[]), result.GetType()); var resultBytes = (byte[])result; Assert.AreEqual(3, resultBytes.Length); Assert.AreEqual(1, resultBytes[0]); Assert.AreEqual(2, resultBytes[1]); Assert.AreEqual(3, resultBytes[2]); }
/// <summary> /// Called when [message]. /// </summary> /// <param name="message">The message.</param> /// <param name="channel">The channel.</param> /// <remarks></remarks> public void OnMessage(Message message, IModel channel) { var value = Encoding.UTF8.GetString(message.Body); logger.Debug("Receiving: " + value); if (this.failed.CompareAndSet(false, true)) { // intentional error (causes exception on connection thread): channel.Abort(); } else { this.latch.Signal(); } }
/// <summary> /// Called when [message]. /// </summary> /// <param name="message">The message.</param> /// <param name="channel">The channel.</param> /// <remarks></remarks> public void OnMessage(Message message, IModel channel) { var value = Encoding.UTF8.GetString(message.Body); try { var counter = this.count.ReturnValueAndIncrement(); if (logger.IsDebugEnabled && counter % 100 == 0) { logger.Debug(value + counter); } if (this.fail) { throw new Exception("Planned failure"); } } finally { this.latch.CountDown(); } }
public void TestReplyToOneDeep() { var mockConnectionFactory = new Mock<ConnectionFactory>(); var mockConnection = new Mock<IConnection>(); var mockChannel = new Mock<IModel>(); mockConnectionFactory.Setup(m => m.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(m => m.IsOpen).Returns(true); mockConnection.Setup(m => m.CreateModel()).Returns(mockChannel.Object); mockChannel.Setup(m => m.CreateBasicProperties()).Returns(() => new BasicProperties()); var template = new RabbitTemplate(new SingleConnectionFactory(mockConnectionFactory.Object)); var replyQueue = new Queue("new.replyTo"); template.ReplyQueue = replyQueue; var messageProperties = new MessageProperties(); messageProperties.ReplyTo = "replyTo1"; var message = new Message(Encoding.UTF8.GetBytes("Hello, world!"), messageProperties); var props = new List<IBasicProperties>(); mockChannel.Setup(m => m.BasicPublish(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<bool>(), It.IsAny<bool>(), It.IsAny<IBasicProperties>(), It.IsAny<byte[]>())).Callback<string, string, bool, bool, IBasicProperties, byte[]>( (a1, a2, a3, a4, a5, a6) => { var basicProps = a5; props.Add(basicProps); var springProps = new DefaultMessagePropertiesConverter().ToMessageProperties(basicProps, null, "UTF-8"); var replyMessage = new Message(Encoding.UTF8.GetBytes("!dlrow olleH"), springProps); template.OnMessage(replyMessage); }); var reply = template.SendAndReceive(message); Assert.IsNotNull(reply); Assert.AreEqual(1, props.Count); var basicProperties = props[0]; Assert.AreEqual("new.replyTo", basicProperties.ReplyTo); Assert.AreEqual("replyTo1", basicProperties.Headers[RabbitTemplate.STACKED_REPLY_TO_HEADER]); Assert.IsNotNull(basicProperties.Headers[RabbitTemplate.STACKED_CORRELATION_HEADER]); }
public void Run() { while (true) { IModel channel = consumer.Model; try { BasicDeliverEventArgs delivery = (BasicDeliverEventArgs) consumer.Queue.Dequeue(); byte[] body = delivery.Body; IMessageProperties messageProperties = new MessageProperties(delivery.BasicProperties, delivery.Exchange, delivery.RoutingKey, delivery.Redelivered, delivery.DeliveryTag, 0); Message message = new Message(body, messageProperties); messageListenerContainer.ProcessMessage(message, channel); } //TODO catch any other exception? What of system signal for shutdown? catch (OperationInterruptedException ex) { // The consumer was removed, either through // channel or connection closure, or through the // action of IModel.BasicCancel(). logger.Debug("Consumer thread interrupted, processing stopped."); break; } catch (EndOfStreamException ex) { // The consumer was cancelled, the model closed, or the // connection went away. logger.Debug("Consumer was cancelled, processing stopped."); break; } } }
/// <summary> /// Converts from a AMQP Message to an Object. /// </summary> /// <param name="message"> /// The message. /// </param> /// <returns> /// The object. /// </returns> /// <exception cref="MessageConversionException"> /// </exception> public override object FromMessage(Message message) { object content = null; var properties = message.MessageProperties; if (properties != null) { var contentType = properties.ContentType; if (contentType != null && contentType.StartsWith("text")) { string encoding = properties.ContentEncoding ?? this.defaultCharset; try { content = SerializationUtils.DeserializeString(message.Body, encoding); } catch (Exception e) { throw new MessageConversionException("failed to convert text-based Message content", e); } } else if (contentType != null && contentType == MessageProperties.CONTENT_TYPE_SERIALIZED_OBJECT) { try { content = SerializationUtils.DeserializeObject(message.Body); } catch (Exception e) { throw new MessageConversionException("failed to convert serialized Message content", e); } } } content = content ?? (content = message.Body); return content; }
/// <summary> /// Perform a commit or message acknowledgement, as appropriate /// </summary> /// <param name="channel">The channel to commit.</param> /// <param name="message">The message to acknowledge.</param> protected virtual void CommitIfNecessary(IModel channel, Message message) { var deliveryTag = message.MessageProperties.DeliveryTag; var ackRequired = !this.AcknowledgeMode.IsAutoAck() && !this.AcknowledgeMode.IsManual(); if (this.IsChannelLocallyTransacted(channel)) { if (ackRequired) { channel.BasicAck((ulong)deliveryTag, true); } RabbitUtils.CommitIfNecessary(channel); } else if (this.IsChannelTransacted && ackRequired) { // Not locally transacted but it is transacted so it // could be synchronized with an external transaction ConnectionFactoryUtils.RegisterDeliveryTag(this.ConnectionFactory, channel, deliveryTag); } else if (ackRequired) { if (ackRequired) { channel.BasicAck((ulong)deliveryTag, true); } } }
/// <summary> /// Invokes the specified listener /// </summary> /// <param name="channel">The channel to operate on.</param> /// <param name="message">The received message.</param> /// <see cref="MessageListener"/> public virtual void InvokeListener(IModel channel, Message message) { var listener = this.MessageListener; if (listener is IChannelAwareMessageListener) { this.DoInvokeListener((IChannelAwareMessageListener)listener, channel, message); } else if (listener is IMessageListener) { this.DoInvokeListener((IMessageListener)listener, message); } else if (listener != null) { throw new ArgumentException("Only MessageListener and SessionAwareMessageListener supported: " + listener); } else { throw new InvalidOperationException("No message listener specified - see property MessageListener"); } }
/// <summary> /// Handle the delivery. /// </summary> /// <param name="delivery"> /// The delivery. /// </param> /// <returns> /// The message. /// </returns> /// <exception cref="Exception"> /// </exception> private Message Handle(Delivery delivery) { if ((delivery == null && this.shutdown != null)) { throw new Exception(string.Format("Shutdown event occurred. Cause: {0}", this.shutdown.ToString())); } if (delivery == null) { return null; } var body = delivery.Body; var envelope = delivery.Envelope; var messageProperties = RabbitUtils.CreateMessageProperties(delivery.Properties, envelope, "UTF-8"); messageProperties.MessageCount = 0; var message = new Message(body, messageProperties); if (this.logger.IsDebugEnabled) { this.logger.Debug("Received message: " + message); } return message; }
/// <summary>Post-process the given message producer before using it to send the response. /// The default implementation is empty.</summary> /// <param name="channel">The channel that will be used to send the message.</param> /// <param name="response">The outgoing message about to be sent.</param> protected virtual void PostProcessChannel(IModel channel, Message response) { }
/// <summary>Sends the given response message to the given destination.</summary> /// <param name="channel">The channel to operate on.</param> /// <param name="replyTo">The replyto property to determine where to send a response.</param> /// <param name="message">The outgoing message about to be sent.</param> protected virtual void SendResponse(IModel channel, Address replyTo, Message message) { this.PostProcessChannel(channel, message); try { Logger.Debug(m => m("Publishing response to exchange = [{0}], routingKey = [{1}]", replyTo.ExchangeName, replyTo.RoutingKey)); channel.BasicPublish( replyTo.ExchangeName, replyTo.RoutingKey, this.mandatoryPublish, this.immediatePublish, this.messagePropertiesConverter.FromMessageProperties(channel, message.MessageProperties, this.encoding), message.Body); } catch (Exception ex) { throw RabbitUtils.ConvertRabbitAccessException(ex); } }
/// <summary>Determine a response destination for the given message.</summary> /// <remarks><para>The default implementation first checks the Rabbit ReplyTo /// property of the supplied request; if that is not /// <code>null</code> /// it is returned; if it is /// <code>null</code> /// , then the configured<see cref="ResponseRoutingKey"/> default response routing key} /// is returned; if this too is /// <code>null</code> /// , then an<see cref="InvalidOperationException"/>is thrown.</para> /// </remarks> /// <param name="request">The original incoming message.</param> /// <returns>the response destination (never /// <code>null</code> /// )</returns> /// <exception cref="InvalidOperationException">if no destination can be determined.</exception> protected virtual Address GetReplyToAddress(Message request) { var replyTo = request.MessageProperties.ReplyToAddress; if (replyTo == null) { if (string.IsNullOrEmpty(this.responseExchange)) { throw new AmqpException("Cannot determine ReplyTo message property value: Request message does not contain reply-to property, and no default response Exchange was set."); } replyTo = new Address(null, this.responseExchange, this.responseRoutingKey); } return replyTo; }
/// <summary> /// Perform a rollback, handling rollback excepitons properly. /// </summary> /// <param name="channel"> /// The channel to rollback. /// </param> /// <param name="message"> /// The message. /// </param> /// <param name="ex"> /// The thrown application exception. /// </param> protected virtual void RollbackOnExceptionIfNecessary(IModel channel, Message message, Exception ex) { var ackRequired = !this.AcknowledgeMode.IsAutoAck() && !this.AcknowledgeMode.IsManual(); try { if (this.IsChannelTransacted) { if (this.logger.IsDebugEnabled) { this.logger.Debug("Initiating transaction rollback on application exception" + ex); } RabbitUtils.RollbackIfNecessary(channel); } if (message != null) { if (ackRequired) { if (this.logger.IsDebugEnabled) { this.logger.Debug("Rejecting message"); } // channel.BasicReject((ulong)message.MessageProperties.DeliveryTag, true); channel.BasicNack((ulong)message.MessageProperties.DeliveryTag, true, true); } if (this.IsChannelTransacted) { // Need to commit the reject (=nack) RabbitUtils.CommitIfNecessary(channel); } } } catch (Exception e) { this.logger.Error("Application exception overriden by rollback exception", ex); throw; } }
/// <summary> /// Invoke the specified listener a Spring Rabbit MessageListener. /// </summary> /// <remarks>Default implementation performs a plain invocation of the /// <code>OnMessage</code> methods</remarks> /// <param name="listener">The listener to invoke.</param> /// <param name="message">The received message.</param> protected virtual void DoInvokeListener(IMessageListener listener, Message message) { try { listener.OnMessage(message); } catch (Exception e) { throw this.WrapToListenerExecutionFailedExceptionIfNeeded(e); } }
/// <summary> /// Executes the specified listener, /// committing or rolling back the transaction afterwards (if necessary). /// </summary> /// <param name="channel"> /// The channel. /// </param> /// <param name="message"> /// The message. /// </param> protected virtual void DoExecuteListener(IModel channel, Message message) { if (!this.IsRunning()) { if (this.logger.IsWarnEnabled) { this.logger.Warn("Rejecting received message because of the listener container " + "having been stopped in the meantime: " + message); } this.RollbackIfNecessary(channel); throw new MessageRejectedWhileStoppingException(); } this.InvokeListener(channel, message); }
/// <summary> /// Invoke the specified listener as Spring SessionAwareMessageListener, /// exposing a new Rabbit Channel (potentially with its own transaction) /// to the listener if demanded. /// </summary> /// <param name="listener">The Spring ISessionAwareMessageListener to invoke.</param> /// <param name="channel">The channel to operate on.</param> /// <param name="message">The received message.</param> /// <see cref="IChannelAwareMessageListener"/> /// <see cref="ExposeListenerChannel"/> protected virtual void DoInvokeListener(IChannelAwareMessageListener listener, IModel channel, Message message) { RabbitResourceHolder resourceHolder = null; try { var channelToUse = channel; if (!this.ExposeListenerChannel) { //We need to expose a separate Channel. resourceHolder = GetTransactionalResourceHolder(); channelToUse = resourceHolder.Channel; } // Actually invoke the message listener try { listener.OnMessage(message, channelToUse); } catch (Exception e) { throw this.WrapToListenerExecutionFailedExceptionIfNeeded(e); } } finally { ConnectionFactoryUtils.ReleaseResources(resourceHolder); } }
/// <summary>Handles the given result object returned from the listener method, sending a response message back. </summary> /// <param name="result">The result object to handle (never /// <code>null</code> /// ).</param> /// <param name="request">The original request message.</param> /// <param name="channel">The channel to operate on (may be /// <code>null</code> /// ).</param> protected virtual void HandleResult(object result, Message request, IModel channel) { if (channel != null) { Logger.Debug(m => m("Listener method returned result [{0}] - generating response message for it", result)); var response = this.BuildMessage(channel, result); this.PostProcessResponse(request, response); var replyTo = this.GetReplyToAddress(request); this.SendResponse(channel, replyTo, response); } else { Logger.Warn(m => m("Listener method returned result [{0}]: not generating response message for it because of no Rabbit Channel given", result)); } }
/// <summary> /// Executes the specified listener, /// committing or rolling back the transaction afterwards (if necessary). /// </summary> /// <param name="channel">The channel.</param> /// <param name="message">The received message.</param> /// <see cref="InvokeListener"/> /// <see cref="CommitIfNecessary"/> /// <see cref="RollbackOnExceptionIfNecessary"/> /// <see cref="HandleListenerException"/> protected virtual void ExecuteListener(IModel channel, Message message) { try { this.DoExecuteListener(channel, message); } catch (Exception ex) { this.HandleListenerException(ex); } }
/// <summary>Get the received exchange.</summary> /// <param name="request">The request.</param> /// <returns>The received exchange.</returns> protected string GetReceivedExchange(Message request) { return request.MessageProperties.ReceivedExchange; }
/// <summary>Called when [message].</summary> /// <param name="message">The message.</param> /// <param name="channel">The channel.</param> public void OnMessage(Message message, IModel channel) { var value = Encoding.UTF8.GetString(message.Body); Logger.Debug("Receiving: " + value); if (this.latch.CurrentCount > 0) { this.latch.Signal(); } }
/// <summary>Post-process the given response message before it will be sent. The default implementation /// sets the response's correlation id to the request message's correlation id.</summary> /// <param name="request">The original incoming message.</param> /// <param name="response">The outgoing Rabbit message about to be sent.</param> protected virtual void PostProcessResponse(Message request, Message response) { var correlation = request.MessageProperties.CorrelationId.ToStringWithEncoding("UTF-8"); if (string.IsNullOrWhiteSpace(correlation)) { if (!string.IsNullOrWhiteSpace(request.MessageProperties.MessageId)) { correlation = request.MessageProperties.MessageId; } } response.MessageProperties.CorrelationId = correlation.ToByteArrayWithEncoding("UTF-8"); }