Пример #1
0
        public void TestNoWait()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();

                // Pull Subscribe.
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                AssertSubscription(sub, STREAM, DURABLE, null, true);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // publish 10 messages
                // no wait, batch size 10, there are 10 messages, we will read them all and not trip nowait
                JsPublish(js, SUBJECT, "A", 10);
                sub.PullNoWait(10);
                IList <Msg> messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);
                AssertAllJetStream(messages);

                // publish 20 messages
                // no wait, batch size 10, there are 20 messages, we will read 10
                JsPublish(js, SUBJECT, "B", 20);
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                // there are still ten messages
                // no wait, batch size 10, there are 20 messages, we will read 10
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                // publish 5 messages
                // no wait, batch size 10, there are 5 messages, we WILL trip nowait
                JsPublish(js, SUBJECT, "C", 5);
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);

                // publish 12 messages
                // no wait, batch size 10, there are more than batch messages we will read 10
                JsPublish(js, SUBJECT, "D", 12);
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                // 2 messages left
                // no wait, less than batch size will WILL trip nowait
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(2, messages.Count);
            });
        }
Пример #2
0
        public void TestAckTerm()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options   = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // TERM
                JsPublish(js, SUBJECT, "TERM", 1);

                sub.Pull(1);
                Msg message = sub.NextMessage(1000);
                Assert.NotNull(message);
                Assert.Equal("TERM1", Encoding.ASCII.GetString(message.Data));
                message.Term();

                sub.Pull(1);
                AssertNoMoreMessages(sub);
            });
        }
Пример #3
0
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In", args, Usage)
                                    .DefaultStream("fetch-stream")
                                    .DefaultSubject("fetch-subject")
                                    .DefaultDurable("fetch-durable")
                                    .DefaultCount(15)
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Start publishing the messages, don't wait for them to finish, simulating an outside producer.
                    JsUtils.PublishInBackground(js, helper.Subject, "fetch-message", helper.Count);

                    // Build our consumer configuration and subscription options.
                    // make sure the ack wait is sufficient to handle the reading and processing of the batch.
                    // Durable is REQUIRED for pull based subscriptions
                    ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                               .WithAckWait(2500)
                                               .Build();
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .WithConfiguration(cc)
                                                       .Build();

                    // subscribe
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    int red = 0;
                    while (red < helper.Count)
                    {
                        IList <Msg> list = sub.Fetch(10, 1000);
                        foreach (Msg m in list)
                        {
                            Console.WriteLine($"{++red}. Message: {m}");
                            m.Ack();
                        }
                    }

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
Пример #4
0
        private void ChangeExPull(IJetStream js, ConsumerConfiguration.ConsumerConfigurationBuilder builder, String changedField)
        {
            NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>(
                () => js.PullSubscribe(SUBJECT, PullSubscribeOptions.Builder().WithConfiguration(builder.Build()).Build()));

            _ChangeEx(e, changedField);
        }
Пример #5
0
        public void TestDurable()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options normally
                PullSubscribeOptions options1 = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();
                _testDurable(js, () => js.PullSubscribe(SUBJECT, options1));

                // bind long form
                PullSubscribeOptions options2 = PullSubscribeOptions.Builder()
                                                .WithStream(STREAM)
                                                .WithDurable(DURABLE)
                                                .WithBind(true)
                                                .Build();
                _testDurable(js, () => js.PullSubscribe(null, options2));

                // bind short form
                PullSubscribeOptions options3 = PullSubscribeOptions.BindTo(STREAM, DURABLE);
                _testDurable(js, () => js.PullSubscribe(null, options3));
            });
        }
Пример #6
0
        public void TestDurableValidation()
        {
            // push
            Assert.Null(PushSubscribeOptions.Builder()
                        .WithDurable(null)
                        .WithConfiguration(ConsumerConfiguration.Builder().WithDurable(null).Build())
                        .Build()
                        .Durable);

            Assert.Equal("y", PushSubscribeOptions.Builder()
                         .WithDurable(null)
                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable("y").Build())
                         .Build()
                         .Durable);

            Assert.Equal("x", PushSubscribeOptions.Builder()
                         .WithDurable("x")
                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable(null).Build())
                         .Build()
                         .Durable);

            Assert.Equal("x", PushSubscribeOptions.Builder()
                         .WithDurable("x")
                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable("x").Build())
                         .Build()
                         .Durable);

            Assert.Throws <NATSJetStreamClientException>(() => PushSubscribeOptions.Builder()
                                                         .WithDurable("x")
                                                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable("y").Build())
                                                         .Build());

            Assert.Null(PushSubscribeOptions.Builder().Build().Durable);

            // pull
            Assert.Equal("y", PullSubscribeOptions.Builder()
                         .WithDurable(null)
                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable("y").Build())
                         .Build()
                         .Durable);

            Assert.Equal("x", PullSubscribeOptions.Builder()
                         .WithDurable("x")
                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable(null).Build())
                         .Build()
                         .Durable);

            Assert.Equal("x", PullSubscribeOptions.Builder()
                         .WithDurable("x")
                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable("x").Build())
                         .Build()
                         .Durable);

            Assert.Throws <NATSJetStreamClientException>(() => PullSubscribeOptions.Builder()
                                                         .WithDurable("x")
                                                         .WithConfiguration(ConsumerConfiguration.Builder().WithDurable("y").Build())
                                                         .Build());
        }
Пример #7
0
        public void TestPullAffirmative()
        {
            PullSubscribeOptions so = PullSubscribeOptions.Builder()
                                      .WithStream(STREAM)
                                      .WithDurable(DURABLE)
                                      .Build();

            Assert.Equal(STREAM, so.Stream);
            Assert.Equal(DURABLE, so.Durable);
            Assert.True(so.Pull);
        }
Пример #8
0
        public void TestBindDurableDeliverSubject()
        {
            Context.RunInJsServer(c =>
            {
                CreateDefaultTestStream(c);

                IJetStream js            = c.CreateJetStreamContext();
                IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                // create a durable push subscriber - has deliver subject
                ConsumerConfiguration ccDurPush = ConsumerConfiguration.Builder()
                                                  .WithDurable(Durable(1))
                                                  .WithDeliverSubject(Deliver(1))
                                                  .Build();
                jsm.AddOrUpdateConsumer(STREAM, ccDurPush);

                // create a durable pull subscriber - notice no deliver subject
                ConsumerConfiguration ccDurPull = ConsumerConfiguration.Builder()
                                                  .WithDurable(Durable(2))
                                                  .Build();
                jsm.AddOrUpdateConsumer(STREAM, ccDurPull);

                // try to pull subscribe against a push durable
                NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>(
                    () => js.PullSubscribe(SUBJECT, PullSubscribeOptions.Builder().WithDurable(Durable(1)).Build()));
                Assert.Contains(JsSubConsumerAlreadyConfiguredAsPush.Id, e.Message);

                // try to pull bind against a push durable
                e = Assert.Throws <NATSJetStreamClientException>(
                    () => js.PullSubscribe(SUBJECT, PullSubscribeOptions.BindTo(STREAM, Durable(1))));
                Assert.Contains(JsSubConsumerAlreadyConfiguredAsPush.Id, e.Message);

                // this one is okay
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, PullSubscribeOptions.Builder().WithDurable(Durable(2)).Build());
                sub.Unsubscribe(); // so I can re-use the durable

                // try to push subscribe against a pull durable
                e = Assert.Throws <NATSJetStreamClientException>(
                    () => js.PushSubscribeSync(SUBJECT, PushSubscribeOptions.Builder().WithDurable(Durable(2)).Build()));
                Assert.Contains(JsSubConsumerAlreadyConfiguredAsPull.Id, e.Message);

                // try to push bind against a pull durable
                e = Assert.Throws <NATSJetStreamClientException>(
                    () => js.PushSubscribeSync(SUBJECT, PushSubscribeOptions.BindTo(STREAM, Durable(2))));
                Assert.Contains(JsSubConsumerAlreadyConfiguredAsPull.Id, e.Message);

                // this one is okay
                js.PushSubscribeSync(SUBJECT, PushSubscribeOptions.Builder().WithDurable(Durable(1)).Build());
            });
        }
Пример #9
0
        public void TestBindErrors()
        {
            Context.RunInJsServer(c =>
            {
                CreateDefaultTestStream(c);

                IJetStream js = c.CreateJetStreamContext();

                PushSubscribeOptions pushso    = PushSubscribeOptions.BindTo(STREAM, DURABLE);
                NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, pushso));
                Assert.Contains(JsSubConsumerNotFoundRequiredInBind.Id, e.Message);

                PullSubscribeOptions pullso = PullSubscribeOptions.BindTo(STREAM, DURABLE);
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PullSubscribe(SUBJECT, pullso));
                Assert.Contains(JsSubConsumerNotFoundRequiredInBind.Id, e.Message);
            });
        }
Пример #10
0
        public void TestGetConsumerInfoFromSubscription()
        {
            Context.RunInJsServer(c =>
            {
                CreateDefaultTestStream(c);

                IJetStream js = c.CreateJetStreamContext();

                IJetStreamPushSyncSubscription psync = js.PushSubscribeSync(SUBJECT);
                ConsumerInfo ci = psync.GetConsumerInformation();
                Assert.Equal(STREAM, ci.Stream);

                PullSubscribeOptions pso        = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();
                IJetStreamPullSubscription pull = js.PullSubscribe(SUBJECT, pso);
                ci = pull.GetConsumerInformation();
                Assert.Equal(STREAM, ci.Stream);
            });
        }
Пример #11
0
        public void TestBindPull()
        {
            Context.RunInJsServer(c =>
            {
                CreateDefaultTestStream(c);
                IJetStream js = c.CreateJetStreamContext();

                JsPublish(js, SUBJECT, 1, 1);

                PullSubscribeOptions pso = PullSubscribeOptions.Builder()
                                           .WithDurable(DURABLE)
                                           .Build();
                IJetStreamPullSubscription s = js.PullSubscribe(SUBJECT, pso);
                s.Pull(1);
                Msg m = s.NextMessage(1000);
                Assert.NotNull(m);
                Assert.Equal(Data(1), Encoding.ASCII.GetString(m.Data));
                m.Ack();
                s.Unsubscribe();

                JsPublish(js, SUBJECT, 2, 1);
                pso = PullSubscribeOptions.Builder()
                      .WithStream(STREAM)
                      .WithDurable(DURABLE)
                      .WithBind(true)
                      .Build();
                s = js.PullSubscribe(SUBJECT, pso);
                s.Pull(1);
                m = s.NextMessage(1000);
                Assert.NotNull(m);
                Assert.Equal(Data(2), Encoding.ASCII.GetString(m.Data));
                m.Ack();
                s.Unsubscribe();

                JsPublish(js, SUBJECT, 3, 1);
                pso = PullSubscribeOptions.BindTo(STREAM, DURABLE);
                s   = js.PullSubscribe(SUBJECT, pso);
                s.Pull(1);
                m = s.NextMessage(1000);
                Assert.NotNull(m);
                Assert.Equal(Data(3), Encoding.ASCII.GetString(m.Data));
            });
        }
Пример #12
0
        public void TestPullValidation()
        {
            PullSubscribeOptions.PullSubscribeOptionsSubscribeOptionsBuilder builder1 = PullSubscribeOptions.Builder();
            Assert.Throws <ArgumentException>(() => builder1.WithStream(HasDot).Build());
            Assert.Throws <ArgumentException>(() => builder1.WithDurable(HasDot).Build());

            ConsumerConfiguration ccBadDur = ConsumerConfiguration.Builder().WithDurable(HasDot).Build();

            Assert.Throws <ArgumentException>(() => builder1.WithConfiguration(ccBadDur).Build());

            // durable directly
            PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();

            // in configuration
            ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithDurable(DURABLE).Build();

            PullSubscribeOptions.Builder().WithConfiguration(cc).Build();

            // new helper
            ConsumerConfiguration.Builder().WithDurable(DURABLE).BuildPullSubscribeOptions();
        }
Пример #13
0
        public void TestAckWaitTimeout()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                           .WithAckWait(1500)
                                           .Build();
                PullSubscribeOptions pso = PullSubscribeOptions.Builder()
                                           .WithDurable(DURABLE)
                                           .WithConfiguration(cc)
                                           .Build();
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, pso);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // Ack Wait timeout
                JsPublish(js, SUBJECT, "WAIT", 1);

                sub.Pull(1);
                Msg message = sub.NextMessage(1000);
                Assert.NotNull(message);
                Assert.Equal("WAIT1", Encoding.ASCII.GetString(message.Data));
                Thread.Sleep(2000);

                sub.Pull(1);
                message = sub.NextMessage(1000);
                Assert.NotNull(message);
                Assert.Equal("WAIT1", Encoding.ASCII.GetString(message.Data));

                sub.Pull(1);
                AssertNoMoreMessages(sub);
            });
        }
Пример #14
0
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In", args, Usage)
                                    .DefaultStream("expires-in-stream")
                                    .DefaultSubject("expires-in-subject")
                                    .DefaultDurable("expires-in-durable")
                                    .DefaultCount(15)
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Start publishing the messages, don't wait for them to finish, simulating an outside producer.
                    JsUtils.PublishInBackground(js, helper.Subject, "expires-in-message", helper.Count);

                    // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .Build();

                    // subscribe
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    bool keepGoing = true;
                    int  red       = 0;
                    while (keepGoing && red < helper.Count)
                    {
                        sub.PullExpiresIn(10, 1000);
                        int round = 0;
                        while (keepGoing && round < 10)
                        {
                            try
                            {
                                Msg m = sub.NextMessage(1000); // first message
                                Console.WriteLine($"{++red}. Message: {m}");
                                m.Ack();
                                round++;
                            }
                            catch (NATSTimeoutException) // timeout means there are no messages available
                            {
                                keepGoing = false;
                            }
                        }
                    }

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
Пример #15
0
        public void TestBasic()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();

                // Pull Subscribe.
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                AssertSubscription(sub, STREAM, DURABLE, null, true);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // publish some amount of messages, but not entire pull size
                JsPublish(js, SUBJECT, "A", 4);

                // start the pull
                sub.Pull(10);

                // read what is available, expect 4
                IList <Msg> messages = ReadMessagesAck(sub);
                int total            = messages.Count;
                ValidateRedAndTotal(4, messages.Count, 4, total);

                // publish some more covering our initial pull and more
                JsPublish(js, SUBJECT, "B", 10);

                // read what is available, expect 6 more
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(6, messages.Count, 10, total);

                // read what is available, should be zero since we didn't re-pull
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(0, messages.Count, 10, total);

                // re-issue the pull
                sub.Pull(10);

                // read what is available, should be 4 left over
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(4, messages.Count, 14, total);

                // publish some more
                JsPublish(js, SUBJECT, "C", 10);

                // read what is available, should be 6 since we didn't finish the last batch
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(6, messages.Count, 20, total);

                // re-issue the pull, but a smaller amount
                sub.Pull(2);

                // read what is available, should be 5 since we changed the pull size
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(2, messages.Count, 22, total);

                // re-issue the pull, since we got the full batch size
                sub.Pull(2);

                // read what is available, should be zero since we didn't re-pull
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(2, messages.Count, 24, total);

                // re-issue the pull, any amount there are no messages
                sub.Pull(1);

                // read what is available, there are none
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(0, messages.Count, 24, total);
            });
        }
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In", args, Usage)
                                    .DefaultStream("fetch-uc-stream")
                                    .DefaultSubject("fetch-uc-subject")
                                    .DefaultDurable("fetch-uc-durable")
                                    .DefaultCount(15)
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Build our consumer configuration and subscription options.
                    // make sure the ack wait is sufficient to handle the reading and processing of the batch.
                    // Durable is REQUIRED for pull based subscriptions
                    ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                               .WithAckWait(2500)
                                               .Build();
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .WithConfiguration(cc)
                                                       .Build();

                    // 0.1 Initialize. subscription
                    // 0.2 Flush outgoing communication with/to the server, useful when app is both JsUtils.Publishing and subscribing.
                    Console.WriteLine("\n----------\n0. Initialize the subscription and pull.");
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    // 1. Fetch, but there are no messages yet.
                    // -  Read the messages, get them all (0)
                    Console.WriteLine("----------\n1. There are no messages yet");
                    IList <Msg> messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count);

                    // 2. Publish 10 messages
                    // -  Fetch messages, get 10
                    Console.WriteLine("----------\n2. Publish 10 which satisfies the batch");
                    JsUtils.Publish(js, helper.Subject, "A", 10);
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 3. Publish 20 messages
                    // -  Fetch messages, only get 10
                    Console.WriteLine("----------\n3. Publish 20 which is larger than the batch size.");
                    JsUtils.Publish(js, helper.Subject, "B", 20);
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 4. There are still messages left from the last
                    // -  Fetch messages, get 10
                    Console.WriteLine("----------\n4. Get the rest of the JsUtils.Publish.");
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 5. Publish 5 messages
                    // -  Fetch messages, get 5
                    // -  Since there are less than batch size we only get what the server has.
                    Console.WriteLine("----------\n5. Publish 5 which is less than batch size.");
                    JsUtils.Publish(js, helper.Subject, "C", 5);
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 5 total messages, we received: " + messages.Count);

                    // 6. Publish 15 messages
                    // -  Fetch messages, only get 10
                    Console.WriteLine("----------\n6. Publish 15 which is more than the batch size.");
                    JsUtils.Publish(js, helper.Subject, "D", 15);
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 7. There are 5 messages left
                    // -  Fetch messages, only get 5
                    Console.WriteLine("----------\n7. There are 5 messages left.");
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 5 messages, we received: " + messages.Count);

                    // 8. Read but don't ack.
                    // -  Fetch messages, get 10, but either take too long to ack them or don't ack them
                    Console.WriteLine("----------\n8. Fetch but don't ack.");
                    JsUtils.Publish(js, helper.Subject, "E", 10);
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    Console.WriteLine("We should have received 10 message, we received: " + messages.Count);
                    Thread.Sleep(3000); // longer than the ackWait

                    // 9. Fetch messages,
                    // -  get the 10 messages we didn't ack
                    Console.WriteLine("----------\n9. Fetch, get the messages we did not ack.");
                    messages = sub.Fetch(10, 3000);
                    JsUtils.Report(messages);
                    foreach (Msg m in messages)
                    {
                        m.Ack();
                    }
                    Console.WriteLine("We should have received 10 message, we received: " + messages.Count);

                    Console.WriteLine("----------\n");

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
Пример #17
0
        public void TestPullExpires()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();

                // Subscribe synchronously.
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                AssertSubscription(sub, STREAM, DURABLE, null, true);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                int expires = 250;       // millis

                // publish 10 messages
                JsPublish(js, SUBJECT, "A", 5);
                sub.PullExpiresIn(10, expires);
                IList <Msg> messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "B", 10);
                sub.PullExpiresIn(10, expires);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "C", 5);
                sub.PullExpiresIn(10, expires);
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "D", 10);
                sub.Pull(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                JsPublish(js, SUBJECT, "E", 5);
                sub.PullExpiresIn(10, expires); // using millis version here
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "F", 10);
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                JsPublish(js, SUBJECT, "G", 5);
                sub.PullExpiresIn(10, expires); // using millis version here
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);

                JsPublish(js, SUBJECT, "H", 10);
                messages = sub.Fetch(10, expires);
                Assert.Equal(10, messages.Count);
                AssertAllJetStream(messages);

                JsPublish(js, SUBJECT, "I", 5);
                sub.PullExpiresIn(10, expires);
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires
            });
        }
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In, Use Cases", args, Usage)
                                    .DefaultStream("expires-in-uc-stream")
                                    .DefaultSubject("expires-in-uc-subject")
                                    .DefaultDurable("expires-in-uc-durable")
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .Build();

                    // 0.1 Initialize. subscription
                    // 0.2 Flush outgoing communication with/to the server, useful when app is both JsUtils.Publishing and subscribing.
                    // 0.3 Start the pull, you don't have to call this again because AckMode.NEXT
                    // -  When we ack a batch message the server starts preparing or adding to the next batch.
                    Console.WriteLine("\n----------\n0. Initialize the subscription and pull.");
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    // 1. Publish some that is less than the batch size.
                    Console.WriteLine("\n----------\n1. Publish some amount of messages, but not entire batch size.");
                    JsUtils.Publish(js, helper.Subject, "A", 6);
                    sub.PullExpiresIn(10, 1200);
                    IList <Msg> messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 6 total messages, we received: " + messages.Count);

                    // 2. Publish some more covering our pull size...
                    Console.WriteLine("----------\n2. Publish more than the batch size.");
                    sub.PullExpiresIn(10, 1200);
                    JsUtils.Publish(js, helper.Subject, "B", 14);
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 3. There are still 4 messages from B, but the batch was finished
                    // -  won't get any messages until a pull is issued.
                    Console.WriteLine("----------\n3. Read without issuing a pull.");
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count);

                    // 4. re-issue the pull to get the last 4
                    Console.WriteLine("----------\n4. Issue the pull to get the last 4.");
                    sub.PullExpiresIn(10, 1200);
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 4 total messages, we received: " + messages.Count);

                    // 5. publish a lot of messages
                    Console.WriteLine("----------\n5. Publish a lot of messages. The last pull was under the batch size.");
                    Console.WriteLine("   Issue another pull with batch size less than number of messages.");
                    JsUtils.Publish(js, helper.Subject, "C", 25);
                    sub.PullExpiresIn(10, 1200);
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 6. there are still more messages
                    Console.WriteLine("----------\n6. Still more messages. Issue another pull with batch size less than number of messages.");
                    sub.PullExpiresIn(10, 1200);
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 7. there are still more messages
                    Console.WriteLine("----------\n7. Still more messages. Issue another pull with batch size more than number of messages.");
                    sub.PullExpiresIn(10, 1200);
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 5 total messages, we received: " + messages.Count);

                    // 8. we got them all
                    Console.WriteLine("----------\n8. No messages left.");
                    sub.PullExpiresIn(10, 1200);
                    messages = JsUtils.ReadMessagesAck(sub, timeout: 2000);
                    Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count);

                    Console.WriteLine("----------\n");

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
Пример #19
0
        public void TestFetch()
        {
            Console.SetOut(new ConsoleWriter(output));

            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                int fetchMs   = 3000;
                int ackWaitMs = fetchMs * 2;

                ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                           .WithAckWait(ackWaitMs)
                                           .Build();

                PullSubscribeOptions options = PullSubscribeOptions.Builder()
                                               .WithDurable(DURABLE)
                                               .WithConfiguration(cc)
                                               .Build();

                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                AssertSubscription(sub, STREAM, DURABLE, null, true);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                IList <Msg> messages = sub.Fetch(10, fetchMs);
                ValidateRead(0, messages.Count);
                AckAll(messages);
                Thread.Sleep(ackWaitMs); // let the pull expire

                JsPublish(js, SUBJECT, "A", 10);
                messages = sub.Fetch(10, fetchMs);
                ValidateRead(10, messages.Count);
                AckAll(messages);

                JsPublish(js, SUBJECT, "B", 20);
                messages = sub.Fetch(10, fetchMs);
                ValidateRead(10, messages.Count);
                AckAll(messages);

                messages = sub.Fetch(10, fetchMs);
                ValidateRead(10, messages.Count);
                AckAll(messages);

                JsPublish(js, SUBJECT, "C", 5);
                messages = sub.Fetch(10, fetchMs);
                ValidateRead(5, messages.Count);
                AckAll(messages);
                Thread.Sleep(fetchMs * 2); // let the pull expire

                JsPublish(js, SUBJECT, "D", 15);
                messages = sub.Fetch(10, fetchMs);
                ValidateRead(10, messages.Count);
                AckAll(messages);

                messages = sub.Fetch(10, fetchMs);
                ValidateRead(5, messages.Count);
                AckAll(messages);

                JsPublish(js, SUBJECT, "E", 10);
                messages = sub.Fetch(10, fetchMs);
                ValidateRead(10, messages.Count);
                Thread.Sleep(ackWaitMs);

                messages = sub.Fetch(10, fetchMs);
                ValidateRead(10, messages.Count);
                AckAll(messages);
            });
        }
Пример #20
0
        public void TestConsumerIsNotModified()
        {
            Context.RunInJsServer(c =>
            {
                CreateDefaultTestStream(c);
                IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                // test with config in issue 105
                ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                           .WithDescription("desc")
                                           .WithAckPolicy(AckPolicy.Explicit)
                                           .WithDeliverPolicy(DeliverPolicy.All)
                                           .WithDeliverSubject(Deliver(1))
                                           .WithDeliverGroup(Queue(1))
                                           .WithDurable(Durable(1))
                                           .WithMaxAckPending(65000)
                                           .WithMaxDeliver(5)
                                           .WithReplayPolicy(ReplayPolicy.Instant)
                                           .Build();
                jsm.AddOrUpdateConsumer(STREAM, cc);

                IJetStream js = c.CreateJetStreamContext();

                PushSubscribeOptions pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(1));
                js.PushSubscribeSync(SUBJECT, Queue(1), pushOpts); // should not throw an error

                // testing numerics
                cc = ConsumerConfiguration.Builder()
                     .WithDeliverPolicy(DeliverPolicy.ByStartSequence)
                     .WithDeliverSubject(Deliver(21))
                     .WithDurable(Durable(21))
                     .WithStartSequence(42)
                     .WithMaxDeliver(43)
                     .WithRateLimitBps(44)
                     .WithMaxAckPending(45)
                     .Build();
                jsm.AddOrUpdateConsumer(STREAM, cc);

                pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(21));
                js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error

                cc = ConsumerConfiguration.Builder()
                     .WithDurable(Durable(22))
                     .WithMaxPullWaiting(46)
                     .Build();
                jsm.AddOrUpdateConsumer(STREAM, cc);

                PullSubscribeOptions pullOpts = PullSubscribeOptions.BindTo(STREAM, Durable(22));
                js.PullSubscribe(SUBJECT, pullOpts); // should not throw an error

                // testing DateTime
                cc = ConsumerConfiguration.Builder()
                     .WithDeliverPolicy(DeliverPolicy.ByStartTime)
                     .WithDeliverSubject(Deliver(3))
                     .WithDurable(Durable(3))
                     .WithStartTime(DateTime.Now.AddHours(1))
                     .Build();
                jsm.AddOrUpdateConsumer(STREAM, cc);

                pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(3));
                js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error

                // testing boolean and duration
                cc = ConsumerConfiguration.Builder()
                     .WithDeliverSubject(Deliver(4))
                     .WithDurable(Durable(4))
                     .WithFlowControl(1000)
                     .WithHeadersOnly(true)
                     .WithAckWait(2000)
                     .Build();
                jsm.AddOrUpdateConsumer(STREAM, cc);

                pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(4));
                js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error

                // testing enums
                cc = ConsumerConfiguration.Builder()
                     .WithDeliverSubject(Deliver(5))
                     .WithDurable(Durable(5))
                     .WithDeliverPolicy(DeliverPolicy.Last)
                     .WithAckPolicy(AckPolicy.None)
                     .WithReplayPolicy(ReplayPolicy.Original)
                     .Build();
                jsm.AddOrUpdateConsumer(STREAM, cc);

                pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(5));
                js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error
            });
        }
Пример #21
0
 private void ChangeOkPull(IJetStream js, ConsumerConfiguration.ConsumerConfigurationBuilder builder)
 {
     js.PullSubscribe(SUBJECT, PullSubscribeOptions.Builder().WithConfiguration(builder.Build()).Build()).Unsubscribe();
 }
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive No Wait, Use Cases", args, Usage)
                                    .DefaultStream("nowait-uc-stream")
                                    .DefaultSubject("nowait-uc-subject")
                                    .DefaultDurable("nowait-uc-durable")
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .Build();

                    // 0.1 Initialize. subscription
                    // 0.2 DO NOT start the pull, no wait works differently than regular pull.
                    //     With no wait, we have to start the pull the first time and every time the
                    //     batch size is exhausted or no waits out.
                    // 0.3 Flush outgoing communication with/to the server, useful when app is both publishing and subscribing.
                    Console.WriteLine("\n----------\n0. Initialize the subscription and pull.");
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    // 1. Start the pull, but there are no messages yet.
                    // -  Read the messages
                    // -  Since there are less than the batch size, we get them all (0)
                    Console.WriteLine("----------\n1. There are no messages yet");
                    sub.PullNoWait(10);
                    IList <Msg> messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count);

                    // 2. Publish 10 messages
                    // -  Start the pull
                    // -  Read the messages
                    // -  Since there are exactly the batch size we get them all
                    Console.WriteLine("----------\n2. Publish 10 which satisfies the batch");
                    JsUtils.Publish(js, helper.Subject, "A", 10);
                    sub.PullNoWait(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 3. Publish 20 messages
                    // -  Start the pull
                    // -  Read the messages
                    Console.WriteLine("----------\n3. Publish 20 which is larger than the batch size.");
                    JsUtils.Publish(js, helper.Subject, "B", 20);
                    sub.PullNoWait(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 4. There are still messages left from the last
                    // -  Start the pull
                    // -  Read the messages
                    Console.WriteLine("----------\n4. Get the rest of the publish.");
                    sub.PullNoWait(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 5. Publish 5 messages
                    // -  Start the pull
                    // -  Read the messages
                    Console.WriteLine("----------\n5. Publish 5 which is less than batch size.");
                    JsUtils.Publish(js, helper.Subject, "C", 5);
                    sub.PullNoWait(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 5 total messages, we received: " + messages.Count);

                    // 6. Publish 14 messages
                    // -  Start the pull
                    // -  Read the messages
                    // -  we do NOT get a nowait status message if there are more or equals messages than the batch
                    Console.WriteLine("----------\n6. Publish 14 which is more than the batch size.");
                    JsUtils.Publish(js, helper.Subject, "D", 14);
                    sub.PullNoWait(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count);

                    // 7. There are 4 messages left
                    // -  Start the pull
                    // -  Read the messages
                    // -  Since there are less than batch size the last message we get will be a status 404 message.
                    Console.WriteLine("----------\n7. There are 4 messages left, which is less than the batch size.");
                    sub.PullNoWait(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 4 messages, we received: " + messages.Count);

                    Console.WriteLine("----------\n");

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
Пример #23
0
        public void TestMoreCreateSubscriptionErrors()
        {
            Context.RunInJsServer(c =>
            {
                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT));
                Assert.Contains(JsSubNoMatchingStreamForSubject.Id, e.Message);

                // create the stream.
                CreateDefaultTestStream(c);

                // general pull push validation
                ConsumerConfiguration ccPush             = ConsumerConfiguration.Builder().WithDurable("pulldur").WithDeliverGroup("cantHave").Build();
                PullSubscribeOptions pullCantHaveDlvrGrp = PullSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PullSubscribe(SUBJECT, pullCantHaveDlvrGrp));
                Assert.Contains(JsSubPullCantHaveDeliverGroup.Id, e.Message);

                ccPush = ConsumerConfiguration.Builder().WithDurable("pulldur").WithDeliverSubject("cantHave").Build();
                PullSubscribeOptions pullCantHaveDlvrSub = PullSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PullSubscribe(SUBJECT, pullCantHaveDlvrSub));
                Assert.Contains(JsSubPullCantHaveDeliverSubject.Id, e.Message);

                ccPush = ConsumerConfiguration.Builder().WithMaxPullWaiting(1).Build();
                PushSubscribeOptions pushSo = PushSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, pushSo));
                Assert.Contains(JsSubPushCantHaveMaxPullWaiting.Id, e.Message);

                ccPush = ConsumerConfiguration.Builder().WithMaxPullWaiting(-1).Build();
                pushSo = PushSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                js.PushSubscribeSync(SUBJECT, pushSo);

                ccPush = ConsumerConfiguration.Builder().WithMaxBatch(1).Build();
                pushSo = PushSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                e      = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, pushSo));

                ccPush = ConsumerConfiguration.Builder().WithMaxBatch(-1).Build();
                pushSo = PushSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                js.PushSubscribeSync(SUBJECT, pushSo);
                Assert.Contains(JsSubPushCantHaveMaxBatch.Id, e.Message);

                ccPush = ConsumerConfiguration.Builder().WithMaxBytes(1).Build();
                pushSo = PushSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                e      = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, pushSo));

                ccPush = ConsumerConfiguration.Builder().WithMaxBytes(-1).Build();
                pushSo = PushSubscribeOptions.Builder().WithConfiguration(ccPush).Build();
                js.PushSubscribeSync(SUBJECT, pushSo);
                Assert.Contains(JsSubPushCantHaveMaxBytes.Id, e.Message);

                // create some consumers
                PushSubscribeOptions psoDurNoQ = PushSubscribeOptions.Builder().WithDurable("durNoQ").Build();
                js.PushSubscribeSync(SUBJECT, psoDurNoQ);

                PushSubscribeOptions psoDurYesQ = PushSubscribeOptions.Builder().WithDurable("durYesQ").Build();
                js.PushSubscribeSync(SUBJECT, "yesQ", psoDurYesQ);

                // already bound
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, psoDurNoQ));
                Assert.Contains(JsSubConsumerAlreadyBound.Id, e.Message);

                // queue match
                PushSubscribeOptions qmatch = PushSubscribeOptions.Builder()
                                              .WithDurable("qmatchdur").WithDeliverGroup("qmatchq").Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, "qnotmatch", qmatch));
                Assert.Contains(JsSubQueueDeliverGroupMismatch.Id, e.Message);

                // queue vs config
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, "notConfigured", psoDurNoQ));
                Assert.Contains(JsSubExistingConsumerNotQueue.Id, e.Message);

                PushSubscribeOptions psoNoVsYes = PushSubscribeOptions.Builder().WithDurable("durYesQ").Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, psoNoVsYes));
                Assert.Contains(JsSubExistingConsumerIsQueue.Id, e.Message);

                PushSubscribeOptions psoYesVsNo = PushSubscribeOptions.Builder().WithDurable("durYesQ").Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, "qnotmatch", psoYesVsNo));
                Assert.Contains(JsSubExistingQueueDoesNotMatchRequestedQueue.Id, e.Message);

                // flow control heartbeat push / pull
                ConsumerConfiguration ccFc = ConsumerConfiguration.Builder().WithDurable("ccFcDur").WithFlowControl(1000).Build();
                ConsumerConfiguration ccHb = ConsumerConfiguration.Builder().WithDurable("ccHbDur").WithIdleHeartbeat(1000).Build();

                PullSubscribeOptions psoPullCcFc = PullSubscribeOptions.Builder().WithConfiguration(ccFc).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PullSubscribe(SUBJECT, psoPullCcFc));
                Assert.Contains(JsSubFcHbNotValidPull.Id, e.Message);

                PullSubscribeOptions psoPullCcHb = PullSubscribeOptions.Builder().WithConfiguration(ccHb).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PullSubscribe(SUBJECT, psoPullCcHb));
                Assert.Contains(JsSubFcHbNotValidPull.Id, e.Message);

                PushSubscribeOptions psoPushCcFc = PushSubscribeOptions.Builder().WithConfiguration(ccFc).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, "cantHaveQ", psoPushCcFc));
                Assert.Contains(JsSubFcHbHbNotValidQueue.Id, e.Message);

                PushSubscribeOptions psoPushCcHb = PushSubscribeOptions.Builder().WithConfiguration(ccHb).Build();
                e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(SUBJECT, "cantHaveQ", psoPushCcHb));
                Assert.Contains(JsSubFcHbHbNotValidQueue.Id, e.Message);
            });
        }
Пример #24
0
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Batch Size, Use Cases", args, Usage)
                                    .DefaultStream("pull-stream")
                                    .DefaultSubject("pull-subject")
                                    .DefaultDurable("pull-durable")
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .Build();

                    // 0.1 Initialize. subscription
                    // 0.2 Flush outgoing communication with/to the server, useful when app is both JsUtils.Publishing and subscribing.
                    // 0.3 Start the pull, you don't have to call this again because AckMode.NEXT
                    // -  When we ack a batch message the server starts preparing or adding to the next batch.
                    Console.WriteLine("\n----------\n0. Initialize the subscription and pull.");
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    sub.Pull(10);

                    // 1. JsUtils.Publish some that is less than the batch size.
                    // -  Do this first as data will typically be published first.
                    Console.WriteLine("----------\n1. JsUtils.Publish some amount of messages, but not entire batch size.");
                    JsUtils.Publish(js, helper.Subject, "A", 4);
                    IList <Msg> messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 4 total messages, we received: " + messages.Count);

                    // 2. JsUtils.Publish some more covering our pull size...
                    // -  Read what is available, expect only 6 b/c 4 + 6 = 10
                    Console.WriteLine("----------\n2. JsUtils.Publish more than the remaining batch size.");
                    JsUtils.Publish(js, helper.Subject, "B", 10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 6 total messages, we received: " + messages.Count);

                    // 3. There are still 4 messages from B, but the batch was finished
                    // -  won't get any messages until a pull is issued.
                    Console.WriteLine("----------\n3. Read without re-issue.");
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count);

                    // 4. re-issue the pull to get the last 4
                    Console.WriteLine("----------\n4. Re-issue to get the last 4.");
                    sub.Pull(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 4 total messages, we received: " + messages.Count);

                    Console.WriteLine("----------\n");

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }