From c01fff4632c337ff44b8503f4592535ce2e11bba Mon Sep 17 00:00:00 2001 From: Ziya Suzen Date: Wed, 12 Mar 2025 20:27:50 +0000 Subject: [PATCH] Add overloads for client extensions --- .../NatsClientExtensions.cs | 18 ++++++++++ .../INatsKVContext.cs | 5 +++ .../NatsClientExtensions.cs | 27 ++++++++++++++ .../NatsKVContext.cs | 14 ++++---- .../ClientExtensionsTest.cs | 28 +++++++++++++++ .../ClientExtensionsTest.cs | 36 +++++++++++++++++++ 6 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 tests/NATS.Client.JetStream.Tests/ClientExtensionsTest.cs create mode 100644 tests/NATS.Client.KeyValueStore.Tests/ClientExtensionsTest.cs diff --git a/src/NATS.Client.JetStream/NatsClientExtensions.cs b/src/NATS.Client.JetStream/NatsClientExtensions.cs index 3c8c0f75b..1cb9d0530 100644 --- a/src/NATS.Client.JetStream/NatsClientExtensions.cs +++ b/src/NATS.Client.JetStream/NatsClientExtensions.cs @@ -21,4 +21,22 @@ public static INatsJSContext CreateJetStreamContext(this INatsClient client) /// Returns an instance of for interacting with JetStream. public static INatsJSContext CreateJetStreamContext(this INatsConnection connection) => new NatsJSContext(connection); + + /// + /// Creates a JetStream context using the provided NATS client. + /// + /// The NATS client used to create the JetStream context. + /// Context options. + /// Returns an instance of for interacting with JetStream. + public static INatsJSContext CreateJetStreamContext(this INatsClient client, NatsJSOpts opts) + => CreateJetStreamContext(client.Connection, opts); + + /// + /// Creates a JetStream context using the provided NATS connection. + /// + /// The NATS connection used to create the JetStream context. + /// Context options. + /// Returns an instance of for interacting with JetStream. + public static INatsJSContext CreateJetStreamContext(this INatsConnection connection, NatsJSOpts opts) + => new NatsJSContext(connection, opts); } diff --git a/src/NATS.Client.KeyValueStore/INatsKVContext.cs b/src/NATS.Client.KeyValueStore/INatsKVContext.cs index 2ceb0b3e7..89bd3da02 100644 --- a/src/NATS.Client.KeyValueStore/INatsKVContext.cs +++ b/src/NATS.Client.KeyValueStore/INatsKVContext.cs @@ -9,6 +9,11 @@ public interface INatsKVContext /// INatsJSContext JetStreamContext { get; } + /// + /// Configuration options for the Nats Key-Value Store operations used within the Key-Value Store context. + /// + NatsKVOpts Opts { get; } + /// /// Create a new Key Value Store or get an existing one /// diff --git a/src/NATS.Client.KeyValueStore/NatsClientExtensions.cs b/src/NATS.Client.KeyValueStore/NatsClientExtensions.cs index 3c616065a..de6f12b3c 100644 --- a/src/NATS.Client.KeyValueStore/NatsClientExtensions.cs +++ b/src/NATS.Client.KeyValueStore/NatsClientExtensions.cs @@ -30,4 +30,31 @@ public static INatsKVContext CreateKeyValueStoreContext(this INatsConnection con /// An instance of which can be used to interact with the Key-Value Store. public static INatsKVContext CreateKeyValueStoreContext(this INatsJSContext context) => new NatsKVContext(context); + + /// + /// Creates a NATS Key-Value Store context using the specified NATS client. + /// + /// The NATS client instance. + /// Context options. + /// An instance of which can be used to interact with the Key-Value Store. + public static INatsKVContext CreateKeyValueStoreContext(this INatsClient client, NatsKVOpts opts) + => CreateKeyValueStoreContext(client.CreateJetStreamContext(), opts); + + /// + /// Creates a NATS Key-Value Store context using the specified NATS connection. + /// + /// The NATS connection instance. + /// Context options. + /// An instance of which can be used to interact with the Key-Value Store. + public static INatsKVContext CreateKeyValueStoreContext(this INatsConnection connection, NatsKVOpts opts) + => CreateKeyValueStoreContext(connection.CreateJetStreamContext(), opts); + + /// + /// Creates a NATS Key-Value Store context using the specified NATS JetStream context. + /// + /// The NATS JetStream context instance. + /// Context options. + /// An instance of which can be used to interact with the Key-Value Store. + public static INatsKVContext CreateKeyValueStoreContext(this INatsJSContext context, NatsKVOpts opts) + => new NatsKVContext(context, opts); } diff --git a/src/NATS.Client.KeyValueStore/NatsKVContext.cs b/src/NATS.Client.KeyValueStore/NatsKVContext.cs index ab9f53563..a79ad0dfa 100644 --- a/src/NATS.Client.KeyValueStore/NatsKVContext.cs +++ b/src/NATS.Client.KeyValueStore/NatsKVContext.cs @@ -22,7 +22,6 @@ public class NatsKVContext : INatsKVContext internal const string KvStreamNamePrefix = "KV_"; private static readonly int KvStreamNamePrefixLen = KvStreamNamePrefix.Length; private static readonly Regex ValidBucketRegex = new(pattern: @"\A[a-zA-Z0-9_-]+\z", RegexOptions.Compiled); - private readonly NatsKVOpts _opts; /// /// Create a new Key Value Store context @@ -32,7 +31,7 @@ public class NatsKVContext : INatsKVContext public NatsKVContext(INatsJSContext context, NatsKVOpts opts) { JetStreamContext = context; - _opts = opts; + Opts = opts; } /// @@ -47,6 +46,9 @@ public NatsKVContext(INatsJSContext context) /// public INatsJSContext JetStreamContext { get; } + /// + public NatsKVOpts Opts { get; } + /// public ValueTask CreateStoreAsync(string bucket, CancellationToken cancellationToken = default) => CreateStoreAsync(new NatsKVConfig(bucket), cancellationToken); @@ -60,7 +62,7 @@ public async ValueTask CreateStoreAsync(NatsKVConfig config, Cance var stream = await JetStreamContext.CreateStreamAsync(streamConfig, cancellationToken); - return new NatsKVStore(config.Bucket, JetStreamContext, stream, _opts); + return new NatsKVStore(config.Bucket, JetStreamContext, stream, Opts); } /// @@ -76,7 +78,7 @@ public async ValueTask GetStoreAsync(string bucket, CancellationTo } // TODO: KV mirror - return new NatsKVStore(bucket, JetStreamContext, stream, _opts); + return new NatsKVStore(bucket, JetStreamContext, stream, Opts); } /// @@ -88,7 +90,7 @@ public async ValueTask UpdateStoreAsync(NatsKVConfig config, Cance var stream = await JetStreamContext.UpdateStreamAsync(streamConfig, cancellationToken); - return new NatsKVStore(config.Bucket, JetStreamContext, stream, _opts); + return new NatsKVStore(config.Bucket, JetStreamContext, stream, Opts); } /// @@ -100,7 +102,7 @@ public async ValueTask CreateOrUpdateStoreAsync(NatsKVConfig confi var stream = await JetStreamContext.CreateOrUpdateStreamAsync(streamConfig, cancellationToken); - return new NatsKVStore(config.Bucket, JetStreamContext, stream, _opts); + return new NatsKVStore(config.Bucket, JetStreamContext, stream, Opts); } /// diff --git a/tests/NATS.Client.JetStream.Tests/ClientExtensionsTest.cs b/tests/NATS.Client.JetStream.Tests/ClientExtensionsTest.cs new file mode 100644 index 000000000..c2f400d11 --- /dev/null +++ b/tests/NATS.Client.JetStream.Tests/ClientExtensionsTest.cs @@ -0,0 +1,28 @@ +using NATS.Net; + +namespace NATS.Client.JetStream.Tests; + +public class ClientExtensionsTest +{ + [Fact] + public void Test() + { + var opts = new NatsJSOpts(new NatsOpts(), apiPrefix: "$TEST"); + + var connection = new NatsConnection(); + Assert.IsType(connection.CreateJetStreamContext(), exactMatch: true); + Assert.IsType(connection.CreateJetStreamContext(), exactMatch: false); + Assert.IsType(connection.CreateJetStreamContext(opts), exactMatch: true); + Assert.IsType(connection.CreateJetStreamContext(opts), exactMatch: false); + Assert.Equal("$JS.API", connection.CreateJetStreamContext().Opts.ApiPrefix); + Assert.Equal("$TEST", connection.CreateJetStreamContext(opts).Opts.ApiPrefix); + + var client = new NatsClient(); + Assert.IsType(client.CreateJetStreamContext(), exactMatch: true); + Assert.IsType(client.CreateJetStreamContext(), exactMatch: false); + Assert.IsType(client.CreateJetStreamContext(opts), exactMatch: true); + Assert.IsType(client.CreateJetStreamContext(opts), exactMatch: false); + Assert.Equal("$JS.API", client.CreateJetStreamContext().Opts.ApiPrefix); + Assert.Equal("$TEST", client.CreateJetStreamContext(opts).Opts.ApiPrefix); + } +} diff --git a/tests/NATS.Client.KeyValueStore.Tests/ClientExtensionsTest.cs b/tests/NATS.Client.KeyValueStore.Tests/ClientExtensionsTest.cs new file mode 100644 index 000000000..a6e3edd5d --- /dev/null +++ b/tests/NATS.Client.KeyValueStore.Tests/ClientExtensionsTest.cs @@ -0,0 +1,36 @@ +using NATS.Net; + +namespace NATS.Client.KeyValueStore.Tests; + +public class ClientExtensionsTest +{ + [Fact] + public void Test() + { + var opts = new NatsKVOpts { UseDirectGetApiWithKeysInSubject = true }; + + var connection = new NatsConnection(); + Assert.IsType(connection.CreateKeyValueStoreContext(), exactMatch: true); + Assert.IsType(connection.CreateKeyValueStoreContext(), exactMatch: false); + Assert.IsType(connection.CreateKeyValueStoreContext(opts), exactMatch: true); + Assert.IsType(connection.CreateKeyValueStoreContext(opts), exactMatch: false); + Assert.False(connection.CreateKeyValueStoreContext().Opts.UseDirectGetApiWithKeysInSubject); + Assert.True(connection.CreateKeyValueStoreContext(opts).Opts.UseDirectGetApiWithKeysInSubject); + + var client = new NatsClient(); + Assert.IsType(client.CreateKeyValueStoreContext(), exactMatch: true); + Assert.IsType(client.CreateKeyValueStoreContext(), exactMatch: false); + Assert.IsType(client.CreateKeyValueStoreContext(opts), exactMatch: true); + Assert.IsType(client.CreateKeyValueStoreContext(opts), exactMatch: false); + Assert.False(client.CreateKeyValueStoreContext().Opts.UseDirectGetApiWithKeysInSubject); + Assert.True(client.CreateKeyValueStoreContext(opts).Opts.UseDirectGetApiWithKeysInSubject); + + var js = new NatsJSContext(connection); + Assert.IsType(js.CreateKeyValueStoreContext(), exactMatch: true); + Assert.IsType(js.CreateKeyValueStoreContext(), exactMatch: false); + Assert.IsType(js.CreateKeyValueStoreContext(opts), exactMatch: true); + Assert.IsType(js.CreateKeyValueStoreContext(opts), exactMatch: false); + Assert.False(js.CreateKeyValueStoreContext().Opts.UseDirectGetApiWithKeysInSubject); + Assert.True(js.CreateKeyValueStoreContext(opts).Opts.UseDirectGetApiWithKeysInSubject); + } +}