Ejemplo n.º 1
0
        public void ShouldOnlySubscribeToUnderlyingSourcesOnce()
        {
            IMessageSource <IEvent>   source1     = A.Fake <IMessageSource <IEvent> >();
            IMessageSource <IMessage> source2     = A.Fake <IMessageSource <IMessage> >();
            IObservable <IEvent>      observable1 = A.Fake <IObservable <IEvent> >();
            IObservable <IMessage>    observable2 = A.Fake <IObservable <IMessage> >();
            IObserver <IMessage>      observer    = A.Fake <IObserver <IMessage> >();

            A.CallTo(() => source1.Messages).Returns(observable1);
            A.CallTo(() => source2.Messages).Returns(observable2);

            MergedMessageSource <IMessage> mergedMessageSource = new MergedMessageSource <IMessage>(new[] { source1, source2 });

            IDisposable sub1 = mergedMessageSource.Messages.OfType <IEvent>().Subscribe(observer);
            IDisposable sub2 = mergedMessageSource.Messages.OfType <IMessage>().Subscribe(observer);

            A.CallTo(() => source1.Messages).MustHaveHappened(Repeated.Exactly.Once);
            A.CallTo(() => observable1.Subscribe(A <IObserver <IMessage> > ._)).MustHaveHappened(Repeated.Exactly.Once);

            A.CallTo(() => source2.Messages).MustHaveHappened(Repeated.Exactly.Once);
            A.CallTo(() => observable2.Subscribe(A <IObserver <IMessage> > ._)).MustHaveHappened(Repeated.Exactly.Once);

            sub1.Dispose();
            sub2.Dispose();
        }
        private IMessageSource <TSourceMessage> GetMessageSource <TSourceMessage>() where TSourceMessage : class, TMessage
        {
            // Find mappings for source types thare are assignable from the target type
            var sourceMessageTypePathMappings = (from mtpm in _messageTypePathMappings
                                                 where (mtpm.MessagingEntityType == MessagingEntityType.Queue
                                                        ||
                                                        mtpm.MessagingEntityType == MessagingEntityType.Subscription)
                                                 &&
                                                 typeof(TSourceMessage).IsAssignableFrom(mtpm.MessageType)
                                                 select mtpm);

            IMessageSource <TSourceMessage> result;

            // If there's only one target path mapping for this message type then just return a single MessageSource<T> instance (avoid overhead of MergedMessageSource)
            if (sourceMessageTypePathMappings.Count() == 1)
            {
                result = CreateMessageSource <TSourceMessage>(sourceMessageTypePathMappings.First());
            }
            else
            {
                result = new MergedMessageSource <TSourceMessage>(sourceMessageTypePathMappings.Select(mtpm => CreateMessageSource <TSourceMessage>(mtpm)));
            }

            return(result);
        }
Ejemplo n.º 3
0
        public void ShouldReturnMessagesFromUnderlyingSources()
        {
            IMessageSource <IEvent>   source1           = A.Fake <IMessageSource <IEvent> >();
            IMessageSource <IMessage> source2           = A.Fake <IMessageSource <IMessage> >();
            IObservable <IEvent>      observable1       = A.Fake <IObservable <IEvent> >();
            IObservable <IMessage>    observable2       = A.Fake <IObservable <IMessage> >();
            IObserver <IMessage>      observer          = A.Fake <IObserver <IMessage> >();
            IObserver <IEvent>        internalObserver1 = null;
            IObserver <IMessage>      internalObserver2 = null;

            A.CallTo(() => source1.Messages).Returns(observable1);
            A.CallTo(() => source2.Messages).Returns(observable2);
            A.CallTo(() => observable1.Subscribe(A <IObserver <IEvent> > ._)).Invokes(call => internalObserver1   = call.GetArgument <IObserver <IEvent> >(0));
            A.CallTo(() => observable2.Subscribe(A <IObserver <IMessage> > ._)).Invokes(call => internalObserver2 = call.GetArgument <IObserver <IMessage> >(0));

            MergedMessageSource <IMessage> mergedMessageSource = new MergedMessageSource <IMessage>(new[] { source1, source2 });

            IDisposable sub1 = mergedMessageSource.Messages.OfType <IEvent>().Subscribe(observer);
            IDisposable sub2 = mergedMessageSource.Messages.OfType <IMessage>().Subscribe(observer);

            Assert.That(internalObserver1, Is.Not.Null);
            Assert.That(internalObserver2, Is.Not.Null);

            IEvent   ev1  = A.Fake <IEvent>();
            IMessage msg2 = A.Fake <IMessage>();

            internalObserver1.OnNext(ev1);
            internalObserver2.OnNext(msg2);

            A.CallTo(() => observer.OnNext(ev1)).MustHaveHappened(Repeated.Exactly.Twice);
            A.CallTo(() => observer.OnNext(msg2)).MustHaveHappened(Repeated.Exactly.Once);

            sub1.Dispose();
            sub2.Dispose();
        }
Ejemplo n.º 4
0
        public void ShouldOnlySubscribeToUnderlyingSourcesOnce()
        {
            IMessageSource<IEvent> source1 = A.Fake<IMessageSource<IEvent>>();
            IMessageSource<IMessage> source2 = A.Fake<IMessageSource<IMessage>>();
            IObservable<IEvent> observable1 = A.Fake<IObservable<IEvent>>();
            IObservable<IMessage> observable2 = A.Fake<IObservable<IMessage>>();
            IObserver<IMessage> observer = A.Fake<IObserver<IMessage>>();

            A.CallTo(() => source1.Messages).Returns(observable1);
            A.CallTo(() => source2.Messages).Returns(observable2);

            MergedMessageSource<IMessage> mergedMessageSource = new MergedMessageSource<IMessage>(new[] { source1, source2 });

            IDisposable sub1 = mergedMessageSource.Messages.OfType<IEvent>().Subscribe(observer);
            IDisposable sub2 = mergedMessageSource.Messages.OfType<IMessage>().Subscribe(observer);

            A.CallTo(() => source1.Messages).MustHaveHappened(Repeated.Exactly.Once);
            A.CallTo(() => observable1.Subscribe(A<IObserver<IMessage>>._)).MustHaveHappened(Repeated.Exactly.Once);

            A.CallTo(() => source2.Messages).MustHaveHappened(Repeated.Exactly.Once);
            A.CallTo(() => observable2.Subscribe(A<IObserver<IMessage>>._)).MustHaveHappened(Repeated.Exactly.Once);

            sub1.Dispose();
            sub2.Dispose();
        }
Ejemplo n.º 5
0
        public void ShouldDisposeUnderlyingSubscriptionOnlyWhenAllSubscriptionsDisposed()
        {
            IMessageSource <IEvent>   source1           = A.Fake <IMessageSource <IEvent> >();
            IMessageSource <IMessage> source2           = A.Fake <IMessageSource <IMessage> >();
            IObservable <IEvent>      observable1       = A.Fake <IObservable <IEvent> >();
            IObservable <IMessage>    observable2       = A.Fake <IObservable <IMessage> >();
            IObserver <IMessage>      observer          = A.Fake <IObserver <IMessage> >();
            IObserver <IEvent>        internalObserver1 = null;
            IObserver <IMessage>      internalObserver2 = null;

            A.CallTo(() => source1.Messages).Returns(observable1);
            A.CallTo(() => source2.Messages).Returns(observable2);
            A.CallTo(() => observable1.Subscribe(A <IObserver <IEvent> > ._)).Invokes(call => internalObserver1   = call.GetArgument <IObserver <IEvent> >(0));
            A.CallTo(() => observable2.Subscribe(A <IObserver <IMessage> > ._)).Invokes(call => internalObserver2 = call.GetArgument <IObserver <IMessage> >(0));

            MergedMessageSource <IMessage> mergedMessageSource = new MergedMessageSource <IMessage>(new[] { source1, source2 });

            IDisposable sub1 = mergedMessageSource.Messages.OfType <IEvent>().Subscribe(observer);
            IDisposable sub2 = mergedMessageSource.Messages.OfType <IMessage>().Subscribe(observer);

            Assert.That(internalObserver1, Is.Not.Null);
            Assert.That(internalObserver2, Is.Not.Null);

            IEvent   ev1  = A.Fake <IEvent>();
            IMessage msg1 = A.Fake <IMessage>();
            IMessage msg2 = A.Fake <IMessage>();

            internalObserver1.OnNext(ev1);
            A.CallTo(() => observer.OnNext(ev1)).MustHaveHappened(Repeated.Exactly.Twice);

            // dispose of first subscription
            sub1.Dispose();

            // second subscription should still be active
            internalObserver2.OnNext(msg1);
            A.CallTo(() => observer.OnNext(msg1)).MustHaveHappened(Repeated.Exactly.Once);

            // dispose of second subscription
            sub2.Dispose();

            // no subscriptions should be active
            internalObserver2.OnNext(msg2);
            A.CallTo(() => observer.OnNext(msg2)).MustNotHaveHappened();
        }
Ejemplo n.º 6
0
        public void ShouldDisposeUnderlyingSubscriptionOnlyWhenAllSubscriptionsDisposed()
        {
            IMessageSource<IEvent> source1 = A.Fake<IMessageSource<IEvent>>();
            IMessageSource<IMessage> source2 = A.Fake<IMessageSource<IMessage>>();
            IObservable<IEvent> observable1 = A.Fake<IObservable<IEvent>>();
            IObservable<IMessage> observable2 = A.Fake<IObservable<IMessage>>();
            IObserver<IMessage> observer = A.Fake<IObserver<IMessage>>();
            IObserver<IEvent> internalObserver1 = null;
            IObserver<IMessage> internalObserver2 = null;

            A.CallTo(() => source1.Messages).Returns(observable1);
            A.CallTo(() => source2.Messages).Returns(observable2);
            A.CallTo(() => observable1.Subscribe(A<IObserver<IEvent>>._)).Invokes(call => internalObserver1 = call.GetArgument<IObserver<IEvent>>(0));
            A.CallTo(() => observable2.Subscribe(A<IObserver<IMessage>>._)).Invokes(call => internalObserver2 = call.GetArgument<IObserver<IMessage>>(0));

            MergedMessageSource<IMessage> mergedMessageSource = new MergedMessageSource<IMessage>(new[] { source1, source2 });

            IDisposable sub1 = mergedMessageSource.Messages.OfType<IEvent>().Subscribe(observer);
            IDisposable sub2 = mergedMessageSource.Messages.OfType<IMessage>().Subscribe(observer);

            Assert.That(internalObserver1, Is.Not.Null);
            Assert.That(internalObserver2, Is.Not.Null);

            IEvent ev1 = A.Fake<IEvent>();
            IMessage msg1 = A.Fake<IMessage>();
            IMessage msg2 = A.Fake<IMessage>();

            internalObserver1.OnNext(ev1);
            A.CallTo(() => observer.OnNext(ev1)).MustHaveHappened(Repeated.Exactly.Twice);

            // dispose of first subscription
            sub1.Dispose();

            // second subscription should still be active
            internalObserver2.OnNext(msg1);
            A.CallTo(() => observer.OnNext(msg1)).MustHaveHappened(Repeated.Exactly.Once);

            // dispose of second subscription
            sub2.Dispose();

            // no subscriptions should be active
            internalObserver2.OnNext(msg2);
            A.CallTo(() => observer.OnNext(msg2)).MustNotHaveHappened();
        }
Ejemplo n.º 7
0
        public async Task ShouldCorrectlyPublishAndSubscribeToMulipleMultiplexedTopics()
        {
            const string brokerUri = "tcp://localhost:61616";
            const string topicName1 = "Obvs.Tests.ShouldCorrectlyPublishAndSubscribeToMulipleMultiplexedTopics1";
            const string topicName2 = "Obvs.Tests.ShouldCorrectlyPublishAndSubscribeToMulipleMultiplexedTopics2";

            IMessagePropertyProvider<IMessage> getProperties = new DefaultPropertyProvider<IMessage>();

            IConnectionFactory connectionFactory = new ConnectionFactory(brokerUri);
            var lazyConnection = new Lazy<IConnection>(() =>
            {
                var conn = connectionFactory.CreateConnection();
                conn.Start();
                return conn;
            });

            IMessagePublisher<IMessage> publisher1 = new MessagePublisher<IMessage>(
                lazyConnection,
                new ActiveMQTopic(topicName1),
                new JsonMessageSerializer(),
                getProperties,
                _testScheduler);

            IMessagePublisher<IMessage> publisher2 = new MessagePublisher<IMessage>(
                lazyConnection,
                new ActiveMQTopic(topicName2),
                new JsonMessageSerializer(),
                getProperties,
                _testScheduler);

            IMessageDeserializer<IMessage>[] deserializers =
            {
                new JsonMessageDeserializer<TestMessage>(),
                new JsonMessageDeserializer<TestMessage2>()
            };

            IMessageSource<IMessage> source = new MergedMessageSource<IMessage>(new[]
            {
                new MessageSource<IMessage>(
                    lazyConnection,
                    deserializers,
                    new ActiveMQTopic(topicName1)),

                new MessageSource<IMessage>(
                    lazyConnection,
                    deserializers,
                    new ActiveMQTopic(topicName2))
            });

            source.Messages.Subscribe(Console.WriteLine);

            await publisher1.PublishAsync(new TestMessage { Id = 1234 });
            await publisher1.PublishAsync(new TestMessage2 { Id = 4567 });
            await publisher2.PublishAsync(new TestMessage { Id = 8910 });
            await publisher2.PublishAsync(new TestMessage2 { Id = 1112 });

            Thread.Sleep(TimeSpan.FromSeconds(3));
        }
Ejemplo n.º 8
0
        public void ShouldCorrectlyPublishAndSubscribeToMulipleMultiplexedTopics()
        {
            const string brokerUri  = "tcp://localhost:61616";
            const string topicName1 = "Obvs.Tests.ShouldCorrectlyPublishAndSubscribeToMulipleMultiplexedTopics1";
            const string topicName2 = "Obvs.Tests.ShouldCorrectlyPublishAndSubscribeToMulipleMultiplexedTopics2";

            IMessagePropertyProvider <IMessage> getProperties = new DefaultPropertyProvider <IMessage>();

            IConnectionFactory connectionFactory = new ConnectionFactory(brokerUri);
            var lazyConnection = new Lazy <IConnection>(() =>
            {
                var conn = connectionFactory.CreateConnection();
                conn.Start();
                return(conn);
            });

            var scheduler = new EventLoopScheduler();

            IMessagePublisher <IMessage> publisher1 = new MessagePublisher <IMessage>(
                lazyConnection,
                new ActiveMQTopic(topicName1),
                new JsonMessageSerializer(),
                getProperties, scheduler);

            IMessagePublisher <IMessage> publisher2 = new MessagePublisher <IMessage>(
                lazyConnection,
                new ActiveMQTopic(topicName2),
                new JsonMessageSerializer(),
                getProperties, scheduler);

            IMessageDeserializer <IMessage>[] deserializers =
            {
                new JsonMessageDeserializer <TestMessage>(),
                new JsonMessageDeserializer <TestMessage2>()
            };

            IMessageSource <IMessage> source = new MergedMessageSource <IMessage>(new[]
            {
                new MessageSource <IMessage>(
                    lazyConnection,
                    deserializers,
                    new ActiveMQTopic(topicName1)),

                new MessageSource <IMessage>(
                    lazyConnection,
                    deserializers,
                    new ActiveMQTopic(topicName2))
            });

            source.Messages.Subscribe(Console.WriteLine);

            publisher1.PublishAsync(new TestMessage {
                Id = 1234
            });
            publisher1.PublishAsync(new TestMessage2 {
                Id = 4567
            });
            publisher2.PublishAsync(new TestMessage {
                Id = 8910
            });
            publisher2.PublishAsync(new TestMessage2 {
                Id = 1112
            });

            Thread.Sleep(TimeSpan.FromSeconds(3));
        }
Ejemplo n.º 9
0
        public void ShouldReturnMessagesFromUnderlyingSources()
        {
            IMessageSource<IEvent> source1 = A.Fake<IMessageSource<IEvent>>();
            IMessageSource<IMessage> source2 = A.Fake<IMessageSource<IMessage>>();
            IObservable<IEvent> observable1 = A.Fake<IObservable<IEvent>>();
            IObservable<IMessage> observable2 = A.Fake<IObservable<IMessage>>();
            IObserver<IMessage> observer = A.Fake<IObserver<IMessage>>();
            IObserver<IEvent> internalObserver1 = null;
            IObserver<IMessage> internalObserver2 = null;

            A.CallTo(() => source1.Messages).Returns(observable1);
            A.CallTo(() => source2.Messages).Returns(observable2);
            A.CallTo(() => observable1.Subscribe(A<IObserver<IEvent>>._)).Invokes(call => internalObserver1 = call.GetArgument<IObserver<IEvent>>(0));
            A.CallTo(() => observable2.Subscribe(A<IObserver<IMessage>>._)).Invokes(call => internalObserver2 = call.GetArgument<IObserver<IMessage>>(0));

            MergedMessageSource<IMessage> mergedMessageSource = new MergedMessageSource<IMessage>(new[] { source1, source2 });

            IDisposable sub1 = mergedMessageSource.Messages.OfType<IEvent>().Subscribe(observer);
            IDisposable sub2 = mergedMessageSource.Messages.OfType<IMessage>().Subscribe(observer);

            Assert.That(internalObserver1, Is.Not.Null);
            Assert.That(internalObserver2, Is.Not.Null);

            IEvent ev1 = A.Fake<IEvent>();
            IMessage msg2 = A.Fake<IMessage>();
            internalObserver1.OnNext(ev1);
            internalObserver2.OnNext(msg2);

            A.CallTo(() => observer.OnNext(ev1)).MustHaveHappened(Repeated.Exactly.Twice);
            A.CallTo(() => observer.OnNext(msg2)).MustHaveHappened(Repeated.Exactly.Once);

            sub1.Dispose();
            sub2.Dispose();
        }