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); } }
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 TestValidConsumerUpdates() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); CreateMemoryStream(jsm, STREAM, SUBJECT_GT); ConsumerConfiguration cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithDeliverSubject(Deliver(2)).Build(); AssertValidAddOrUpdate(jsm, cc); cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithAckWait(Duration.OfSeconds(5)).Build(); AssertValidAddOrUpdate(jsm, cc); cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithRateLimitBps(100).Build(); AssertValidAddOrUpdate(jsm, cc); cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithMaxAckPending(100).Build(); AssertValidAddOrUpdate(jsm, cc); cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithMaxDeliver(4).Build(); AssertValidAddOrUpdate(jsm, cc); }); }
public void TestDeliverSubjectValidation() { Assert.Null(PushSubscribeOptions.Builder() .WithDeliverSubject(null) .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverSubject(null).Build()) .Build() .DeliverSubject); Assert.Equal("y", PushSubscribeOptions.Builder() .WithDeliverSubject(null) .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverSubject("y").Build()) .Build() .DeliverSubject); Assert.Equal("x", PushSubscribeOptions.Builder() .WithDeliverSubject("x") .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverSubject(null).Build()) .Build() .DeliverSubject); Assert.Equal("x", PushSubscribeOptions.Builder() .WithDeliverSubject("x") .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverSubject("x").Build()) .Build() .DeliverSubject); Assert.Throws <NATSJetStreamClientException>(() => PushSubscribeOptions.Builder() .WithDeliverSubject("x") .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverSubject("y").Build()) .Build()); }
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()); }
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 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); }); }
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()); }); }
private void AddConsumers(IJetStreamManagement jsm, string stream, int count, string durableVary, string filterSubject) { for (int x = 0; x < count; x++) { String dur = Durable(durableVary, x + 1); ConsumerConfiguration cc = ConsumerConfiguration.Builder() .WithDurable(dur) .WithFilterSubject(filterSubject) .Build(); ConsumerInfo ci = jsm.AddOrUpdateConsumer(stream, cc); Assert.Equal(dur, ci.Name); Assert.Equal(dur, ci.ConsumerConfiguration.Durable); Assert.Empty(ci.ConsumerConfiguration.DeliverSubject); } }
public void TestGetConsumerInfo() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); CreateDefaultTestStream(jsm); Assert.Throws <NATSJetStreamException>(() => jsm.DeleteConsumer(STREAM, DURABLE)); ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithDurable(DURABLE).Build(); ConsumerInfo ci = jsm.AddOrUpdateConsumer(STREAM, cc); Assert.Equal(STREAM, ci.Stream); Assert.Equal(DURABLE, ci.Name); ci = jsm.GetConsumerInfo(STREAM, DURABLE); Assert.Equal(STREAM, ci.Stream); Assert.Equal(DURABLE, ci.Name); Assert.Throws <NATSJetStreamException>(() => jsm.GetConsumerInfo(STREAM, Durable(999))); }); }
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(); } }
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)); }); }
private ConsumerConfiguration PrepForUpdateTest(IJetStreamManagement jsm) { try { jsm.DeleteConsumer(STREAM, Durable(1)); } catch (Exception) { /* ignore */ } ConsumerConfiguration cc = ConsumerConfiguration.Builder() .WithDurable(Durable(1)) .WithAckPolicy(AckPolicy.Explicit) .WithDeliverSubject(Deliver(1)) .WithMaxDeliver(3) .WithFilterSubject(SUBJECT_GT) .Build(); AssertValidAddOrUpdate(jsm, cc); return(cc); }
public void TestCreateConsumersWithFilters() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); // plain subject CreateDefaultTestStream(jsm); ConsumerConfiguration.ConsumerConfigurationBuilder builder = ConsumerConfiguration.Builder().WithDurable(DURABLE); jsm.AddOrUpdateConsumer(STREAM, builder.WithFilterSubject(SUBJECT).Build()); Assert.Throws <NATSJetStreamException>(() => jsm.AddOrUpdateConsumer(STREAM, builder.WithFilterSubject(SubjectDot("not-match")).Build())); // wildcard subject jsm.DeleteStream(STREAM); CreateMemoryStream(jsm, STREAM, SUBJECT_STAR); jsm.AddOrUpdateConsumer(STREAM, builder.WithFilterSubject(SubjectDot("A")).Build()); Assert.Throws <NATSJetStreamException>(() => jsm.AddOrUpdateConsumer(STREAM, builder.WithFilterSubject(SubjectDot("not-match")).Build())); // gt subject jsm.DeleteStream(STREAM); CreateMemoryStream(jsm, STREAM, SUBJECT_GT); jsm.AddOrUpdateConsumer(STREAM, builder.WithFilterSubject(SubjectDot("A")).Build()); Assert.Throws <NATSJetStreamException>(() => jsm.AddOrUpdateConsumer(STREAM, builder.WithFilterSubject(SubjectDot("not-match")).Build())); // try to filter against durable with mismatch, pull IJetStream js = c.CreateJetStreamContext(); jsm.AddOrUpdateConsumer(STREAM, ConsumerConfiguration.Builder() .WithDurable(Durable(42)) .WithFilterSubject(SubjectDot("F")) .Build() ); }); }
public void TestInvalidConsumerUpdates() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); CreateMemoryStream(jsm, STREAM, SUBJECT_GT); ConsumerConfiguration cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithDeliverPolicy(DeliverPolicy.New).Build(); AssertInvalidConsumerUpdate(jsm, cc); cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithFilterSubject(SUBJECT_STAR).Build(); AssertInvalidConsumerUpdate(jsm, cc); cc = PrepForUpdateTest(jsm); cc = ConsumerConfiguration.Builder(cc).WithIdleHeartbeat(Duration.OfMillis(111)).Build(); AssertInvalidConsumerUpdate(jsm, cc); }); }
public void TestAddDeleteConsumer() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); CreateMemoryStream(jsm, STREAM, Subject(0), Subject(1)); IList <ConsumerInfo> list = jsm.GetConsumers(STREAM); Assert.Empty(list); // Assert.Throws<ArgumentException>(() => ConsumerConfiguration cc = ConsumerConfiguration.Builder().Build(); Assert.Throws <ArgumentException>(() => jsm.AddOrUpdateConsumer(null, cc)); Assert.Throws <ArgumentNullException>(() => jsm.AddOrUpdateConsumer(STREAM, null)); Assert.Throws <ArgumentNullException>(() => jsm.AddOrUpdateConsumer(STREAM, cc)); ConsumerConfiguration cc0 = ConsumerConfiguration.Builder() .WithDurable(Durable(0)) .Build(); ConsumerInfo ci = jsm.AddOrUpdateConsumer(STREAM, cc0); Assert.Equal(Durable(0), ci.Name); Assert.Equal(Durable(0), ci.ConsumerConfiguration.Durable); Assert.Empty(ci.ConsumerConfiguration.DeliverSubject); ConsumerConfiguration cc1 = ConsumerConfiguration.Builder() .WithDurable(Durable(1)) .WithDeliverSubject(Deliver(1)) .Build(); ci = jsm.AddOrUpdateConsumer(STREAM, cc1); Assert.Equal(Durable(1), ci.Name); Assert.Equal(Durable(1), ci.ConsumerConfiguration.Durable); Assert.Equal(Deliver(1), ci.ConsumerConfiguration.DeliverSubject); IList <string> consumers = jsm.GetConsumerNames(STREAM); Assert.Equal(2, consumers.Count); Assert.True(jsm.DeleteConsumer(STREAM, cc1.Durable)); consumers = jsm.GetConsumerNames(STREAM); Assert.Single(consumers); Assert.Throws <NATSJetStreamException>(() => jsm.DeleteConsumer(STREAM, cc1.Durable)); }); }
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(); }
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]); }); }
// ---------------------------------------------------------------------------------------------------- // Pull // ---------------------------------------------------------------------------------------------------- private static void SubPull(Context ctx, IConnection c, Stats stats, int id) { IJetStream js = c.CreateJetStreamContext(ctx.GetJetStreamOptions()); // Really only need to lock when queueing b/c it's the same durable... // To ensure protection from multiple threads trying make the same consumer because string durable = ctx.GetSubDurable(id); IJetStreamPullSubscription sub; lock (QueueLock) { sub = js.PullSubscribe(ctx.Subject, ConsumerConfiguration.Builder() .WithAckPolicy(ctx.AckPolicy) .WithAckWait(ctx.AckWaitSeconds) .WithDurable(durable) .BuildPullSubscribeOptions() ); } _subPullFetch(ctx, stats, sub, id, durable); }
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); }); }
public void TestValidateDurableRequired() { AllowedRequired((s, r) => Validator.ValidateDurableRequired(s, null), Plain, HasPrintable); NotAllowedRequired((s, r) => Validator.ValidateDurableRequired(s, null), null, string.Empty, HasSpace, HasDot, HasStar, HasGt, HasLow, Has127); NotAllowedRequired((s, r) => Validator.ValidateDurableRequired(s, null), _utfOnlyStrings); foreach (var data in new [] { Plain, HasPrintable, HasDollar }) { ConsumerConfiguration ccAllowed = ConsumerConfiguration.Builder().WithDurable(data).Build(); Assert.Equal(data, Validator.ValidateDurableRequired(null, ccAllowed)); } foreach (var data in new [] { null, string.Empty, HasSpace, HasDot, HasStar, HasGt, HasLow, Has127 }) { ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithDurable(data).Build(); NotAllowedRequired((s, r) => Validator.ValidateDurableRequired(null, cc)); } foreach (var data in _utfOnlyStrings) { ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithDurable(data).Build(); NotAllowedRequired((s, r) => Validator.ValidateDurableRequired(null, cc)); } }
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); }); }
private ConsumerConfiguration.ConsumerConfigurationBuilder PullDurableBuilder() { return(ConsumerConfiguration.Builder().WithDurable(PULL_DURABLE)); }
private ConsumerConfiguration.ConsumerConfigurationBuilder PushDurableBuilder() { return(ConsumerConfiguration.Builder().WithDurable(PUSH_DURABLE).WithDeliverSubject(DELIVER)); }
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 }); }
private void SetupConsumer(IJetStreamManagement jsm, int i, String fs) { jsm.AddOrUpdateConsumer(STREAM, ConsumerConfiguration.Builder().WithDeliverSubject(Deliver(i)).WithDurable(Durable(i)).WithFilterSubject(fs).Build()); }
public void TestFilterSubjectEphemeral() { Context.RunInJsServer(c => { // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); string subjectWild = SUBJECT + ".*"; string subjectA = SUBJECT + ".A"; string subjectB = SUBJECT + ".B"; // create the stream. CreateMemoryStream(c, STREAM, subjectWild); JsPublish(js, subjectA, 1); JsPublish(js, subjectB, 1); JsPublish(js, subjectA, 1); JsPublish(js, subjectB, 1); // subscribe to the wildcard ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithAckPolicy(AckPolicy.None).Build(); PushSubscribeOptions pso = PushSubscribeOptions.Builder().WithConfiguration(cc).Build(); IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(subjectWild, pso); c.Flush(1000); Msg m = sub.NextMessage(1000); Assert.Equal(subjectA, m.Subject); Assert.Equal(1U, m.MetaData.StreamSequence); m = sub.NextMessage(1000); Assert.Equal(subjectB, m.Subject); Assert.Equal(2U, m.MetaData.StreamSequence); m = sub.NextMessage(1000); Assert.Equal(subjectA, m.Subject); Assert.Equal(3U, m.MetaData.StreamSequence); m = sub.NextMessage(1000); Assert.Equal(subjectB, m.Subject); Assert.Equal(4U, m.MetaData.StreamSequence); // subscribe to A cc = ConsumerConfiguration.Builder().WithFilterSubject(subjectA).WithAckPolicy(AckPolicy.None).Build(); pso = PushSubscribeOptions.Builder().WithConfiguration(cc).Build(); sub = js.PushSubscribeSync(subjectWild, pso); c.Flush(1000); m = sub.NextMessage(1000); Assert.Equal(subjectA, m.Subject); Assert.Equal(1U, m.MetaData.StreamSequence); m = sub.NextMessage(1000); Assert.Equal(subjectA, m.Subject); Assert.Equal(3U, m.MetaData.StreamSequence); Assert.Throws <NATSTimeoutException>(() => sub.NextMessage(1000)); // subscribe to B cc = ConsumerConfiguration.Builder().WithFilterSubject(subjectB).WithAckPolicy(AckPolicy.None).Build(); pso = PushSubscribeOptions.Builder().WithConfiguration(cc).Build(); sub = js.PushSubscribeSync(subjectWild, pso); c.Flush(1000); m = sub.NextMessage(1000); Assert.Equal(subjectB, m.Subject); Assert.Equal(2U, m.MetaData.StreamSequence); m = sub.NextMessage(1000); Assert.Equal(subjectB, m.Subject); Assert.Equal(4U, m.MetaData.StreamSequence); Assert.Throws <NATSTimeoutException>(() => sub.NextMessage(1000)); }); }
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 void TestDeliveryPolicy() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); IJetStream js = c.CreateJetStreamContext(); CreateMemoryStream(jsm, STREAM, SUBJECT_STAR); string subjectA = SubjectDot("A"); string subjectB = SubjectDot("B"); js.Publish(subjectA, DataBytes(1)); js.Publish(subjectA, DataBytes(2)); Thread.Sleep(1500); js.Publish(subjectA, DataBytes(3)); js.Publish(subjectB, DataBytes(91)); js.Publish(subjectB, DataBytes(92)); // DeliverPolicy.All PushSubscribeOptions pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverPolicy(DeliverPolicy.All).Build()) .Build(); IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(subjectA, pso); Msg m1 = sub.NextMessage(1000); AssertMessage(m1, 1); Msg m2 = sub.NextMessage(1000); AssertMessage(m2, 2); Msg m3 = sub.NextMessage(1000); AssertMessage(m3, 3); // DeliverPolicy.Last pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverPolicy(DeliverPolicy.Last).Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); Msg m = sub.NextMessage(1000); AssertMessage(m, 3); AssertNoMoreMessages(sub); // DeliverPolicy.New - No new messages between subscribe and next message pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverPolicy(DeliverPolicy.New).Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); AssertNoMoreMessages(sub); // DeliverPolicy.New - New message between subscribe and next message sub = js.PushSubscribeSync(subjectA, pso); js.Publish(subjectA, DataBytes(4)); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.ByStartSequence pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartSequence) .WithStartSequence(3) .Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 3); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.ByStartTime pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartTime) .WithStartTime(m3.MetaData.Timestamp.AddSeconds(-1)) .Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 3); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.LastPerSubject pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.LastPerSubject) .WithFilterSubject(subjectA) .Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.ByStartSequence with a deleted record PublishAck pa4 = js.Publish(subjectA, DataBytes(4)); PublishAck pa5 = js.Publish(subjectA, DataBytes(5)); js.Publish(subjectA, DataBytes(6)); jsm.DeleteMessage(STREAM, pa4.Seq); jsm.DeleteMessage(STREAM, pa5.Seq); pso = ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartSequence) .WithStartSequence(pa4.Seq) .BuildPushSubscribeOptions(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 6); }); }