예제 #1
0
        public void WillCallBackAfterTimeHasElapsed()
        {
            var justSomeCorrelationId    = Guid.NewGuid().ToString();
            var justSomeSubCorrelationId = Guid.NewGuid().ToString();

            client.Send(new TimeoutRequest
            {
                CorrelationId = justSomeCorrelationId,
                CustomData    = justSomeSubCorrelationId,
                Timeout       = 2.Seconds()
            });
            var timeoutExpired = false;

            handlerActivator
            .Handle <TimeoutReply>(m =>
            {
                Assert.AreEqual(justSomeCorrelationId, m.CorrelationId, "Correlation ID was wrong");
                Assert.AreEqual(justSomeSubCorrelationId, m.CustomData, "Custom data was wrong");

                timeoutExpired = true;
            });

            Thread.Sleep(2.5.Seconds());

            timeoutExpired.ShouldBe(true);
        }
예제 #2
0
        public void CanMakeSimpleDeferralOfMessages()
        {
            // arrange
            var messages = new List <Tuple <string, DateTime> >();

            handlerActivator.Handle <MessageWithText>(m => messages.Add(new Tuple <string, DateTime>(m.Text, DateTime.UtcNow)));

            var timeOfDeferral    = DateTime.UtcNow;
            var acceptedTolerance = 2.Seconds();

            // act
            bus.Defer(10.Seconds(), new MessageWithText {
                Text = "deferred 10 seconds"
            });
            bus.Defer(5.Seconds(), new MessageWithText {
                Text = "deferred 5 seconds"
            });

            Thread.Sleep(10.Seconds() + acceptedTolerance + acceptedTolerance);

            // assert
            messages.Count.ShouldBe(2);
            messages[0].Item1.ShouldBe("deferred 5 seconds");
            messages[0].Item2.ElapsedSince(timeOfDeferral).ShouldBeGreaterThan(5.Seconds() - acceptedTolerance);
            messages[0].Item2.ElapsedSince(timeOfDeferral).ShouldBeLessThan(5.Seconds() + acceptedTolerance);

            messages[1].Item1.ShouldBe("deferred 10 seconds");
            messages[1].Item2.ElapsedSince(timeOfDeferral).ShouldBeGreaterThan(10.Seconds() - acceptedTolerance);
            messages[1].Item2.ElapsedSince(timeOfDeferral).ShouldBeLessThan(10.Seconds() + acceptedTolerance);
        }
예제 #3
0
        public void CanPreserveCustomHeadersOnDeferredMessage()
        {
            // arrange
            var deferredMessageReceived = new ManualResetEvent(false);
            IDictionary <string, object> receivedHeaders = null;

            handlerActivator.Handle <MessageWithText>(m =>
            {
                receivedHeaders = MessageContext.GetCurrent().Headers;

                deferredMessageReceived.Set();
            });

            var message = new MessageWithText {
                Text = "hello"
            };

            bus.AttachHeader(message, Headers.UserName, "joe");
            bus.AttachHeader(message, "test-custom1", "bimmelim!");
            bus.AttachHeader(message, "test-custom2", "w00t!");

            // act
            bus.Defer(1.Seconds(), message);
            deferredMessageReceived.WaitUntilSetOrDie(3.Seconds());

            // assert
            receivedHeaders.ShouldNotBe(null);
            receivedHeaders.ShouldContainKeyAndValue(Headers.UserName, "joe");
            receivedHeaders.ShouldContainKeyAndValue("test-custom1", "bimmelim!");
            receivedHeaders.ShouldContainKeyAndValue("test-custom2", "w00t!");
        }
예제 #4
0
        public void CanRequestReplyViaGateway()
        {
            // arrange
            var resetEvent = new ManualResetEvent(false);

            orderSystemHandlerActivator.Handle <JustSomeRequest>(req =>
            {
                Console.WriteLine("Got request for {0}", req.ForWhat);
                orderSystem.Reply(new JustSomeReply {
                    What = "you got " + req.ForWhat
                });
            });
            priceDeskHandlerActivator.Handle <JustSomeReply>(rep =>
            {
                Console.WriteLine("Got reply with {0}", rep.What);
                resetEvent.Set();
            });

            // act
            priceDesk.Send(new JustSomeRequest {
                ForWhat = "beers!!!11 what else????"
            });

            // assert
            var timeout = 5.Seconds();

            Assert.That(resetEvent.WaitOne(timeout), Is.True, "Oh noes, reset event wasn't set within timeout of {0}", timeout);
        }
예제 #5
0
        public void DoesNotReturnTheSameTimeoutMultipleTimes()
        {
            // arrange
            var receivedCorrelationIds      = new List <string>();
            var correlationIdWeCanRecognize = Guid.NewGuid().ToString();

            handlerActivator.Handle <TimeoutReply>(reply => receivedCorrelationIds.Add(reply.CorrelationId));

            // act
            client.Send(new TimeoutRequest
            {
                CorrelationId = correlationIdWeCanRecognize,
                Timeout       = 2.Seconds(),
            });
            Thread.Sleep(5.Seconds());

            // assert
            receivedCorrelationIds.Count.ShouldBe(1);
        }
예제 #6
0
        public void MessageHandlingIsTransactional()
        {
            // arrange
            const string senderQueue     = "test.commitrollback.sender";
            const string middlemanQueue  = "test.commitrollback.middleman";
            const string recipient1Queue = "test.commitrollback.recipient1";
            const string recipient2Queue = "test.commitrollback.recipient2";

            // sender
            var sender = factory.CreateBus(senderQueue, new HandlerActivatorForTesting());

            // middleman
            var failCounter = 0;
            var middlemanHandlerActivator = new HandlerActivatorForTesting();
            var middleman = factory.CreateBus(middlemanQueue, middlemanHandlerActivator);

            middlemanHandlerActivator.Handle <string>(str =>
            {
                failCounter++;

                middleman.Advanced.Routing.Send(recipient1Queue, string.Format("mr. 1, this is my fail count: {0}", failCounter));
                middleman.Advanced.Routing.Send(recipient2Queue, string.Format("mr. 2, this is my fail count: {0}", failCounter));

                if (failCounter < 3)
                {
                    throw new ApplicationException("oh noes!!!!");
                }
            });

            // two recipients
            var recipient1Received = new List <string>();
            var recipient2Received = new List <string>();

            factory.CreateBus(recipient1Queue, new HandlerActivatorForTesting().Handle <string>(recipient1Received.Add));
            factory.CreateBus(recipient2Queue, new HandlerActivatorForTesting().Handle <string>(recipient2Received.Add));

            factory.StartAll();

            Thread.Sleep(0.5.Seconds());

            // act
            sender.Advanced.Routing.Send(middlemanQueue, "hello there my man!");

            Thread.Sleep(2.Seconds());

            // assert
            failCounter.ShouldBe(3);
            recipient1Received.ShouldBe(new List <string> {
                "mr. 1, this is my fail count: 3"
            });
            recipient2Received.ShouldBe(new List <string> {
                "mr. 2, this is my fail count: 3"
            });
        }
예제 #7
0
        public void CanProperlyCommitUnitOfWork()
        {
            // arrange
            handlerActivatorForTesting.Handle <string>(str => unitOfWorkManager.RegisterEvent("Handled message: " + str));

            // act
            receiveMessages.Deliver(MessageWith("hello there!"));
            worker.Start();
            Thread.Sleep(500);
            worker.Stop();

            // assert
            unitOfWorkManager.Events
            .ShouldBe(new[]
            {
                "Unit of work created: 1",
                "Handled message: hello there!",
                "1: committed",
                "1: disposed",
            });
        }
예제 #8
0
        public void PricedeskCanSendOrdersToOrdersystemViaGateway()
        {
            // arrange
            var resetEvent = new ManualResetEvent(false);

            orderSystemHandlerActivator.Handle <PlaceOrderRequest>(req =>
            {
                if (req.What == "beer" && req.HowMuch == 12)
                {
                    resetEvent.Set();
                }
            });
            var timeout = 5.Seconds();

            // act
            pricedesk.Send(new PlaceOrderRequest {
                What = "beer", HowMuch = 12
            });

            // assert
            Assert.That(resetEvent.WaitOne(timeout), Is.True, "Request was not received in order system within timeout of {0}", timeout);
        }
예제 #9
0
        public void IgnoresAutoCorrelationWhenCorrelationIsExplicitlySetUp(bool abandonReply)
        {
            // arrange
            var anotherSaga = new AnotherSaga(sagaBus, abandonReply);

            sagaHandlerActivator.UseHandler(anotherSaga);

            serviceHandlerActivator.Handle <RequestWithCorrelationId>(req => serviceBus.Reply(new ReplyWithCorrelationId {
                Correlationid = req.Correlationid
            }));

            // act
            initiatorBus.Send(new InitiateRequestReply());
            Thread.Sleep(3.Seconds());

            // assert
            sagaPersister.Count().ShouldBe(1);
            var sagaData = sagaPersister.Single();

            sagaData.ShouldBeTypeOf <SomeSagaData>();
            ((SomeSagaData)sagaData).GotTheReply.ShouldBe(!abandonReply);
        }
        public void SendersInputQueueUsesGlobalAddressing()
        {
            // arrange
            var resetEvent    = new ManualResetEvent(false);
            var returnAddress = "";

            recipientHandlers.Handle <string>(s =>
            {
                returnAddress = MessageContext.GetCurrent().ReturnAddress;
                resetEvent.Set();
            });

            // act
            sender.Routing.Send(RecipientInputQueueName, "yo dawg!!");

            // assert
            Assert.That(resetEvent.WaitOne(1.Seconds()), Is.True, "The message was not received withing timeout of 1 second");
            returnAddress.ShouldBe(SenderInputQueueName + "@" + Environment.MachineName);
        }
예제 #11
0
        public void RequestReplyWorks()
        {
            var requestorGotMessageEvent = new ManualResetEvent(false);
            var requestorBus             = CreateBus(RequestorQueueName,
                                                     new HandlerActivatorForTesting().Handle <string>(
                                                         str => requestorGotMessageEvent.Set()));

            var replierHandlerFactory = new HandlerActivatorForTesting();
            var replierBus            = CreateBus(ReplierQueueName, replierHandlerFactory);

            replierHandlerFactory.Handle <string>(str => replierBus.Reply("pong!"));

            requestorBus.Start();
            replierBus.Start();
            requestorBus.Routing.Send(ReplierQueueName, "ping?");

            if (!requestorGotMessageEvent.WaitOne(TimeSpan.FromSeconds(3)))
            {
                Assert.Fail("Requestor did not receive a reply within timeout");
            }
        }
        public void RequestReplyWorks()
        {
            var requestorGotMessageEvent = new ManualResetEvent(false);
            var requestorBus = CreateBus(RequestorQueueName,
                                         new HandlerActivatorForTesting().Handle<string>(
                                             str => requestorGotMessageEvent.Set()));

            var replierHandlerFactory = new HandlerActivatorForTesting();
            var replierBus = CreateBus(ReplierQueueName, replierHandlerFactory);

            replierHandlerFactory.Handle<string>(str => replierBus.Reply("pong!"));

            requestorBus.Start();
            replierBus.Start();
            requestorBus.Routing.Send(ReplierQueueName, "ping?");

            if (!requestorGotMessageEvent.WaitOne(TimeSpan.FromSeconds(3)))
            {
                Assert.Fail("Requestor did not receive a reply within timeout");
            }
        }
예제 #13
0
        public void CanMoveMessageToErrorQueueForExceptionsInHooks(string whenToThrow)
        {
            // arrange
            var senderBus = CreateBus(SenderQueueName, new HandlerActivatorForTesting()).Start(1);
            var errorQueue = GetMessageQueue(ReceiverErrorQueueName);

            var activator = new HandlerActivatorForTesting().Handle<string>(s => { });
            var bus = CreateBus(ReceiverQueueName, activator,
                                new InMemorySubscriptionStorage(), new SagaDataPersisterForTesting(),
                                ReceiverErrorQueueName);

            switch (whenToThrow)
            {
                case "beforeTransport":
                    bus.Events.BeforeTransportMessage += (_, __) =>
                        {
                            throw new Exception("HELLO!");
                        };
                    break;

                case "afterTransport":
                    bus.Events.AfterTransportMessage += (_, __, ___) =>
                        {
                            throw new Exception("HELLO!");
                        };
                    break;

                case "beforeLogical":
                    bus.Events.BeforeMessage += (_, __) =>
                        {
                            throw new Exception("HELLO!");
                        };
                    break;

                case "afterLogical":
                    bus.Events.AfterMessage += (_, __, ___) =>
                        {
                            throw new Exception("HELLO!");
                        };
                    break;

                case "poison":
                    // make sure the poison event gets raised
                    activator.Handle<string>(str =>
                        {
                            throw new Exception("HELLO!");
                        });

                    bus.Events.PoisonMessage += (_, __, ___) =>
                        {
                            throw new Exception("HELLO!");
                        };
                    break;

                case "commitHook":
                    activator.Handle<string>(str => Transaction.Current
                                                        .EnlistVolatile(new ThingToEnlistThatWillFailOn(commit: true),
                                                                       EnlistmentOptions.None));
                    break;

                case "rollbackHook":
                    activator.Handle<string>(str =>
                        {
                            Transaction.Current
                                .EnlistVolatile(new ThingToEnlistThatWillFailOn(rollback: true),
                                                EnlistmentOptions.None);

                            throw new Exception("HELLO!");
                        });
                    break;

                case "prepareHook":
                    activator.Handle<string>(str => Transaction.Current
                                                        .EnlistVolatile(new ThingToEnlistThatWillFailOn(prepare: true),
                                                                       EnlistmentOptions.None));
                    break;

                case "inDoubtHook":
                    activator.Handle<string>(str => Transaction.Current
                                                        .EnlistVolatile(new ThingToEnlistThatWillFailOn(inDoubt: true),
                                                                       EnlistmentOptions.None));
                    break;
            }

            bus.Start(1);

            senderBus.Routing.Send(ReceiverQueueName, "HELLO!");

            var transportMessage = (ReceivedTransportMessage)errorQueue.Receive(TimeSpan.FromSeconds(3)).Body;
            var errorMessage = serializer.Deserialize(transportMessage);

            errorMessage.Messages[0].ShouldBe("HELLO!");

            errorMessage.GetHeader(Headers.SourceQueue).ShouldBe(ReceiverQueueName + "@" + Environment.MachineName);
            errorMessage.GetHeader(Headers.ErrorMessage).ShouldContain("System.Exception: HELLO!");
        }
예제 #14
0
        public void CanMoveMessageToErrorQueueForExceptionsInHooks(string whenToThrow)
        {
            // arrange
            var senderBus  = CreateBus(SenderQueueName, new HandlerActivatorForTesting()).Start(1);
            var errorQueue = GetMessageQueue(ReceiverErrorQueueName);

            var activator = new HandlerActivatorForTesting();
            var bus       = CreateBus(ReceiverQueueName, activator,
                                      new InMemorySubscriptionStorage(), new SagaDataPersisterForTesting(),
                                      ReceiverErrorQueueName);

            switch (whenToThrow)
            {
            case "beforeTransport":
                bus.Events.BeforeTransportMessage += (_, __) =>
                {
                    throw new Exception("HELLO!");
                };
                break;

            case "afterTransport":
                bus.Events.AfterTransportMessage += (_, __, ___) =>
                {
                    throw new Exception("HELLO!");
                };
                break;

            case "beforeLogical":
                bus.Events.BeforeMessage += (_, __) =>
                {
                    throw new Exception("HELLO!");
                };
                break;

            case "afterLogical":
                bus.Events.AfterMessage += (_, __, ___) =>
                {
                    throw new Exception("HELLO!");
                };
                break;

            case "poison":
                // make sure the poison event gets raised
                activator.Handle <string>(str =>
                {
                    throw new Exception("HELLO!");
                });

                bus.Events.PoisonMessage += (_, __) =>
                {
                    throw new Exception("HELLO!");
                };
                break;
            }

            bus.Start(1);

            senderBus.Routing.Send(ReceiverQueueName, "HELLO!");

            var transportMessage = (ReceivedTransportMessage)errorQueue.Receive(TimeSpan.FromSeconds(3)).Body;
            var errorMessage     = serializer.Deserialize(transportMessage);

            errorMessage.Messages[0].ShouldBe("HELLO!");

            errorMessage.GetHeader(Headers.SourceQueue).ShouldBe(ReceiverQueueName + "@" + Environment.MachineName);
            errorMessage.GetHeader(Headers.ErrorMessage).ShouldContain("System.Exception: HELLO!");
        }