mirror of https://github.com/dapr/dotnet-sdk.git
Add support for delete operations (#198)
* Add support for delete operations * Removing extra spaces to fix build break. Co-authored-by: Aman Bhardwaj <amanbha@users.noreply.github.com>
This commit is contained in:
parent
c4f80f10b6
commit
b02aa3f02b
|
|
@ -52,5 +52,13 @@ namespace Dapr
|
|||
/// <typeparam name="TValue">The data type.</typeparam>
|
||||
/// <returns>A <see cref="ValueTask" /> that will complete when the operation has completed.</returns>
|
||||
public abstract ValueTask SaveStateAsync<TValue>(string key, TValue value, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the value associated with the provided <paramref name="key" /> in the Dapr state store.
|
||||
/// </summary>
|
||||
/// <param name="key">The state key.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask" /> that will complete when the operation has completed.</returns>
|
||||
public abstract ValueTask DeleteStateAsync(string key, CancellationToken cancellationToken = default);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,10 +56,20 @@ namespace Dapr
|
|||
public TValue Value { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Saves the the current value of <see cref="Value" /> to the state store.
|
||||
/// Deletes the entry assocated with <see cref="Key" /> in the state store.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="Task" /> that will complete when the operation has completed.</returns>
|
||||
/// <returns>A <see cref="ValueTask" /> that will complete when the operation has completed.</returns>
|
||||
public ValueTask DeleteAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return this.client.DeleteStateAsync(this.Key, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves the current value of <see cref="Value" /> to the state store.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask" /> that will complete when the operation has completed.</returns>
|
||||
public ValueTask SaveAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
return this.client.SaveStateAsync(this.Key, this.Value, cancellationToken);
|
||||
|
|
|
|||
|
|
@ -122,6 +122,44 @@ namespace Dapr
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the value associated with the provided <paramref name="key" /> in the Dapr state store.
|
||||
/// </summary>
|
||||
/// <param name="key">The state key.</param>
|
||||
/// <param name="cancellationToken">A <see cref="CancellationToken" /> that can be used to cancel the operation.</param>
|
||||
/// <returns>A <see cref="ValueTask" /> that will complete when the operation has completed.</returns>
|
||||
public async override ValueTask DeleteStateAsync(string key, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
throw new ArgumentException("The value cannot be null or empty.", nameof(key));
|
||||
}
|
||||
|
||||
// Docs: https://github.com/dapr/docs/blob/master/reference/api/state.md#delete-state
|
||||
var url = this.client.BaseAddress == null ? $"http://localhost:{DefaultHttpPort}{StatePath}/{key}" : $"{StatePath}/{key}";
|
||||
var request = new HttpRequestMessage(HttpMethod.Delete, url);
|
||||
|
||||
var response = await this.client.SendAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
// 200: success
|
||||
//
|
||||
// To avoid being overload coupled we handle a range of 2XX status codes in common use for DELETEs.
|
||||
if ((int)response.StatusCode >= 200 && (int)response.StatusCode <= 204)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.Content != null)
|
||||
{
|
||||
var error = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||
throw new HttpRequestException($"Failed to delete state with status code '{response.StatusCode}': {error}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new HttpRequestException($"Failed to delete state with status code '{response.StatusCode}'.");
|
||||
}
|
||||
}
|
||||
|
||||
private static AsyncJsonContent<T> CreateContent<T>(T obj, JsonSerializerOptions serializerOptions)
|
||||
{
|
||||
return new AsyncJsonContent<T>(obj, serializerOptions);
|
||||
|
|
|
|||
|
|
@ -27,15 +27,13 @@ namespace Dapr
|
|||
|
||||
public override ValueTask SaveStateAsync<TValue>(string key, TValue value, CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
this.State.Remove(key);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.State[key] = value;
|
||||
}
|
||||
this.State[key] = value;
|
||||
return new ValueTask(Task.CompletedTask);
|
||||
}
|
||||
|
||||
public override ValueTask DeleteStateAsync(string key, CancellationToken cancellationToken = default)
|
||||
{
|
||||
this.State.Remove(key);
|
||||
return new ValueTask(Task.CompletedTask);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -175,6 +175,37 @@ namespace Dapr.Client.Test
|
|||
await task;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteStateAsync_CanDeleteState()
|
||||
{
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new StateHttpClient(httpClient, new JsonSerializerOptions());
|
||||
|
||||
var task = client.DeleteStateAsync("test");
|
||||
|
||||
httpClient.Requests.TryDequeue(out var entry).Should().BeTrue();
|
||||
entry.Request.RequestUri.ToString().Should().Be(DeleteStateUrl(3500, "test"));
|
||||
|
||||
entry.Respond(new HttpResponseMessage(HttpStatusCode.OK));
|
||||
await task;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeleteStateAsync_ThrowsForNonSuccess()
|
||||
{
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new StateHttpClient(httpClient, new JsonSerializerOptions());
|
||||
|
||||
var task = client.DeleteStateAsync("test");
|
||||
|
||||
httpClient.Requests.TryDequeue(out var entry).Should().BeTrue();
|
||||
entry.Request.RequestUri.ToString().Should().Be(DeleteStateUrl(3500, "test"));
|
||||
|
||||
entry.Respond(new HttpResponseMessage(HttpStatusCode.NotAcceptable));
|
||||
|
||||
await FluentActions.Awaiting(async () => await task).Should().ThrowAsync<HttpRequestException>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetStateEntryAsync_CanReadState()
|
||||
{
|
||||
|
|
@ -252,6 +283,34 @@ namespace Dapr.Client.Test
|
|||
await task;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetStateEntryAsync_CanDeleteState()
|
||||
{
|
||||
var httpClient = new TestHttpClient();
|
||||
var client = new StateHttpClient(httpClient, new JsonSerializerOptions());
|
||||
|
||||
var task = client.GetStateEntryAsync<Widget>("test");
|
||||
|
||||
httpClient.Requests.TryDequeue(out var entry).Should().BeTrue();
|
||||
entry.Request.RequestUri.ToString().Should().Be(GetStateUrl(3500, "test"));
|
||||
|
||||
entry.RespondWithJson(new Widget() { Size = "small", Color = "yellow", });
|
||||
|
||||
var state = await task;
|
||||
state.Key.Should().Be("test");
|
||||
state.Value.Size.Should().Be("small");
|
||||
state.Value.Color.Should().Be("yellow");
|
||||
|
||||
state.Value.Color = "green";
|
||||
var task2 = state.DeleteAsync();
|
||||
|
||||
httpClient.Requests.TryDequeue(out entry).Should().BeTrue();
|
||||
entry.Request.RequestUri.ToString().Should().Be(DeleteStateUrl(3500, "test"));
|
||||
|
||||
entry.Respond(new HttpResponseMessage(HttpStatusCode.OK));
|
||||
await task;
|
||||
}
|
||||
|
||||
private static string GetStateUrl(int port, string key)
|
||||
{
|
||||
return $"http://localhost:{port}/v1.0/state/{key}";
|
||||
|
|
@ -262,6 +321,11 @@ namespace Dapr.Client.Test
|
|||
return $"http://localhost:{port}/v1.0/state";
|
||||
}
|
||||
|
||||
private static string DeleteStateUrl(int port, string key)
|
||||
{
|
||||
return $"http://localhost:{port}/v1.0/state/{key}";
|
||||
}
|
||||
|
||||
private class Widget
|
||||
{
|
||||
public string Size { get; set; }
|
||||
|
|
|
|||
Loading…
Reference in New Issue