diff --git a/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache b/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache index ee908eb89942..eb5be40d3ae2 100644 --- a/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache +++ b/modules/openapi-generator/src/main/resources/csharp/ApiClient.mustache @@ -14,20 +14,22 @@ using System.Text; using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; -{{^netStandard}} +{{^net60OrLater}} using System.Web; -{{/netStandard}} +{{/net60OrLater}} using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; {{#supportsRetry}} using Polly; {{/supportsRetry}} {{#hasOAuthMethods}} using {{packageName}}.Client.Auth; {{/hasOAuthMethods}} +using {{packageName}}.{{modelPackage}}; namespace {{packageName}}.Client { @@ -68,10 +70,10 @@ namespace {{packageName}}.Client /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is {{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return (({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -116,7 +118,7 @@ namespace {{packageName}}.Client if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -127,7 +129,7 @@ namespace {{packageName}}.Client if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -149,13 +151,13 @@ namespace {{packageName}}.Client public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -203,7 +205,7 @@ namespace {{packageName}}.Client /// public ApiClient() { - _baseUrl = {{packageName}}.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -260,14 +262,14 @@ namespace {{packageName}}.Client /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -375,7 +377,7 @@ namespace {{packageName}}.Client var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -385,6 +387,13 @@ namespace {{packageName}}.Client return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -429,31 +438,32 @@ namespace {{packageName}}.Client return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + {{#hasOAuthMethods}} if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && @@ -475,27 +485,14 @@ namespace {{packageName}}.Client { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -553,111 +550,85 @@ namespace {{packageName}}.Client } } - {{#supportsAsync}} - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - {{#hasOAuthMethods}} - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - {{/hasOAuthMethods}} - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - {{#supportsRetry}} - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - {{/supportsRetry}} - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); - {{#supportsRetry}} + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } - {{/supportsRetry}} + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof({{{packageName}}}.{{modelPackage}}.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) - { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); - } - else if (typeof(T).Name == "Stream") // for binary response + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T)(object)new MemoryStream(response.RawBytes); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Byte[]") // for byte response + else { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + {{#supportsAsync}} + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + {{#supportsRetry}} + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + {{/supportsRetry}} + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + {{#supportsRetry}} + } + {{/supportsRetry}} + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -670,7 +641,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -685,7 +656,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -700,7 +671,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -715,7 +686,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -730,7 +701,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -745,7 +716,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -760,7 +731,7 @@ namespace {{packageName}}.Client /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/echo_api/csharp-restsharp/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/echo_api/csharp-restsharp/src/Org.OpenAPITools/Client/ApiClient.cs index c569deebc531..1f3056ed28e2 100644 --- a/samples/client/echo_api/csharp-restsharp/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/echo_api/csharp-restsharp/src/Org.OpenAPITools/Client/ApiClient.cs @@ -23,13 +23,14 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -70,10 +71,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -118,7 +119,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -129,7 +130,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -151,13 +152,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -204,7 +205,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -261,14 +262,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -376,7 +377,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -386,6 +387,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -430,57 +438,45 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + using (RestClient client = new RestClient(clientOptions, configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -538,90 +534,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + return client.Deserialize(policyResult.Result); + } + else { - InterceptRequest(request); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; + } + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => + { + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) - { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); - } - else if (typeof(T).Name == "Stream") // for binary response + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T)(object)new MemoryStream(response.RawBytes); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Byte[]") // for byte response + else { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -634,7 +620,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -649,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -664,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -679,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -694,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -709,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -724,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ApiClient.cs index a5389ded4f2e..789c14ac264c 100644 --- a/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/others/csharp-complex-files/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,12 +22,15 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -68,10 +71,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -116,7 +119,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -127,7 +130,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -149,13 +152,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -202,7 +205,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -259,14 +262,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -374,7 +377,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -384,6 +387,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -428,57 +438,45 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + using (RestClient client = new RestClient(clientOptions, configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -536,90 +534,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + return client.Deserialize(policyResult.Result); + } + else { - InterceptRequest(request); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; + } + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => + { + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) - { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); - } - else if (typeof(T).Name == "Stream") // for binary response + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T)(object)new MemoryStream(response.RawBytes); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Byte[]") // for byte response + else { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -632,7 +620,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -647,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -662,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -677,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -692,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -707,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -722,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ApiClient.cs index 4482bbdbfbc8..7f9fc8d8a175 100644 --- a/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net4.7/MultipleFrameworks/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,13 +22,16 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -69,10 +72,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -117,7 +120,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -128,7 +131,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -150,13 +153,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -203,7 +206,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -260,14 +263,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -375,7 +378,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -385,6 +388,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -429,31 +439,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -473,27 +484,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -551,104 +549,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -661,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -676,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -691,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -706,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -721,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -736,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -751,7 +725,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs index b10e49166a65..0ad9a7e2d52c 100644 --- a/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net4.7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs @@ -28,8 +28,10 @@ using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -70,10 +72,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -118,7 +120,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -129,7 +131,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -151,13 +153,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -204,7 +206,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -261,14 +263,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -376,7 +378,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -386,6 +388,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -430,31 +439,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -474,27 +484,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -552,104 +549,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -662,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -677,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -692,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -707,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -722,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -737,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -752,7 +725,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs index b10e49166a65..0ad9a7e2d52c 100644 --- a/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net4.8/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs @@ -28,8 +28,10 @@ using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -70,10 +72,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -118,7 +120,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -129,7 +131,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -151,13 +153,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -204,7 +206,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -261,14 +263,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -376,7 +378,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -386,6 +388,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -430,31 +439,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -474,27 +484,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -552,104 +549,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -662,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -677,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -692,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -707,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -722,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -737,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -752,7 +725,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net6/ParameterMappings/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net6/ParameterMappings/src/Org.OpenAPITools/Client/ApiClient.cs index 6c224944b4c7..fe40f39ad5b3 100644 --- a/samples/client/petstore/csharp/restsharp/net6/ParameterMappings/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net6/ParameterMappings/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,13 +22,14 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -69,10 +70,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -117,7 +118,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -128,7 +129,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -150,13 +151,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -203,7 +204,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -260,14 +261,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -375,7 +376,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -385,6 +386,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -429,57 +437,45 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + using (RestClient client = new RestClient(clientOptions, configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -537,90 +533,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + return client.Deserialize(policyResult.Result); + } + else { - InterceptRequest(request); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; + } + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => + { + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) - { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); - } - else if (typeof(T).Name == "Stream") // for binary response + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T)(object)new MemoryStream(response.RawBytes); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Byte[]") // for byte response + else { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -633,7 +619,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -648,7 +634,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -663,7 +649,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -678,7 +664,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -693,7 +679,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -708,7 +694,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -723,7 +709,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net7/EnumMappings/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net7/EnumMappings/src/Org.OpenAPITools/Client/ApiClient.cs index b10e49166a65..69279ed569c7 100644 --- a/samples/client/petstore/csharp/restsharp/net7/EnumMappings/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net7/EnumMappings/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,14 +22,15 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -70,10 +71,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -118,7 +119,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -129,7 +130,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -151,13 +152,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -204,7 +205,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -261,14 +262,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -376,7 +377,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -386,6 +387,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -430,31 +438,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -474,27 +483,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -552,104 +548,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -662,7 +634,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -677,7 +649,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -692,7 +664,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -707,7 +679,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -722,7 +694,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -737,7 +709,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -752,7 +724,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs index b10e49166a65..69279ed569c7 100644 --- a/samples/client/petstore/csharp/restsharp/net7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net7/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,14 +22,15 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -70,10 +71,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -118,7 +119,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -129,7 +130,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -151,13 +152,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -204,7 +205,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -261,14 +262,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -376,7 +377,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -386,6 +387,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -430,31 +438,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -474,27 +483,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -552,104 +548,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -662,7 +634,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -677,7 +649,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -692,7 +664,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -707,7 +679,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -722,7 +694,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -737,7 +709,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -752,7 +724,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/net7/UseDateTimeForDate/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/net7/UseDateTimeForDate/src/Org.OpenAPITools/Client/ApiClient.cs index 594bf890cb88..9190dbea600a 100644 --- a/samples/client/petstore/csharp/restsharp/net7/UseDateTimeForDate/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/net7/UseDateTimeForDate/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,13 +22,14 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; -using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -69,10 +70,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -117,7 +118,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -128,7 +129,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -150,13 +151,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -203,7 +204,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -260,14 +261,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -375,7 +376,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -385,6 +386,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -429,57 +437,45 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + using (RestClient client = new RestClient(clientOptions, configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -537,90 +533,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + return client.Deserialize(policyResult.Result); + } + else { - InterceptRequest(request); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; + } + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => + { + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) - { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); - } - else if (typeof(T).Name == "Stream") // for binary response + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T)(object)new MemoryStream(response.RawBytes); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Byte[]") // for byte response + else { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -633,7 +619,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -648,7 +634,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -663,7 +649,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -678,7 +664,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -693,7 +679,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -708,7 +694,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -723,7 +709,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ApiClient.cs index 3c0762f55399..0ad9a7e2d52c 100644 --- a/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/standard2.0/ConditionalSerialization/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,13 +22,16 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -69,10 +72,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -117,7 +120,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -128,7 +131,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -150,13 +153,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -203,7 +206,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -260,14 +263,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -375,7 +378,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -385,6 +388,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -429,31 +439,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -473,27 +484,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -551,104 +549,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -661,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -676,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -691,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -706,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -721,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -736,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -751,7 +725,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken); diff --git a/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs b/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs index 3c0762f55399..0ad9a7e2d52c 100644 --- a/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs +++ b/samples/client/petstore/csharp/restsharp/standard2.0/Petstore/src/Org.OpenAPITools/Client/ApiClient.cs @@ -22,13 +22,16 @@ using System.Threading; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using RestSharp; using RestSharp.Serializers; using RestSharpMethod = RestSharp.Method; +using FileIO = System.IO.File; using Polly; using Org.OpenAPITools.Client.Auth; +using Org.OpenAPITools.Model; namespace Org.OpenAPITools.Client { @@ -69,10 +72,10 @@ public CustomJsonCodec(JsonSerializerSettings serializerSettings, IReadableConfi /// A JSON string. public string Serialize(object obj) { - if (obj != null && obj is Org.OpenAPITools.Model.AbstractOpenAPISchema) + if (obj != null && obj is AbstractOpenAPISchema) { // the object to be serialized is an oneOf/anyOf schema - return ((Org.OpenAPITools.Model.AbstractOpenAPISchema)obj).ToJson(); + return ((AbstractOpenAPISchema)obj).ToJson(); } else { @@ -117,7 +120,7 @@ internal object Deserialize(RestResponse response, Type type) if (match.Success) { string fileName = filePath + ClientUtils.SanitizeFilename(match.Groups[1].Value.Replace("\"", "").Replace("'", "")); - File.WriteAllBytes(fileName, bytes); + FileIO.WriteAllBytes(fileName, bytes); return new FileStream(fileName, FileMode.Open); } } @@ -128,7 +131,7 @@ internal object Deserialize(RestResponse response, Type type) if (type.Name.StartsWith("System.Nullable`1[[System.DateTime")) // return a datetime object { - return DateTime.Parse(response.Content, null, System.Globalization.DateTimeStyles.RoundtripKind); + return DateTime.Parse(response.Content, null, DateTimeStyles.RoundtripKind); } if (type == typeof(string) || type.Name.StartsWith("System.Nullable")) // return primitive type @@ -150,13 +153,13 @@ internal object Deserialize(RestResponse response, Type type) public ISerializer Serializer => this; public IDeserializer Deserializer => this; - public string[] AcceptedContentTypes => RestSharp.ContentType.JsonAccept; + public string[] AcceptedContentTypes => ContentType.JsonAccept; public SupportsContentType SupportsContentType => contentType => contentType.Value.EndsWith("json", StringComparison.InvariantCultureIgnoreCase) || contentType.Value.EndsWith("javascript", StringComparison.InvariantCultureIgnoreCase); - public ContentType ContentType { get; set; } = RestSharp.ContentType.Json; + public ContentType ContentType { get; set; } = ContentType.Json; public DataFormat DataFormat => DataFormat.Json; } @@ -203,7 +206,7 @@ public partial class ApiClient : ISynchronousClient, IAsynchronousClient /// public ApiClient() { - _baseUrl = Org.OpenAPITools.Client.GlobalConfiguration.Instance.BasePath; + _baseUrl = GlobalConfiguration.Instance.BasePath; } /// @@ -260,14 +263,14 @@ private RestSharpMethod Method(HttpMethod method) /// /// Provides all logic for constructing a new RestSharp . - /// At this point, all information for querying the service is known. Here, it is simply - /// mapped into the RestSharp request. + /// At this point, all information for querying the service is known. + /// Here, it is simply mapped into the RestSharp request. /// /// The http verb. /// The target path (or resource). /// The additional request options. - /// A per-request configuration object. It is assumed that any merge with - /// GlobalConfiguration has been done before calling this method. + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. /// [private] A new RestRequest instance. /// private RestRequest NewRequest( @@ -375,7 +378,7 @@ private RestRequest NewRequest( var bytes = ClientUtils.ReadAsBytes(file); var fileStream = file as FileStream; if (fileStream != null) - request.AddFile(fileParam.Key, bytes, System.IO.Path.GetFileName(fileStream.Name)); + request.AddFile(fileParam.Key, bytes, Path.GetFileName(fileStream.Name)); else request.AddFile(fileParam.Key, bytes, "no_file_name_provided"); } @@ -385,6 +388,13 @@ private RestRequest NewRequest( return request; } + /// + /// Transforms a RestResponse instance into a new ApiResponse instance. + /// At this point, we have a concrete http response from the service. + /// Here, it is simply mapped into the [public] ApiResponse object. + /// + /// The RestSharp response object + /// A new ApiResponse instance. private ApiResponse ToApiResponse(RestResponse response) { T result = response.Data; @@ -429,31 +439,32 @@ private ApiResponse ToApiResponse(RestResponse response) return transformed; } - private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + /// + /// Executes the HTTP request for the current service. + /// Based on functions received it can be async or sync. + /// + /// Local function that executes http request and returns http response. + /// Local function to specify options for the service. + /// The RestSharp request object + /// The RestSharp options object + /// A per-request configuration object. + /// It is assumed that any merge with GlobalConfiguration has been done before calling this method. + /// A new ApiResponse instance. + private ApiResponse ExecClient(Func> getResponse, Action setOptions, RestRequest request, RequestOptions options, IReadableConfiguration configuration) { var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - var cookies = new CookieContainer(); - - if (options.Cookies != null && options.Cookies.Count > 0) - { - foreach (var cookie in options.Cookies) - { - cookies.Add(new Cookie(cookie.Name, cookie.Value)); - } - } - var clientOptions = new RestClientOptions(baseUrl) { ClientCertificates = configuration.ClientCertificates, - CookieContainer = cookies, MaxTimeout = configuration.Timeout, Proxy = configuration.Proxy, UserAgent = configuration.UserAgent, UseDefaultCredentials = configuration.UseDefaultCredentials, RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback }; - + setOptions(clientOptions); + if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && !string.IsNullOrEmpty(configuration.OAuthClientId) && !string.IsNullOrEmpty(configuration.OAuthClientSecret) && @@ -473,27 +484,14 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea { InterceptRequest(request); - RestResponse response; - if (RetryConfiguration.RetryPolicy != null) - { - var policy = RetryConfiguration.RetryPolicy; - var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) - { - ErrorException = policyResult.FinalException - }; - } - else - { - response = client.Execute(request); - } + RestResponse response = getResponse(client); // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + if (typeof(AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) { try { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + response.Data = (T)typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); } catch (Exception ex) { @@ -551,104 +549,80 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea } } - private async Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + private RestResponse DeserializeRestResponseFromPolicy(RestClient client, RestRequest request, PolicyResult policyResult) { - var baseUrl = configuration.GetOperationServerUrl(options.Operation, options.OperationIndex) ?? _baseUrl; - - var clientOptions = new RestClientOptions(baseUrl) + if (policyResult.Outcome == OutcomeType.Successful) { - ClientCertificates = configuration.ClientCertificates, - MaxTimeout = configuration.Timeout, - Proxy = configuration.Proxy, - UserAgent = configuration.UserAgent, - UseDefaultCredentials = configuration.UseDefaultCredentials, - RemoteCertificateValidationCallback = configuration.RemoteCertificateValidationCallback - }; - - if (!string.IsNullOrEmpty(configuration.OAuthTokenUrl) && - !string.IsNullOrEmpty(configuration.OAuthClientId) && - !string.IsNullOrEmpty(configuration.OAuthClientSecret) && - configuration.OAuthFlow != null) + return client.Deserialize(policyResult.Result); + } + else { - clientOptions.Authenticator = new OAuthAuthenticator( - configuration.OAuthTokenUrl, - configuration.OAuthClientId, - configuration.OAuthClientSecret, - configuration.OAuthFlow, - SerializerSettings, - configuration); + return new RestResponse(request) + { + ErrorException = policyResult.FinalException + }; } - - using (RestClient client = new RestClient(clientOptions, - configureSerialization: serializerConfig => serializerConfig.UseSerializer(() => new CustomJsonCodec(SerializerSettings, configuration)))) + } + + private ApiResponse Exec(RestRequest request, RequestOptions options, IReadableConfiguration configuration) + { + Action setOptions = (clientOptions) => { - InterceptRequest(request); + var cookies = new CookieContainer(); - RestResponse response; - if (RetryConfiguration.AsyncRetryPolicy != null) + if (options.Cookies != null && options.Cookies.Count > 0) { - var policy = RetryConfiguration.AsyncRetryPolicy; - var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); - response = (policyResult.Outcome == OutcomeType.Successful) ? client.Deserialize(policyResult.Result) : new RestResponse(request) + foreach (var cookie in options.Cookies) { - ErrorException = policyResult.FinalException - }; - } - else - { - response = await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + cookies.Add(new Cookie(cookie.Name, cookie.Value)); + } } + clientOptions.CookieContainer = cookies; + }; - // if the response type is oneOf/anyOf, call FromJSON to deserialize the data - if (typeof(Org.OpenAPITools.Model.AbstractOpenAPISchema).IsAssignableFrom(typeof(T))) + Func> getResponse = (client) => + { + if (RetryConfiguration.RetryPolicy != null) { - response.Data = (T) typeof(T).GetMethod("FromJson").Invoke(null, new object[] { response.Content }); + var policy = RetryConfiguration.RetryPolicy; + var policyResult = policy.ExecuteAndCapture(() => client.Execute(request)); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - else if (typeof(T).Name == "Stream") // for binary response + else { - response.Data = (T)(object)new MemoryStream(response.RawBytes); - } - else if (typeof(T).Name == "Byte[]") // for byte response - { - response.Data = (T)(object)response.RawBytes; + return client.Execute(request); } + }; - InterceptResponse(request, response); + return ExecClient(getResponse, setOptions, request, options, configuration); + } - var result = ToApiResponse(response); - if (response.ErrorMessage != null) - { - result.ErrorText = response.ErrorMessage; - } + private Task> ExecAsync(RestRequest request, RequestOptions options, IReadableConfiguration configuration, CancellationToken cancellationToken = default(CancellationToken)) + { + Action setOptions = (clientOptions) => + { + //no extra options + }; - if (response.Cookies != null && response.Cookies.Count > 0) + Func> getResponse = (client) => + { + Func>> action = async () => { - if (result.Cookies == null) result.Cookies = new List(); - foreach (var restResponseCookie in response.Cookies.Cast()) + if (RetryConfiguration.AsyncRetryPolicy != null) { - var cookie = new Cookie( - restResponseCookie.Name, - restResponseCookie.Value, - restResponseCookie.Path, - restResponseCookie.Domain - ) - { - Comment = restResponseCookie.Comment, - CommentUri = restResponseCookie.CommentUri, - Discard = restResponseCookie.Discard, - Expired = restResponseCookie.Expired, - Expires = restResponseCookie.Expires, - HttpOnly = restResponseCookie.HttpOnly, - Port = restResponseCookie.Port, - Secure = restResponseCookie.Secure, - Version = restResponseCookie.Version - }; - - result.Cookies.Add(cookie); + var policy = RetryConfiguration.AsyncRetryPolicy; + var policyResult = await policy.ExecuteAndCaptureAsync((ct) => client.ExecuteAsync(request, ct), cancellationToken).ConfigureAwait(false); + return DeserializeRestResponseFromPolicy(client, request, policyResult); } - } - return result; - } + else + { + return await client.ExecuteAsync(request, cancellationToken).ConfigureAwait(false); + } + }; + return action().Result; + }; + + return Task.FromResult>(ExecClient(getResponse, setOptions, request, options, configuration)); } #region IAsynchronousClient @@ -661,7 +635,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> GetAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Get, path, options, config), options, config, cancellationToken); @@ -676,7 +650,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PostAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Post, path, options, config), options, config, cancellationToken); @@ -691,7 +665,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PutAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Put, path, options, config), options, config, cancellationToken); @@ -706,7 +680,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> DeleteAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Delete, path, options, config), options, config, cancellationToken); @@ -721,7 +695,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> HeadAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Head, path, options, config), options, config, cancellationToken); @@ -736,7 +710,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> OptionsAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Options, path, options, config), options, config, cancellationToken); @@ -751,7 +725,7 @@ private ApiResponse Exec(RestRequest request, RequestOptions options, IRea /// GlobalConfiguration has been done before calling this method. /// Token that enables callers to cancel the request. /// A Task containing ApiResponse - public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) + public Task> PatchAsync(string path, RequestOptions options, IReadableConfiguration configuration = null, CancellationToken cancellationToken = default) { var config = configuration ?? GlobalConfiguration.Instance; return ExecAsync(NewRequest(HttpMethod.Patch, path, options, config), options, config, cancellationToken);