예제 #1
0
        public void Register(Message message)
        {
            timeoutMessageIds.Write(writer =>
            {
                var timeToSend = XmlConvert.ToDateTime(message.Headers["time-to-send"], XmlDateTimeSerializationMode.Utc);

                logger.DebugFormat("Registering message {0} to be sent at {1} on {2}",
                                   message.Id, timeToSend, queue.QueueName);

                writer.Add(timeToSend, message.Id);
            });
        }
예제 #2
0
        public void Register(Message message)
        {
            timeoutMessageIds.Write(writer =>
            {
                var timeToSend = XmlConvert.ToDateTime(message.Headers["time-to-send"], XmlDateTimeSerializationMode.Utc);

                logger.DebugFormat("Registering message {0} to be sent at {1} on {2}",
                                   message.Id, timeToSend, queue.QueueName);

                writer.Add(timeToSend, message.Id);
            });
        }
 public static Message[] ToMessages(byte[] buffer)
 {
     using(var ms = new MemoryStream(buffer))
     using (var br = new BinaryReader(ms))
     {
         var numberOfMessages = br.ReadInt32();
         var msgs = new Message[numberOfMessages];
         for (int i = 0; i < numberOfMessages; i++)
         {
             msgs[i] = new Message
             {
                 Id = new MessageId
                 {
                     SourceInstanceId = new Guid(br.ReadBytes(16)),
                     MessageIdentifier = new Guid(br.ReadBytes(16))
                 },
                 Queue = br.ReadString(),
                 SubQueue = br.ReadString(),
                 Priority = br.ReadInt16(),
                 SentAt = DateTime.FromBinary(br.ReadInt64()),
             };
             var headerCount = br.ReadInt32();
             msgs[i].Headers = new NameValueCollection(headerCount);
             for (var j = 0; j < headerCount; j++)
             {
                 msgs[i].Headers.Add(
                     br.ReadString(),
                     br.ReadString()
                     );
             }
             var byteCount = br.ReadInt32();
             msgs[i].Data = br.ReadBytes(byteCount);
             if(string.IsNullOrEmpty(msgs[i].SubQueue))
                 msgs[i].SubQueue = null;
         }
         return msgs;
     }
 }
예제 #4
0
        public void MoveTo(string subqueue, Message message)
        {
            AssertNotDisposedOrDisposing();
            EnsureEnslistment();

            queueStorage.Global(actions =>
            {
                var queue = actions.GetQueue(message.Queue);
                var bookmark = queue.MoveTo(subqueue, (PersistentMessage)message);
                actions.RegisterUpdateToReverse(Enlistment.Id,
                    bookmark, MessageStatus.ReadyToDeliver,
                    message.SubQueue
                    );
                actions.Commit();
            });

            if(((PersistentMessage)message).Status == MessageStatus.ReadyToDeliver)
                OnMessageReceived(message);

            var updatedMessage = new Message
                                     {
                                         Id = message.Id,
                                         Data = message.Data,
                                         Headers = message.Headers,
                                         Queue = message.Queue,
                                         SubQueue = subqueue,
                                         SentAt = message.SentAt
                                     };

            OnMessageQueuedForReceive(updatedMessage);
        }
예제 #5
0
        public MessageBookmark Enqueue(Message message)
        {
            var bm = new MessageBookmark { QueueName = queueName };
            using (var updateMsgs = new Update(session, msgs, JET_prep.Insert))
            {
                var messageStatus = MessageStatus.InTransit;
                var persistentMessage = message as PersistentMessage;
                if (persistentMessage != null)
                    messageStatus = persistentMessage.Status;

                Api.SetColumn(session, msgs, msgsColumns["timestamp"], message.SentAt.ToOADate());
                Api.SetColumn(session, msgs, msgsColumns["data"], message.Data);
                Api.SetColumn(session, msgs, msgsColumns["instance_id"], message.Id.SourceInstanceId.ToByteArray());
                Api.SetColumn(session, msgs, msgsColumns["msg_id"], message.Id.MessageIdentifier.ToByteArray());
                Api.SetColumn(session, msgs, msgsColumns["subqueue"], message.SubQueue, Encoding.Unicode);
                Api.SetColumn(session, msgs, msgsColumns["headers"], message.Headers.ToQueryString(), Encoding.Unicode);
                Api.SetColumn(session, msgs, msgsColumns["status"], (int)messageStatus);

                updateMsgs.Save(bm.Bookmark, bm.Size, out bm.Size);
            }
            if (string.IsNullOrEmpty(message.SubQueue) == false &&
                Subqueues.Contains(message.SubQueue) == false)
            {
                actions.AddSubqueueTo(queueName, message.SubQueue);
                subqueues = subqueues.Union(new[] { message.SubQueue }).ToArray();
            }

            logger.DebugFormat("Enqueuing msg to '{0}' with subqueue: '{1}'. Id: {2}", queueName,
                message.SubQueue,
                message.Id);
            changeNumberOfMessages(1);
            return bm;
        }
        public void WhenSendingDuplicateMessageTwiceWillGetItOnlyOnce()
        {
            var msg = new Message
            {
                Id = MessageId.GenerateRandom(),
                Queue = "h",
                Data = Encoding.Unicode.GetBytes("hello"),
                SentAt = DateTime.Now
            };
            for (int i = 0; i < 2; i++)
            {
                var wait = new ManualResetEvent(false);
                var sender = new Sender
                {
                    Destination = new Endpoint("localhost", 23456),
                    Failure = exception => Assert.False(true),
                    Success = () => null,
                    Messages = new[] { msg, },
                };
                sender.SendCompleted += () => wait.Set();
                sender.Send();
                wait.WaitOne();
            }

            using (var tx = new TransactionScope())
            {
                var message = queueManager.Receive("h", null);
                Assert.Equal("hello", Encoding.Unicode.GetString(message.Data));

                tx.Complete();
            }

            using (var tx = new TransactionScope())
            {
                Assert.Throws<TimeoutException>(() => queueManager.Receive("h", null, TimeSpan.Zero));

                tx.Complete();
            }
        }
 public static string OutboundInstanceName(this Endpoint endpoint, Message message)
 {
     return string.Format("{0}:{1}/{2}/{3}",
                          endpoint.Host, endpoint.Port, message.Queue, message.SubQueue)
         .TrimEnd('/');
 }
 public MessageEventArgs(Endpoint endpoint, Message message)
 {
     Endpoint = endpoint;
     Message = message;
 }
예제 #9
0
 private void OnMessageQueuedForReceive(Message message)
 {
     OnMessageQueuedForReceive(new MessageEventArgs(null, message));
 }
예제 #10
0
        public void MoveTo(string subqueue, Message message)
        {
            AssertNotDisposedOrDisposing();
            EnsureEnslistment();

            queueStorage.Global(actions =>
            {
                var queue = actions.GetQueue(message.Queue);
                var bookmark = queue.MoveTo(subqueue, (PersistentMessage)message);
                actions.RegisterUpdateToReverse(Enlistment.Id,
                    bookmark, MessageStatus.ReadyToDeliver,
                    message.SubQueue
                    );
                actions.Commit();
            });
        }
예제 #11
0
        public void WillTellSenderIfCommitFailed()
        {
            var acceptance = MockRepository.GenerateStub<IMessageAcceptance>();
            acceptance.Stub(x => x.Commit()).Throw(new InvalidOperationException());

            using (var reciever = new Receiver(endpointToListenTo, messages => acceptance))
            {
                reciever.CompletedRecievingMessages += () => wait.Set();
                reciever.Start();

                using (var client = new TcpClient())
                {
                    client.Connect(endpointToListenTo);
                    var stream = client.GetStream();
                    var serialize = new Message[0].Serialize();
                    stream.Write(BitConverter.GetBytes(serialize.Length), 0, 4);
                    stream.Write(serialize, 0, serialize.Length);

                    var buffer = new byte[ProtocolConstants.RecievedBuffer.Length];
                    stream.Read(buffer, 0, buffer.Length);

                    Assert.Equal(ProtocolConstants.Recieved, Encoding.Unicode.GetString(buffer));

                    stream.Write(ProtocolConstants.AcknowledgedBuffer, 0, ProtocolConstants.AcknowledgedBuffer.Length);

                    buffer = new byte[ProtocolConstants.RevertBuffer.Length];
                    stream.Read(buffer, 0, buffer.Length);

                    Assert.Equal(ProtocolConstants.Revert, Encoding.Unicode.GetString(buffer));
                }

                wait.WaitOne();
            }
        }
예제 #12
0
        public void WillLetSenderKnowThatMessagesWereSentToInvalidQueue()
        {
            using (var reciever = new Receiver(endpointToListenTo, messages =>
            {
                throw new QueueDoesNotExistsException();
            }))
            {
                reciever.CompletedRecievingMessages += () => wait.Set();
                reciever.Start();

                using (var client = new TcpClient())
                {
                    client.Connect(endpointToListenTo);
                    var stream = client.GetStream();
                    var serialize = new Message[0].Serialize();
                    stream.Write(BitConverter.GetBytes(serialize.Length), 0, 4);
                    stream.Write(serialize, 0, serialize.Length);

                    var buffer = new byte[ProtocolConstants.ProcessingFailureBuffer.Length];
                    stream.Read(buffer, 0, buffer.Length);

                    Assert.Equal(ProtocolConstants.QueueDoesNotExists, Encoding.Unicode.GetString(buffer));
                }

                wait.WaitOne();
            }
        }
예제 #13
0
        public void WillCallAbortAcceptanceIfSenderSendNonConfirmation()
        {
            var acceptance = MockRepository.GenerateStub<IMessageAcceptance>();
            using (var reciever = new Receiver(endpointToListenTo, messages => acceptance))
            {
                reciever.CompletedRecievingMessages += () => wait.Set();
                reciever.Start();

                using (var client = new TcpClient())
                {
                    client.Connect(endpointToListenTo);
                    var stream = client.GetStream();
                    var serialize = new Message[0].Serialize();
                    stream.Write(BitConverter.GetBytes(serialize.Length), 0, 4);
                    stream.Write(serialize, 0, serialize.Length);

                    var buffer = new byte[ProtocolConstants.RecievedBuffer.Length];
                    stream.Read(buffer, 0, buffer.Length);

                    Assert.Equal(ProtocolConstants.Recieved, Encoding.Unicode.GetString(buffer));

                    var bytes = Encoding.Unicode.GetBytes("Unknowledged");
                    stream.Write(bytes, 0, bytes.Length);
                }

                wait.WaitOne();
            }

            acceptance.AssertWasCalled(x => x.Abort());
        }
예제 #14
0
 public void MoveTo(string subqueue, Message message)
 {
     queueManager.MoveTo(subqueue, message);
 }
 protected override IMessageAcceptance AcceptMessages(Message[] msgs)
 {
     throw new Exception("Cannot accept messages.");
 }
예제 #16
0
        public MessageId Send(Uri uri, MessagePayload payload)
        {
            if (waitingForAllMessagesToBeSent)
                throw new CannotSendWhileWaitingForAllMessagesToBeSentException("Currently waiting for all messages to be sent, so we cannot send. You probably have a race condition in your application.");

            EnsureEnslistment();
            var parts = uri.AbsolutePath.Substring(1).Split('/');
            var queue = parts[0];
            string subqueue = null;
            if (parts.Length > 1)
            {
                subqueue = string.Join("/", parts.Skip(1).ToArray());
            }

            Guid msgId = Guid.Empty;

            var port = uri.Port;
            if (port == -1)
                port = 2200;
            var destination = new Endpoint(uri.Host, port);

            queueStorage.Global(actions =>
            {
                msgId = actions.RegisterToSend(destination, queue,
                                               subqueue, payload, Enlistment.Id);

                actions.Commit();
            });

            var messageId = new MessageId
                                {
                                    SourceInstanceId = queueStorage.Id,
                                    MessageIdentifier = msgId
                                };
            var message = new Message
            {
                Id = messageId,
                Data = payload.Data,
                Headers = payload.Headers,
                Queue = queue,
                SubQueue = subqueue
            };

            OnMessageQueuedForSend(new MessageEventArgs(destination, message));

            return messageId;
        }
예제 #17
0
 protected virtual IMessageAcceptance AcceptMessages(Message[] msgs)
 {
     var bookmarks = new List<MessageBookmark>();
     queueStorage.Global(actions =>
     {
         foreach (var msg in receivedMsgs.Filter(msgs, message => message.Id))
         {
             var queue = actions.GetQueue(msg.Queue);
             var bookmark = queue.Enqueue(msg);
             bookmarks.Add(bookmark);
         }
         actions.Commit();
     });
     return new MessageAcceptance(this, bookmarks, msgs, queueStorage);
 }
 public static string InboundInstanceName(this IQueueManager queueManager, Message message)
 {
     return queueManager.InboundInstanceName(message.Queue, message.SubQueue);
 }
예제 #19
0
 private void OnMessageReceived(Message message)
 {
     OnMessageReceived(new MessageEventArgs(null, message));
 }
        private void TestEventUpdatesCorrectInstance(Action<IQueueManager> @event, Message message, string expectedInstanceName)
        {
            Setup();

            var e = new MessageEventArgs(new Endpoint("localhost", 123), message);
            queueManager.Raise(@event, null, e);

            Assert.Equal(expectedInstanceName, performanceMonitor.InstanceName);
        }