public void Multiple_Local_Services_Should_Be_Available()
        {
            ManualResetEvent _updateEvent = new ManualResetEvent(false);

            LocalBus.Subscribe <UpdateMessage>(msg => _updateEvent.Set());

            ManualResetEvent _deleteEvent = new ManualResetEvent(false);


            LocalBus.Subscribe <DeleteMessage>(
                delegate { _deleteEvent.Set(); });


            DeleteMessage dm = new DeleteMessage();

            LocalBus.Publish(dm);

            UpdateMessage um = new UpdateMessage();

            LocalBus.Publish(um);

            Assert.That(_deleteEvent.WaitOne(TimeSpan.FromSeconds(4), true), Is.True,
                        "Timeout expired waiting for message");

            Assert.That(_updateEvent.WaitOne(TimeSpan.FromSeconds(4), true), Is.True,
                        "Timeout expired waiting for message");
        }
예제 #2
0
        public void Adding_many_dynamic_and_removing_should_retain_dynamics()
        {
            var dynamicA = new FutureMessage <A>();
            var dynamicB = new FutureMessage <B>();
            var dynamicC = new FutureMessage <C>();
            var dynamicD = new FutureMessage <D>();

            UnsubscribeAction subscriptionA = RemoteBus.SubscribeHandler <A>(dynamicA.Set);
            UnsubscribeAction subscriptionB = RemoteBus.SubscribeHandler <B>(dynamicB.Set);
            UnsubscribeAction subscriptionC = RemoteBus.SubscribeHandler <C>(dynamicC.Set);
            UnsubscribeAction subscriptionD = RemoteBus.SubscribeHandler <D>(dynamicD.Set);

            LocalBus.HasSubscription <D>(8.Seconds()).Any().ShouldBeTrue("No D subscription");
            try
            {
                subscriptionA().ShouldBeFalse("A static not remaining");
                subscriptionB().ShouldBeFalse("B static not remaining");
                subscriptionC().ShouldBeFalse("C static not remaining");

                LocalBus.Publish(new A());
                LocalBus.Publish(new B());
                LocalBus.Publish(new C());
                LocalBus.Publish(new D());

                _receivedA.IsAvailable(8.Seconds()).ShouldBeTrue("A not received");
                _receivedB.IsAvailable(8.Seconds()).ShouldBeTrue("B not received");
                _receivedC.IsAvailable(8.Seconds()).ShouldBeTrue("C not received");
                dynamicD.IsAvailable(8.Seconds()).ShouldBeTrue("D should have been received");
            }
            finally
            {
                subscriptionD();
            }
        }
        public void The_message_should_be_delivered_to_a_remote_subscriber_with_a_reply()
        {
            ManualResetEvent _updateEvent = new ManualResetEvent(false);

            Action <UpdateMessage> handler =
                msg =>
            {
                _updateEvent.Set();

                RemoteBus.Publish(new UpdateAcceptedMessage());
            };

            ManualResetEvent _repliedEvent = new ManualResetEvent(false);

            RemoteBus.Subscribe(handler);

            LocalBus.Subscribe <UpdateAcceptedMessage>(
                delegate { _repliedEvent.Set(); });

            UpdateMessage um = new UpdateMessage();

            LocalBus.Publish(um);

            Assert.That(_updateEvent.WaitOne(TimeSpan.FromSeconds(3), true), Is.True,
                        "Timeout expired waiting for message");

            Assert.That(_repliedEvent.WaitOne(TimeSpan.FromSeconds(3), true), Is.True, "NO response message received");
        }
예제 #4
0
        protected override void EstablishContext()
        {
            base.EstablishContext();

            _ping   = new PingMessage();
            _future = new FutureMessage <PingMessage, Guid>(_ping.CorrelationId);

            _unsubscribe = RemoteBus.SubscribeHandler <PingMessage>(message => { _future.Set(message); });


            RemoteBus.ShouldHaveRemoteSubscriptionFor <PingMessage>();

            LocalBus.ShouldHaveRemoteSubscriptionFor <PingMessage>();

            Trace.WriteLine("LocalBus");

            LocalBus.OutboundPipeline.Trace();

            Trace.WriteLine("RemoteBus");

            RemoteBus.OutboundPipeline.Trace();


            LocalBus.Publish(_ping);
        }
예제 #5
0
        public void Perform_a_large_request_response_pool()
        {
            const int repeatCount = 20000;

            int responsesReceived = 0;

            ManualResetEvent completed = new ManualResetEvent(false);

            LocalBus.Subscribe <PingMessage>(x => CurrentMessage.Respond(new PongMessage(x.CorrelationId)));
            LocalBus.Subscribe <PongMessage>(x =>
            {
                if (Interlocked.Increment(ref responsesReceived) == repeatCount)
                {
                    completed.Set();
                }
            });

            Thread.Sleep(3.Seconds());

            Stopwatch stopwatch = Stopwatch.StartNew();

            for (int index = 0; index < repeatCount; index++)
            {
                LocalBus.Publish(new PingMessage());
            }

            bool success = completed.WaitOne(60.Seconds(), true);

            stopwatch.Stop();

            Trace.WriteLine(string.Format("Elapsed Time for {0} messages = {1}", repeatCount * 2, stopwatch.Elapsed));
            Trace.WriteLine(string.Format("Messages Per Second = {0}", repeatCount * 2000 / stopwatch.ElapsedMilliseconds));
        }
예제 #6
0
        public void It_should_only_be_handled_once()
        {
            LocalBus.InboundPipeline.Trace();

            LocalBus.Publish(new TopLevelClass
            {
                Priority = 1,
                Text     = "Special"
            });

            _first.WaitUntilCompleted(8.Seconds()).ShouldBeTrue("First");
            _second.WaitUntilCompleted(8.Seconds()).ShouldBeTrue("Second");
            _third.WaitUntilCompleted(8.Seconds()).ShouldBeTrue("Third");

            while (_receiveEvent.WaitOne(8.Seconds()))
            {
                ;
            }

            for (int i = 0; i < _exceptions.Count; i++)
            {
                Console.WriteLine("Exception: {0}", _exceptions[i].Message);
            }

            _exceptions.Count.ShouldEqual(0, "Some messages were received more than once");
        }
예제 #7
0
        public void Should_contain_two_messages_should_be_correlated_by_tag_and_id()
        {
            Guid timeoutId = Guid.NewGuid();

            LocalBus.Publish(new ScheduleTimeout(timeoutId, 10.Seconds(), 1));

            TimeoutSaga firstTimeout = _timeoutSagaRepository.ShouldContainSaga(x => x.TimeoutId == timeoutId && x.Tag == 1);

            firstTimeout.ShouldBeInState(TimeoutSaga.WaitingForTime);

            LocalBus.Publish(new CancelTimeout {
                CorrelationId = timeoutId, Tag = 1
            });

            LocalBus.Publish(new ScheduleTimeout(timeoutId, 10.Seconds(), 2));
            TimeoutSaga secondTimeout = _timeoutSagaRepository.ShouldContainSaga(x => x.TimeoutId == timeoutId && x.Tag == 2);

            secondTimeout.ShouldBeInState(TimeoutSaga.WaitingForTime);

            firstTimeout.ShouldBeInState(TimeoutSaga.Completed);

            Trace.WriteLine("Sagas:");
            foreach (TimeoutSaga saga in _timeoutSagaRepository.Where(x => true))
            {
                Trace.WriteLine("Saga: " + saga.CorrelationId + ", TimeoutId: " + saga.TimeoutId + ", Tag: " + saga.Tag +
                                ", State: " + saga.CurrentState.Name);
            }
        }
예제 #8
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()));
        }
예제 #9
0
        public void Should_scale_threads_to_meet_demand()
        {
            var now     = DateTime.Now;
            var latency = new List <long>();

            for (int i = 0; i < 100; i++)
            {
                var timer = Stopwatch.StartNew();
                LocalBus.Publish(new A());
                Assert.IsTrue(_before.WaitOne(30.Seconds()), "Consumer thread failed to start");
                timer.Stop();
                latency.Add(timer.ElapsedMilliseconds);
            }

            Console.WriteLine("Average latency: {0}ms", latency.Average());

            _wait.Set();

            for (int i = 0; i < 100; i++)
            {
                Assert.IsTrue(_after.WaitOne(30.Seconds()), "Consumer thread failed to complete");
            }

            Console.WriteLine("Elapsed Time: {0}", DateTime.Now - now);
        }
예제 #10
0
        public void Should_process_the_saga_normally()
        {
            Guid transactionId = NewId.NextGuid();

            Trace.WriteLine("Creating transaction for " + transactionId);

            int startValue = 1;

            var startConcurrentSaga = new StartConcurrentSaga
            {
                CorrelationId = transactionId, Name = "Chris", Value = startValue
            };

            LocalBus.Publish(startConcurrentSaga);
            Trace.WriteLine("Just published the start message");

            _sagaRepository.ShouldContainSaga(transactionId).ShouldNotBeNull();

            int nextValue = 2;
            var continueConcurrentSaga = new ContinueConcurrentSaga {
                CorrelationId = transactionId, Value = nextValue
            };

            LocalBus.Publish(continueConcurrentSaga);
            Trace.WriteLine("Just published the continue message");

            ConcurrentSaga saga = _sagaRepository
                                  .ShouldContainSaga(x => x.CorrelationId == transactionId && x.Value == nextValue);

            saga.ShouldNotBeNull();
            saga.ShouldBeInState(ConcurrentSaga.Completed);
        }
예제 #11
0
        public void A_response_should_be_published_if_no_reply_address_is_specified()
        {
            PingMessage ping = new PingMessage();

            TestMessageConsumer <PongMessage> otherConsumer = new TestMessageConsumer <PongMessage>();

            RemoteBus.Subscribe(otherConsumer);

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

            LocalBus.Subscribe(consumer);

            FutureMessage <PongMessage> pong = new FutureMessage <PongMessage>();

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

                CurrentMessage.Respond(pong.Message);
            });

            LocalBus.Publish(ping);

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

            consumer.ShouldHaveReceivedMessage(pong.Message, 3.Seconds());
            otherConsumer.ShouldHaveReceivedMessage(pong.Message, 1.Seconds());
        }
예제 #12
0
        protected override void EstablishContext()
        {
            base.EstablishContext();
            _faultFuture = new FutureMessage <Fault <PingMessage, Guid> >();

            LocalBus.SubscribeHandler <PingMessage>(message =>
            {
                using (new TransactionScope())
                {
                }
            });
            LocalBus.SubscribeHandler <Fault <PingMessage, Guid> >(message =>
            {
                if (_faultFuture.IsAvailable(TimeSpan.Zero))
                {
                    return;
                }

                _faultFuture.Set(message);
            });

            LocalBus.ShouldHaveRemoteSubscriptionFor <PingMessage>();
            LocalBus.ShouldHaveRemoteSubscriptionFor <Fault <PingMessage, Guid> >();

            _ping = new PingMessage();

            LocalBus.Publish(_ping);
        }
예제 #13
0
        public void Should_process_the_messages_in_order_and_not_at_the_same_time()
        {
            Guid transactionId = NewId.NextGuid();

            Trace.WriteLine("Creating transaction for " + transactionId);

            int startValue = 1;

            var startConcurrentSaga = new StartConcurrentSaga
            {
                CorrelationId = transactionId, Name = "Chris", Value = startValue
            };

            LocalBus.Publish(startConcurrentSaga);
            LocalBus.Publish(startConcurrentSaga);
            Trace.WriteLine("Just published the start message");

            _sagaRepository.ShouldContainSaga(transactionId).ShouldNotBeNull();

            int nextValue = 2;
            var continueConcurrentSaga = new ContinueConcurrentSaga {
                CorrelationId = transactionId, Value = nextValue
            };

            LocalBus.Publish(continueConcurrentSaga);
            Trace.WriteLine("Just published the continue message");

            _sagaRepository.ShouldContainSaga(x => x.CorrelationId == transactionId && x.Value == nextValue).
            ShouldNotBeNull();

            Thread.Sleep(8000);

            LocalEndpoint.ShouldNotContain <StartConcurrentSaga>();
            LocalErrorEndpoint.ShouldContain <StartConcurrentSaga>();
        }
예제 #14
0
 public void A_message_is_published()
 {
     LocalBus.Publish(new A
     {
         StringA = "ValueA",
     });
 }
        public void Multiple_messages_should_be_delivered_to_the_appropriate_remote_subscribers()
        {
            ManualResetEvent _updateEvent = new ManualResetEvent(false);

            RemoteBus.Subscribe <UpdateMessage>(
                delegate { _updateEvent.Set(); });

            ManualResetEvent _deleteEvent = new ManualResetEvent(false);

            RemoteBus.Subscribe <DeleteMessage>(
                delegate { _deleteEvent.Set(); });

            DeleteMessage dm = new DeleteMessage();

            LocalBus.Publish(dm);

            UpdateMessage um = new UpdateMessage();

            LocalBus.Publish(um);

            Assert.That(_deleteEvent.WaitOne(TimeSpan.FromSeconds(6), true), Is.True,
                        "Timeout expired waiting for message");

            Assert.That(_updateEvent.WaitOne(TimeSpan.FromSeconds(6), true), Is.True,
                        "Timeout expired waiting for message");
        }
예제 #16
0
        public void Should_process_the_messages_in_order_and_not_at_the_same_time()
        {
            UnsubscribeAction unsubscribeAction = LocalBus.SubscribeSaga(_sagaRepository);

            Guid transactionId = NewId.NextGuid();

            Trace.WriteLine("Creating transaction for " + transactionId);

            int startValue = 1;

            var startConcurrentSaga = new StartConcurrentSaga
            {
                CorrelationId = transactionId, Name = "Chris", Value = startValue
            };

            LocalBus.Publish(startConcurrentSaga);

            var saga = _sagaRepository.ShouldContainSaga(transactionId, 8.Seconds());

            Assert.IsNotNull(saga);

            int nextValue = 2;
            var continueConcurrentSaga = new ContinueConcurrentSaga {
                CorrelationId = transactionId, Value = nextValue
            };

            LocalBus.Publish(continueConcurrentSaga);

            saga = _sagaRepository.ShouldContainSaga(x => x.CorrelationId == transactionId && x.Value == nextValue, 8.Seconds());
            Assert.IsNotNull(saga);

            unsubscribeAction();

            Assert.AreEqual(nextValue, saga.Value);
        }
예제 #17
0
        public void The_retry_count_should_be_set_on_the_message()
        {
            FutureMessage <PingMessage> future = new FutureMessage <PingMessage>();

            bool first = true;

            LocalBus.Subscribe <PingMessage>(message =>
            {
                if (first)
                {
                    Assert.AreEqual(0, CurrentMessage.Headers.RetryCount);

                    CurrentMessage.RetryLater();

                    first = false;
                }
                else
                {
                    Assert.AreEqual(1, CurrentMessage.Headers.RetryCount);

                    future.Set(message);
                }
            });

            LocalBus.Publish(new PingMessage());

            Assert.IsTrue(future.IsAvailable(5.Seconds()));
        }
예제 #18
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());
        }
예제 #19
0
        protected override void EstablishContext()
        {
            base.EstablishContext();

            LocalBus.Publish <IProxyMe>(new { IntValue = _intValue, StringValue = _stringValue, CorrelationId = _correlationId });

            _received.IsAvailable(8.Seconds());
        }
예제 #20
0
 public void If_endpoint_down_a_heartbeat_should_revive()
 {
     MakeSagaDown();
     Repository.Where(x => x.CurrentState == HealthSaga.Down).Count().ShouldEqual(1);
     LocalBus.Publish(new Heartbeat(_id, LocalBus.ControlBus.Endpoint.Uri, LocalBus.Endpoint.Uri, 0));
     Thread.Sleep(1500);
     Repository.Where(x => x.CurrentState == HealthSaga.Healthy).Count().ShouldEqual(1);
 }
예제 #21
0
        public void If_a_saga_is_suspect_a_pong_should_fix()
        {
            MakeSagaSuspect();

            LocalBus.Publish(new PingEndpointResponse(_id, LocalBus.ControlBus.Endpoint.Uri, LocalBus.Endpoint.Uri, 0));
            Thread.Sleep(500);
            Repository.Where(x => x.CurrentState == HealthSaga.Healthy).Count().ShouldEqual(1);
        }
예제 #22
0
        public void Should_receive_a_message_in_scope()
        {
            const string name = "Joe";

            LocalBus.Publish(new SimpleMessageClass(name));

            CheckScopeConsumer.Last.Name.ShouldEqual(name);
        }
예제 #23
0
        protected override void EstablishContext()
        {
            base.EstablishContext();

            RemoteBus.ShouldHaveSubscriptionFor <MyMessage>();

            LocalBus.Publish(new MyMessage());
        }
예제 #24
0
        public void Should_have_received_a()
        {
            var message = new A();

            LocalBus.Publish(message);

            TestConsumerBase <A> .OnlyOneShouldHaveReceivedMessage(message, 8.Seconds());
        }
예제 #25
0
 public void A_message_is_published()
 {
     LocalBus.Publish(new Nobody_listening_parent
     {
         StringA = "ValueA",
         StringB = "ValueB",
     });
 }
        public void A_dynamically_correlated_message_is_published()
        {
            Message = new ApproveSimpleCustomer()
            {
                CustomerId = CustomerId,
            };

            LocalBus.Publish(Message);
        }
        public void A_message_is_published()
        {
            _message = new A
            {
                StringA = "ValueA",
            };

            LocalBus.Publish(_message);
        }
예제 #28
0
        public void A_reactive_query_is_observing_a_bus_message()
        {
            _observable = LocalBus.AsObservable <PingMessage>();

            _thatJustHappened = new Future <PingMessage>();
            _subscription     = _observable.Subscribe(m => _thatJustHappened.Complete(m));

            LocalBus.Publish(new PingMessage());
        }
예제 #29
0
        public void Should_properly_encapsulate_the_consumer_invocation()
        {
            LocalBus.Publish(new A());

            MyConsumer.Called.IsAvailable(8.Seconds()).ShouldBeTrue();

            _first.IsAvailable(8.Seconds()).ShouldBeTrue("Interceptor not called first");
            _second.IsAvailable(8.Seconds()).ShouldBeTrue("Interceptor not called second");
        }
        public void A_start_message_is_received()
        {
            Message = new StartSimpleSaga
            {
                CorrelationId = SagaId,
                CustomerId    = CustomerId,
            };

            LocalBus.Publish(Message);
        }