Пример #1
0
        private void _testPushDurableSubSync(string durable, string deliverSubject, IConnection nc,
                                             PushSyncSubSupplier supplier)
        {
            IJetStreamPushSyncSubscription sub = supplier.Invoke();

            AssertSubscription(sub, STREAM, durable, deliverSubject, false);

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

            ValidateRedAndTotal(5, messages.Count, 5, total);

            // read again, nothing should be there
            messages = ReadMessagesAck(sub);
            total   += messages.Count;
            ValidateRedAndTotal(0, messages.Count, 5, total);

            sub.Unsubscribe();
            nc.Flush(1000); // flush outgoing communication with/to the server

            // re-subscribe
            sub = supplier.Invoke();
            nc.Flush(1000); // flush outgoing communication with/to the server

            // read again, nothing should be there
            messages = ReadMessagesAck(sub);
            total   += messages.Count;
            ValidateRedAndTotal(0, messages.Count, 5, total);

            sub.Unsubscribe();
            nc.Flush(1000); // flush outgoing communication with/to the server
        }
Пример #2
0
        public void TestJetStreamPushEphemeral(string deliverSubject)
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

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

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

                // Build our subscription options.
                PushSubscribeOptions options = PushSubscribeOptions.Builder()
                                               .WithDeliverSubject(deliverSubject)
                                               .Build();

                // Subscription 1
                IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(SUBJECT, options);
                AssertSubscription(sub, STREAM, null, deliverSubject, false);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                IList <Msg> messages1 = ReadMessagesAck(sub);
                int total             = messages1.Count;
                ValidateRedAndTotal(5, messages1.Count, 5, total);

                // read again, nothing should be there
                IList <Msg> messages0 = ReadMessagesAck(sub);
                total += messages0.Count;
                ValidateRedAndTotal(0, messages0.Count, 5, total);

                sub.Unsubscribe();

                // Subscription 2
                sub = js.PushSubscribeSync(SUBJECT, options);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // read what is available, same messages
                IList <Msg> messages2 = ReadMessagesAck(sub);
                total = messages2.Count;
                ValidateRedAndTotal(5, messages2.Count, 5, total);

                // read again, nothing should be there
                messages0 = ReadMessagesAck(sub);
                total    += messages0.Count;
                ValidateRedAndTotal(0, messages0.Count, 5, total);

                AssertSameMessages(messages1, messages2);
            });
        }
Пример #3
0
        public void TestOrderedConsumerSync()
        {
            Console.SetOut(new ConsoleWriter(output));

            Context.RunInJsServer(c =>
            {
                // Setup
                IJetStream js  = c.CreateJetStreamContext();
                string subject = Subject(111);
                CreateMemoryStream(c, Stream(111), subject);

                // Get this in place before any subscriptions are made
                JetStream.PushMessageManagerFactoryImpl =
                    (conn, so, cc, queueMode, syncMode) =>
                    new OrderedTestDropSimulator(conn, so, cc, queueMode, syncMode);

                // The options will be used in various ways
                PushSubscribeOptions pso = PushSubscribeOptions.Builder().WithOrdered(true).Build();

                // Test queue exception
                NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeSync(subject, QUEUE, pso));
                Assert.Contains(JsSubOrderedNotAllowOnQueues.Id, e.Message);

                // Setup sync subscription
                IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(subject, pso);
                Thread.Sleep(1000);

                // Published messages will be intercepted by the OrderedTestDropSimulator
                JsPublish(js, subject, 101, 6);

                ulong streamSeq = 1;
                while (streamSeq < 7)
                {
                    Msg m = sub.NextMessage(1000);
                    if (m != null)
                    {
                        Assert.Equal(streamSeq, m.MetaData.StreamSequence);
                        Assert.Equal(ExpectedConSeqNums[streamSeq - 1], m.MetaData.ConsumerSequence);
                        ++streamSeq;
                    }
                }

                sub.Unsubscribe();
                EnsureNotBound(sub);
            });
        }
Пример #4
0
        private void VisitSubject(string subject, DeliverPolicy deliverPolicy, bool headersOnly, bool ordered, Action <Msg> action)
        {
            PushSubscribeOptions pso = PushSubscribeOptions.Builder()
                                       .WithOrdered(ordered)
                                       .WithConfiguration(
                ConsumerConfiguration.Builder()
                .WithAckPolicy(AckPolicy.None)
                .WithDeliverPolicy(deliverPolicy)
                .WithHeadersOnly(headersOnly)
                .Build())
                                       .Build();

            IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(subject, pso);

            try
            {
                bool  lastTimedOut = false;
                ulong pending      = sub.GetConsumerInformation().CalculatedPending;
                while (pending > 0) // no need to loop if nothing pending
                {
                    try
                    {
                        Msg m = sub.NextMessage(js.Timeout);
                        action.Invoke(m);
                        if (--pending == 0)
                        {
                            return;
                        }
                        lastTimedOut = false;
                    }
                    catch (NATSTimeoutException)
                    {
                        if (lastTimedOut)
                        {
                            return; // two timeouts in a row is enough
                        }
                        lastTimedOut = true;
                    }
                }
            }
            finally
            {
                sub.Unsubscribe();
            }
        }
Пример #5
0
        public void TestMessageWithHeadersOnly()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

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

                MsgHeader h = new MsgHeader();
                h["foo"]    = "bar";
                js.Publish(new Msg(SUBJECT, h, DataBytes(1)));

                // Build our subscription options.
                PushSubscribeOptions options = ConsumerConfiguration.Builder()
                                               .WithHeadersOnly(true).BuildPushSubscribeOptions();

                IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(SUBJECT, options);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                Msg m = sub.NextMessage(1000);
                Assert.Empty(m.Data);
                Assert.True(m.HasHeaders);
                Assert.Equal("bar", m.Header["foo"]);
                Assert.Equal("6", m.Header[JetStreamConstants.MsgSizeHeader]);

                sub.Unsubscribe();

                // without headers only
                sub = js.PushSubscribeSync(SUBJECT);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server
                m = sub.NextMessage(1000);
                Assert.Equal(6, m.Data.Length);
                Assert.True(m.HasHeaders);
                Assert.Equal("bar", m.Header["foo"]);
                Assert.Null(m.Header[JetStreamConstants.MsgSizeHeader]);
            });
        }
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Push Subscribe Basic Sync", args, Usage)
                                    .DefaultStream("example-stream")
                                    .DefaultSubject("example-subject")
                                    .DefaultCount(0, true) // true indicated 0 means unlimited
                                                           // .DefaultDurable("push-sub-basic-sync-durable")
                                    .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);

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

                    // Build our subscription options.
                    // * A push subscription means the server will "push" us messages.
                    // * Durable means the server will remember where we are if we use that name.
                    // * Durable can by null or empty, the builder treats them the same.
                    // * The stream name is not technically required. If it is not provided, the
                    //   code building the subscription will look it up by making a request to the server.
                    //   If you know the stream name, you might as well supply it and save a trip to the server.
                    PushSubscribeOptions so = PushSubscribeOptions.Builder()
                                              .WithStream(helper.Stream)
                                              .WithDurable(helper.Durable) // it's okay if this is null, the builder handles it
                                              .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);
            }
        }
        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);
            }
        }