This is an automated email from the ASF dual-hosted git repository.

maciej pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iggy.git


The following commit(s) were added to refs/heads/master by this push:
     new bdf0b2e3f feat(csharp): implement get_snapshot method in C# SDK (#2698)
bdf0b2e3f is described below

commit bdf0b2e3fda3cde5d065a1768ea98b965afcc780
Author: Atharva Lade <[email protected]>
AuthorDate: Sun Feb 8 13:11:57 2026 -0600

    feat(csharp): implement get_snapshot method in C# SDK (#2698)
---
 .../Iggy_SDK.Tests.Integration/SystemTests.cs      | 17 +++++++++++++++
 .../csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs  | 15 +++++++++++++
 .../csharp/Iggy_SDK/Enums/SnapshotCompression.cs   | 12 +++++------
 .../csharp/Iggy_SDK/Enums/SystemSnapshotType.cs    | 14 ++++++------
 foreign/csharp/Iggy_SDK/IggyClient/IIggySystem.cs  | 16 ++++++++++++++
 .../Implementations/HttpMessageStream.cs           | 25 ++++++++++++++++++++++
 .../IggyClient/Implementations/TcpMessageStream.cs | 11 ++++++++++
 7 files changed, 97 insertions(+), 13 deletions(-)

diff --git a/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs 
b/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs
index 5bb7acd78..3cc9a446c 100644
--- a/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs
+++ b/foreign/csharp/Iggy_SDK.Tests.Integration/SystemTests.cs
@@ -181,6 +181,23 @@ public class SystemTests
         await Should.NotThrowAsync(Fixture.Clients[protocol].PingAsync());
     }
 
+    [Test]
+    [DependsOn(nameof(Ping_Should_Pong))]
+    
[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
+    public async Task GetSnapshot_Should_Return_ValidZipData(Protocol protocol)
+    {
+        var snapshot = await Fixture.Clients[protocol].GetSnapshotAsync(
+            SnapshotCompression.Deflated,
+            [SystemSnapshotType.Test]);
+
+        snapshot.ShouldNotBeNull();
+        snapshot.Length.ShouldBeGreaterThan(0);
+
+        // Verify it's a valid ZIP archive by checking the ZIP magic bytes 
(PK\x03\x04)
+        snapshot[0].ShouldBe((byte)'P');
+        snapshot[1].ShouldBe((byte)'K');
+    }
+
     // [Test]
     // [DependsOn(nameof(Ping_Should_Pong))]
     // 
[MethodDataSource<IggyServerFixture>(nameof(IggyServerFixture.ProtocolData))]
diff --git a/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs 
b/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs
index 1a0da05f2..9764d196e 100644
--- a/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs
+++ b/foreign/csharp/Iggy_SDK/Contracts/Tcp/TcpContracts.cs
@@ -837,6 +837,21 @@ internal static class TcpContracts
         };
     }
 
+    internal static byte[] GetSnapshot(SnapshotCompression compression, 
IList<SystemSnapshotType> snapshotTypes)
+    {
+        // Binary format: [compression_code: u8] [types_count: u8] 
[type_code_1: u8] [type_code_2: u8] ...
+        var length = 1 + 1 + snapshotTypes.Count;
+        Span<byte> bytes = stackalloc byte[length];
+        bytes[0] = (byte)compression;
+        bytes[1] = (byte)snapshotTypes.Count;
+        for (var i = 0; i < snapshotTypes.Count; i++)
+        {
+            bytes[2 + i] = (byte)snapshotTypes[i];
+        }
+
+        return bytes.ToArray();
+    }
+
     internal static byte[] DeleteOffset(Identifier streamId, Identifier 
topicId, Consumer consumer, uint? partitionId)
     {
         Span<byte> bytes =
diff --git a/foreign/csharp/Iggy_SDK/Enums/SnapshotCompression.cs 
b/foreign/csharp/Iggy_SDK/Enums/SnapshotCompression.cs
index dcb853556..b3a475a1c 100644
--- a/foreign/csharp/Iggy_SDK/Enums/SnapshotCompression.cs
+++ b/foreign/csharp/Iggy_SDK/Enums/SnapshotCompression.cs
@@ -23,20 +23,20 @@ namespace Apache.Iggy.Enums;
 public enum SnapshotCompression
 {
     /// Store the file as is
-    Stored,
+    Stored = 1,
 
     /// Compress the file using Deflate
-    Deflated,
+    Deflated = 2,
 
     /// Compress the file using BZIP2
-    Bzip2,
+    Bzip2 = 3,
 
     /// Compress the file using ZStandard
-    Zstd,
+    Zstd = 4,
 
     /// Compress the file using LZMA
-    Lzma,
+    Lzma = 5,
 
     /// Compress the file using XZ
-    Xz
+    Xz = 6
 }
diff --git a/foreign/csharp/Iggy_SDK/Enums/SystemSnapshotType.cs 
b/foreign/csharp/Iggy_SDK/Enums/SystemSnapshotType.cs
index 51c0e9db0..56c1b28d3 100644
--- a/foreign/csharp/Iggy_SDK/Enums/SystemSnapshotType.cs
+++ b/foreign/csharp/Iggy_SDK/Enums/SystemSnapshotType.cs
@@ -23,23 +23,23 @@ namespace Apache.Iggy.Enums;
 public enum SystemSnapshotType
 {
     /// Overview of the filesystem.
-    FilesystemOverview,
+    FilesystemOverview = 1,
 
     /// List of currently running processes.
-    ProcessList,
+    ProcessList = 2,
 
     /// Resource usage statistics of the system.
-    ResourceUsage,
+    ResourceUsage = 3,
 
     /// Test snapshot type for development purposes.
-    Test,
+    Test = 4,
 
     /// Server logs
-    ServerLogs,
+    ServerLogs = 5,
 
     /// Server configuration
-    ServerConfig,
+    ServerConfig = 6,
 
     /// Everything
-    All
+    All = 100
 }
diff --git a/foreign/csharp/Iggy_SDK/IggyClient/IIggySystem.cs 
b/foreign/csharp/Iggy_SDK/IggyClient/IIggySystem.cs
index 79c4460e1..32acfcec8 100644
--- a/foreign/csharp/Iggy_SDK/IggyClient/IIggySystem.cs
+++ b/foreign/csharp/Iggy_SDK/IggyClient/IIggySystem.cs
@@ -16,6 +16,7 @@
 // under the License.
 
 using Apache.Iggy.Contracts;
+using Apache.Iggy.Enums;
 
 namespace Apache.Iggy.IggyClient;
 
@@ -90,4 +91,19 @@ public interface IIggySystem
     /// <param name="token">The cancellation token to cancel the 
operation.</param>
     /// <returns>A task representing the asynchronous operation.</returns>
     Task PingAsync(CancellationToken token = default);
+
+    /// <summary>
+    ///     Captures and packages the current system state as a snapshot.
+    /// </summary>
+    /// <remarks>
+    ///     The snapshot is returned as raw bytes of a ZIP archive. The 
contents depend on
+    ///     the requested snapshot types (filesystem overview, process list, 
resource usage, etc.).
+    ///     Authentication is required.
+    /// </remarks>
+    /// <param name="compression">The compression method to use for the 
snapshot archive.</param>
+    /// <param name="snapshotTypes">The types of system information to include 
in the snapshot.</param>
+    /// <param name="token">The cancellation token to cancel the 
operation.</param>
+    /// <returns>A task that represents the asynchronous operation and returns 
the snapshot as raw bytes of a ZIP archive.</returns>
+    Task<byte[]> GetSnapshotAsync(SnapshotCompression compression, 
IList<SystemSnapshotType> snapshotTypes,
+        CancellationToken token = default);
 }
diff --git 
a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs 
b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs
index 73db25c1d..fc293a39f 100644
--- a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs
+++ b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/HttpMessageStream.cs
@@ -455,6 +455,31 @@ public class HttpMessageStream : IIggyClient
         }
     }
 
+    /// <inheritdoc />
+    public async Task<byte[]> GetSnapshotAsync(SnapshotCompression compression,
+        IList<SystemSnapshotType> snapshotTypes, CancellationToken token = 
default)
+    {
+        // Rust serde uses default derive (PascalCase) for these enums, not 
snake_case.
+        // We use .ToString() to produce PascalCase names matching Rust's 
serde expectations.
+        var request = new
+        {
+            compression = compression.ToString(),
+            snapshot_types = snapshotTypes.Select(t => t.ToString()).ToList()
+        };
+        var json = JsonSerializer.Serialize(request, _jsonSerializerOptions);
+        var data = new StringContent(json, Encoding.UTF8, "application/json");
+
+        var response = await _httpClient.PostAsync("/snapshot", data, token);
+
+        if (response.IsSuccessStatusCode)
+        {
+            return await response.Content.ReadAsByteArrayAsync(token);
+        }
+
+        await HandleResponseAsync(response);
+        return [];
+    }
+
     /// <inheritdoc />
     public Task ConnectAsync(CancellationToken token = default)
     {
diff --git 
a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs 
b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs
index 1d7c665a6..a952338f2 100644
--- a/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs
+++ b/foreign/csharp/Iggy_SDK/IggyClient/Implementations/TcpMessageStream.cs
@@ -535,6 +535,17 @@ public sealed class TcpMessageStream : IIggyClient
         await SendWithResponseAsync(payload, token);
     }
 
+    /// <inheritdoc />
+    public async Task<byte[]> GetSnapshotAsync(SnapshotCompression compression,
+        IList<SystemSnapshotType> snapshotTypes, CancellationToken token = 
default)
+    {
+        var message = TcpContracts.GetSnapshot(compression, snapshotTypes);
+        var payload = new byte[4 + BufferSizes.INITIAL_BYTES_LENGTH + 
message.Length];
+        TcpMessageStreamHelpers.CreatePayload(payload, message, 
CommandCodes.GET_SNAPSHOT_CODE);
+
+        return await SendWithResponseAsync(payload, token);
+    }
+
     /// <inheritdoc />
     public async Task ConnectAsync(CancellationToken token = default)
     {

Reply via email to