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); }
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(); }
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(); }
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(); }
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(); }
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)); }
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)); }
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(); }