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 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 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 }); }
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); } }