public void DoesNotLeakMessages() { // arrange const string inputQueueName = "test.leak.input"; var queue = TrackDisposable(new MsmqMessageQueue(inputQueueName)); var body = Encoding.UTF8.GetBytes(new string('*', 32768)); var message = new TransportMessageToSend { Headers = new Dictionary <string, object> { { Headers.MessageId, "msg-1" } }, Body = body }; var weakMessageRef = new WeakReference(message); var weakBodyRef = new WeakReference(body); // act queue.Send(inputQueueName, message, new NoTransaction()); message = null; body = null; GC.Collect(); GC.WaitForPendingFinalizers(); // assert Assert.That(weakMessageRef.IsAlive, Is.False, "Expected the message to have been collected"); Assert.That(weakBodyRef.IsAlive, Is.False, "Expected the body bytes to have been collected"); }
/// <summary> /// Sends a copy of the specified <see cref="TransportMessageToSend"/> using the underlying implementation of <see cref="ISendMessages"/> /// with an encrypted message body and additional headers /// </summary> public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var clone = new TransportMessageToSend { Headers = message.Headers.Clone(), Label = message.Label, Body = message.Body, }; if (compressionHelper != null) { var compresssionResult = compressionHelper.Compress(clone.Body); if (compresssionResult.Item1) { clone.Headers[Headers.Compression] = Headers.CompressionTypes.GZip; } clone.Body = compresssionResult.Item2; } if (encryptionHelper != null) { var iv = encryptionHelper.GenerateNewIv(); clone.Body = encryptionHelper.Encrypt(clone.Body, iv); clone.Headers[Headers.Encrypted] = null; clone.Headers[Headers.EncryptionSalt] = iv; } innerSendMessages.Send(destinationQueueName, clone, context); }
public void ItsSymmetric() { var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary <string, object> { { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() } }, Body = Guid.NewGuid().ToByteArray(), }; transport.Send("test", toSend, new NoTransaction()); var receivedTransportMessage = sender.SentMessage.ToReceivedTransportMessage(); receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = transport.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
public void CanSendAndReceiveMessageWithHeaders() { // arrange var encoding = Encoding.UTF7; var transportMessageToSend = new TransportMessageToSend { Body = encoding.GetBytes("this is some data"), Headers = new Dictionary <string, object> { { "key1", "value1" }, { "key2", "value2" }, } }; // act sender.Send(receiver.InputQueue, transportMessageToSend, new NoTransaction()); Thread.Sleep(MaximumExpectedQueueLatency); var receivedTransportMessage = receiver.ReceiveMessage(new NoTransaction()); // assert encoding.GetString(receivedTransportMessage.Body).ShouldBe("this is some data"); var headers = receivedTransportMessage.Headers; headers.ShouldNotBe(null); headers.Count.ShouldBe(2); headers.ShouldContainKeyAndValue("key1", "value1"); headers.ShouldContainKeyAndValue("key2", "value2"); 5.Times(() => receiver.ReceiveMessage(new NoTransaction()).ShouldBe(null)); }
public void CanEncryptStuff() { // arrange var transportMessageToSend = new TransportMessageToSend { Headers = new Dictionary <string, object> { { "test", "blah!" } }, Label = "label", Body = Encoding.UTF7.GetBytes("Hello world!"), }; // act transport.Send("test", transportMessageToSend, new NoTransaction()); // assert var sentMessage = sender.SentMessage; sentMessage.Headers.Count.ShouldBe(3); sentMessage.Headers["test"].ShouldBe("blah!"); sentMessage.Label.ShouldBe("label"); sentMessage.Body.ShouldNotBe(Encoding.UTF7.GetBytes("Hello world!")); sentMessage.Headers.ShouldContainKey(Headers.Encrypted); sentMessage.Headers.ShouldContainKey(Headers.EncryptionSalt); Console.WriteLine("iv: " + sentMessage.Headers[Headers.EncryptionSalt]); Console.WriteLine(string.Join(", ", sentMessage.Body.Select(b => b.ToString()))); }
public void ExchangeCreatedIfPusblishWithExchangePerType() { var exchangeName = typeof(TransportMessageToSend).FullName; using (var adapter = new BuiltinContainerAdapter()) { DeleteQueue("test.input"); DeleteQueue("test.error"); DeleteExchange(exchangeName); var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") }; var bus = Configure.With(adapter) .Transport(t => t.UseRabbitMq(ConnectionString, "test.input", "test.error") .ManageSubscriptions() .UseOneExchangePerMessageTypeRouting()) .CreateBus() .Start(); bus.Publish(msg); Assert.True(ExchangeExists(exchangeName)); } }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { try { if (!context.IsTransactional) { using (var model = GetConnection().CreateModel()) { var headers = GetHeaders(model, message); model.BasicPublish(ExchangeName, destinationQueueName, headers, message.Body); } } else { var model = GetSenderModel(context); model.BasicPublish(ExchangeName, destinationQueueName, GetHeaders(model, message), message.Body); } } catch (Exception e) { ErrorOnConnection(e); throw; } }
public void CanSendMessagesDirectlyToExchange(int mode) { // arrange var routeUsingExchanges = mode > 1; var exchangeAsAddress = mode > 2; var sender = GetQueue("test.sender", removeExiting: true, oneExchangePerType: routeUsingExchanges, inputExchange: exchangeAsAddress ? "ex-test.sender" : null); var recipient = GetQueue("test.recipient", removeExiting: true, oneExchangePerType: true, inputExchange: "ex-test.recipient"); // act using (var tx = new TransactionScope()) { var ctx = new AmbientTransactionContext(); var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") }; sender.Send("@ex-test.recipient", msg, ctx); sender.Send("@ex-test.recipient", msg, ctx); sender.Send("@ex-test.recipient", msg, ctx); tx.Complete(); } // assert var receivedTransportMessages = GetAllMessages(recipient); receivedTransportMessages.Count.ShouldBe(3); }
void EnsureInitialized(TransportMessageToSend message, string queueName) { // don't create recipient queue if multicasting if (message.Headers.ContainsKey(Headers.Multicast)) { message.Headers.Remove(Headers.Multicast); return; } if (initializedQueues.Contains(queueName)) { return; } lock (initializedQueues) { if (initializedQueues.Contains(queueName)) { return; } InitializeLogicalQueue(queueName); initializedQueues.Add(queueName); } }
static int GetMessagePriority(TransportMessageToSend message) { if (!message.Headers.ContainsKey(PriorityHeaderKey)) { return(DefaultMessagePriority); } var priorityAsString = message.Headers[PriorityHeaderKey].ToString(); try { var priority = int.Parse(priorityAsString); if (priority < 0 || priority > 255) { throw new ArgumentException(string.Format("Message priority out of range: {0}", priority)); } return(priority); } catch (Exception exception) { throw new FormatException( string.Format( "Could not decode message priority '{0}' - message priority must be an integer value in the [0;255] range", priorityAsString), exception); } }
public void CanGenerateValidKey() { var key = RijndaelEncryptionTransportDecorator.GenerateKeyBase64(); var localInstance = new RijndaelEncryptionTransportDecorator(sender, receiver, key); var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary <string, object> { { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() } }, Body = Guid.NewGuid().ToByteArray(), }; localInstance.Send("test", toSend, new NoTransaction()); var receivedTransportMessage = sender.SentMessage.ToReceivedTransportMessage(); receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = localInstance.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
public void CanSendMessagesInTransaction(bool commitTransactionAndExpectMessagesToBeThere) { // arrange var sender = GetQueue("test.tx.sender"); var recipient = GetQueue("test.tx.recipient"); // act using (var tx = new TransactionScope()) { var ctx = new AmbientTransactionContext(); var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") }; sender.Send(recipient.InputQueue, msg, ctx); sender.Send(recipient.InputQueue, msg, ctx); sender.Send(recipient.InputQueue, msg, ctx); if (commitTransactionAndExpectMessagesToBeThere) { tx.Complete(); } } // assert var receivedTransportMessages = GetAllMessages(recipient); receivedTransportMessages.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0); }
public void Log(string destination, TransportMessageToSend message) { var encoding = MessageLoggerHelper.GetEncoding(message.Headers); if (encoding == null) { _logger.WarnFormat("Unable to guess encoding for outgoing message with id '{0}' and destination {1}?!", MessageLoggerHelper.GetMessageId(message.Headers), destination); return; } _logger.Log(_logLevel, () => { var messageLog = new StringBuilder(); string id = MessageLoggerHelper.GetMessageId(message.Headers); messageLog.AppendFormat("Outgoing message ('{0}') and destination {1} headers:", id, destination); Append(messageLog, id, message.Headers); return(messageLog.ToString()); }); _logger.Log(_logLevel, () => { var messageLog = new StringBuilder(); string id = MessageLoggerHelper.GetMessageId(message.Headers); messageLog.AppendFormat("Outgoing message ('{0}') and destination {1} body:", id, destination); Append(messageLog, id, message.Body, encoding); return(messageLog.ToString()); }); }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var outputQueue = cloudQueueClient.GetQueueReference(destinationQueueName); using (var memoryStream = new MemoryStream()) { var formatter = new BinaryFormatter(); var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Headers = message.Headers, Body = message.Body, Label = message.Label, }; formatter.Serialize(memoryStream, receivedTransportMessage); memoryStream.Position = 0; var cloudQueueMessage = new CloudQueueMessage(memoryStream.ToArray()); var timeToLive = GetTimeToLive(message); if (timeToLive.HasValue) { outputQueue.AddMessage(cloudQueueMessage, timeToLive.Value); } else { outputQueue.AddMessage(cloudQueueMessage); } } }
/// <summary> /// Sends the given <see cref="TransportMessageToSend"/> to the input queue specified by <see cref="inputQueueName"/> /// using MSMQ /// </summary> public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var recipientPath = MsmqUtil.GetSenderPath(destinationQueueName); try { if (!context.IsTransactional) { using (var outputQueue = GetMessageQueue(recipientPath)) using (var transaction = new MessageQueueTransaction()) { transaction.Begin(); outputQueue.Send(message, transaction); transaction.Commit(); } return; } using (var outputQueue = GetMessageQueue(recipientPath)) { outputQueue.Send(message, GetTransaction(context)); } } catch (Exception e) { throw new ApplicationException(string.Format("An error occurred while attempting to send {0} to {1}", message, destinationQueueName), e); } }
public void ItsSymmetric() { var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary <string, string> { { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() } }, Body = Guid.NewGuid().ToByteArray(), }; transport.Send("test", toSend); var sentMessage = sender.SentMessage; var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Label = sentMessage.Label, Headers = sentMessage.Headers, Body = sentMessage.Body }; receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = transport.ReceiveMessage(); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); expectedHeaders[Headers.Encrypted] = null; receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
public void CanSendMessagesInTransactionToMultipleQueues(bool commitTransactionAndExpectMessagesToBeThere) { // arrange var sender = GetQueue("test.tx.sender"); var firstRecipient = GetQueue("test.tx.recipient1"); var secondRecipient = GetQueue("test.tx.recipient2"); // act using (var tx = new TransactionScope()) { var msg = new TransportMessageToSend { Body = Encoding.UTF8.GetBytes("this is a message!") }; sender.Send(firstRecipient.InputQueue, msg); sender.Send(firstRecipient.InputQueue, msg); sender.Send(firstRecipient.InputQueue, msg); sender.Send(secondRecipient.InputQueue, msg); sender.Send(secondRecipient.InputQueue, msg); sender.Send(secondRecipient.InputQueue, msg); if (commitTransactionAndExpectMessagesToBeThere) { tx.Complete(); } } // assert var receivedTransportMessagesFromFirstRecipient = GetAllMessages(firstRecipient); var receivedTransportMessagesFromSecondRecipient = GetAllMessages(secondRecipient); receivedTransportMessagesFromFirstRecipient.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0); receivedTransportMessagesFromSecondRecipient.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0); }
/// <summary> /// Initializes a new instance of the <see cref="IdempotentSagaResults" /> class. /// </summary> /// <param name="id">The id.</param> /// <param name="message">The message.</param> /// <param name="serializerType">Type of the serializer.</param> public IdempotentSagaResults(string id, TransportMessageToSend message, Type serializerType) : this() { Id = id; Headers = message.Headers; Message = message.Body; Serializer = serializerType.AssemblyQualifiedName; }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { if (!context.IsTransactional) { var envelopeToSendImmediately = new Envelope { Body = message.Body, Headers = message.Headers != null ? message .Headers .ToDictionary(h => h.Key, h => h.Value.ToString()) : null, Label = message.Label, }; var backoffTimes = new[] { 1, 2, 5, 10, 10, 10, 10, 10, 20, 20, 20, 30, 30, 30, 30 } .Select(seconds => TimeSpan.FromSeconds(seconds)) .ToArray(); new Retrier(backoffTimes) .RetryOn <ServerBusyException>() .RetryOn <MessagingCommunicationException>() .RetryOn <TimeoutException>() .TolerateInnerExceptionsAsWell() .Do(() => { using (var messageToSendImmediately = new BrokeredMessage(envelopeToSendImmediately)) { messageToSendImmediately.Properties[LogicalQueuePropertyKey] = destinationQueueName; topicClient.Send(messageToSendImmediately); } }); return; } // if the batch is null, we're doing tx send outside of a message handler if (context[AzureServiceBusMessageBatch] == null) { context[AzureServiceBusMessageBatch] = new List <Tuple <string, Envelope> >(); context.DoCommit += () => DoCommit(context); } var envelope = new Envelope { Body = message.Body, Headers = message.Headers != null ? message.Headers.ToDictionary(h => h.Key, h => h.Value.ToString()) : null, Label = message.Label, }; var messagesToSend = (List <Tuple <string, Envelope> >)context[AzureServiceBusMessageBatch]; messagesToSend.Add(Tuple.Create(destinationQueueName, envelope)); }
private TimeSpan? GetTimeToLive(TransportMessageToSend message) { if (message.Headers != null && message.Headers.ContainsKey(Headers.TimeToBeReceived)) { return TimeSpan.Parse((string)message.Headers[Headers.TimeToBeReceived]); } return null; }
private TimeSpan?GetTimeToLive(TransportMessageToSend message) { if (message.Headers != null && message.Headers.ContainsKey(Headers.TimeToBeReceived)) { return(TimeSpan.Parse((string)message.Headers[Headers.TimeToBeReceived])); } return(null); }
string Serialize(TransportMessageToSend message) { return(JsonConvert.SerializeObject(new ReceivedTransportMessage { Id = message.Headers.ContainsKey(Headers.MessageId) ? message.Headers[Headers.MessageId].ToString() : Guid.NewGuid().ToString(), Body = message.Body, Headers = message.Headers, }, SuperSecretSerializerSettings)); }
public void AddsHeaderToEncryptedMessage() { // arrange var transportMessageToSend = new TransportMessageToSend { Body = new byte[] { 123, 125 } }; // act transport.Send("somewhere", transportMessageToSend, new NoTransaction()); // assert sender.SentMessage.Headers.ShouldContainKey(Headers.Encrypted); }
Envelope CreateEnvelope(TransportMessageToSend message) { return(new Envelope { Body = message.Body, Headers = message.Headers != null ? message.Headers.ToDictionary(h => h.Key, h => h.Value.ToString()) : null, Label = message.Label, }); }
public static ReceivedTransportMessage ToReceivedTransportMessage(this TransportMessageToSend message) { return(new ReceivedTransportMessage { Headers = message.Headers, Body = message.Body, Label = message.Label, Id = Guid.NewGuid() .ToString() }); }
public void Send(string destinationQueueName, TransportMessageToSend message) { var transportMessageToSend = new TransportMessageToSend { Headers = message.Headers, Label = message.Label, Body = Encrypt(message.Body), }; innerSendMessages.Send(destinationQueueName, transportMessageToSend); }
static IBasicProperties GetHeaders(IModel modelToUse, TransportMessageToSend message) { var props = modelToUse.CreateBasicProperties(); if (message.Headers != null) { props.Headers = message.Headers .ToHashtable(kvp => kvp.Key, kvp => PossiblyEncode(kvp.Value)); if (message.Headers.ContainsKey(Headers.ReturnAddress)) { props.ReplyTo = (string)message.Headers[Headers.ReturnAddress]; } if (message.Headers.ContainsKey(Headers.TimeToBeReceived)) { var timeToBeReceived = message.Headers[Headers.TimeToBeReceived] as string; if (timeToBeReceived == null) { throw new ArgumentException( string.Format( "Message header contains the {0} header, but the value is {1} and not a string as expected!", Headers.TimeToBeReceived, message.Headers[Headers.TimeToBeReceived])); } try { var timeSpan = TimeSpan.Parse(timeToBeReceived); var milliseconds = (int)timeSpan.TotalMilliseconds; if (milliseconds <= 0) { throw new ArgumentException( string.Format( "Cannot set TTL message expiration to {0} milliseconds! Please specify a positive value!", milliseconds)); } props.Expiration = milliseconds.ToString(); } catch (Exception e) { throw new FormatException(string.Format( "Could not set TTL message expiration on message - apparently, '{0}' is not a valid TTL TimeSpan", timeToBeReceived), e); } } } props.MessageId = Guid.NewGuid().ToString(); props.SetPersistent(true); return(props); }
public void Send(string destinationQueueName, TransportMessageToSend message) { var recipientPath = MsmqUtil.GetFullPath(destinationQueueName); using (var outputQueue = GetMessageQueue(recipientPath)) { var transactionWrapper = GetOrCreateTransactionWrapper(); outputQueue.Send(message, transactionWrapper.MessageQueueTransaction); transactionWrapper.Commit(); } }
public void Send(string destinationQueueName, TransportMessageToSend message) { var transportMessageToSend = new TransportMessageToSend { Headers = message.Headers.Clone(), Label = message.Label, Body = Encrypt(message.Body), }; transportMessageToSend.Headers[Headers.Encrypted] = null; innerSendMessages.Send(destinationQueueName, transportMessageToSend); }
internal void InternalSend(List <string> destinations, TransportMessageToSend transportMessage, ITransactionContext transactionContext) { foreach (var destination in destinations) { try { sendMessages.Send(destination, transportMessage, transactionContext); } catch (Exception exception) { throw new ApplicationException(string.Format( "An exception occurred while attempting to send {0} to {1} (transaction context: {2})", transportMessage, destination, transactionContext), exception); } } }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var iv = helper.GenerateNewIv(); var transportMessageToSend = new TransportMessageToSend { Headers = message.Headers.Clone(), Label = message.Label, Body = helper.Encrypt(message.Body, iv), }; transportMessageToSend.Headers[Headers.Encrypted] = null; transportMessageToSend.Headers[Headers.EncryptionSalt] = iv; innerSendMessages.Send(destinationQueueName, transportMessageToSend, context); }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var headers = message.Headers; if (headers.ContainsKey(Headers.Compression)) { headers[MessageWasCompressedKey] = true; } if (headers.ContainsKey(Headers.Encrypted)) { headers[MessageWasEncryptedKey] = true; } innerSender.Send(destinationQueueName, message, context); }
/// <summary> /// Sends a copy of the specified <see cref="TransportMessageToSend"/> using the underlying implementation of <see cref="ISendMessages"/> /// with an encrypted message body and additional headers /// </summary> public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var iv = helper.GenerateNewIv(); var transportMessageToSend = new TransportMessageToSend { Headers = message.Headers.Clone(), Label = message.Label, Body = helper.Encrypt(message.Body, iv), }; transportMessageToSend.Headers[Headers.Encrypted] = null; transportMessageToSend.Headers[Headers.EncryptionSalt] = iv; innerSendMessages.Send(destinationQueueName, transportMessageToSend, context); }
public void CheckSendPerformance(int count) { var queue = new MsmqMessageQueue("test.msmq.performance", "error").PurgeInputQueue(); var transportMessageToSend = new TransportMessageToSend { Headers = new Dictionary<string, string>(), Body = new byte[1024], Label = "this is just a label" }; var stopwatch = Stopwatch.StartNew(); count.Times(() => queue.Send("test.msmq.performance", transportMessageToSend)); var totalSeconds = stopwatch.Elapsed.TotalSeconds; Console.WriteLine("Sending {0} messages took {1:0} s - that's {2:0} msg/s", count, totalSeconds, count/totalSeconds); }
/// <summary> /// Sends the specified message to the logical queue specified by <seealso cref="destinationQueueName"/> by writing /// a JSON serialied text to a file in the corresponding directory. The actual write operation is delayed until /// the commit phase of the queue transaction unless we're non-transactional, in which case it is written immediately. /// </summary> public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { EnsureQueueInitialized(destinationQueueName); var destinationDirectory = GetDirectoryForQueueNamed(destinationQueueName); var serializedMessage = Serialize(message); var fileName = GetNextFileName(); var fullPath = Path.Combine(destinationDirectory, fileName); Action commitAction = () => File.WriteAllText(fullPath, serializedMessage, FavoriteEncoding); if (context.IsTransactional) { context.DoCommit += commitAction; } else { commitAction(); } }
IBasicProperties GetHeaders(IModel model, TransportMessageToSend message) { var props = model.CreateBasicProperties(); if (message.Headers != null) { props.Headers = message.Headers.ToDictionary(e => e.Key, e => Encoding.GetBytes(e.Value)); if (message.Headers.ContainsKey(Headers.ReturnAddress)) { props.ReplyTo = message.Headers[Headers.ReturnAddress]; } } props.MessageId = Guid.NewGuid().ToString(); return props; }
byte[] GetBody(TransportMessageToSend message) { return message.Body; }
public void Send(string destinationQueueName, TransportMessageToSend message) { WithModel(m => m.BasicPublish(ExchangeName, destinationQueueName, GetHeaders(m, message), GetBody(message))); }
IBasicProperties GetHeaders(IModel modelToUse, TransportMessageToSend message) { var props = modelToUse.CreateBasicProperties(); var persistentMessage = true; if (message.Headers != null) { props.Headers = message.Headers .ToHashtable(kvp => kvp.Key, kvp => PossiblyEncode(kvp.Value)); if (message.Headers.ContainsKey(Headers.MessageId)) { // Not sure if message-id is always an string, so let's convert // whatever the user specified to string and move on. (pruiz) props.MessageId = Convert.ToString(message.Headers[Headers.MessageId]); } if (message.Headers.ContainsKey(Headers.ReturnAddress)) { props.ReplyTo = (string)message.Headers[Headers.ReturnAddress]; } if (message.Headers.ContainsKey(Headers.TimeToBeReceived)) { var timeToBeReceived = message.Headers[Headers.TimeToBeReceived] as string; if (timeToBeReceived == null) { throw new ArgumentException( string.Format( "Message header contains the {0} header, but the value is {1} and not a string as expected!", Headers.TimeToBeReceived, message.Headers[Headers.TimeToBeReceived])); } try { var timeSpan = TimeSpan.Parse(timeToBeReceived); var milliseconds = (int)timeSpan.TotalMilliseconds; if (milliseconds <= 0) { throw new ArgumentException( string.Format( "Cannot set TTL message expiration to {0} milliseconds! Please specify a positive value!", milliseconds)); } props.Expiration = milliseconds.ToString(); } catch (Exception e) { throw new FormatException(string.Format( "Could not set TTL message expiration on message - apparently, '{0}' is not a valid TTL TimeSpan", timeToBeReceived), e); } } if (message.Headers.ContainsKey(InternalHeaders.MessageDurability)) { var durableMessages = (message.Headers[InternalHeaders.MessageDurability] ?? "").ToString(); bool result; if (bool.TryParse(durableMessages, out result)) { persistentMessage = result; } else { throw new ArgumentException( string.Format("Could not parse the value '{0}' from the '{1}' header into a proper bool", durableMessages, InternalHeaders.MessageDurability)); } } } // If not already set, specify a unique message's Id. if (string.IsNullOrWhiteSpace(props.MessageId)) props.MessageId = Guid.NewGuid().ToString(); props.SetPersistent(persistentMessage); return props; }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { SentMessage = message; }
static int GetMessagePriority(TransportMessageToSend message) { if (!message.Headers.ContainsKey(PriorityHeaderKey)) return DefaultMessagePriority; var priorityAsString = message.Headers[PriorityHeaderKey].ToString(); try { var priority = int.Parse(priorityAsString); if (priority < 0 || priority > 255) { throw new ArgumentException(string.Format("Message priority out of range: {0}", priority)); } return priority; } catch (Exception exception) { throw new FormatException( string.Format( "Could not decode message priority '{0}' - message priority must be an integer value in the [0;255] range", priorityAsString), exception); } }
static IBasicProperties GetHeaders(IModel modelToUse, TransportMessageToSend message) { var props = modelToUse.CreateBasicProperties(); if (message.Headers != null) { props.Headers = message.Headers .ToHashtable(kvp => kvp.Key, kvp => PossiblyEncode(kvp.Value)); if (message.Headers.ContainsKey(Headers.ReturnAddress)) { props.ReplyTo = (string)message.Headers[Headers.ReturnAddress]; } } props.MessageId = Guid.NewGuid().ToString(); props.SetPersistent(true); return props; }
static IBasicProperties GetHeaders(IModel modelToUse, TransportMessageToSend message) { var props = modelToUse.CreateBasicProperties(); if (message.Headers != null) { props.Headers = message.Headers .ToHashtable(kvp => kvp.Key, kvp => PossiblyEncode(kvp.Value)); if (message.Headers.ContainsKey(Headers.ReturnAddress)) { props.ReplyTo = (string)message.Headers[Headers.ReturnAddress]; } if (message.Headers.ContainsKey(Headers.TimeToBeReceived)) { var timeToBeReceived = message.Headers[Headers.TimeToBeReceived] as string; if (timeToBeReceived == null) { throw new ArgumentException( string.Format( "Message header contains the {0} header, but the value is {1} and not a string as expected!", Headers.TimeToBeReceived, message.Headers[Headers.TimeToBeReceived])); } try { var timeSpan = TimeSpan.Parse(timeToBeReceived); var milliseconds = (int)timeSpan.TotalMilliseconds; if (milliseconds <= 0) { throw new ArgumentException( string.Format( "Cannot set TTL message expiration to {0} milliseconds! Please specify a positive value!", milliseconds)); } props.Expiration = milliseconds.ToString(); } catch (Exception e) { throw new FormatException(string.Format( "Could not set TTL message expiration on message - apparently, '{0}' is not a valid TTL TimeSpan", timeToBeReceived), e); } } } props.MessageId = Guid.NewGuid().ToString(); props.SetPersistent(true); return props; }
public void CanSendMessagesDirectlyToExchangeWithRoutingKey(int mode) { // arrange var routeUsingExchanges = mode > 1; var exchangeAsAddress = mode > 2; var sender = GetQueue("test.sender", removeExiting: true, oneExchangePerType: routeUsingExchanges, inputExchange: exchangeAsAddress ? "ex-test.sender" : null); var recipient = GetQueue("test.recipient", removeExiting: true); using (var cm = new ConnectionManager(ConnectionString, "test.sender")) using (var conn = cm.GetConnection()) using (var model = conn.CreateModel()) { model.QueueBind("test.recipient", "ex-test.recipient", "sample"); } // act using (var tx = new TransactionScope()) { var ctx = new AmbientTransactionContext(); var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") }; sender.Send("*****@*****.**", msg, ctx); sender.Send("*****@*****.**", msg, ctx); sender.Send("*****@*****.**", msg, ctx); tx.Complete(); } // assert var receivedTransportMessages = GetAllMessages(recipient); receivedTransportMessages.Count.ShouldBe(3); }
public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { if (!context.IsTransactional) { var envelopeToSendImmediately = CreateEnvelope(message); var backoffTimes = new[] { 1, 2, 5, 10, 10, 10, 10, 10, 20, 20, 20, 30, 30, 30, 30 } .Select(seconds => TimeSpan.FromSeconds(seconds)) .ToArray(); new Retrier(backoffTimes) .RetryOn<ServerBusyException>() .RetryOn<MessagingCommunicationException>() .RetryOn<TimeoutException>() .TolerateInnerExceptionsAsWell() .Do(() => { using (var messageToSendImmediately = CreateBrokeredMessage(envelopeToSendImmediately)) { GetClientFor(destinationQueueName).Send(messageToSendImmediately); } }); return; } // if the batch is null, we're doing tx send outside of a message handler - this means // that we must initialize the collection of messages to be sent if (context[AzureServiceBusMessageBatch] == null) { context[AzureServiceBusMessageBatch] = new List<Tuple<string, Envelope>>(); context.DoCommit += () => DoCommit(context); } var envelope = CreateEnvelope(message); var messagesToSend = (List<Tuple<string, Envelope>>)context[AzureServiceBusMessageBatch]; messagesToSend.Add(Tuple.Create(destinationQueueName, envelope)); }
public void CanEncryptStuff() { // arrange var transportMessageToSend = new TransportMessageToSend { Headers = new Dictionary<string, object> { { "test", "blah!" } }, Label = "label", Body = Encoding.UTF7.GetBytes("Hello world!"), }; // act transport.Send("test", transportMessageToSend, new NoTransaction()); // assert var sentMessage = sender.SentMessage; sentMessage.Headers.Count.ShouldBe(3); sentMessage.Headers["test"].ShouldBe("blah!"); sentMessage.Label.ShouldBe("label"); sentMessage.Body.ShouldNotBe(Encoding.UTF7.GetBytes("Hello world!")); sentMessage.Headers.ShouldContainKey(Headers.Encrypted); sentMessage.Headers.ShouldContainKey(Headers.EncryptionSalt); Console.WriteLine("iv: " + sentMessage.Headers[Headers.EncryptionSalt]); Console.WriteLine(string.Join(", ", sentMessage.Body.Select(b => b.ToString()))); }
Envelope CreateEnvelope(TransportMessageToSend message) { return new Envelope { Body = message.Body, Headers = message.Headers != null ? message.Headers.ToDictionary(h => h.Key, h => h.Value.ToString()) : null, Label = message.Label, }; }
public void ItsSymmetric(int howManyGuidsToSend) { EnableEncryption(); EnableCompression(); var semiRandomBytes = Enumerable .Repeat(Guid.NewGuid(), howManyGuidsToSend) .SelectMany(guid => guid.ToByteArray()) .ToArray(); var someCustomHeaders = new Dictionary<string, object> { {"some random header", Guid.NewGuid().ToString()}, {"another random header", Guid.NewGuid().ToString()} }; var messageToSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = someCustomHeaders, Body = semiRandomBytes }; transport.Send("test", messageToSend, new NoTransaction()); var wireMessage = sender.SentMessage; var receivedTransportMessage = wireMessage.ToReceivedTransportMessage(); receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = transport.ReceiveMessage(new NoTransaction()); Console.WriteLine(@" Transport message to send: headers: {1} body size: {0} Wire transport message: headers: {3} body size: {2} Received transport message: headers: {5} body size: {4} ", messageToSend.Body.Length, FormatHeaders(messageToSend.Headers), wireMessage.Body.Length, FormatHeaders(wireMessage.Headers), receivedMessage.Body.Length, FormatHeaders(receivedMessage.Headers)); receivedMessage.Label.ShouldBe(messageToSend.Label); var expectedHeaders = messageToSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(messageToSend.Body); }
public void CanSendMessagesInTransactionToMultipleQueues(bool commitTransactionAndExpectMessagesToBeThere) { // arrange var sender = GetQueue("test.tx.sender"); var firstRecipient = GetQueue("test.tx.recipient1"); var secondRecipient = GetQueue("test.tx.recipient2"); // act using (var tx = new TransactionScope()) { var ctx = new AmbientTransactionContext(); var msg = new TransportMessageToSend { Body = Encoding.GetBytes("this is a message!") }; sender.Send(firstRecipient.InputQueue, msg, ctx); sender.Send(firstRecipient.InputQueue, msg, ctx); sender.Send(firstRecipient.InputQueue, msg, ctx); sender.Send(secondRecipient.InputQueue, msg, ctx); sender.Send(secondRecipient.InputQueue, msg, ctx); sender.Send(secondRecipient.InputQueue, msg, ctx); if (commitTransactionAndExpectMessagesToBeThere) tx.Complete(); } // assert var receivedTransportMessagesFromFirstRecipient = GetAllMessages(firstRecipient); var receivedTransportMessagesFromSecondRecipient = GetAllMessages(secondRecipient); receivedTransportMessagesFromFirstRecipient.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0); receivedTransportMessagesFromSecondRecipient.Count.ShouldBe(commitTransactionAndExpectMessagesToBeThere ? 3 : 0); }
/// <summary> /// Sends the specified <see cref="TransportMessageToSend"/> to the logical queue specified by <paramref name="destinationQueueName"/>. /// What actually happens, is that a row is inserted into the messages table, setting the 'recipient' column to the specified /// queue. /// </summary> public void Send(string destinationQueueName, TransportMessageToSend message, ITransactionContext context) { var connection = GetConnectionPossiblyFromContext(context); try { using (var command = connection.CreateCommand()) { command.CommandText = string.Format(@"insert into [{0}] ([recipient], [headers], [label], [body], [priority]) values (@recipient, @headers, @label, @body, @priority)", messageTableName); var label = message.Label ?? "(no label)"; log.Debug("Sending message with label {0} to {1}", label, destinationQueueName); var priority = GetMessagePriority(message); command.Parameters.Add("recipient", SqlDbType.NVarChar, 200).Value = destinationQueueName; command.Parameters.Add("headers", SqlDbType.NVarChar, Max).Value = DictionarySerializer.Serialize(message.Headers); command.Parameters.Add("label", SqlDbType.NVarChar, Max).Value = label; command.Parameters.Add("body", SqlDbType.VarBinary, Max).Value = message.Body; command.Parameters.Add("priority", SqlDbType.TinyInt, 1).Value = priority; command.ExecuteNonQuery(); } if (!context.IsTransactional) { commitAction(connection); } } finally { if (!context.IsTransactional) { releaseConnection(connection); } } }
public void CanGenerateValidKey() { var key = RijndaelEncryptionTransportDecorator.GenerateKeyBase64(); var localInstance = new RijndaelEncryptionTransportDecorator(sender, receiver, key); var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary<string, object> { {Guid.NewGuid().ToString(), Guid.NewGuid().ToString()} }, Body = Guid.NewGuid().ToByteArray(), }; localInstance.Send("test", toSend, new NoTransaction()); var sentMessage = sender.SentMessage; var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Label = sentMessage.Label, Headers = sentMessage.Headers, Body = sentMessage.Body }; receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = localInstance.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
public void ItsSymmetric() { var toSend = new TransportMessageToSend { Label = Guid.NewGuid().ToString(), Headers = new Dictionary<string, object> { {Guid.NewGuid().ToString(), Guid.NewGuid().ToString()} }, Body = Guid.NewGuid().ToByteArray(), }; transport.Send("test", toSend, new NoTransaction()); var sentMessage = sender.SentMessage; var receivedTransportMessage = new ReceivedTransportMessage { Id = Guid.NewGuid().ToString(), Label = sentMessage.Label, Headers = sentMessage.Headers, Body = sentMessage.Body }; receiver.SetUpReceive(receivedTransportMessage); var receivedMessage = transport.ReceiveMessage(new NoTransaction()); receivedMessage.Label.ShouldBe(toSend.Label); var expectedHeaders = toSend.Headers.Clone(); receivedMessage.Headers.ShouldBe(expectedHeaders); receivedMessage.Body.ShouldBe(toSend.Body); }
void EnsureInitialized(TransportMessageToSend message, string queueName) { // don't create recipient queue if multicasting if (message.Headers.ContainsKey(Headers.Multicast)) { message.Headers.Remove(Headers.Multicast); return; } if (initializedQueues.Contains(queueName)) return; lock (initializedQueues) { if (initializedQueues.Contains(queueName)) return; InitializeLogicalQueue(queueName); initializedQueues.Add(queueName); } }