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); }); }
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)); }); }
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); }); }
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); }
public void TestOrderedConsumerAsync() { Console.SetOut(new ConsoleWriter(output)); Context.RunInJsServer(c => { // Setup IJetStream js = c.CreateJetStreamContext(); string subject = Subject(222); CreateMemoryStream(c, Stream(222), 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 void DummyTestHandler(object sender, MsgHandlerEventArgs args) { } NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>(() => js.PushSubscribeAsync(subject, QUEUE, DummyTestHandler, false, pso)); Assert.Contains(JsSubOrderedNotAllowOnQueues.Id, e.Message); // Setup async subscription CountdownEvent latch = new CountdownEvent(6); InterlockedInt received = new InterlockedInt(); InterlockedLong[] ssFlags = new InterlockedLong[6]; InterlockedLong[] csFlags = new InterlockedLong[6]; void TestHandler(object sender, MsgHandlerEventArgs args) { int i = received.Increment() - 1; ssFlags[i] = new InterlockedLong((long)args.msg.MetaData.StreamSequence); csFlags[i] = new InterlockedLong((long)args.msg.MetaData.ConsumerSequence); latch.Signal(); } js.PushSubscribeAsync(subject, TestHandler, false, pso); Thread.Sleep(1000); // Published messages will be intercepted by the OrderedTestDropSimulator JsPublish(js, subject, 101, 6); // wait for the messages latch.Wait(); // Loop through the messages to make sure I get stream sequence 1 to 6 ulong expectedStreamSeq = 1; while (expectedStreamSeq <= 6) { int idx = (int)expectedStreamSeq - 1; Assert.Equal(expectedStreamSeq, (ulong)ssFlags[idx].Read()); Assert.Equal(ExpectedConSeqNums[idx], (ulong)csFlags[idx].Read()); ++expectedStreamSeq; } }); }
private void SubscribeOk(IJetStream js, IJetStreamManagement jsm, string fs, string ss) { int i = Rndm.Next(); // just want a unique number SetupConsumer(jsm, i, fs); js.PushSubscribeSync(ss, ConsumerConfiguration.Builder().WithDurable(Durable(i)).BuildPushSubscribeOptions()).Unsubscribe(); }
public void TestQueueSubWorkflow() { Context.RunInJsServer(c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); // Setup the subscribers // - the PushSubscribeOptions can be re-used since all the subscribers are the same // - use a concurrent integer to track all the messages received // - have a list of subscribers and threads so I can track them PushSubscribeOptions pso = PushSubscribeOptions.Builder().WithDurable(DURABLE).Build(); InterlockedLong allReceived = new InterlockedLong(); IList <JsQueueSubscriber> subscribers = new List <JsQueueSubscriber>(); IList <Thread> subThreads = new List <Thread>(); for (int id = 1; id <= 3; id++) { // setup the subscription IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(SUBJECT, QUEUE, pso); // create and track the runnable JsQueueSubscriber qs = new JsQueueSubscriber(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(DefaultTimeout); // flush outgoing communication with/to the server // create and start the publishing Thread pubThread = new Thread(new JsPublisher(js, 100).Run); pubThread.Start(); // wait for all threads to finish pubThread.Join(5000); foreach (Thread t in subThreads) { t.Join(5000); } ISet <string> uniqueDatas = new HashSet <string>(); // count int count = 0; foreach (JsQueueSubscriber qs in subscribers) { int r = qs.received; Assert.True(r > 0); count += r; foreach (string s in qs.datas) { Assert.True(uniqueDatas.Add(s)); } } Assert.Equal(100, count); }); }
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); } }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("Push Subscribe Basic Async", args, Usage) .DefaultStream("example-stream") .DefaultSubject("example-subject") .Build(); try { using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions())) { JsUtils.CreateStreamWhenDoesNotExist(c, helper.Stream, helper.Subject); IJetStream js = c.CreateJetStreamContext(); new Thread(() => { js.PushSubscribeAsync(helper.Subject, (sender, a) => { a.Message.Ack(); Console.WriteLine(Encoding.UTF8.GetString(a.Message.Data)); }, false); }).Start(); Thread.Sleep(3000); } } catch (Exception ex) { helper.ReportException(ex); } }
public void TestHandlerSub() { Context.RunInJsServer(c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); // publish some messages JsPublish(js, SUBJECT, 10); CountdownEvent latch = new CountdownEvent(10); int received = 0; void TestHandler(object sender, MsgHandlerEventArgs args) { received++; args.Message.Ack(); latch.Signal(); } // Subscribe using the handler js.PushSubscribeAsync(SUBJECT, TestHandler, false); // Wait for messages to arrive using the countdown latch. latch.Wait(); Assert.Equal(10, received); }); }
public void TestPublishNoAck() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); JetStreamOptions jso = JetStreamOptions.Builder().WithPublishNoAck(true).Build(); IJetStream js = c.CreateJetStreamContext(jso); string data1 = "noackdata1"; string data2 = "noackdata2"; PublishAck pa = js.Publish(SUBJECT, Encoding.ASCII.GetBytes(data1)); Assert.Null(pa); Task <PublishAck> task = js.PublishAsync(SUBJECT, Encoding.ASCII.GetBytes(data2)); Assert.Null(task.Result); IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(SUBJECT); Msg m = sub.NextMessage(DefaultTimeout); Assert.NotNull(m); Assert.Equal(data1, Encoding.ASCII.GetString(m.Data)); m = sub.NextMessage(DefaultTimeout); Assert.NotNull(m); Assert.Equal(data2, Encoding.ASCII.GetString(m.Data)); }); }
public static void JsPublish(IJetStream js, string subject, int startId, int count) { for (int x = 0; x < count; x++) { js.Publish(new Msg(subject, DataBytes(startId++))); } }
public JsQueueSubscriber(int id, int msgCount, IJetStream js, IJetStreamPushSyncSubscription sub, InterlockedLong allReceived) { this.id = id; this.msgCount = msgCount; this.sub = sub; this.allReceived = allReceived; received = 0; datas = new List <string>(); }
public void TestJetStreamPublishDefaultOptions() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); IJetStream js = c.CreateJetStreamContext(); PublishAck ack = JsPublish(js); Assert.Equal(1U, ack.Seq); }); }
private void SubscribeEx(IJetStream js, IJetStreamManagement jsm, string fs, string ss) { int i = Rndm.Next(); // just want a unique number SetupConsumer(jsm, i, fs); NATSJetStreamClientException e = Assert.Throws <NATSJetStreamClientException>( () => js.PushSubscribeSync(ss, ConsumerConfiguration.Builder().WithDurable(Durable(i)).BuildPushSubscribeOptions())); Assert.Contains(JsSubSubjectDoesNotMatchFilter.Id, e.Message); }
public static void JsPublish(IJetStream js, string subject, string prefix, int startId, int count) { int end = startId + count - 1; for (int x = startId; x <= end; x++) { string data = prefix + x; js.Publish(new Msg(subject, Encoding.ASCII.GetBytes(data))); } }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("JetStream Publish Vs Core Publish", args, Usage) .DefaultStream("js-or-core-stream") .DefaultSubject("js-or-core-subject") .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 a JetStream context IJetStream js = c.CreateJetStreamContext(); // Regular Nats publish is straightforward c.Publish(helper.Subject, Encoding.ASCII.GetBytes("regular-message")); // A JetStream publish allows you to set publish options // that a regular publish does not. // A JetStream publish returns an ack of the publish. There // is no ack in a regular message. Msg msg = new Msg(helper.Subject, Encoding.ASCII.GetBytes("js-message")); PublishAck pa = js.Publish(msg); Console.WriteLine(pa); // set up the subscription IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(helper.Subject); c.Flush(500); // flush outgoing communication with/to the server // Both messages appear in the stream as JetStream messages msg = sub.NextMessage(500); msg.Ack(); Console.WriteLine("Received Data: '" + Encoding.ASCII.GetString(msg.Data) + "'\n Meta: " + msg.MetaData); msg = sub.NextMessage(500); msg.Ack(); Console.WriteLine("Received Data: '" + Encoding.ASCII.GetString(msg.Data) + "'\n Meta: " + msg.MetaData); // delete the stream since we are done with it. jsm.DeleteStream(helper.Stream); } } catch (Exception ex) { helper.ReportException(ex); } }
public void TestPushSyncFlowControl() { InterlockedInt fcps = new InterlockedInt(); Action <Options> optionsModifier = opts => { opts.FlowControlProcessedEventHandler = (sender, args) => { fcps.Increment(); }; }; Context.RunInJsServer(new TestServerInfo(TestSeedPorts.AutoPort.Increment()), optionsModifier, c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); byte[] data = new byte[8192]; int MSG_COUNT = 1000; for (int x = 100_000; x < MSG_COUNT + 100_000; x++) { byte[] fill = Encoding.ASCII.GetBytes("" + x); Array.Copy(fill, 0, data, 0, 6); js.Publish(new Msg(SUBJECT, data)); } InterlockedInt count = new InterlockedInt(); HashSet <string> set = new HashSet <string>(); ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithFlowControl(1000).Build(); PushSubscribeOptions pso = PushSubscribeOptions.Builder().WithConfiguration(cc).Build(); IJetStreamPushSyncSubscription ssub = js.PushSubscribeSync(SUBJECT, pso); for (int x = 0; x < MSG_COUNT; x++) { Msg msg = ssub.NextMessage(1000); byte[] fill = new byte[6]; Array.Copy(msg.Data, 0, fill, 0, 6); string id = Encoding.ASCII.GetString(fill); if (set.Add(id)) { count.Increment(); } msg.Ack(); } Assert.Equal(MSG_COUNT, count.Read()); Assert.True(fcps.Read() > 0); }); }
private static void PubSync(Context ctx, IConnection c, Stats stats, int id) { IJetStream js = c.CreateJetStreamContext(); if (ctx.LatencyFlag) { _pub(ctx, stats, id, (s, p) => js.Publish(BuildLatencyMessage(s, p))); } else { _pub(ctx, stats, id, (s, p) => js.Publish(s, p)); } }
public void TestJetStreamSubscribeErrors() { Context.RunInJsServer(c => { IJetStream js = c.CreateJetStreamContext(); // stream not found PushSubscribeOptions psoInvalidStream = PushSubscribeOptions.Builder().WithStream(STREAM).Build(); Assert.Throws <NATSJetStreamException>(() => js.PushSubscribeSync(SUBJECT, psoInvalidStream)); void AssertThrowsForSubject(Func <object> testCode) { ArgumentException ae = Assert.Throws <ArgumentException>(testCode); Assert.StartsWith("Subject", ae.Message); } void AssertThrowsForQueue(Func <object> testCode) { ArgumentException ae = Assert.Throws <ArgumentException>(testCode); Assert.StartsWith("Queue", ae.Message); } void AssertThrowsForHandler(Func <object> testCode) { ArgumentNullException ae = Assert.Throws <ArgumentNullException>(testCode); Assert.Equal("Handler", ae.ParamName); } // subject AssertThrowsForSubject(() => js.PushSubscribeSync(HasSpace)); AssertThrowsForSubject(() => js.PushSubscribeSync(null, (PushSubscribeOptions)null)); AssertThrowsForSubject(() => js.PushSubscribeSync(HasSpace, Plain)); AssertThrowsForSubject(() => js.PushSubscribeSync(null, Plain, null)); AssertThrowsForSubject(() => js.PushSubscribeAsync(HasSpace, null, false)); AssertThrowsForSubject(() => js.PushSubscribeAsync(HasSpace, null, false, null)); AssertThrowsForSubject(() => js.PushSubscribeAsync(HasSpace, Plain, null, false)); AssertThrowsForSubject(() => js.PushSubscribeAsync(HasSpace, Plain, null, false, null)); // queue AssertThrowsForQueue(() => js.PushSubscribeSync(Plain, HasSpace)); AssertThrowsForQueue(() => js.PushSubscribeSync(Plain, HasSpace, null)); AssertThrowsForQueue(() => js.PushSubscribeAsync(Plain, HasSpace, null, false)); AssertThrowsForQueue(() => js.PushSubscribeAsync(Plain, HasSpace, null, false, null)); // handler AssertThrowsForHandler(() => js.PushSubscribeAsync(Plain, null, false)); AssertThrowsForHandler(() => js.PushSubscribeAsync(Plain, null, false, null)); AssertThrowsForHandler(() => js.PushSubscribeAsync(Plain, Plain, null, false)); AssertThrowsForHandler(() => js.PushSubscribeAsync(Plain, Plain, null, false, null)); }); }
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); }); }
public void TestPublishVarieties() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); IJetStream js = c.CreateJetStreamContext(); PublishAck pa = js.Publish(SUBJECT, DataBytes(1)); AssertPublishAck(pa, 1); Msg msg = new Msg(SUBJECT, DataBytes(2)); pa = js.Publish(msg); AssertPublishAck(pa, 2); PublishOptions po = PublishOptions.Builder().Build(); pa = js.Publish(SUBJECT, DataBytes(3), po); AssertPublishAck(pa, 3); msg = new Msg(SUBJECT, DataBytes(4)); pa = js.Publish(msg, po); AssertPublishAck(pa, 4); pa = js.Publish(SUBJECT, null); AssertPublishAck(pa, 5); msg = new Msg(SUBJECT); pa = js.Publish(msg); AssertPublishAck(pa, 6); pa = js.Publish(SUBJECT, null, po); AssertPublishAck(pa, 7); msg = new Msg(SUBJECT); pa = js.Publish(msg, po); AssertPublishAck(pa, 8); IJetStreamPushSyncSubscription s = js.PushSubscribeSync(SUBJECT); AssertNextMessage(s, Data(1)); AssertNextMessage(s, Data(2)); AssertNextMessage(s, Data(3)); AssertNextMessage(s, Data(4)); AssertNextMessage(s, null); // 5 AssertNextMessage(s, null); // 6 AssertNextMessage(s, null); // 7 AssertNextMessage(s, null); // 8 // bad subject Assert.Throws <NATSNoRespondersException>(() => js.Publish(Subject(999), null)); }); }
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()); }); }
public static void PublishInBackground(IJetStream js, String subject, String prefix, int count) { new Thread(() => { try { for (int x = 1; x <= count; x++) { js.Publish(subject, Encoding.ASCII.GetBytes(prefix + "-" + x)); } } catch (Exception e) { Console.WriteLine(e); Environment.Exit(-1); } }).Start(); Thread.Sleep(100); // give the publish thread a little time to get going }
private void _testDurable(IJetStream js, PullSubSupplier supplier) { JsPublish(js, SUBJECT, 2); IJetStreamPullSubscription sub = supplier.Invoke(); // start the pull sub.PullNoWait(4); IList <Msg> messages = ReadMessagesAck(sub); ValidateRedAndTotal(2, messages.Count, 2, 2); sub.Unsubscribe(); }
public void TestInternalLookupConsumerInfoCoverage() { Context.RunInJsServer(c => { // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); CreateDefaultTestStream(c); // - consumer not found // - stream does not exist JetStreamTestImpl jst = new JetStreamTestImpl(c); Assert.Null(jst.TestLookupConsumerInfo(STREAM, DURABLE)); Assert.Throws <NATSJetStreamException>(() => jst.TestLookupConsumerInfo(Stream(999), DURABLE)); }); }
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); }); }
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); }); }
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)); }); }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("JetStream Publish", args, Usage) .DefaultStream("example-stream") .DefaultSubject("example-subject") .DefaultPayload("Hello") .DefaultCount(10) .Build(); try { using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions())) { // Use the utility to create a stream stored in memory. JsUtils.CreateStreamOrUpdateSubjects(c, helper.Stream, helper.Subject); // create a JetStream context IJetStream js = c.CreateJetStreamContext(); int stop = helper.Count < 2 ? 2 : helper.Count + 1; for (int x = 1; x < stop; x++) { // make unique message data if you want more than 1 message byte[] data = helper.Count < 2 ? Encoding.UTF8.GetBytes(helper.Payload) : Encoding.UTF8.GetBytes(helper.Payload + "-" + x); // Publish a message and print the results of the publish acknowledgement. Msg msg = new Msg(helper.Subject, null, helper.Header, data); // We'll use the defaults for this simple example, but there are options // to constrain publishing to certain streams, expect sequence numbers and // more. See the JetStreamPublishWithOptionsUseCases example for details. // An exception will be thrown if there is a failure. PublishAck pa = js.Publish(msg); Console.WriteLine("Published message '{0}' on subject '{1}', stream '{2}', seqno '{3}'.", Encoding.UTF8.GetString(data), helper.Subject, pa.Stream, pa.Seq); } } } catch (Exception ex) { helper.ReportException(ex); } }