simplify http build code (#754)

* simplify request code

* re generate code

* remove unused tracing from websocket

* dotnet fmt

* fix warning

* fix warning

* make fmt and stylecop happy together
This commit is contained in:
Boshi Lian
2021-12-19 09:01:26 -08:00
committed by GitHub
parent 743e859889
commit 1778d446d1
5 changed files with 10156 additions and 24365 deletions

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security;
using System.Text.RegularExpressions;
using NJsonSchema;
using Nustache.Core;
@@ -20,8 +21,8 @@ namespace KubernetesGenerator
public void RegisterHelper()
{
Helpers.Register(nameof(ToXmlDoc), ToXmlDoc);
Helpers.Register(nameof(AddCurly), AddCurly);
Helpers.Register(nameof(EscapeDataString), EscapeDataString);
Helpers.Register(nameof(ToInterpolationPathString), ToInterpolationPathString);
Helpers.Register(nameof(IfGroupPathParamContainsGroup), IfGroupPathParamContainsGroup);
}
private void ToXmlDoc(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
@@ -90,42 +91,23 @@ namespace KubernetesGenerator
}
}
public void AddCurly(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
public void ToInterpolationPathString(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
RenderBlock fn, RenderBlock inverse)
{
var s = arguments?.FirstOrDefault() as string;
if (s != null)
var p = arguments?.FirstOrDefault() as string;
if (p != null)
{
context.Write("{" + s + "}");
context.Write(Regex.Replace(p, "{(.+?)}", (m) => "{" + generalNameHelper.GetDotNetName(m.Groups[1].Value) + "}"));
}
}
public void EscapeDataString(RenderContext context, IList<object> arguments,
IDictionary<string, object> options,
public void IfGroupPathParamContainsGroup(RenderContext context, IList<object> arguments, IDictionary<string, object> options,
RenderBlock fn, RenderBlock inverse)
{
var name = generalNameHelper.GetDotNetName(arguments[0] as string);
var type = arguments[1] as JsonObjectType?;
if (name == "pretty")
var p = arguments?.FirstOrDefault() as string;
if (p?.StartsWith("apis/{group}") == true)
{
context.Write($"{name}.Value ? \"true\" : \"false\"");
return;
}
switch (type)
{
case JsonObjectType.String:
context.Write($"System.Uri.EscapeDataString({name})");
break;
case JsonObjectType.Boolean:
context.Write($"{name}.Value ? \"true\" : \"false\"");
break;
case JsonObjectType.Integer:
context.Write($"{name}.Value");
break;
default:
throw new ArgumentException("type not supportted");
fn(null);
}
}
}

View File

@@ -46,42 +46,33 @@ namespace k8s
{{/operation.parameters}}
// Construct URL
var _baseUrl = BaseUri.AbsoluteUri;
var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "{{path}}").ToString();
{{#operation.parameters}}
{{#IfKindIs . "path"}}
_url = _url.Replace("{{AddCurly name}}", {{GetDotNetName name}});
{{/IfKindIs . "path"}}
{{/operation.parameters}}
_url = _url.Replace("/apis//", "/api/");
List<string> _queryParameters = new List<string>();
var url = new System.Uri(BaseUri, $"{{ToInterpolationPathString path}}").ToString();
{{#IfGroupPathParamContainsGroup path}}
url = url.Replace("/apis//", "/api/");
{{/IfGroupPathParamContainsGroup}}
var q = new QueryBuilder();
{{#operation.parameters}}
{{#IfKindIs . "query"}}
if ({{GetDotNetName name}} != null)
{
_queryParameters.Add(string.Format("{{name}}={0}", {{EscapeDataString name type}}));
}
q.Append("{{name}}", {{GetDotNetName name}});
{{/IfKindIs . "query"}}
{{/operation.parameters}}
if (_queryParameters.Count > 0)
{
_url += "?" + string.Join("&", _queryParameters);
}
url += q.ToString();
// Create HTTP transport
var _httpRequest = CreateRequest(_url, HttpMethod.{{Method}}, customHeaders);
var httpRequest = CreateRequest(url, HttpMethod.{{Method}}, customHeaders);
{{#IfParamContains operation "body"}}
var _httpResponse = await SendRequest(body, _httpRequest, cancellationToken);
var httpResponse = await SendRequest(body, httpRequest, cancellationToken);
{{/IfParamContains operation "body"}}
{{#IfParamDoesNotContain operation "body"}}
var _httpResponse = await SendRequestRaw("", _httpRequest, cancellationToken);
var httpResponse = await SendRequestRaw("", httpRequest, cancellationToken);
{{/IfParamDoesNotContain operation "body"}}
// Create Result
{{#IfReturnType operation "void"}}
HttpOperationResponse _result = new HttpOperationResponse() { Request = _httpRequest, Response = _httpResponse };
HttpOperationResponse result = new HttpOperationResponse() { Request = httpRequest, Response = httpResponse };
{{/IfReturnType operation "void"}}
{{#IfReturnType operation "obj"}}
var _result = await CreateResultAsync{{GetReturnType operation "<>"}}(_httpRequest,
_httpResponse,
var result = await CreateResultAsync{{GetReturnType operation "<>"}}(httpRequest,
httpResponse,
{{#IfParamContains operation "watch"}}
watch,
{{/IfParamContains operation "watch"}}
@@ -91,12 +82,12 @@ namespace k8s
cancellationToken);
{{/IfReturnType operation "obj"}}
{{#IfReturnType operation "stream"}}
var _result = new HttpOperationResponse{{GetReturnType operation "<>"}}() {
Request = _httpRequest,
Response = _httpResponse,
Body = await _httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false) };
var result = new HttpOperationResponse{{GetReturnType operation "<>"}}() {
Request = httpRequest,
Response = httpResponse,
Body = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false) };
{{/IfReturnType operation "stream"}}
return _result;
return result;
}
{{/.}}
}

View File

@@ -83,27 +83,6 @@ namespace k8s
}
}
// Tracing
var shouldTrace = ServiceClientTracing.IsEnabled;
string invocationId = null;
if (shouldTrace)
{
invocationId = ServiceClientTracing.NextInvocationId.ToString();
var tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("command", command);
tracingParameters.Add("container", container);
tracingParameters.Add("name", name);
tracingParameters.Add("namespace", @namespace);
tracingParameters.Add("stderr", stderr);
tracingParameters.Add("stdin", stdin);
tracingParameters.Add("stdout", stdout);
tracingParameters.Add("tty", tty);
tracingParameters.Add("webSocketSubProtol", webSocketSubProtol);
tracingParameters.Add("cancellationToken", cancellationToken);
ServiceClientTracing.Enter(invocationId, this, nameof(WebSocketNamespacedPodExecAsync),
tracingParameters);
}
// Construct URL
var uriBuilder = new UriBuilder(BaseUri);
uriBuilder.Scheme = BaseUri.Scheme == "https" ? "wss" : "ws";
@@ -137,7 +116,7 @@ namespace k8s
uriBuilder.Query =
query.ToString(1, query.Length - 1); // UriBuilder.Query doesn't like leading '?' chars, so trim it
return StreamConnectAsync(uriBuilder.Uri, invocationId, webSocketSubProtol, customHeaders,
return StreamConnectAsync(uriBuilder.Uri, webSocketSubProtol, customHeaders,
cancellationToken);
}
@@ -162,21 +141,6 @@ namespace k8s
throw new ArgumentNullException(nameof(ports));
}
// Tracing
var shouldTrace = ServiceClientTracing.IsEnabled;
string invocationId = null;
if (shouldTrace)
{
invocationId = ServiceClientTracing.NextInvocationId.ToString();
var tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("name", name);
tracingParameters.Add("@namespace", @namespace);
tracingParameters.Add("ports", ports);
tracingParameters.Add("webSocketSubProtocol", webSocketSubProtocol);
tracingParameters.Add("cancellationToken", cancellationToken);
ServiceClientTracing.Enter(invocationId, this, nameof(WebSocketNamespacedPodPortForwardAsync),
tracingParameters);
}
// Construct URL
var uriBuilder = new UriBuilder(BaseUri);
@@ -202,7 +166,7 @@ namespace k8s
uriBuilder.Query = q.ToString();
return StreamConnectAsync(uriBuilder.Uri, invocationId, webSocketSubProtocol, customHeaders,
return StreamConnectAsync(uriBuilder.Uri, webSocketSubProtocol, customHeaders,
cancellationToken);
}
@@ -222,26 +186,6 @@ namespace k8s
throw new ArgumentNullException(nameof(@namespace));
}
// Tracing
var shouldTrace = ServiceClientTracing.IsEnabled;
string invocationId = null;
if (shouldTrace)
{
invocationId = ServiceClientTracing.NextInvocationId.ToString();
var tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("container", container);
tracingParameters.Add("name", name);
tracingParameters.Add("namespace", @namespace);
tracingParameters.Add("stderr", stderr);
tracingParameters.Add("stdin", stdin);
tracingParameters.Add("stdout", stdout);
tracingParameters.Add("tty", tty);
tracingParameters.Add("webSocketSubProtol", webSocketSubProtol);
tracingParameters.Add("cancellationToken", cancellationToken);
ServiceClientTracing.Enter(invocationId, this, nameof(WebSocketNamespacedPodAttachAsync),
tracingParameters);
}
// Construct URL
var uriBuilder = new UriBuilder(BaseUri);
uriBuilder.Scheme = BaseUri.Scheme == "https" ? "wss" : "ws";
@@ -262,21 +206,17 @@ namespace k8s
uriBuilder.Query =
query.ToString(1, query.Length - 1); // UriBuilder.Query doesn't like leading '?' chars, so trim it
return StreamConnectAsync(uriBuilder.Uri, invocationId, webSocketSubProtol, customHeaders,
return StreamConnectAsync(uriBuilder.Uri, webSocketSubProtol, customHeaders,
cancellationToken);
}
protected async Task<WebSocket> StreamConnectAsync(Uri uri, string invocationId = null,
string webSocketSubProtocol = null, Dictionary<string, List<string>> customHeaders = null,
CancellationToken cancellationToken = default)
protected async Task<WebSocket> StreamConnectAsync(Uri uri, string webSocketSubProtocol = null, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default)
{
if (uri == null)
{
throw new ArgumentNullException(nameof(uri));
}
var shouldTrace = ServiceClientTracing.IsEnabled;
// Create WebSocket transport objects
var webSocketBuilder = CreateWebSocketBuilder();
@@ -387,22 +327,10 @@ namespace k8s
throw ex;
}
}
catch (Exception ex)
catch (Exception)
{
if (shouldTrace)
{
ServiceClientTracing.Error(invocationId, ex);
}
throw;
}
finally
{
if (shouldTrace)
{
ServiceClientTracing.Exit(invocationId, null);
}
}
return webSocket;
}

View File

@@ -9,10 +9,20 @@ namespace k8s
{
public partial class Kubernetes
{
private Uri baseuri;
/// <summary>
/// The base URI of the service.
/// </summary>
public Uri BaseUri { get; set; }
public Uri BaseUri
{
get => baseuri;
set
{
var baseUrl = value?.AbsoluteUri ?? throw new ArgumentNullException(nameof(BaseUri));
baseuri = new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/"));
}
}
/// <summary>
/// Subscription credentials which uniquely identify client subscription.
@@ -132,6 +142,7 @@ namespace k8s
/// <exception cref="ArgumentNullException">
/// Thrown when a required parameter is null
/// </exception>
[Obsolete]
public Kubernetes(ServiceClientCredentials credentials, HttpClient httpClient, bool disposeHttpClient)
: this(httpClient, disposeHttpClient)
{
@@ -249,6 +260,43 @@ namespace k8s
return result;
}
private class QueryBuilder
{
private List<string> parameters = new List<string>();
public void Append(string key, params object[] values)
{
foreach (var value in values)
{
switch (value)
{
case int intval:
parameters.Add($"{key}={intval}");
break;
case string strval:
parameters.Add($"{key}={Uri.EscapeDataString(strval)}");
break;
case bool boolval:
parameters.Add($"{key}={(boolval ? "true" : "false")}");
break;
default:
// null
break;
}
}
}
public override string ToString()
{
if (parameters.Count > 0)
{
return "?" + string.Join("&", parameters);
}
return "";
}
}
private HttpRequestMessage CreateRequest(string url, HttpMethod method, IDictionary<string, IList<string>> customHeaders)
{
var httpRequest = new HttpRequestMessage();

File diff suppressed because it is too large Load Diff