Esempio n. 1
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());
            });
        }
Esempio n. 2
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);
            });
        }
Esempio n. 3
0
        public void TestJetStreamPushDurableSubAsync()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

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

                // publish some messages
                JsPublish(js, SUBJECT, 5);

                // Build our subscription options normally
                PushSubscribeOptions optionsSync1 = PushSubscribeOptions.Builder()
                                                    .WithDurable(Durable(1))
                                                    .WithDeliverSubject(Deliver(1))
                                                    .Build();

                _testPushDurableSubAsync(js, h => js.PushSubscribeAsync(SUBJECT, h, false, optionsSync1));

                // bind long form
                jsm.AddOrUpdateConsumer(STREAM,
                                        ConsumerConfiguration.Builder()
                                        .WithDurable(Durable(2))
                                        .WithDeliverSubject(Deliver(2))
                                        .Build());
                PushSubscribeOptions options2 = PushSubscribeOptions.Builder()
                                                .WithStream(STREAM)
                                                .WithDurable(Durable(2))
                                                .WithBind(true)
                                                .Build();
                _testPushDurableSubAsync(js, h => js.PushSubscribeAsync(null, h, false, options2));

                // bind short form
                jsm.AddOrUpdateConsumer(STREAM,
                                        ConsumerConfiguration.Builder()
                                        .WithDurable(Durable(3))
                                        .WithDeliverSubject(Deliver(3))
                                        .Build());
                PushSubscribeOptions options3 = PushSubscribeOptions.BindTo(STREAM, Durable(3));
                _testPushDurableSubAsync(js, h => js.PushSubscribeAsync(null, h, false, options3));
            });
        }
Esempio n. 4
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
            });
        }
Esempio n. 5
0
        public void TestJetStreamSubscribe()
        {
            Context.RunInJsServer(c =>
            {
                IJetStream js            = c.CreateJetStreamContext();
                IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                CreateDefaultTestStream(jsm);
                JsPublish(js);

                // default ephemeral subscription.
                IJetStreamPushSyncSubscription s = js.PushSubscribeSync(SUBJECT);
                Msg m = s.NextMessage(DefaultTimeout);
                Assert.NotNull(m);
                Assert.Equal(DATA, Encoding.UTF8.GetString(m.Data));
                IList <String> names = jsm.GetConsumerNames(STREAM);
                Assert.Equal(1, names.Count);

                // default subscribe options // ephemeral subscription.
                s = js.PushSubscribeSync(SUBJECT, PushSubscribeOptions.Builder().Build());
                m = s.NextMessage(DefaultTimeout);
                Assert.NotNull(m);
                Assert.Equal(DATA, Encoding.UTF8.GetString(m.Data));
                names = jsm.GetConsumerNames(STREAM);
                Assert.Equal(2, names.Count);

                // set the stream
                PushSubscribeOptions pso = PushSubscribeOptions.Builder()
                                           .WithStream(STREAM).WithDurable(DURABLE).Build();
                s = js.PushSubscribeSync(SUBJECT, pso);
                m = s.NextMessage(DefaultTimeout);
                Assert.NotNull(m);
                Assert.Equal(DATA, Encoding.UTF8.GetString(m.Data));
                names = jsm.GetConsumerNames(STREAM);
                Assert.Equal(3, names.Count);

                // coverage
                js.PushSubscribeSync(SUBJECT);
                js.PushSubscribeSync(SUBJECT, (PushSubscribeOptions)null);
                js.PushSubscribeSync(SUBJECT, QUEUE, null);
                js.PushSubscribeAsync(SUBJECT, (o, a) => {}, false);
                js.PushSubscribeAsync(SUBJECT, (o, a) => {}, false, null);
                js.PushSubscribeAsync(SUBJECT, QUEUE, (o, a) => {}, false, null);

                // bind with w/o subject
                jsm.AddOrUpdateConsumer(STREAM,
                                        ConsumerConfiguration.Builder()
                                        .WithDurable(Durable(101))
                                        .WithDeliverSubject(Deliver(101))
                                        .Build());
                PushSubscribeOptions psoBind = PushSubscribeOptions.BindTo(STREAM, Durable(101));
                js.PushSubscribeSync(null, psoBind).Unsubscribe();
                js.PushSubscribeSync("", psoBind).Unsubscribe();
                js.PushSubscribeAsync(null, (o, a) => { }, false, psoBind).Unsubscribe();
                js.PushSubscribeAsync("", (o, a) => { }, false, psoBind);

                jsm.AddOrUpdateConsumer(STREAM,
                                        ConsumerConfiguration.Builder()
                                        .WithDurable(Durable(102))
                                        .WithDeliverSubject(Deliver(102))
                                        .WithDeliverGroup(Queue(102))
                                        .Build());
                psoBind = PushSubscribeOptions.BindTo(STREAM, Durable(102));
                js.PushSubscribeSync(null, Queue(102), psoBind).Unsubscribe();
                js.PushSubscribeSync("", Queue(102), psoBind).Unsubscribe();
                js.PushSubscribeAsync(null, Queue(102), (o, a) => { }, false, psoBind).Unsubscribe();
                js.PushSubscribeAsync("", Queue(102), (o, a) => { }, false, psoBind);
            });
        }
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("NATS JetStream Push Subscribe Queue Durable", args, Usage)
                                    .DefaultStream("qdur-stream")
                                    .DefaultSubject("qdur-subject")
                                    .DefaultQueue("qdur-queue")
                                    .DefaultDurable("qdur-durable")
                                    .DefaultDeliverSubject("qdur-deliver")
                                    .DefaultCount(100)
                                    .DefaultSubsCount(5)
                                    .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);

                    IJetStream js = c.CreateJetStreamContext();

                    Console.WriteLine();

                    // create the consumer ahead of time
                    ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                               .WithDurable(helper.Durable)
                                               .WithDeliverSubject(helper.DeliverSubject)
                                               .WithDeliverGroup(helper.Queue)
                                               .Build();
                    jsm.AddOrUpdateConsumer(helper.Stream, cc);

                    // we will just bind to that consumer
                    PushSubscribeOptions pso = PushSubscribeOptions.BindTo(helper.Stream, helper.Durable);

                    InterlockedLong           allReceived = new InterlockedLong();
                    IList <JsQueueSubscriber> subscribers = new List <JsQueueSubscriber>();
                    IList <Thread>            subThreads  = new List <Thread>();
                    for (int id = 1; id <= helper.SubsCount; id++)
                    {
                        // setup the subscription
                        IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(helper.Subject, helper.Queue, pso);

                        // create and track the runnable
                        JsQueueSubscriber qs = new JsQueueSubscriber(id, 100, js, sub, allReceived);
                        subscribers.Add(qs);

                        // create, track and start the thread
                        Thread t = new Thread(qs.Run);
                        subThreads.Add(t);
                        t.Start();
                    }
                    c.Flush(500); // flush outgoing communication with/to the server

                    // create and start the publishing
                    Thread pubThread = new Thread(() =>
                    {
                        for (int x = 1; x <= helper.Count; x++)
                        {
                            js.Publish(helper.Subject, Encoding.ASCII.GetBytes("Data # " + x));
                        }
                    });
                    pubThread.Start();

                    // wait for all threads to finish
                    pubThread.Join(10000);
                    foreach (Thread t in subThreads)
                    {
                        t.Join(10000);
                    }

                    foreach (JsQueueSubscriber qs in subscribers)
                    {
                        qs.Report();
                    }

                    Console.WriteLine();

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("NATS JetStream Push Subscribe Bind Durable", args, Usage)
                                    .DefaultStream("example-stream")
                                    .DefaultSubject("example-subject")
                                    .DefaultDurable("bind-durable")
                                    .DefaultDeliverSubject("bind-deliver")
                                    .DefaultCount(0, true) // true indicated 0 means unlimited
                                    .Build();

            int count = helper.Count < 1 ? int.MaxValue : helper.Count;

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // The stream (and data) must exist
                    JsUtils.ExitIfStreamNotExists(c, helper.Stream);

                    // The durable consumer must already exist. Usually it would be made in configuration
                    // or via the NATS CLI but we are making it here.
                    // Important: The consumer must have a deliver subject when made this way or it will be
                    // understood to be a pull consumer by the server.
                    // NOTE: If you ran this example already, the consumer will have been created
                    //       This is not a problem if it is exactly the same. Most ConsumerConfiguration
                    //       properties are not modifiable once created.
                    ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                               .WithDurable(helper.Durable)
                                               .WithDeliverSubject(helper.DeliverSubject)
                                               .Build();
                    c.CreateJetStreamManagementContext().AddOrUpdateConsumer(helper.Stream, cc);

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

                    // bind subscribe to the stream - either variety will work
                    // V1. Version designed specifically for this purpose.
                    PushSubscribeOptions so = PushSubscribeOptions.BindTo(helper.Stream, helper.Durable);

                    // V2. optional long form
                    // PushSubscribeOptions so = PushSubscribeOptions.Builder()
                    // .WithBind(true)
                    // .WithStream(helper.Stream)
                    // .WithDurable(helper.Durable)
                    // .Build();

                    // Subscribe synchronously, then just wait for messages.
                    IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(helper.Subject, so);
                    c.Flush(5000);

                    int red = 0;
                    while (count > 0)
                    {
                        try
                        {
                            Msg msg = sub.NextMessage(1000);
                            Console.WriteLine("\nMessage Received:");
                            if (msg.HasHeaders)
                            {
                                Console.WriteLine("  Headers:");
                                foreach (string key in msg.Header.Keys)
                                {
                                    foreach (string value in msg.Header.GetValues(key))
                                    {
                                        Console.WriteLine($"    {key}: {value}");
                                    }
                                }
                            }

                            Console.WriteLine("  Subject: {0}\n  Data: {1}\n", msg.Subject, Encoding.UTF8.GetString(msg.Data));
                            Console.WriteLine("  " + msg.MetaData);

                            // Because this is a synchronous subscriber, there's no auto-ack.
                            // The default Consumer Configuration AckPolicy is Explicit
                            // so we need to ack the message or it'll be redelivered.
                            msg.Ack();

                            ++red;
                            --count;
                        }
                        catch (NATSTimeoutException) // timeout means there are no messages available
                        {
                            count = 0;               // ran out of messages
                        }
                    }

                    Console.WriteLine("\n" + red + " message(s) were received.\n");

                    sub.Unsubscribe();
                    c.Flush(5000);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }