Skip to content

Commit

Permalink
Create snapshot functionality (#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
DaneAffinity authored Dec 9, 2023
1 parent 04a2e7f commit 756ca6a
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 0 deletions.
9 changes: 9 additions & 0 deletions examples/Example/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ async static Task Main(string[] args)

// Example retrieve health information
await ExampleRetrieveHealth(typesenseClient);

// Example create collection snapshot
await ExampleCreateSnapshot(typesenseClient);
}

private static async Task ExampleCreateCollection(ITypesenseClient typesenseClient)
Expand Down Expand Up @@ -482,4 +485,10 @@ private static async Task ExampleRetrieveHealth(ITypesenseClient typesenseClient
var health = await typesenseClient.RetrieveHealth();
Console.WriteLine($"Retrieved stats: {JsonSerializer.Serialize(health)}");
}

private static async Task ExampleCreateSnapshot(ITypesenseClient typesenseClient)
{
var snapshotResponse = await typesenseClient.CreateSnapshot("/my_snapshot_path");
Console.WriteLine($"Snapshot: {JsonSerializer.Serialize(snapshotResponse)}");
}
}
15 changes: 15 additions & 0 deletions src/Typesense/ITypesenseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -689,4 +689,19 @@ Task<List<ImportResponse>> ImportDocuments<T>(
/// <exception cref="TypesenseApiException"></exception>
/// <exception cref="TypesenseApiServiceUnavailableException"></exception>
Task<HealthResponse> RetrieveHealth(CancellationToken ctk = default);

/// <summary>
/// Asynchronously initiates a snapshot operation on the Typesense server.
/// </summary>
/// <param name="snapshotPath">The file system path on the Typesense server where the snapshot data will be written.</param>
/// <param name="ctk">The optional cancellation token.</param>
/// <returns>
/// A task that represents the asynchronous operation. The task result contains the outcome of the snapshot creation.
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="TypesenseApiException"></exception>
/// <exception cref="TypesenseApiBadRequestException"></exception>
/// <exception cref="TypesenseApiNotFoundException"></exception>
/// <exception cref="TypesenseApiServiceUnavailableException"></exception>
Task<SnapshotResponse> CreateSnapshot(string snapshotPath, CancellationToken ctk = default);
}
15 changes: 15 additions & 0 deletions src/Typesense/SnapshotResponse.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;

namespace Typesense;

public record SnapshotResponse
{
[JsonPropertyName("success")]
public bool Success { get; init; }

[JsonConstructor]
public SnapshotResponse(bool success)
{
Success = success;
}
}
24 changes: 24 additions & 0 deletions src/Typesense/TypesenseClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,17 @@ public async Task<HealthResponse> RetrieveHealth(CancellationToken ctk = default
return HandleEmptyStringJsonSerialize<HealthResponse>(response);
}

public async Task<SnapshotResponse> CreateSnapshot(string snapshotPath, CancellationToken ctk = default)
{
if (string.IsNullOrWhiteSpace(snapshotPath))
throw new ArgumentException(
"The snapshot path must not be null, empty or consist of whitespace characters only.",
nameof(snapshotPath));

var response = await Post($"/operations/snapshot?snapshot_path={Uri.EscapeDataString(snapshotPath)}", ctk).ConfigureAwait(false);
return HandleEmptyStringJsonSerialize<SnapshotResponse>(response, _jsonNameCaseInsentiveTrue);
}

private static string CreateUrlParameters<T>(T queryParameters)
where T : notnull
{
Expand Down Expand Up @@ -610,6 +621,19 @@ private async Task<string> Delete(string path, CancellationToken ctk = default)
: throw GetException(response.StatusCode, responseString);
}

private async Task<string> Post(string path, CancellationToken ctk = default)
{
var postAsyncContentNull = async (string path, CancellationToken ctk) =>
{
return await _httpClient.PostAsync(path, null, ctk).ConfigureAwait(false);
};

var (response, responseString) = await HandleHttpResponse(postAsyncContentNull, path, ctk).ConfigureAwait(false);
return response.IsSuccessStatusCode
? responseString
: throw GetException(response.StatusCode, responseString);
}

private async Task<string> Post(string path, string json, CancellationToken ctk = default)
{
using var stringContent = GetApplicationJsonStringContent(json);
Expand Down
11 changes: 11 additions & 0 deletions test/Typesense.Tests/TypesenseClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1840,6 +1840,17 @@ public async Task Can_retrieve_health()
}
}

[Fact, TestPriority(35)]
public async Task Can_create_snapshot()
{
var response = await _client.CreateSnapshot("/my_snapshot_path");

using (var scope = new AssertionScope())
{
response.Success.Should().BeTrue();
}
}

private async Task CreateCompanyCollection()
{
var schema = new Schema(
Expand Down

0 comments on commit 756ca6a

Please sign in to comment.