Skip to content

Avoid additional serialization/deserialization of response bodies #1372

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/KubernetesClient.Models/KubernetesJson.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ public static TValue Deserialize<TValue>(Stream json, JsonSerializerOptions json
return JsonSerializer.Deserialize<TValue>(json, jsonSerializerOptions ?? JsonSerializerOptions);
}


public static string Serialize(object value, JsonSerializerOptions jsonSerializerOptions = null)
{
return JsonSerializer.Serialize(value, jsonSerializerOptions ?? JsonSerializerOptions);
Expand Down
60 changes: 30 additions & 30 deletions src/KubernetesClient/GenericClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,112 +36,112 @@ public GenericClient(IKubernetes kubernetes, string group, string version, strin
public async Task<T> CreateAsync<T>(T obj, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.CreateClusterCustomObjectWithHttpMessagesAsync(obj, group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.CreateClusterCustomObjectWithHttpMessagesAsync<T>(obj, group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> CreateNamespacedAsync<T>(T obj, string ns, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.CreateNamespacedCustomObjectWithHttpMessagesAsync(obj, group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.CreateNamespacedCustomObjectWithHttpMessagesAsync<T>(obj, group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> ListAsync<T>(CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.ListClusterCustomObjectWithHttpMessagesAsync(group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.ListClusterCustomObjectWithHttpMessagesAsync<T>(group, version, plural, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> ListNamespacedAsync<T>(string ns, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.ListNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.ListNamespacedCustomObjectWithHttpMessagesAsync<T>(group, version, ns, plural, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> ReadNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.GetNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.GetNamespacedCustomObjectWithHttpMessagesAsync<T>(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> ReadAsync<T>(string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.GetClusterCustomObjectWithHttpMessagesAsync(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.GetClusterCustomObjectWithHttpMessagesAsync<T>(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> DeleteAsync<T>(string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.DeleteClusterCustomObjectWithHttpMessagesAsync(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.DeleteClusterCustomObjectWithHttpMessagesAsync<T>(group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> DeleteNamespacedAsync<T>(string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.DeleteNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.DeleteNamespacedCustomObjectWithHttpMessagesAsync<T>(group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> PatchAsync<T>(V1Patch patch, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.PatchClusterCustomObjectWithHttpMessagesAsync(patch, group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.PatchClusterCustomObjectWithHttpMessagesAsync<T>(patch, group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> PatchNamespacedAsync<T>(V1Patch patch, string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.PatchNamespacedCustomObjectWithHttpMessagesAsync(patch, group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.PatchNamespacedCustomObjectWithHttpMessagesAsync<T>(patch, group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> ReplaceAsync<T>(T obj, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.ReplaceClusterCustomObjectWithHttpMessagesAsync(obj, group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.ReplaceClusterCustomObjectWithHttpMessagesAsync<T>(obj, group, version, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public async Task<T> ReplaceNamespacedAsync<T>(T obj, string ns, string name, CancellationToken cancel = default)
where T : IKubernetesObject
{
var resp = await kubernetes.CustomObjects.ReplaceNamespacedCustomObjectWithHttpMessagesAsync(obj, group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return KubernetesJson.Deserialize<T>(resp.Body.ToString());
var resp = await kubernetes.CustomObjects.ReplaceNamespacedCustomObjectWithHttpMessagesAsync<T>(obj, group, version, ns, plural, name, cancellationToken: cancel).ConfigureAwait(false);
return resp.Body;
}

public IAsyncEnumerable<(WatchEventType, T)> WatchAsync<T>(Action<Exception> onError = null, CancellationToken cancel = default)
where T : IKubernetesObject
{
var respTask = kubernetes.CustomObjects.ListClusterCustomObjectWithHttpMessagesAsync(group, version, plural, watch: true, cancellationToken: cancel);
return respTask.WatchAsync<T, object>();
var respTask = kubernetes.CustomObjects.ListClusterCustomObjectWithHttpMessagesAsync<T>(group, version, plural, watch: true, cancellationToken: cancel);
return respTask.WatchAsync<T, T>();
}

public IAsyncEnumerable<(WatchEventType, T)> WatchNamespacedAsync<T>(string ns, Action<Exception> onError = null, CancellationToken cancel = default)
where T : IKubernetesObject
{
var respTask = kubernetes.CustomObjects.ListNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, watch: true, cancellationToken: cancel);
return respTask.WatchAsync<T, object>();
var respTask = kubernetes.CustomObjects.ListNamespacedCustomObjectWithHttpMessagesAsync<T>(group, version, ns, plural, watch: true, cancellationToken: cancel);
return respTask.WatchAsync<T, T>();
}

public Watcher<T> Watch<T>(Action<WatchEventType, T> onEvent, Action<Exception> onError = null, Action onClosed = null)
where T : IKubernetesObject
{
var respTask = kubernetes.CustomObjects.ListClusterCustomObjectWithHttpMessagesAsync(group, version, plural, watch: true);
var respTask = kubernetes.CustomObjects.ListClusterCustomObjectWithHttpMessagesAsync<T>(group, version, plural, watch: true);
return respTask.Watch(onEvent, onError, onClosed);
}

public Watcher<T> WatchNamespaced<T>(string ns, Action<WatchEventType, T> onEvent, Action<Exception> onError = null, Action onClosed = null)
where T : IKubernetesObject
{
var respTask = kubernetes.CustomObjects.ListNamespacedCustomObjectWithHttpMessagesAsync(group, version, ns, plural, watch: true);
var respTask = kubernetes.CustomObjects.ListNamespacedCustomObjectWithHttpMessagesAsync<T>(group, version, ns, plural, watch: true);
return respTask.Watch(onEvent, onError, onClosed);
}

Expand Down
23 changes: 23 additions & 0 deletions src/LibKubernetesGenerator/templates/IOperations.cs.template
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,28 @@ public partial interface I{{name}}Operations
IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders = null,
CancellationToken cancellationToken = default);

{{#IfReturnType operation "object"}}
/// <summary>
/// {{ToXmlDoc operation.description}}
/// </summary>
{{#operation.parameters}}
/// <param name="{{GetDotNetName .}}">
/// {{ToXmlDoc description}}
/// </param>
{{/operation.parameters}}
/// <param name="customHeaders">
/// The headers that will be added to request.
/// </param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
/// </param>
Task<HttpOperationResponse<T>> {{GetMethodName operation "WithHttpMessagesAsync"}}<T>(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName . "true"}},
{{/operation.parameters}}
IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders = null,
CancellationToken cancellationToken = default);
{{/IfReturnType operation "object"}}

{{/apis}}
}
67 changes: 63 additions & 4 deletions src/LibKubernetesGenerator/templates/Operations.cs.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,15 @@ namespace k8s;
public partial class AbstractKubernetes : I{{name}}Operations
{
{{#apis}}
/// <inheritdoc/>
async Task<HttpOperationResponse{{GetReturnType operation "<>"}}> I{{name}}Operations.{{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#IfReturnType operation "void"}}
private async Task<HttpOperationResponse> I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}(
{{/IfReturnType operation "void"}}
{{#IfReturnType operation "obj"}}
private async Task<HttpOperationResponse<T>> I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}<T>(
{{/IfReturnType operation "obj"}}
{{#IfReturnType operation "stream"}}
private async Task<HttpOperationResponse<Stream>> I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}(
{{/IfReturnType operation "stream"}}
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName .}},
{{/operation.parameters}}
Expand Down Expand Up @@ -64,7 +71,7 @@ public partial class AbstractKubernetes : I{{name}}Operations
HttpOperationResponse result = new HttpOperationResponse() { Request = httpRequest, Response = httpResponse };
{{/IfReturnType operation "void"}}
{{#IfReturnType operation "obj"}}
var result = await CreateResultAsync{{GetReturnType operation "<>"}}(
var result = await CreateResultAsync<T>(
httpRequest,
httpResponse,
{{#IfParamContains operation "watch"}}
Expand All @@ -76,12 +83,64 @@ public partial class AbstractKubernetes : I{{name}}Operations
cancellationToken);
{{/IfReturnType operation "obj"}}
{{#IfReturnType operation "stream"}}
var result = new HttpOperationResponse{{GetReturnType operation "<>"}}() {
var result = new HttpOperationResponse<Stream>() {
Request = httpRequest,
Response = httpResponse,
Body = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false) };
{{/IfReturnType operation "stream"}}
return result;
}

/// <inheritdoc/>
async Task<HttpOperationResponse{{GetReturnType operation "<>"}}> I{{name}}Operations.{{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName .}},
{{/operation.parameters}}
IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders,
CancellationToken cancellationToken)
{
{{#IfReturnType operation "void"}}
return await I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetName .}},
{{/operation.parameters}}
customHeaders,
cancellationToken).ConfigureAwait(false);
{{/IfReturnType operation "void"}}
{{#IfReturnType operation "obj"}}
return await I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}{{GetReturnType operation "<>"}}(
{{#operation.parameters}}
{{GetDotNetName .}},
{{/operation.parameters}}
customHeaders,
cancellationToken).ConfigureAwait(false);
{{/IfReturnType operation "obj"}}
{{#IfReturnType operation "stream"}}
return await I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}(
{{#operation.parameters}}
{{GetDotNetName .}},
{{/operation.parameters}}
customHeaders,
cancellationToken).ConfigureAwait(false);
{{/IfReturnType operation "stream"}}
}

{{#IfReturnType operation "object"}}
/// <inheritdoc/>
async Task<HttpOperationResponse<T>> I{{name}}Operations.{{GetMethodName operation "WithHttpMessagesAsync"}}<T>(
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName .}},
{{/operation.parameters}}
IReadOnlyDictionary<string, IReadOnlyList<string>> customHeaders,
CancellationToken cancellationToken)
{
return await I{{name}}Operations_{{GetMethodName operation "WithHttpMessagesAsync"}}<T>(
{{#operation.parameters}}
{{GetDotNetName .}},
{{/operation.parameters}}
customHeaders,
cancellationToken).ConfigureAwait(false);
}
{{/IfReturnType operation "object"}}
{{/apis}}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,35 @@ public static partial class {{name}}OperationsExtensions
{{/operation.parameters}}
CancellationToken.None
).GetAwaiter().GetResult();
}
}

{{#IfReturnType operation "object"}}
/// <summary>
/// {{ToXmlDoc operation.description}}
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
{{#operation.parameters}}
/// <param name="{{GetDotNetName .}}">
/// {{ToXmlDoc description}}
/// </param>
{{/operation.parameters}}
public static T {{GetMethodName operation ""}}<T>(
this I{{name}}Operations operations
{{#operation.parameters}}
,{{GetDotNetType .}} {{GetDotNetName . "true"}}
{{/operation.parameters}}
)
{
return operations.{{GetMethodName operation "Async"}}<T>(
{{#operation.parameters}}
{{GetDotNetName .}},
{{/operation.parameters}}
CancellationToken.None
).GetAwaiter().GetResult();
}
{{/IfReturnType operation "object"}}

/// <summary>
/// {{ToXmlDoc operation.description}}
Expand Down Expand Up @@ -92,5 +120,39 @@ public static partial class {{name}}OperationsExtensions
{{/IfReturnType operation "void"}}
}

{{#IfReturnType operation "object"}}
/// <summary>
/// {{ToXmlDoc operation.description}}
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
{{#operation.parameters}}
/// <param name="{{GetDotNetName .}}">
/// {{ToXmlDoc description}}
/// </param>
{{/operation.parameters}}
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the asynchronous operation.
/// </param>
public static async Task<T> {{GetMethodName operation "Async"}}<T>(
this I{{name}}Operations operations,
{{#operation.parameters}}
{{GetDotNetType .}} {{GetDotNetName . "true"}},
{{/operation.parameters}}
CancellationToken cancellationToken = default(CancellationToken))
{
using (var _result = await operations.{{GetMethodName operation "WithHttpMessagesAsync"}}<T>(
{{#operation.parameters}}
{{GetDotNetName .}},
{{/operation.parameters}}
null,
cancellationToken).ConfigureAwait(false))
{
return _result.Body;
}
}
{{/IfReturnType}}

{{/apis}}
}