public async Task Client_Should_be_able_to_publish_and_consume_messages_When_publishing_one_by_one()
        {
            var subject  = Context.GenerateSubject();
            var messages = new[]
            {
                "My test string\r\nwith two lines and\ttabs!",
                "Foo bar!",
                "My async test string\r\nwith two lines and\ttabs!",
                "Async Foo bar!"
            };

            _sync    = Sync.Max(4);
            _client1 = await Context.ConnectClientAsync();

            _client1.MsgOpStream.Subscribe(msg => _sync.Release(msg));
            _client1.Sub(subject);

            await Context.DelayAsync();

            _client1.Pub(subject, messages[0]);
            _client1.Pub(subject, Encoding.UTF8.GetBytes(messages[1]));
            await _client1.PubAsync(subject, messages[2]);

            await _client1.PubAsync(subject, Encoding.UTF8.GetBytes(messages[3]));

            _sync.WaitForAll();
            _sync.InterceptedCount.Should().Be(messages.Length);
            _sync.Intercepted.Select(m => m.GetPayloadAsString()).ToArray().Should().Contain(messages);
        }
        public async Task Client_Should_throw_if_pub_after_disconnected()
        {
            var subject = Context.GenerateSubject();
            var body    = new byte[0];

            _client1 = await Context.ConnectClientAsync();

            // Succeeds
            _client1.Pub(subject, "body");
            _client1.Pub(subject, "body", "repy.to.subject");
            _client1.Pub(subject, body.AsMemory());
            _client1.Pub(subject, body.AsMemory(), "repy.to.subject");

            // Disconnect from NATS per user request
            _client1.Disconnect();
            Assert.False(_client1.IsConnected);

            // Fails after being disconnected
            Should.ThrowNatsException(() => _client1.Pub(subject, "body"));
            Should.ThrowNatsException(() => _client1.Pub(subject, "body", "reply.to.subject"));
            Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory()));
            Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory(), "reply.to.subject"));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body"));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body", "reply.to.subject"));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory()));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory(), "reply.to.subject"));
        }
Beispiel #3
0
        public async Task Given_subscribed_with_overlapping_wildcards_async_using_handler_It_should_get_only_subcription_messages()
        {
            const string subjectNs = "foo.tests.";

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            // First subscription
            await _client.SubAsync(subjectNs + ">");

            // Second, overlapping subscription
            var subscription = await _client.SubAsync(subjectNs + "*", stream => stream.Subscribe(msg => _sync.Release(msg)));

            await Context.DelayAsync();

            await _client.PubAsync(subjectNs + "type1", "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type2", "Test2");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type3", "Test3");

            _sync.WaitForAny();

            _sync.InterceptedCount.Should().Be(3);
            _sync.Intercepted.Select(i => i.SubscriptionId).Should().OnlyContain(i => i == subscription.SubscriptionInfo.Id);
        }
Beispiel #4
0
        public async Task Given_subscribed_async_using_handler_When_the_subscription_has_been_disposed_It_should_not_get_messages()
        {
            var subject = Context.GenerateSubject();

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            var s = await _client.SubAsync(subject, stream => stream.Subscribe(msg => _sync.Release(msg)));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subject, "Test2");

            _sync.WaitForAny();

            s.Dispose();

            await _client.PubAsync(subject, "Test3");

            await Context.DelayAsync();

            _sync.InterceptedCount.Should().Be(2);
        }
Beispiel #5
0
        public async Task Given_subscribed_When_unsubscribing_async_It_should_not_get_any_further_messages()
        {
            var subject = Context.GenerateSubject();

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            var s = _client.Sub(subject, stream => stream.Subscribe(NatsObserver.Delegating <MsgOp>(msg => _sync.Release(msg))));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subject, "Test2");

            _sync.WaitForAny();

            await _client.UnsubAsync(s.SubscriptionInfo);

            await _client.PubAsync(subject, "Test3");

            await Context.DelayAsync();

            _sync.InterceptedCount.Should().Be(2);
        }
        public async Task Client_Should_be_able_to_publish_When_no_subscribers_exists()
        {
            _client1 = await Context.ConnectClientAsync();

            _client1.Pub("Test", "test message");
            await _client1.PubAsync("Test", "Test message");
        }
Beispiel #7
0
        public async Task Client_Should_be_able_to_handle_large_message_When_using_explicit_flush_although_auto_flush(int messageCount)
        {
            var message    = new string('b', 16384);
            var exceptions = new List <Exception>();
            var subject    = Context.GenerateSubject();
            var cnInfo     = Context.GetConnectionInfo();

            cnInfo.PubFlushMode = PubFlushMode.Auto;

            _sync    = Sync.Max(messageCount);
            _client1 = await Context.ConnectClientAsync(cnInfo);

            _client1.Events.OfType <ClientWorkerFailed>().Subscribe(ev => exceptions.Add(ev.Exception));
            _client1.OpStream.OfType <MsgOp>().SubscribeSafe(msg => _sync.Release(msg), ex => exceptions.Add(ex));
            await _client1.SubAsync(subject);

            await Context.DelayAsync();

            for (var i = 0; i < messageCount; i++)
            {
                await _client1.PubAsync(subject, message);

                await _client1.FlushAsync();
            }

            _sync.WaitForAll();

            exceptions.Should().BeEmpty();
            _sync.InterceptedCount.Should().Be(messageCount);
            _sync.Intercepted
            .Select(m => m.GetPayloadAsString())
            .Should().OnlyContain(m => m == message);
        }
Beispiel #8
0
        public static async Task RunAsync(ConnectionInfo cnInfo)
        {
            using (var client = new NatsClient("Publisher", cnInfo))
            {
                client.Connect();

                while (true)
                {
                    Console.WriteLine("Say what? (blank=quit)");
                    var message = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(message))
                    {
                        break;
                    }

                    Console.WriteLine("To what \"Child\" Subject? (blank=quit)");
                    var subject = Console.ReadLine();
                    if (string.IsNullOrWhiteSpace(subject))
                    {
                        break;
                    }

                    await client.PubAsync($"demo.{subject}", message);
                }
            }
        }
        public async Task Client_Should_throw_if_pub_when_never_connected()
        {
            var subject = Context.GenerateSubject();
            var body    = new byte[0];

            _client1 = Context.CreateClient();

            Should.ThrowNatsException(() => _client1.Pub(subject, "body"));
            Should.ThrowNatsException(() => _client1.Pub(subject, "body", "reply.to.subject"));
            Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory()));
            Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory(), "reply.to.subject"));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body"));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body", "reply.to.subject"));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory()));

            await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory(), "reply.to.subject"));
        }
Beispiel #10
0
        public async Task Client_Should_not_reconnect_after_failure_When_not_configured_to_do_so()
        {
            var subject = Context.GenerateSubject();
            var wasDisconnectedDueToFailure = false;
            var wasReconnected = false;

            var ex             = new Exception("This will destroy things.");
            var throwingLogger = new Mock <ILogger>();

            throwingLogger.Setup(f => f.Error(It.IsAny <string>(), It.IsAny <Exception>())).Throws(ex);
            LoggerManager.Resolve = type => throwingLogger.Object;

            _sync = Sync.MaxTwo();

            var cnInfo = Context.GetConnectionInfo();

            cnInfo.AutoReconnectOnFailure = false;
            _client = new NatsClient(cnInfo);
            await _client.ConnectAsync();

            await _client.SubAsync(subject);

            _client.Events
            .OfType <ClientDisconnected>()
            .Where(ev => ev.Reason == DisconnectReason.DueToFailure)
            .Subscribe(ev =>
            {
                wasDisconnectedDueToFailure = true;
                _sync.Release();
            });

            _client.Events
            .OfType <ClientConnected>()
            .Subscribe(ev =>
            {
                wasReconnected = true;
                _sync.Release();
            });

            _client.MsgOpStream.Subscribe(msg => throw new Exception("Fail"));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "This message will fail");

            //Wait for the Disconnected release and the potential Connected release
            _sync.WaitForAny();

            wasDisconnectedDueToFailure.Should().BeTrue();
            wasReconnected.Should().BeFalse();
            _client.IsConnected.Should().BeFalse();
        }
Beispiel #11
0
        public async Task Given_subscribed_async_using_observer_and_subscribed_to_other_subject_as_well_It_should_only_get_subject_specific_messages()
        {
            var subject                  = Context.GenerateSubject();
            var otherSubject             = subject + "fail";
            var interceptedSubjects      = new List <string>();
            var interceptedOtherSubjects = new List <string>();

            _sync   = Sync.MaxTwo();
            _client = await Context.ConnectClientAsync();

            await _client.SubAsync(subject, stream => stream.Subscribe(msg =>
            {
                interceptedSubjects.Add(msg.Subject);
                _sync.Release();
            }));

            _client.Sub(otherSubject, stream => stream.Subscribe(msg =>
            {
                interceptedOtherSubjects.Add(msg.Subject);
                _sync.Release();
            }));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subject, "Test2");

            _sync.WaitForAny();
            await _client.PubAsync(otherSubject, "Test3");

            _sync.WaitForAny();

            interceptedSubjects.Should().HaveCount(2);
            interceptedSubjects.Should().OnlyContain(i => i == subject);
            interceptedOtherSubjects.Should().HaveCount(1);
            interceptedOtherSubjects.Should().OnlyContain(i => i == otherSubject);
        }
Beispiel #12
0
        public async Task Given_subscribed_with_wildcard_async_using_handler_It_should_get_messages()
        {
            const string subjectNs = "foo.tests.";

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            await _client.SubAsync(subjectNs + "*", stream => stream.Subscribe(msg => _sync.Release(msg)));

            await Context.DelayAsync();

            await _client.PubAsync(subjectNs + "type1", "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type2", "Test2");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type3", "Test3");

            _sync.WaitForAny();

            _sync.InterceptedCount.Should().Be(3);
            _sync.Intercepted.Select(i => i.Subject).Should().OnlyContain(i => i.StartsWith(subjectNs));
        }
Beispiel #13
0
        public async Task Given_subscribed_When_disconnectiong_and_connecting_again_It_should_resubscribe_and_get_messages()
        {
            var subject = Context.GenerateSubject();

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            _client.Sub(subject, stream => stream.Subscribe(NatsObserver.Delegating <MsgOp>(msg => _sync.Release(msg))));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "Test1");

            _sync.WaitForAny();
            _client.Disconnect();

            await _client.ConnectAsync();

            await _client.PubAsync(subject, "Test2");

            _sync.WaitForAny();

            _sync.InterceptedCount.Should().Be(2);
        }
Beispiel #14
0
        public async Task Client_Should_dispatch_to_all_subscribed_clients()
        {
            var subject    = Context.GenerateSubject();
            var nr1Receive = new ConcurrentQueue <MsgOp>();
            var nr2Receive = new ConcurrentQueue <MsgOp>();
            var nr3Receive = new ConcurrentQueue <MsgOp>();

            _sync    = Sync.MaxTwo();
            _client1 = await Context.ConnectClientAsync();

            _client2 = await Context.ConnectClientAsync();

            _client3 = await Context.ConnectClientAsync();

            _client1.OpStream.OfType <MsgOp>().Subscribe(msg => nr1Receive.Enqueue(msg));

            _client2.OpStream.OfType <MsgOp>().Subscribe(msg =>
            {
                nr2Receive.Enqueue(msg);
                _sync.Release(msg);
            });
            _client2.Sub(subject);

            _client3.OpStream.OfType <MsgOp>().Subscribe(msg =>
            {
                nr3Receive.Enqueue(msg);
                _sync.Release(msg);
            });
            await _client3.SubAsync(subject);

            await Context.DelayAsync();

            _client1.Pub(subject, "mess1");
            _sync.WaitForAll();

            await _client1.PubAsync(subject, "mess2");

            _sync.WaitForAll();

            _sync.InterceptedCount.Should().Be(4);
            nr1Receive.Count.Should().Be(0);
            nr2Receive.Count.Should().Be(2);
            nr3Receive.Count.Should().Be(2);
        }
        public async Task Client_Should_not_reconnect_after_failure_When_not_configured_to_do_so()
        {
            const string subject = "test";
            var          wasDisconnectedDueToFailure = false;
            var          wasReconnected = false;

            var ex             = new Exception("This will destroy things.");
            var throwingLogger = new Mock <ILogger>();

            throwingLogger.Setup(f => f.Error(It.Is <string>(m => m == "Error in observer while emitting value."), It.IsAny <Exception>())).Throws(ex);
            LoggerManager.Resolve = type => throwingLogger.Object;

            _client = new NatsClient(_cnInfoWithNoAutoReconnect);
            _client.Connect();

            await _client.SubAsync(subject);

            _client.Events.OfType <ClientDisconnected>()
            .Where(ev => ev.Reason == DisconnectReason.DueToFailure)
            .Subscribe(ev =>
            {
                wasDisconnectedDueToFailure = true;
                ReleaseOne();
            });

            _client.Events.OfType <ClientConnected>()
            .Subscribe(ev =>
            {
                wasReconnected = true;
                ReleaseOne();
            });

            _client.MsgOpStream.Subscribe(msg => throw new Exception("Fail"));

            await _client.PubAsync(subject, "This message will fail");

            //Wait for the Disconnected release and the potential Connected release
            WaitOne();
            WaitOne();

            wasDisconnectedDueToFailure.Should().BeTrue();
            wasReconnected.Should().BeFalse();
            _client.IsConnected.Should().BeFalse();
        }
Beispiel #16
0
        public async Task Given_subscribed_sync_using_observer_and_subscribed_to_other_subject_as_well_It_should_only_get_subject_specific_messages()
        {
            var subject             = GenerateSubject();
            var otherSubject        = subject + "fail";
            var interceptedSubjects = new List <string>();

            _client.Sub(subject, stream => stream.Subscribe(msg =>
            {
                interceptedSubjects.Add(msg.Subject);
                ReleaseOne();
            }));
            _client.Sub(otherSubject, stream => stream.Subscribe(msg => ReleaseOne()));

            await _client.PubAsync(subject, "Test1");

            WaitOne();
            await _client.PubAsync(subject, "Test2");

            WaitOne();
            await _client.PubAsync(otherSubject, "Test3");

            WaitOne();

            interceptedSubjects.Should().HaveCount(2);
            interceptedSubjects.Should().OnlyContain(i => i == subject);
        }