예제 #1
0
        public void Should_throw_an_exception_if_a_fault_was_published()
        {
            var pongReceived  = new FutureMessage <PongMessage>();
            var faultReceived = new FutureMessage <Fault <PingMessage> >();
            var pingReceived  = new FutureMessage <PingMessage>();

            RemoteBus.SubscribeContextHandler <PingMessage>(x =>
            {
                pingReceived.Set(x.Message);

                throw new InvalidOperationException("This should carry over to the calling request");
            });
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = Debugger.IsAttached ? 5.Minutes() : 24.Seconds();

            LocalBus.PublishRequest(ping, x =>
            {
                x.Handle <PongMessage>(pongReceived.Set);
                x.HandleFault(faultReceived.Set);

                x.SetTimeout(timeout);
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            faultReceived.IsAvailable(timeout).ShouldBeTrue("The fault was not received");
            pongReceived.IsAvailable(1.Seconds()).ShouldBeFalse("The pong was not received");
        }
예제 #2
0
        public void Should_support_send_as_well()
        {
            var pongReceived = new FutureMessage <PongMessage>();
            var pingReceived = new FutureMessage <PingMessage>();

            RemoteBus.SubscribeContextHandler <PingMessage>(x =>
            {
                pingReceived.Set(x.Message);
                x.Respond(new PongMessage {
                    TransactionId = x.Message.TransactionId
                });
            });
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 8.Seconds();

            RemoteBus.Endpoint.SendRequest(ping, LocalBus, x =>
            {
                x.Handle <PongMessage>(message =>
                {
                    message.TransactionId.ShouldEqual(ping.TransactionId,
                                                      "The response correlationId did not match");
                    pongReceived.Set(message);
                });

                x.SetTimeout(timeout);
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeTrue("The pong was not received");
        }
예제 #3
0
        public void Should_throw_a_timeout_exception_for_async_when_end_is_called()
        {
            var pongReceived   = new FutureMessage <PongMessage>();
            var pingReceived   = new FutureMessage <PingMessage>();
            var callbackCalled = new FutureMessage <IAsyncResult>();

            RemoteBus.SubscribeHandler <PingMessage>(pingReceived.Set);
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 2.Seconds();

            LocalBus.BeginPublishRequest(ping, callbackCalled.Set, null, x =>
            {
                x.Handle <PongMessage>(pongReceived.Set);

                x.SetTimeout(timeout);
            });

            callbackCalled.IsAvailable(8.Seconds()).ShouldBeTrue("Callback was not invoked");

            Assert.Throws <RequestTimeoutException>(
                () => { LocalBus.EndPublishRequest <PingMessage>(callbackCalled.Message); },
                "A timeout exception should have been thrown");

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeFalse("The pong should not have been received");
        }
예제 #4
0
        public void The_retry_count_should_be_set_on_the_message()
        {
            var future = new FutureMessage <PingMessage>();

            bool first = true;

            LocalBus.SubscribeHandler <PingMessage>(message =>
            {
                if (first)
                {
                    Assert.AreEqual(0, LocalBus.Context().RetryCount);

                    LocalBus.MessageContext <PingMessage>().RetryLater();

                    first = false;
                }
                else
                {
                    Assert.AreEqual(1, LocalBus.Context().RetryCount);

                    future.Set(message);
                }
            });

            LocalBus.ShouldHaveRemoteSubscriptionFor <PingMessage>();

            LocalBus.Publish(new PingMessage());

            Assert.IsTrue(future.IsAvailable(20.Seconds()));
        }
예제 #5
0
        public void Should_not_complete_timeout_if_handler_completes()
        {
            var pongReceived   = new FutureMessage <PongMessage>();
            var continueCalled = new FutureMessage <Task <PongMessage> >();
            var timeoutCalled  = new FutureMessage <PingMessage>();

            TimeSpan timeout = 8.Seconds();

            var ping = new PingMessage();
            ITaskRequest <PingMessage> request = LocalBus.PublishRequestAsync(ping, x =>
            {
                x.HandleTimeout(4.Seconds(), timeoutCalled.Set);

                x.Handle <PongMessage>(pongReceived.Set)
                .ContinueWith(continueCalled.Set);
            });

            pongReceived.IsAvailable(timeout).ShouldBeTrue("The pong was not received");

            request.Task.Wait(timeout).ShouldBeTrue("Task was not completed");

            request.GetResponseTask <PongMessage>().Wait(timeout).ShouldBeTrue("The response task was not completed");

            continueCalled.IsAvailable(timeout).ShouldBeTrue("The continuation was not called");

            timeoutCalled.IsAvailable(2.Seconds()).ShouldBeFalse("The timeout should not have been called");
        }
예제 #6
0
        public void Should_throw_a_timeout_exception_if_no_response_received()
        {
            var pongReceived = new FutureMessage <PongMessage>();
            var pingReceived = new FutureMessage <PingMessage>();

            RemoteBus.SubscribeHandler <PingMessage>(pingReceived.Set);
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 2.Seconds();

            Assert.Throws <RequestTimeoutException>(() =>
            {
                LocalBus.PublishRequest(ping, x =>
                {
                    x.Handle <PongMessage>(pongReceived.Set);

                    x.SetTimeout(timeout);
                });
            }, "A timeout exception should have been thrown");

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeFalse("The pong should not have been received");
        }
예제 #7
0
        public void Should_call_timeout_callback_if_timeout_occurs()
        {
            var pongCompleted = new FutureMessage <PongMessage>();
            var pongCancelled = new FutureMessage <bool>();

            Task <PongMessage> pongTask;

            var ping = new PingMessage();
            ITaskRequest <PingMessage> request = LocalBus.PublishRequestAsync(ping, x =>
            {
                x.SetTimeout(1.Seconds());

                pongTask = x.Handle <PongMessage>(message => { });
                pongTask.ContinueWith(t => pongCompleted.Set(t.Result), TaskContinuationOptions.OnlyOnRanToCompletion);
                pongTask.ContinueWith((Task t) => pongCancelled.Set(t.IsCanceled), TaskContinuationOptions.OnlyOnCanceled);
            });

            var aggregateException = Assert.Throws <AggregateException>(() => request.Task.Wait(8.Seconds()));

            Assert.IsInstanceOf <RequestTimeoutException>(aggregateException.InnerExceptions.First());

            pongCompleted.IsAvailable(1.Seconds()).ShouldBeFalse("We only asked to be notified on success");

            pongCancelled.IsAvailable(1.Seconds()).ShouldBeTrue("We like to know we were cancelled due to timeout");
        }
예제 #8
0
        public void Should_use_a_clean_syntax_following_standard_conventions()
        {
            var pongReceived = new FutureMessage <PongMessage>();
            var pingReceived = new FutureMessage <PingMessage>();

            RemoteBus.SubscribeContextHandler <PingMessage>(x =>
            {
                pingReceived.Set(x.Message);
                x.Respond(new PongMessage {
                    TransactionId = x.Message.TransactionId
                });
            });
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 8.Seconds();

            LocalBus.PublishRequest(ping, x =>
            {
                x.Handle <PongMessage>(message =>
                {
                    message.TransactionId.ShouldEqual(ping.TransactionId,
                                                      "The response correlationId did not match");
                    pongReceived.Set(message);
                });

                x.SetTimeout(timeout);
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeTrue("The pong was not received");
        }
예제 #9
0
        public void A_response_should_be_sent_directly_if_a_reply_address_is_specified()
        {
            var ping = new PingMessage();

            var otherConsumer = new TestMessageConsumer <PongMessage>();

            RemoteBus.SubscribeInstance(otherConsumer);

            var consumer = new TestCorrelatedConsumer <PongMessage, Guid>(ping.CorrelationId);

            LocalBus.SubscribeInstance(consumer);

            var pong = new FutureMessage <PongMessage>();

            RemoteBus.SubscribeHandler <PingMessage>(message =>
            {
                pong.Set(new PongMessage(message.CorrelationId));

                RemoteBus.Context().Respond(pong.Message);
            });

            RemoteBus.ShouldHaveRemoteSubscriptionFor <PongMessage>();
            LocalBus.ShouldHaveRemoteSubscriptionFor <PongMessage>();
            LocalBus.ShouldHaveRemoteSubscriptionFor <PingMessage>();

            LocalBus.Publish(ping, context => context.SendResponseTo(LocalBus));

            Assert.IsTrue(pong.IsAvailable(8.Seconds()), "No pong generated");

            consumer.ShouldHaveReceivedMessage(pong.Message, 8.Seconds());
            otherConsumer.ShouldNotHaveReceivedMessage(pong.Message, 1.Seconds());
        }
예제 #10
0
        protected override void ConfigureLocalBus(IServiceBusConfigurator configurator)
        {
            base.ConfigureLocalBus(configurator);

            _received = new FutureMessage <IProxyMe>();

            configurator.Subscribe(x => { x.Handler <IProxyMe>((message) => _received.Set(message)); });
        }
예제 #11
0
        protected override void EstablishContext()
        {
            base.EstablishContext();

            LocalBus.ShouldHaveRemoteSubscriptionFor <PingMessage>();

            _pingReceived = new FutureMessage <PingMessage>();
        }
예제 #12
0
        public void A_consumer_type_should_be_created_to_receive_the_message()
        {
            var fm = new FutureMessage <PingMessage>();

            LocalBus.SubscribeConsumer <PingHandler>(() => new PingHandler(fm));
            RemoteBus.ShouldHaveSubscriptionFor <PingMessage>();

            int old = PingHandler.Pinged;

            RemoteBus.Publish(new PingMessage());
            fm.IsAvailable(1.Seconds());
            Assert.That(PingHandler.Pinged, Is.GreaterThan(old));
        }
예제 #13
0
        public void A_consumer_object_should_receive_the_message()
        {
            var fm      = new FutureMessage <PingMessage>();
            var handler = new PingHandler(fm);

            LocalBus.SubscribeInstance(handler);
            RemoteBus.ShouldHaveSubscriptionFor <PingMessage>();

            int old = PingHandler.Pinged;

            RemoteBus.Publish(new PingMessage());
            fm.IsAvailable(1.Seconds());
            Assert.That(PingHandler.Pinged, Is.GreaterThan(old));
        }
예제 #14
0
        public void Should_call_timeout_callback_if_timeout_occurs_and_not_fault()
        {
            var continueCalled = new FutureMessage <PingMessage>();

            var ping = new PingMessage();
            ITaskRequest <PingMessage> request = LocalBus.PublishRequestAsync(ping, x =>
            {
                //
                x.HandleTimeout(1.Seconds(), continueCalled.Set);
            });

            request.Task.Wait(8.Seconds()).ShouldBeTrue("Should have completed successfully");

            continueCalled.IsAvailable(8.Seconds()).ShouldBeTrue("The timeout continuation was not called");
        }
예제 #15
0
        public void The_source_address_should_pass()
        {
            var received = new FutureMessage <PingMessage>();

            LocalBus.SubscribeHandler <PingMessage>(message =>
            {
                Assert.AreEqual(LocalBus.Endpoint.Address.Uri, LocalBus.Context().SourceAddress);

                received.Set(message);
            });

            LocalBus.Publish(new PingMessage());

            Assert.IsTrue(received.IsAvailable(5.Seconds()), "No message was received");
        }
        public void Subscring_to_an_endpoint_should_accept_and_dispatch_messages()
        {
            var  fm      = new FutureMessage <PingMessage>();
            bool workDid = false;

            LocalBus.SubscribeHandler <PingMessage>(
                (msg) => { workDid = true; fm.Set(msg); },
                delegate { return(true); });

            RemoteBus.ShouldHaveSubscriptionFor <PingMessage>();

            RemoteBus.Publish(_message);
            fm.IsAvailable(1.Seconds());
            Assert.That(workDid, Is.True, "Lazy Test!");
        }
예제 #17
0
        public void Should_request_an_instance_of_the_consumer_for_each_message()
        {
            var called = new FutureMessage <PingMessage>();

            var ping = new PingMessage();

            var getter = MockRepository.GenerateMock <HandlerSelector <PingMessage> >();

            getter.Expect(x => x(null)).IgnoreArguments().Return(x => called.Set(x.Message));

            LocalBus.SubscribeHandlerSelector(getter);

            LocalBus.Publish(ping);

            called.IsAvailable(3.Seconds()).ShouldBeTrue();
        }
예제 #18
0
        public void The_correlation_id_should_pass()
        {
            Guid id = Guid.NewGuid();

            var received = new FutureMessage <PingMessage>();

            LocalBus.SubscribeHandler <PingMessage>(message =>
            {
                Assert.AreEqual(id.ToString(), LocalBus.Context().CorrelationId);

                received.Set(message);
            });

            LocalBus.Publish(new PingMessage(), context => context.SetCorrelationId(id.ToString()));

            Assert.IsTrue(received.IsAvailable(5.Seconds()), "No message was received");
        }
예제 #19
0
        public void A_random_header_should_pass()
        {
            Guid id = Guid.NewGuid();

            var received = new FutureMessage <PingMessage>();

            LocalBus.SubscribeHandler <PingMessage>(message =>
            {
                Assert.AreEqual(id.ToString(), LocalBus.Context().Headers["RequestId"]);

                received.Set(message);
            });

            LocalBus.Publish(new PingMessage(), context => context.SetHeader("RequestId", id.ToString()));

            Assert.IsTrue(received.IsAvailable(5.Seconds()), "No message was received");
        }
예제 #20
0
        public void Should_throw_a_handler_exception_on_the_calling_thread_using_async()
        {
            var pongReceived   = new FutureMessage <PongMessage>();
            var pingReceived   = new FutureMessage <PingMessage>();
            var callbackCalled = new FutureMessage <IAsyncResult>();

            RemoteBus.SubscribeContextHandler <PingMessage>(x =>
            {
                pingReceived.Set(x.Message);
                x.Respond(new PongMessage {
                    TransactionId = x.Message.TransactionId
                });
            });
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 18.Seconds();

            LocalBus.BeginPublishRequest(ping, callbackCalled.Set, null, x =>
            {
                x.Handle <PongMessage>(message =>
                {
                    pongReceived.Set(message);

                    throw new InvalidOperationException("I got it, but I am naughty with it.");
                });

                x.SetTimeout(timeout);
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeTrue("The pong was not received");

            callbackCalled.IsAvailable(timeout).ShouldBeTrue("Called was not called");

            var exception =
                Assert.Throws <RequestException>(
                    () => { LocalBus.EndPublishRequest <PingMessage>(callbackCalled.Message); },
                    "A request exception should have been thrown");

            exception.Response.ShouldBeAnInstanceOf <PongMessage>();
            exception.InnerException.ShouldBeAnInstanceOf <InvalidOperationException>();
        }
예제 #21
0
        public void Should_support_the_asynchronous_programming_model()
        {
            var pongReceived   = new FutureMessage <PongMessage>();
            var pingReceived   = new FutureMessage <PingMessage>();
            var callbackCalled = new FutureMessage <IAsyncResult>();

            RemoteBus.SubscribeContextHandler <PingMessage>(x =>
            {
                pingReceived.Set(x.Message);
                x.Respond(new PongMessage {
                    TransactionId = x.Message.TransactionId
                });
            });
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 18.Seconds();

            LocalBus.BeginPublishRequest(ping, callbackCalled.Set, null, x =>
            {
                x.Handle <PongMessage>(message =>
                {
                    message.TransactionId.ShouldEqual(ping.TransactionId,
                                                      "The response correlationId did not match");
                    pongReceived.Set(message);
                });

                x.SetTimeout(timeout);
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeTrue("The pong was not received");

            callbackCalled.IsAvailable(timeout).ShouldBeTrue("The callback was not called");

            bool result = LocalBus.EndPublishRequest <PingMessage>(callbackCalled.Message);

            Assert.IsTrue(result, "EndRequest should be true");
        }
예제 #22
0
        public void Should_ignore_a_response_that_was_not_for_us()
        {
            var pongReceived = new FutureMessage <PongMessage>();
            var pingReceived = new FutureMessage <PingMessage>();
            var badResponse  = new FutureMessage <PongMessage>();

            LocalBus.SubscribeHandler <PongMessage>(pongReceived.Set);

            RemoteBus.SubscribeContextHandler <PingMessage>(x =>
            {
                RemoteBus.ShouldHaveRemoteSubscriptionFor <PongMessage>();

                pingReceived.Set(x.Message);
                RemoteBus.Publish(new PongMessage {
                    TransactionId = x.Message.TransactionId
                });
            });
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 8.Seconds();

            Assert.Throws <RequestTimeoutException>(() =>
            {
                RemoteBus.Endpoint.SendRequest(ping, LocalBus, x =>
                {
                    x.Handle <PongMessage>(badResponse.Set);

                    x.SetTimeout(timeout);
                });
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeTrue("The pong was not received");
            badResponse.IsAvailable(2.Seconds()).ShouldBeFalse("Should not have received a response");
        }
예제 #23
0
        public void Should_call_the_timeout_handler_and_not_throw_an_exception()
        {
            var pongReceived  = new FutureMessage <PongMessage>();
            var pingReceived  = new FutureMessage <PingMessage>();
            var timeoutCalled = new FutureMessage <bool>();

            RemoteBus.SubscribeHandler <PingMessage>(pingReceived.Set);
            LocalBus.ShouldHaveSubscriptionFor <PingMessage>();

            var ping = new PingMessage();

            TimeSpan timeout = 2.Seconds();

            LocalBus.PublishRequest(ping, x =>
            {
                x.Handle <PongMessage>(pongReceived.Set);

                x.HandleTimeout(timeout, () => timeoutCalled.Set(true));
            });

            pingReceived.IsAvailable(timeout).ShouldBeTrue("The ping was not received");
            pongReceived.IsAvailable(timeout).ShouldBeFalse("The pong should not have been received");
            timeoutCalled.IsAvailable(timeout).ShouldBeTrue("The timeout handler was not called");
        }
예제 #24
0
        protected override void EstablishContext()
        {
            base.EstablishContext();

            _pingReceived = new FutureMessage <PingMessage>();
        }
예제 #25
0
 public PingHandler(FutureMessage <PingMessage> fm)
 {
     _fm = fm;
 }