diff --git a/Samples/3b-custom-transformations/generated/configuration.yaml b/Samples/3b-custom-transformations/generated/configuration.yaml index 5deba63a4..112c94347 100644 --- a/Samples/3b-custom-transformations/generated/configuration.yaml +++ b/Samples/3b-custom-transformations/generated/configuration.yaml @@ -46,6 +46,7 @@ output-artifact: - configuration.yaml - source-file-csharp - source-file-jsonrpcclient +require: [] use: [] clear-output-folder: {} use-extension: @@ -233,6 +234,24 @@ scope-cm/emitter: output-uri-expr: | "code-model-v1" client-side-validation: true +declare-directive: + set: '{ transform: `return ${JSON.stringify($)}` }' + where-operation: |- + (() => { + switch ($context.from) { + case "code-model-v1": + return { from: "code-model-v1", where: `$.operations[*].methods[?(@.serializedName == ${JSON.stringify($)})]` }; + case "swagger-document": + default: + return { from: "swagger-document", where: `$.paths.*[?(@.operationId == ${JSON.stringify($)})]` }; + } + })() + remove-operation: |- + { + from: 'swagger-document', + "where-operation": $, + transform: 'return undefined' + } scope-csharp/emitter: input-artifact: source-file-csharp output-uri-expr: $key diff --git a/Samples/3g-require-config/.gitignore b/Samples/3g-require-config/.gitignore new file mode 100644 index 000000000..07bf13eaa --- /dev/null +++ b/Samples/3g-require-config/.gitignore @@ -0,0 +1,2 @@ +Client/* +!Client/SwaggerPetstore.cs \ No newline at end of file diff --git a/Samples/3g-require-config/Client/SwaggerPetstore.cs b/Samples/3g-require-config/Client/SwaggerPetstore.cs new file mode 100644 index 000000000..6d8f5c437 --- /dev/null +++ b/Samples/3g-require-config/Client/SwaggerPetstore.cs @@ -0,0 +1,2946 @@ +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is +// regenerated. +// + +namespace Petstore +{ + using Microsoft.Rest; + using Microsoft.Rest.Serialization; + using Models; + using Newtonsoft.Json; + using System.Collections; + using System.Collections.Generic; + using System.IO; + using System.Net; + using System.Net.Http; + using System.Net.Http.Headers; + using System.Threading; + using System.Threading.Tasks; + + /// + /// This is a sample server Petstore server. You can find out more about + /// Swagger at <a + /// href="http://swagger.io">http://swagger.io</a> or on + /// irc.freenode.net, #swagger. For this sample, you can use the api key + /// "special-key" to test the authorization filters + /// + public partial class SwaggerPetstore : ServiceClient, ISwaggerPetstore + { + /// + /// The base URI of the service. + /// + public System.Uri BaseUri { get; set; } + + /// + /// Gets or sets json serialization settings. + /// + public JsonSerializerSettings SerializationSettings { get; private set; } + + /// + /// Gets or sets json deserialization settings. + /// + public JsonSerializerSettings DeserializationSettings { get; private set; } + + /// + /// Initializes a new instance of the SwaggerPetstore class. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + public SwaggerPetstore(params DelegatingHandler[] handlers) : base(handlers) + { + Initialize(); + } + + /// + /// Initializes a new instance of the SwaggerPetstore class. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + public SwaggerPetstore(HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : base(rootHandler, handlers) + { + Initialize(); + } + + /// + /// Initializes a new instance of the SwaggerPetstore class. + /// + /// + /// Optional. The base URI of the service. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + public SwaggerPetstore(System.Uri baseUri, params DelegatingHandler[] handlers) : this(handlers) + { + if (baseUri == null) + { + throw new System.ArgumentNullException("baseUri"); + } + BaseUri = baseUri; + } + + /// + /// Initializes a new instance of the SwaggerPetstore class. + /// + /// + /// Optional. The base URI of the service. + /// + /// + /// Optional. The http client handler used to handle http transport. + /// + /// + /// Optional. The delegating handlers to add to the http client pipeline. + /// + /// + /// Thrown when a required parameter is null + /// + public SwaggerPetstore(System.Uri baseUri, HttpClientHandler rootHandler, params DelegatingHandler[] handlers) : this(rootHandler, handlers) + { + if (baseUri == null) + { + throw new System.ArgumentNullException("baseUri"); + } + BaseUri = baseUri; + } + + /// + /// An optional partial-method to perform custom initialization. + /// + partial void CustomInitialize(); + /// + /// Initializes client properties. + /// + private void Initialize() + { + BaseUri = new System.Uri("http://petstore.swagger.io/v2"); + SerializationSettings = new JsonSerializerSettings + { + Formatting = Newtonsoft.Json.Formatting.Indented, + DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc, + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + DeserializationSettings = new JsonSerializerSettings + { + DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat, + DateTimeZoneHandling = Newtonsoft.Json.DateTimeZoneHandling.Utc, + NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore, + ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize, + ContractResolver = new ReadOnlyJsonContractResolver(), + Converters = new List + { + new Iso8601TimeSpanConverter() + } + }; + CustomInitialize(); + } + /// + /// Fake endpoint to test byte array in body parameter for adding a new pet to + /// the store + /// + /// + /// Pet object in the form of byte array + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task AddPetUsingByteArrayWithHttpMessagesAsync(string body = default(string), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "AddPetUsingByteArray", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 405) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Add a new pet to the store + /// + /// + /// Adds a new pet to the store. You may receive an HTTP invalid input if your + /// pet is invalid. + /// + /// + /// Pet object that needs to be added to the store + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task AddPetWithHttpMessagesAsync(Pet body = default(Pet), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (body != null) + { + body.Validate(); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "AddPet", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 405) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Update an existing pet + /// + /// + /// Pet object that needs to be added to the store + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task UpdatePetWithHttpMessagesAsync(Pet body = default(Pet), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (body != null) + { + body.Validate(); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "UpdatePet", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("PUT"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 405 && (int)_statusCode != 404 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Finds Pets by status + /// + /// + /// Multiple status values can be provided with comma seperated strings + /// + /// + /// Status values that need to be considered for filter + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task>> FindPetsByStatusWithHttpMessagesAsync(IList status = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("status", status); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "FindPetsByStatus", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/findByStatus").ToString(); + List _queryParameters = new List(); + if (status != null) + { + _queryParameters.Add(string.Format("status={0}", System.Uri.EscapeDataString(string.Join(",", status)))); + } + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse>(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + IList _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.CreateListXmlDeserializer(XmlSerialization.ToDeserializer(e => Pet.XmlDeserialize(e)), null))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject>(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Finds Pets by tags + /// + /// + /// Muliple tags can be provided with comma seperated strings. Use tag1, tag2, + /// tag3 for testing. + /// + /// + /// Tags to filter by + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task>> FindPetsByTagsWithHttpMessagesAsync(IList tags = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("tags", tags); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "FindPetsByTags", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/findByTags").ToString(); + List _queryParameters = new List(); + if (tags != null) + { + _queryParameters.Add(string.Format("tags={0}", System.Uri.EscapeDataString(string.Join(",", tags)))); + } + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse>(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + IList _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.CreateListXmlDeserializer(XmlSerialization.ToDeserializer(e => Pet.XmlDeserialize(e)), null))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject>(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Fake endpoint to test byte array return by 'Find pet by ID' + /// + /// + /// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API + /// error conditions + /// + /// + /// ID of pet that needs to be fetched + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> FindPetsWithByteArrayWithHttpMessagesAsync(long petId, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("petId", petId); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "FindPetsWithByteArray", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/{petId}").ToString(); + _url = _url.Replace("{petId}", System.Uri.EscapeDataString(SafeJsonConvert.SerializeObject(petId, SerializationSettings).Trim('"'))); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + string _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.ToDeserializer(e => (string)e))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Find pet by ID + /// + /// + /// Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API + /// error conditions + /// + /// + /// ID of pet that needs to be fetched + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetPetByIdWithHttpMessagesAsync(long petId, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("petId", petId); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetPetById", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/{petId}").ToString(); + _url = _url.Replace("{petId}", System.Uri.EscapeDataString(SafeJsonConvert.SerializeObject(petId, SerializationSettings).Trim('"'))); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + Pet _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.ToDeserializer(e => Pet.XmlDeserialize(e)))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Updates a pet in the store with form data + /// + /// + /// ID of pet that needs to be updated + /// + /// + /// Updated name of the pet + /// + /// + /// Updated status of the pet + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task UpdatePetWithFormWithHttpMessagesAsync(string petId, string name = default(string), string status = default(string), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (petId == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "petId"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("petId", petId); + tracingParameters.Add("name", name); + tracingParameters.Add("status", status); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "UpdatePetWithForm", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/{petId}").ToString(); + _url = _url.Replace("{petId}", System.Uri.EscapeDataString(petId)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + List> values = new List>(); + if(name != null) + { + values.Add("name", name); + } + if(status != null) + { + values.Add("status", status); + } + FormUrlEncodedContent _formContent = new FormUrlEncodedContent(values); + _httpRequest.Content = _formContent; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 405) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Deletes a pet + /// + /// + /// Pet id to delete + /// + /// + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task DeletePetWithHttpMessagesAsync(long petId, string apiKey = default(string), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("apiKey", apiKey); + tracingParameters.Add("petId", petId); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "DeletePet", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/{petId}").ToString(); + _url = _url.Replace("{petId}", System.Uri.EscapeDataString(SafeJsonConvert.SerializeObject(petId, SerializationSettings).Trim('"'))); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("DELETE"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + if (apiKey != null) + { + if (_httpRequest.Headers.Contains("api_key")) + { + _httpRequest.Headers.Remove("api_key"); + } + _httpRequest.Headers.TryAddWithoutValidation("api_key", apiKey); + } + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// uploads an image + /// + /// + /// ID of pet to update + /// + /// + /// Additional data to pass to server + /// + /// + /// file to upload + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task UploadFileWithHttpMessagesAsync(long petId, string additionalMetadata = default(string), Stream file = default(Stream), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("petId", petId); + tracingParameters.Add("additionalMetadata", additionalMetadata); + tracingParameters.Add("file", file); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "UploadFile", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "pet/{petId}/uploadImage").ToString(); + _url = _url.Replace("{petId}", System.Uri.EscapeDataString(SafeJsonConvert.SerializeObject(petId, SerializationSettings).Trim('"'))); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + MultipartFormDataContent _multiPartContent = new MultipartFormDataContent(); + if (additionalMetadata != null) + { + StringContent _additionalMetadata = new StringContent(additionalMetadata, System.Text.Encoding.UTF8); + _multiPartContent.Add(_additionalMetadata, "additionalMetadata"); + } + if (file != null) + { + StreamContent _file = new StreamContent(file); + _file.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); + FileStream _fileAsFileStream = file as FileStream; + if (_fileAsFileStream != null) + { + ContentDispositionHeaderValue _contentDispositionHeaderValue = new ContentDispositionHeaderValue("form-data"); + _contentDispositionHeaderValue.Name = "file"; + _contentDispositionHeaderValue.FileName = _fileAsFileStream.Name; + _file.Headers.ContentDisposition = _contentDispositionHeaderValue; + } + _multiPartContent.Add(_file, "file"); + } + _httpRequest.Content = _multiPartContent; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if (!_httpResponse.IsSuccessStatusCode) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Returns pet inventories by status + /// + /// + /// Returns a map of status codes to quantities + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task>> GetInventoryWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetInventory", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "store/inventory").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse>(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + IDictionary _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.CreateDictionaryXmlDeserializer(XmlSerialization.ToDeserializer(e => (int?)e)))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject>(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Place an order for a pet + /// + /// + /// order placed for purchasing the pet + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> PlaceOrderWithHttpMessagesAsync(Order body = default(Order), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "PlaceOrder", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "store/order").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + Order _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.ToDeserializer(e => Order.XmlDeserialize(e)))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Find purchase order by ID + /// + /// + /// For valid response try integer IDs with value <= 5 or > 10. Other + /// values will generated exceptions + /// + /// + /// ID of pet that needs to be fetched + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetOrderByIdWithHttpMessagesAsync(string orderId, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (orderId == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "orderId"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("orderId", orderId); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetOrderById", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "store/order/{orderId}").ToString(); + _url = _url.Replace("{orderId}", System.Uri.EscapeDataString(orderId)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + Order _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.ToDeserializer(e => Order.XmlDeserialize(e)))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Delete purchase order by ID + /// + /// + /// For valid response try integer IDs with value < 1000. Anything above + /// 1000 or nonintegers will generate API errors + /// + /// + /// ID of the order that needs to be deleted + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task DeleteOrderWithHttpMessagesAsync(string orderId, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (orderId == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "orderId"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("orderId", orderId); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "DeleteOrder", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "store/order/{orderId}").ToString(); + _url = _url.Replace("{orderId}", System.Uri.EscapeDataString(orderId)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("DELETE"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Create user + /// + /// + /// This can only be done by the logged in user. + /// + /// + /// Created user object + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task CreateUserWithHttpMessagesAsync(User body = default(User), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "CreateUser", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if (!_httpResponse.IsSuccessStatusCode) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Creates list of users with given input array + /// + /// + /// List of user object + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task CreateUsersWithArrayInputWithHttpMessagesAsync(IList body = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "CreateUsersWithArrayInput", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/createWithArray").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if (!_httpResponse.IsSuccessStatusCode) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Creates list of users with given input array + /// + /// + /// List of user object + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task CreateUsersWithListInputWithHttpMessagesAsync(IList body = default(IList), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "CreateUsersWithListInput", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/createWithList").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("POST"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if (!_httpResponse.IsSuccessStatusCode) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Logs user into the system + /// + /// + /// The user name for login + /// + /// + /// The password for login in clear text + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> LoginUserWithHttpMessagesAsync(string username = default(string), string password = default(string), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("username", username); + tracingParameters.Add("password", password); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "LoginUser", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/login").ToString(); + List _queryParameters = new List(); + if (username != null) + { + _queryParameters.Add(string.Format("username={0}", System.Uri.EscapeDataString(username))); + } + if (password != null) + { + _queryParameters.Add(string.Format("password={0}", System.Uri.EscapeDataString(password))); + } + if (_queryParameters.Count > 0) + { + _url += "?" + string.Join("&", _queryParameters); + } + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + string _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.ToDeserializer(e => (string)e))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Logs out current logged in user session + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task LogoutUserWithHttpMessagesAsync(Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "LogoutUser", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/logout").ToString(); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if (!_httpResponse.IsSuccessStatusCode) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Get user by user name + /// + /// + /// The name that needs to be fetched. Use user1 for testing. + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when unable to deserialize the response + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task> GetUserByNameWithHttpMessagesAsync(string username, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (username == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "username"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("username", username); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "GetUserByName", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/{username}").ToString(); + _url = _url.Replace("{username}", System.Uri.EscapeDataString(username)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("GET"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 200 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + // Deserialize Response + if ((int)_statusCode == 200) + { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + try + { + User _tmp_ = null; + if (_httpResponse.Content.Headers.ContentType.MediaType == "application/xml" && + XmlSerialization.Root(XmlSerialization.ToDeserializer(e => User.XmlDeserialize(e)))(System.Xml.Linq.XElement.Parse(_responseContent), out _tmp_)) + { + _result.Body = _tmp_; + } + else + { + _result.Body = SafeJsonConvert.DeserializeObject(_responseContent, DeserializationSettings); + } + } + catch (JsonException ex) + { + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw new SerializationException("Unable to deserialize the response.", _responseContent, ex); + } + } + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Updated user + /// + /// + /// This can only be done by the logged in user. + /// + /// + /// name that need to be deleted + /// + /// + /// Updated user object + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task UpdateUserWithHttpMessagesAsync(string username, User body = default(User), Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (username == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "username"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("username", username); + tracingParameters.Add("body", body); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "UpdateUser", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/{username}").ToString(); + _url = _url.Replace("{username}", System.Uri.EscapeDataString(username)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("PUT"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + if(body != null) + { + _requestContent = SafeJsonConvert.SerializeObject(body, SerializationSettings); + _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8); + _httpRequest.Content.Headers.ContentType =MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); + } + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + /// + /// Delete user + /// + /// + /// This can only be done by the logged in user. + /// + /// + /// The name that needs to be deleted + /// + /// + /// Headers that will be added to request. + /// + /// + /// The cancellation token. + /// + /// + /// Thrown when the operation returned an invalid status code + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// Thrown when a required parameter is null + /// + /// + /// A response object containing the response body and response headers. + /// + public async Task DeleteUserWithHttpMessagesAsync(string username, Dictionary> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) + { + if (username == null) + { + throw new ValidationException(ValidationRules.CannotBeNull, "username"); + } + // Tracing + bool _shouldTrace = ServiceClientTracing.IsEnabled; + string _invocationId = null; + if (_shouldTrace) + { + _invocationId = ServiceClientTracing.NextInvocationId.ToString(); + Dictionary tracingParameters = new Dictionary(); + tracingParameters.Add("username", username); + tracingParameters.Add("cancellationToken", cancellationToken); + ServiceClientTracing.Enter(_invocationId, this, "DeleteUser", tracingParameters); + } + // Construct URL + var _baseUrl = BaseUri.AbsoluteUri; + var _url = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "user/{username}").ToString(); + _url = _url.Replace("{username}", System.Uri.EscapeDataString(username)); + // Create HTTP transport objects + var _httpRequest = new HttpRequestMessage(); + HttpResponseMessage _httpResponse = null; + _httpRequest.Method = new HttpMethod("DELETE"); + _httpRequest.RequestUri = new System.Uri(_url); + // Set Headers + + + if (customHeaders != null) + { + foreach(var _header in customHeaders) + { + if (_httpRequest.Headers.Contains(_header.Key)) + { + _httpRequest.Headers.Remove(_header.Key); + } + _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value); + } + } + + // Serialize Request + string _requestContent = null; + // Send Request + if (_shouldTrace) + { + ServiceClientTracing.SendRequest(_invocationId, _httpRequest); + } + cancellationToken.ThrowIfCancellationRequested(); + _httpResponse = await HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false); + if (_shouldTrace) + { + ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse); + } + HttpStatusCode _statusCode = _httpResponse.StatusCode; + cancellationToken.ThrowIfCancellationRequested(); + string _responseContent = null; + if ((int)_statusCode != 404 && (int)_statusCode != 400) + { + var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode)); + if (_httpResponse.Content != null) { + _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); + } + else { + _responseContent = string.Empty; + } + ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent); + ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent); + if (_shouldTrace) + { + ServiceClientTracing.Error(_invocationId, ex); + } + _httpRequest.Dispose(); + if (_httpResponse != null) + { + _httpResponse.Dispose(); + } + throw ex; + } + // Create Result + var _result = new HttpOperationResponse(); + _result.Request = _httpRequest; + _result.Response = _httpResponse; + if (_shouldTrace) + { + ServiceClientTracing.Exit(_invocationId, _result); + } + return _result; + } + + } +} diff --git a/Samples/3g-require-config/pétstöre.json b/Samples/3g-require-config/pétstöre.json new file mode 100644 index 000000000..8445743d7 --- /dev/null +++ b/Samples/3g-require-config/pétstöre.json @@ -0,0 +1,1109 @@ +{ + "swagger": "2.0", + "info": { + "description": "This is a sample server Petstore server. You can find out more about Swagger at http://swagger.io or on irc.freenode.net, #swagger. For this sample, you can use the api key \"special-key\" to test the authorization filters", + "version": "1.0.0", + "title": "Swagger Petstore", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "email": "apiteam@swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "host": "petstore.swagger.io", + "basePath": "/v2", + "schemes": [ + "http" + ], + "paths": { + "/pet?testing_byte_array=true": { + "post": { + "tags": [ + "pet" + ], + "summary": "Fake endpoint to test byte array in body parameter for adding a new pet to the store", + "description": "", + "operationId": "addPetUsingByteArray", + "consumes": [ + "application/json", + "application/xml" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object in the form of byte array", + "required": false, + "schema": { + "type": "string", + "format": "binary" + } + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet": { + "post": { + "tags": [ + "pet" + ], + "summary": "Add a new pet to the store", + "description": "Adds a new pet to the store. You may receive an HTTP invalid input if your pet is invalid.", + "operationId": "addPet", + "consumes": [ + "application/json", + "application/xml" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": false, + "schema": { + "$ref": "#/definitions/Pet" + } + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + }, + "put": { + "tags": [ + "pet" + ], + "summary": "Update an existing pet", + "description": "", + "operationId": "updatePet", + "consumes": [ + "application/json", + "application/xml" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Pet object that needs to be added to the store", + "required": false, + "schema": { + "$ref": "#/definitions/Pet" + } + } + ], + "responses": { + "405": { + "description": "Validation exception" + }, + "404": { + "description": "Pet not found" + }, + "400": { + "description": "Invalid ID supplied" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/findByStatus": { + "get": { + "tags": [ + "pet" + ], + "summary": "Finds Pets by status", + "description": "Multiple status values can be provided with comma seperated strings", + "operationId": "findPetsByStatus", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "status", + "in": "query", + "description": "Status values that need to be considered for filter", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "default": "available" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "400": { + "description": "Invalid status value" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/findByTags": { + "get": { + "tags": [ + "pet" + ], + "summary": "Finds Pets by tags", + "description": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.", + "operationId": "findPetsByTags", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "tags", + "in": "query", + "description": "Tags to filter by", + "required": false, + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Pet" + } + } + }, + "400": { + "description": "Invalid tag value" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/{petId}?testing_byte_array=true": { + "get": { + "tags": [ + "pet" + ], + "summary": "Fake endpoint to test byte array return by 'Find pet by ID'", + "description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions", + "operationId": "findPetsWithByteArray", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be fetched", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "404": { + "description": "Pet not found" + }, + "200": { + "description": "successful operation", + "schema": { + "type": "string", + "format": "binary" + } + }, + "400": { + "description": "Invalid ID supplied" + } + }, + "security": [ + { + "api_key": [] + }, + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/{petId}": { + "get": { + "tags": [ + "pet" + ], + "summary": "Find pet by ID", + "description": "Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions", + "operationId": "getPetById", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be fetched", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "404": { + "description": "Pet not found" + }, + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Pet" + } + }, + "400": { + "description": "Invalid ID supplied" + } + }, + "security": [ + { + "api_key": [] + }, + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + }, + "post": { + "tags": [ + "pet" + ], + "summary": "Updates a pet in the store with form data", + "description": "", + "operationId": "updatePetWithForm", + "consumes": [ + "application/x-www-form-urlencoded" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet that needs to be updated", + "required": true, + "type": "string" + }, + { + "name": "name", + "in": "formData", + "description": "Updated name of the pet", + "required": false, + "type": "string" + }, + { + "name": "status", + "in": "formData", + "description": "Updated status of the pet", + "required": false, + "type": "string" + } + ], + "responses": { + "405": { + "description": "Invalid input" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + }, + "delete": { + "tags": [ + "pet" + ], + "summary": "Deletes a pet", + "description": "", + "operationId": "deletePet", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "api_key", + "in": "header", + "description": "", + "required": false, + "type": "string" + }, + { + "name": "petId", + "in": "path", + "description": "Pet id to delete", + "required": true, + "type": "integer", + "format": "int64" + } + ], + "responses": { + "400": { + "description": "Invalid pet value" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/pet/{petId}/uploadImage": { + "post": { + "tags": [ + "pet" + ], + "summary": "uploads an image", + "description": "", + "operationId": "uploadFile", + "consumes": [ + "multipart/form-data" + ], + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "petId", + "in": "path", + "description": "ID of pet to update", + "required": true, + "type": "integer", + "format": "int64" + }, + { + "name": "additionalMetadata", + "in": "formData", + "description": "Additional data to pass to server", + "required": false, + "type": "string" + }, + { + "name": "file", + "in": "formData", + "description": "file to upload", + "required": false, + "type": "file" + } + ], + "responses": { + "default": { + "description": "successful operation" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + }, + "/store/inventory": { + "get": { + "tags": [ + "store" + ], + "summary": "Returns pet inventories by status", + "description": "Returns a map of status codes to quantities", + "operationId": "getInventory", + "produces": [ + "application/json", + "application/xml" + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int32" + } + } + } + }, + "security": [ + { + "api_key": [] + } + ] + } + }, + "/store/order": { + "post": { + "tags": [ + "store" + ], + "summary": "Place an order for a pet", + "description": "", + "operationId": "placeOrder", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "order placed for purchasing the pet", + "required": false, + "schema": { + "$ref": "#/definitions/Order" + } + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Order" + } + }, + "400": { + "description": "Invalid Order" + } + }, + "security": [ + { + "test_api_client_id": [], + "test_api_client_secret": [] + } + ] + } + }, + "/store/order/{orderId}": { + "get": { + "tags": [ + "store" + ], + "summary": "Find purchase order by ID", + "description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions", + "operationId": "getOrderById", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "orderId", + "in": "path", + "description": "ID of pet that needs to be fetched", + "required": true, + "type": "string" + } + ], + "responses": { + "404": { + "description": "Order not found" + }, + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/Order" + } + }, + "400": { + "description": "Invalid ID supplied" + } + }, + "security": [ + { + "test_api_key_header": [] + }, + { + "test_api_key_query": [] + } + ] + }, + "delete": { + "tags": [ + "store" + ], + "summary": "Delete purchase order by ID", + "description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors", + "operationId": "deleteOrder", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "orderId", + "in": "path", + "description": "ID of the order that needs to be deleted", + "required": true, + "type": "string" + } + ], + "responses": { + "404": { + "description": "Order not found" + }, + "400": { + "description": "Invalid ID supplied" + } + } + } + }, + "/user": { + "post": { + "tags": [ + "user" + ], + "summary": "Create user", + "description": "This can only be done by the logged in user.", + "operationId": "createUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "Created user object", + "required": false, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/createWithArray": { + "post": { + "tags": [ + "user" + ], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithArrayInput", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "List of user object", + "required": false, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/createWithList": { + "post": { + "tags": [ + "user" + ], + "summary": "Creates list of users with given input array", + "description": "", + "operationId": "createUsersWithListInput", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "in": "body", + "name": "body", + "description": "List of user object", + "required": false, + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + } + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/login": { + "get": { + "tags": [ + "user" + ], + "summary": "Logs user into the system", + "description": "", + "operationId": "loginUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "query", + "description": "The user name for login", + "required": false, + "type": "string" + }, + { + "name": "password", + "in": "query", + "description": "The password for login in clear text", + "required": false, + "type": "string" + } + ], + "responses": { + "200": { + "description": "successful operation", + "schema": { + "type": "string" + } + }, + "400": { + "description": "Invalid username/password supplied" + } + } + } + }, + "/user/logout": { + "get": { + "tags": [ + "user" + ], + "summary": "Logs out current logged in user session", + "description": "", + "operationId": "logoutUser", + "produces": [ + "application/json", + "application/xml" + ], + "responses": { + "default": { + "description": "successful operation" + } + } + } + }, + "/user/{username}": { + "get": { + "tags": [ + "user" + ], + "summary": "Get user by user name", + "description": "", + "operationId": "getUserByName", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "The name that needs to be fetched. Use user1 for testing. ", + "required": true, + "type": "string" + } + ], + "responses": { + "404": { + "description": "User not found" + }, + "200": { + "description": "successful operation", + "schema": { + "$ref": "#/definitions/User" + }, + "examples": { + "application/json": { + "id": 1, + "username": "johnp", + "firstName": "John", + "lastName": "Public", + "email": "johnp@swagger.io", + "password": "-secret-", + "phone": "0123456789", + "userStatus": 0 + } + } + }, + "400": { + "description": "Invalid username supplied" + } + } + }, + "put": { + "tags": [ + "user" + ], + "summary": "Updated user", + "description": "This can only be done by the logged in user.", + "operationId": "updateUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "name that need to be deleted", + "required": true, + "type": "string" + }, + { + "in": "body", + "name": "body", + "description": "Updated user object", + "required": false, + "schema": { + "$ref": "#/definitions/User" + } + } + ], + "responses": { + "404": { + "description": "User not found" + }, + "400": { + "description": "Invalid user supplied" + } + } + }, + "delete": { + "tags": [ + "user" + ], + "summary": "Delete user", + "description": "This can only be done by the logged in user.", + "operationId": "deleteUser", + "produces": [ + "application/json", + "application/xml" + ], + "parameters": [ + { + "name": "username", + "in": "path", + "description": "The name that needs to be deleted", + "required": true, + "type": "string" + } + ], + "responses": { + "404": { + "description": "User not found" + }, + "400": { + "description": "Invalid username supplied" + } + } + } + } + }, + "securityDefinitions": { + "api_key": { + "type": "apiKey", + "name": "api_key", + "in": "header" + }, + "petstore_auth": { + "type": "oauth2", + "authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog", + "flow": "implicit", + "scopes": { + "write:pets": "modify pets in your account", + "read:pets": "read your pets" + } + }, + "test_api_client_id": { + "type": "apiKey", + "name": "x-test_api_client_id", + "in": "header" + }, + "test_api_client_secret": { + "type": "apiKey", + "name": "x-test_api_client_secret", + "in": "header" + }, + "test_api_key_header": { + "type": "apiKey", + "name": "test_api_key_header", + "in": "header" + }, + "test_api_key_query": { + "type": "apiKey", + "name": "test_api_key_query", + "in": "query" + } + }, + "definitions": { + "User": { + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "username": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "phone": { + "type": "string" + }, + "userStatus": { + "type": "integer", + "format": "int32", + "description": "User Status" + } + }, + "xml": { + "name": "User" + } + }, + "Category": { + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Category" + } + }, + "Pet": { + "required": [ + "name", + "photoUrls" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64", + "title": "The id of the pet.", + "description": "A more detailed description of the id of the pet." + }, + "category": { + "$ref": "#/definitions/Category" + }, + "name": { + "type": "string", + "example": "doggie" + }, + "photoUrls": { + "type": "array", + "xml": { + "name": "photoUrl", + "wrapped": true + }, + "items": { + "type": "string" + } + }, + "tags": { + "type": "array", + "xml": { + "name": "tag", + "wrapped": true + }, + "items": { + "$ref": "#/definitions/Tag" + } + }, + "status": { + "type": "string", + "description": "pet status in the store", + "enum": [ + "available", + "pending", + "sold" + ] + } + }, + "title": "A pet", + "description": "A group of properties representing a pet.", + "xml": { + "name": "Pet" + } + }, + "Tag": { + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + } + }, + "xml": { + "name": "Tag" + } + }, + "Order": { + "properties": { + "id": { + "type": "integer", + "format": "int64", + "readOnly": true + }, + "petId": { + "type": "integer", + "format": "int64" + }, + "quantity": { + "type": "integer", + "format": "int32" + }, + "shipDate": { + "type": "string", + "format": "date-time" + }, + "status": { + "type": "string", + "description": "Order Status", + "enum": [ + "placed", + "approved", + "delivered" + ] + }, + "complete": { + "type": "boolean" + } + }, + "xml": { + "name": "Order" + } + } + } +} \ No newline at end of file diff --git a/Samples/3g-require-config/readme.md b/Samples/3g-require-config/readme.md new file mode 100644 index 000000000..e1dd41c62 --- /dev/null +++ b/Samples/3g-require-config/readme.md @@ -0,0 +1,20 @@ +# Scenario: Include further configuration files + +> see https://aka.ms/autorest + + +One can include other configuration files into the current one using `require`: + +``` yaml +require: # can be a single relative/absolute path/URL or an array of such + - ../1a-code-generation-minimal/readme.md +``` + +However, note that paths within included configuration files will be resolved relative to *this* file instead of the included one. +This becomes relevant for `input-file`s or further `require`s in referenced files. +Use `require` together with `batch` mode and `base-folder` if the intent is to invoke AutoRest on other, self-contained configuration files. + +Common use cases for external configuration files include extracting and reusing: +- verbose code generation settings +- large numbers of directives +- declarations \ No newline at end of file diff --git a/Samples/3g-require-config/shell/code.txt b/Samples/3g-require-config/shell/code.txt new file mode 100644 index 000000000..c22708346 --- /dev/null +++ b/Samples/3g-require-config/shell/code.txt @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/Samples/3g-require-config/shell/stderr.txt b/Samples/3g-require-config/shell/stderr.txt new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Samples/3g-require-config/shell/stderr.txt @@ -0,0 +1 @@ + diff --git a/Samples/3g-require-config/shell/stdout.txt b/Samples/3g-require-config/shell/stdout.txt new file mode 100644 index 000000000..048246aed --- /dev/null +++ b/Samples/3g-require-config/shell/stdout.txt @@ -0,0 +1,4 @@ +(C) 2017 **Microsoft Corporation.** +# AutoRest code generation utility [version: 2.0.0] +https://aka.ms/autorest +Including configuration file '/Samples/1a-code-generation-minimal/readme.md' diff --git a/Samples/test/error-behavior/config-bad-syntax/shell/code.txt b/Samples/test/error-behavior/config-bad-syntax/shell/code.txt index d8263ee98..56a6051ca 100644 --- a/Samples/test/error-behavior/config-bad-syntax/shell/code.txt +++ b/Samples/test/error-behavior/config-bad-syntax/shell/code.txt @@ -1 +1 @@ -2 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/error-behavior/config-bad-syntax/shell/stderr.txt b/Samples/test/error-behavior/config-bad-syntax/shell/stderr.txt index 4d59d64f9..c4ee8f310 100644 --- a/Samples/test/error-behavior/config-bad-syntax/shell/stderr.txt +++ b/Samples/test/error-behavior/config-bad-syntax/shell/stderr.txt @@ -1,4 +1,2 @@ - /Samples/test/error-behavior/config-bad-syntax/readme.md:6:0 - at ... -{ Error: [OperationAbortedException] Error occurred. Exiting. ERROR: Syntax error: Invalid YAML object. diff --git a/Samples/test/error-behavior/config-bad-syntax/shell/stdout.txt b/Samples/test/error-behavior/config-bad-syntax/shell/stdout.txt index a7a07aa23..a49fa899a 100644 --- a/Samples/test/error-behavior/config-bad-syntax/shell/stdout.txt +++ b/Samples/test/error-behavior/config-bad-syntax/shell/stdout.txt @@ -1,3 +1,4 @@ (C) 2017 **Microsoft Corporation.** +[OperationAbortedException] Error occurred. Exiting. # AutoRest code generation utility [version: 2.0.0] https://aka.ms/autorest diff --git a/Samples/test/error-behavior/openapi-json-bad-syntax/shell/code.txt b/Samples/test/error-behavior/openapi-json-bad-syntax/shell/code.txt index bf0d87ab1..56a6051ca 100644 --- a/Samples/test/error-behavior/openapi-json-bad-syntax/shell/code.txt +++ b/Samples/test/error-behavior/openapi-json-bad-syntax/shell/code.txt @@ -1 +1 @@ -4 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/error-behavior/openapi-md-bad-syntax/shell/code.txt b/Samples/test/error-behavior/openapi-md-bad-syntax/shell/code.txt index c7930257d..56a6051ca 100644 --- a/Samples/test/error-behavior/openapi-md-bad-syntax/shell/code.txt +++ b/Samples/test/error-behavior/openapi-md-bad-syntax/shell/code.txt @@ -1 +1 @@ -7 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stderr.txt b/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stderr.txt index d9f4d2331..d0085d94c 100644 --- a/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stderr.txt +++ b/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stderr.txt @@ -2,8 +2,6 @@ - /Samples/test/error-behavior/openapi-md-bad-syntax/tiny.md:59:15 - /Samples/test/error-behavior/openapi-md-bad-syntax/tiny.md:65:18 - /Samples/test/error-behavior/openapi-md-bad-syntax/tiny.md:65:4 - at ... -{ Error: [OperationAbortedException] Error occurred. Exiting. ERROR: Syntax Error Encountered: Syntax error: bad indentation of a mapping entry ERROR: Syntax Error Encountered: Syntax error: bad indentation of a mapping entry ERROR: Syntax Error Encountered: Syntax error: bad indentation of a mapping entry diff --git a/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stdout.txt b/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stdout.txt index 19e3e83f3..a7a07aa23 100644 --- a/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stdout.txt +++ b/Samples/test/error-behavior/openapi-md-bad-syntax/shell/stdout.txt @@ -1,4 +1,3 @@ (C) 2017 **Microsoft Corporation.** # AutoRest code generation utility [version: 2.0.0] https://aka.ms/autorest -Process() Cancelled due to exception : [OperationAbortedException] Error occurred. Exiting. diff --git a/Samples/test/error-behavior/openapi-not-swagger/shell/code.txt b/Samples/test/error-behavior/openapi-not-swagger/shell/code.txt index e440e5c84..56a6051ca 100644 --- a/Samples/test/error-behavior/openapi-not-swagger/shell/code.txt +++ b/Samples/test/error-behavior/openapi-not-swagger/shell/code.txt @@ -1 +1 @@ -3 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/code.txt b/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/code.txt index bf0d87ab1..56a6051ca 100644 --- a/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/code.txt +++ b/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/code.txt @@ -1 +1 @@ -4 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stderr.txt b/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stderr.txt index 51c6ffed3..04f9c099e 100644 --- a/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stderr.txt +++ b/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stderr.txt @@ -1,6 +1,4 @@ - /Samples/test/error-behavior/openapi-yaml-bad-file-reference/tiny.yaml ($) - at ... -{ Error: [OperationAbortedException] Error occurred. Exiting. ERROR: Referenced file '/Samples/test/error-behavior/openapi-yaml-bad-file-reference/i-do-not-exist.json' not found FATAL: Error: [OperationAbortedException] Error occurred. Exiting. FATAL: swagger-document/loader - FAILED diff --git a/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stdout.txt b/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stdout.txt index 15558c06b..94b927323 100644 --- a/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stdout.txt +++ b/Samples/test/error-behavior/openapi-yaml-bad-file-reference/shell/stdout.txt @@ -1,5 +1,4 @@ (C) 2017 **Microsoft Corporation.** # AutoRest code generation utility [version: 2.0.0] https://aka.ms/autorest -Process() Cancelled due to exception : [OperationAbortedException] Error occurred. Exiting. WARNING: Failed to blame {"path":[]} in '"/Samples/test/error-behavior/openapi-yaml-bad-file-reference/tiny.yaml"' (Error: Object '/Samples/test/error-behavior/openapi-yaml-bad-file-reference/tiny.yaml' does not exist.) diff --git a/Samples/test/error-behavior/openapi-yaml-bad-reference/shell/code.txt b/Samples/test/error-behavior/openapi-yaml-bad-reference/shell/code.txt index bf0d87ab1..56a6051ca 100644 --- a/Samples/test/error-behavior/openapi-yaml-bad-reference/shell/code.txt +++ b/Samples/test/error-behavior/openapi-yaml-bad-reference/shell/code.txt @@ -1 +1 @@ -4 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/error-behavior/openapi-yaml-bad-syntax/shell/code.txt b/Samples/test/error-behavior/openapi-yaml-bad-syntax/shell/code.txt index c7930257d..56a6051ca 100644 --- a/Samples/test/error-behavior/openapi-yaml-bad-syntax/shell/code.txt +++ b/Samples/test/error-behavior/openapi-yaml-bad-syntax/shell/code.txt @@ -1 +1 @@ -7 \ No newline at end of file +1 \ No newline at end of file diff --git a/Samples/test/hidden-methods/readme.md b/Samples/test/hidden-methods/readme.md index 0d0d6d84a..63e77e2a7 100644 --- a/Samples/test/hidden-methods/readme.md +++ b/Samples/test/hidden-methods/readme.md @@ -21,7 +21,7 @@ csharp: - output-folder: ClientFancy directive: from: code-model-v1 - where: $.operations[*].methods[?(@.serializedName == "Cowbell_Add")] + where-operation: Cowbell_Add transform: $.hidden = true ``` diff --git a/Samples/test/remove-methods/readme.md b/Samples/test/remove-methods/readme.md index 1672818b2..78e568895 100644 --- a/Samples/test/remove-methods/readme.md +++ b/Samples/test/remove-methods/readme.md @@ -17,9 +17,7 @@ batch: output-folder: ClientFancy # add the following directive to your configuration to hide operation `Cowbell_Add` directive: - - from: swagger-document - where: $.paths.*[?(@.operationId == "Cowbell_Add")] - transform: return undefined + - remove-operation: Cowbell_Add # for demonstration purposes, also emit a Swagger file that represents the original Swagger minus the removed operation output-artifact: swagger-document.yaml ``` @@ -30,7 +28,5 @@ The directive finds method `Cowbell_Add` and removes the corresponding object gr Add a `directive` as follows in order to remove an operation with operation ID ``: ``` yaml false -from: swagger-document -where: $.paths.*[?(@.operationId == "")] -transform: return undefined +remove-operation: ``` diff --git a/src/autorest-core/app.ts b/src/autorest-core/app.ts index bef3b0d5a..4c2b968b4 100644 --- a/src/autorest-core/app.ts +++ b/src/autorest-core/app.ts @@ -257,43 +257,34 @@ async function currentMain(autorestArgs: string[]): Promise { api.GeneratedFile.Subscribe((_, artifact) => artifacts.push(artifact)); api.ClearFolder.Subscribe((_, folder) => clearFolders.push(folder)); - try { - const config = (await api.view); + const config = (await api.view); - // maybe a resource schema batch process - if (config["resource-schema-batch"]) { - return await resourceSchemaBatch(api); - } + // maybe a resource schema batch process + if (config["resource-schema-batch"]) { + return await resourceSchemaBatch(api); + } - // maybe a merge process - if (config["merge"]) { - return await merge(api); - } + // maybe a merge process + if (config["merge"]) { + return await merge(api); + } - if (config["batch"]) { - await batch(api); - } - else { - const result = await api.Process().finish; - if (result !== true) { - throw result; - } - } - - // perform file system operations. - for (const folder of clearFolders) { - try { await ClearFolder(folder); } catch (e) { } - } - for (const artifact of artifacts) { - await WriteString(artifact.uri, artifact.content); + if (config["batch"]) { + await batch(api); + } + else { + const result = await api.Process().finish; + if (result !== true) { + throw result; } } - catch (e) { - api.Message.Dispatch({ - Channel: Channel.Fatal, - Text: e - }); - exitcode = exitcode || 1; + + // perform file system operations. + for (const folder of clearFolders) { + try { await ClearFolder(folder); } catch (e) { } + } + for (const artifact of artifacts) { + await WriteString(artifact.uri, artifact.content); } // return the exit code to the caller. @@ -469,26 +460,22 @@ async function main() { exitcode = await currentMain(autorestArgs); } - // for relaxed profiling (assuming that no one calls `main` from electron... use AAAL!) - if (require("process").versions.electron) await new Promise(_ => { }); - process.exit(exitcode); } catch (e) { + // be very careful about the following check: + // - doing the inversion (instanceof Error) doesn't reliably work since that seems to return false on Errors marshalled from safeEval if (e instanceof Exception) { - console.log(e.message); - - if (autorestArgs.indexOf("--debug")) { + if (autorestArgs.indexOf("--debug") !== -1) { console.log(e); + } else { + console.log(e.message); } process.exit(e.exitCode); } - if (e instanceof Error) { + if (e !== false) { console.error(e); - process.exit(1); } - - console.error(e); process.exit(1); } } diff --git a/src/autorest-core/lib/autorest-core.ts b/src/autorest-core/lib/autorest-core.ts index 34880c8d5..2cd207174 100644 --- a/src/autorest-core/lib/autorest-core.ts +++ b/src/autorest-core/lib/autorest-core.ts @@ -42,16 +42,16 @@ export class AutoRest extends EventEmitter { public static async LiterateToJson(content: string): Promise { try { - let autorest = new AutoRest({ - EnumerateFileUris: async function (folderUri: string): Promise> { return []; }, + let autorest = new AutoRest({ + EnumerateFileUris: async function (folderUri: string): Promise> { return []; }, ReadFile: async (f: string): Promise => f == "none:///empty-file.md" ? content || "# empty file" : "# empty file" - }); - let result = ""; + }); + let result = ""; autorest.AddConfiguration({ "input-file": "none:///empty-file.md", "output-artifact": ["swagger-document"] }); - autorest.GeneratedFile.Subscribe((source, artifact) => { - result = artifact.content; - }); - // run autorest and wait. + autorest.GeneratedFile.Subscribe((source, artifact) => { + result = artifact.content; + }); + // run autorest and wait. await (await autorest.Process()).finish; return result; @@ -212,25 +212,22 @@ export class AutoRest extends EventEmitter { view.messageEmitter.removeAllListeners(); return true; } catch (e) { - if (e instanceof Error) { - /* if (!(e instanceof OperationCanceledException)) { - console.error(e.message); - } */ - this.Message.Dispatch({ Channel: Channel.Debug, Text: `Process() Cancelled due to exception : ${e.message}` }); - this.Finished.Dispatch(e); - + if (e instanceof Exception) { + // console.error(e); + this.Finished.Dispatch(false); if (view) { view.messageEmitter.removeAllListeners(); } - return e; + return false; } - // console.error(e); - this.Finished.Dispatch(false); + this.Message.Dispatch({ Channel: Channel.Debug, Text: `Process() Cancelled due to exception : ${e.message}` }); + this.Finished.Dispatch(e); + if (view) { view.messageEmitter.removeAllListeners(); } - return false; + return e; } }; return { diff --git a/src/autorest-core/lib/configuration.ts b/src/autorest-core/lib/configuration.ts index 0591a480a..82cb925ad 100644 --- a/src/autorest-core/lib/configuration.ts +++ b/src/autorest-core/lib/configuration.ts @@ -22,10 +22,11 @@ import { exists } from './ref/async'; import { CancellationToken, CancellationTokenSource } from './ref/cancellation'; import { stringify } from './ref/jsonpath'; import { From } from './ref/linq'; -import { CreateFileUri, CreateFolderUri, EnsureIsFolderUri, ResolveUri } from './ref/uri'; +import { CreateFileUri, CreateFolderUri, EnsureIsFolderUri, ExistsUri, ResolveUri } from './ref/uri'; import { BlameTree } from './source-map/blaming'; import { MergeOverwriteOrAppend, resolveRValue } from './source-map/merging'; import { TryDecodeEnhancedPositionFromName } from './source-map/source-map'; +import { safeEval } from './ref/safe-eval'; const untildify: (path: string) => string = require("untildify"); @@ -37,9 +38,11 @@ export interface AutoRestConfigurationImpl { "input-file"?: string[] | string; "base-folder"?: string; "directive"?: Directive[] | Directive; + "declare-directive"?: { [name: string]: string }; "output-artifact"?: string[] | string; "message-format"?: "json"; "use-extension"?: { [extensionName: string]: string }; + "require"?: string[] | string; "vscode"?: any; // activates VS Code specific behavior and does *NOT* influence the core's behavior (only consumed by VS Code extension) "override-info"?: any; // make sure source maps are pulling it! (see "composite swagger" method) @@ -198,7 +201,6 @@ export class ConfigurationView { /* @internal */public configFileFolderUri: string, ...configs: Array // decreasing priority ) { - // TODO: fix configuration loading, note that there was no point in passing that DataStore used // for loading in here as all connection to the sources is lost when passing `Array` instead of `DataHandleRead`s... // theoretically the `ValuesOf` approach and such won't support blaming (who to blame if $.directives[3] sucks? which code block was it from) @@ -207,6 +209,7 @@ export class ConfigurationView { "directive": [], "input-file": [], "output-artifact": [], + "require": [], "use": [], }; @@ -235,7 +238,6 @@ export class ConfigurationView { } else { this.config = this.rawConfig; } - this.suppressor = new Suppressor(this); this.Message({ Channel: Channel.Debug, Text: `Creating ConfigurationView : ${configs.length} sections.` }); } @@ -244,7 +246,7 @@ export class ConfigurationView { return Object.getOwnPropertyNames(this.config); } - public Dump(title: string = "") { + public Dump(title: string = ""): void { console.log(`\n${title}\n===================================`) for (const each of Object.getOwnPropertyNames(this.config)) { console.log(`${each} : ${(this.config)[each]}`); @@ -294,9 +296,37 @@ export class ConfigurationView { }); } - public get Directives(): Iterable { - return From(ValuesOf(this.config["directive"])) - .Select(each => new DirectiveView(each)); + public get IncludedConfigurationFiles(): string[] { + return From(ValuesOf(this.config["require"])) + .Select(each => this.ResolveAsPath(each)) + .ToArray(); + } + + public get Directives(): DirectiveView[] { + const plainDirectives = ValuesOf(this.config["directive"]); + const declarations = this.config["declare-directive"] || {}; + const expandDirective = (dir: Directive): Iterable => { + const makro = Object.keys(dir).filter(makro => declarations[makro])[0]; + if (!makro) { + return [dir]; // nothing to expand + } + // prepare directive + let parameters = (dir as any)[makro]; + if (!Array.isArray(parameters)) { + parameters = [parameters]; + } + dir = { ...dir }; + delete (dir as any)[makro]; + // call makro + const makroResults: any = From(parameters).SelectMany(parameter => { + // console.log(new Error().stack); + const result = safeEval(declarations[makro], { $: parameter, $context: dir }); + return Array.isArray(result) ? result : [result]; + }).ToArray(); + return From(makroResults).SelectMany((result: any) => expandDirective(Object.assign(result, dir))); + }; + // makro expansion + return From(plainDirectives).SelectMany(expandDirective).Select(each => new DirectiveView(each)).ToArray(); } public get InputFileUris(): string[] { @@ -390,7 +420,7 @@ export class ConfigurationView { return [s]; } - return blameTree.BlameLeafs().map(r => { document: r.source, Position: Object.assign(TryDecodeEnhancedPositionFromName(r.name) || {}, { line: r.line, column: r.column }) }); + return blameTree.BlameLeafs().map(r => { document: r.source, Position: { ...TryDecodeEnhancedPositionFromName(r.name), line: r.line, column: r.column } }); }); //console.log("---"); @@ -484,7 +514,7 @@ export class ConfigurationView { export class Configuration { public constructor( - private fileSystem?: IFileSystem, + private fileSystem: IFileSystem = new RealFileSystem(), private configFileOrFolderUri?: string, ) { } @@ -516,7 +546,7 @@ export class Configuration { private async DesugarRawConfig(configs: any): Promise { // shallow copy configs = Object.assign({}, configs); - configs["use-extension"] = Object.assign({}, configs["use-extension"]); + configs["use-extension"] = { ...configs["use-extension"] }; if (configs.hasOwnProperty('licence-header')) { configs['license-header'] = configs['licence-header']; @@ -560,23 +590,54 @@ export class Configuration { : null; const configFileFolderUri = configFileUri ? ResolveUri(configFileUri, "./") : (this.configFileOrFolderUri || "file:///"); - const createView = () => new ConfigurationView(messageEmitter, configFileFolderUri, ...configSegments); - const configSegments: any[] = []; + const createView = () => new ConfigurationView(messageEmitter, configFileFolderUri, ...configSegments); const addSegments = async (configs: any[]): Promise => { configSegments.push(...await this.DesugarRawConfigs(configs)); }; // 1. overrides (CLI, ...) await addSegments(configs); // 2. file if (configFileUri !== null) { - const inputView = messageEmitter.DataStore.GetReadThroughScope(this.fileSystem as IFileSystem); + const inputView = messageEmitter.DataStore.GetReadThroughScope(this.fileSystem); const blocks = await this.ParseCodeBlocks( await inputView.ReadStrict(configFileUri), createView(), "config"); await addSegments(blocks); } - // 3. default configuration + // 3. resolve 'require'd configuration + const addedConfigs = new Set(); + while (true) { + const tmpView = createView(); + const additionalConfigs = tmpView.IncludedConfigurationFiles.filter(ext => !addedConfigs.has(ext)); + if (additionalConfigs.length === 0) { + break; + } + // acquire additional configs + for (const additionalConfig of additionalConfigs) { + try { + messageEmitter.Message.Dispatch({ + Channel: Channel.Verbose, + Text: `Including configuration file '${additionalConfig}'` + }); + addedConfigs.add(additionalConfig); + // merge config + const inputView = messageEmitter.DataStore.GetReadThroughScope(this.fileSystem); + const blocks = await this.ParseCodeBlocks( + await inputView.ReadStrict(additionalConfig), + tmpView, + `require-config-${additionalConfig}`); + await addSegments(blocks); + } catch (e) { + messageEmitter.Message.Dispatch({ + Channel: Channel.Fatal, + Text: `Failed to acquire 'require'd configuration '${additionalConfig}'` + }); + throw e; + } + } + } + // 4. default configuration if (includeDefault) { const inputView = messageEmitter.DataStore.GetReadThroughScope(new RealFileSystem()); const blocks = await this.ParseCodeBlocks( @@ -585,7 +646,7 @@ export class Configuration { "default-config"); await addSegments(blocks); } - // 4. resolve externals + // 5. resolve extensions const extMgr = await this.extensionManager; const addedExtensions = new Set(); while (true) { @@ -680,10 +741,23 @@ export class Configuration { public static async DetectConfigurationFile(fileSystem: IFileSystem, configFileOrFolderUri: string | null, messageEmitter?: MessageEmitter, walkUpFolders: boolean = false): Promise { const originalConfigFileOrFolderUri = configFileOrFolderUri; + // if (!configFileOrFolderUri || configFileOrFolderUri.endsWith(".md")) { return configFileOrFolderUri; } + // try querying the Uri directly + if (ExistsUri(configFileOrFolderUri)) { + try { + const content = await fileSystem.ReadFile(configFileOrFolderUri); + if (content.indexOf(Constants.MagicString) > -1) { + return configFileOrFolderUri; + } + } catch (e) { + // that didn't work... try next + } + } + // search for a config file, walking up the folder tree while (configFileOrFolderUri !== null) { // scan the filesystem items for the configuration. diff --git a/src/autorest-core/lib/data-store/data-store.ts b/src/autorest-core/lib/data-store/data-store.ts index deed26905..93142feaf 100644 --- a/src/autorest-core/lib/data-store/data-store.ts +++ b/src/autorest-core/lib/data-store/data-store.ts @@ -96,7 +96,7 @@ class ReadThroughDataSource extends DataSource { } public async Read(uri: string): Promise { - uri = ToRawDataUrl(uri); + uri = ToRawDataUrl(uri); // makes sure logical paths (like for source maps) also reference the URLs of the actual data // sync cache (inner stuff is racey!) if (!this.cache[uri]) { diff --git a/src/autorest-core/lib/exception.ts b/src/autorest-core/lib/exception.ts index 671647757..4cc440ef9 100644 --- a/src/autorest-core/lib/exception.ts +++ b/src/autorest-core/lib/exception.ts @@ -6,7 +6,7 @@ export class Exception extends Error { constructor(message: string, public exitCode: number = 1) { - super(message.indexOf('[') == -1 ? `[Exception] ${message}` : message); + super(message.includes('[') ? message : `[Exception] ${message}`); Object.setPrototypeOf(this, Exception.prototype); } diff --git a/src/autorest-core/lib/file-system.ts b/src/autorest-core/lib/file-system.ts index 0d23484ed..a7408ed61 100644 --- a/src/autorest-core/lib/file-system.ts +++ b/src/autorest-core/lib/file-system.ts @@ -5,9 +5,8 @@ import { MessageEmitter } from './configuration'; import { ConfigurationView } from './autorest-core'; import { Channel } from "./message"; -import { EnumerateFiles } from "./ref/uri"; +import { EnumerateFiles, ToRawDataUrl, ResolveUri, ReadUri, WriteString } from './ref/uri'; import { From } from "./ref/linq"; -import { ResolveUri, ReadUri, WriteString } from "./ref/uri"; import * as Constants from './constants'; export interface IFileSystem { @@ -70,6 +69,7 @@ export class RealFileSystem implements IFileSystem { } // handles: +// - GitHub URI adjustment // - GitHub auth export class EnhancedFileSystem implements IFileSystem { public constructor(private githubAuthToken?: string) { @@ -81,6 +81,8 @@ export class EnhancedFileSystem implements IFileSystem { ]); } async ReadFile(uri: string): Promise { + uri = ToRawDataUrl(uri); + const headers: { [key: string]: string } = {}; // check for GitHub OAuth token diff --git a/src/autorest-core/lib/parsing/literate-yaml.ts b/src/autorest-core/lib/parsing/literate-yaml.ts index 2ae6de74a..eae8fb765 100644 --- a/src/autorest-core/lib/parsing/literate-yaml.ts +++ b/src/autorest-core/lib/parsing/literate-yaml.ts @@ -112,11 +112,19 @@ export function EvaluateGuard(rawFenceGuard: string, contextObject: any): boolea let guardResult = false; let expressionFence: string = ''; try { + if (!fence.includes("$(")) { + try { + return safeEval(fence); + } catch (e) { + return false; + } + } + expressionFence = `${resolveRValue(fence, "", contextObject, null, 2)}`; // is there unresolved values? May be old-style. Or the values aren't defined. // Let's run it only if there are no unresolved values for now. - if (expressionFence.indexOf("$(") == -1) { + if (!expressionFence.includes("$(")) { return safeEval(expressionFence); } } catch (E) { @@ -126,7 +134,7 @@ export function EvaluateGuard(rawFenceGuard: string, contextObject: any): boolea // is this a single $( ... ) expression ? match = /^\$\((.*)\)$/.exec(fence.trim()); - const guardExpression = match && match[1].indexOf("$(") == -1 && match[1]; + const guardExpression = match && !match[1].includes("$(") && match[1]; if (!guardExpression) { // Nope. this isn't an old style expression. // at best, it can be an expression that doesn't have all the values resolved. @@ -135,7 +143,7 @@ export function EvaluateGuard(rawFenceGuard: string, contextObject: any): boolea } // fall back to original behavior, where the whole expression is in the $( ... ) - const context = Object.assign({ $: contextObject }, contextObject); + const context = { $: contextObject, ...contextObject }; try { guardResult = safeEval(guardExpression, context); diff --git a/src/autorest-core/lib/pipeline/manipulation.ts b/src/autorest-core/lib/pipeline/manipulation.ts index cf34e9a02..b3604b478 100644 --- a/src/autorest-core/lib/pipeline/manipulation.ts +++ b/src/autorest-core/lib/pipeline/manipulation.ts @@ -17,7 +17,7 @@ export class Manipulator { private ctr = 0; public constructor(private config: ConfigurationView) { - this.transformations = From(config.Directives).ToArray(); + this.transformations = config.Directives; } private MatchesSourceFilter(document: string, transform: DirectiveView, artifact: string | null): boolean { @@ -57,22 +57,6 @@ export class Manipulator { } data = result.result; } - // set - for (const s of trans.set) { - const result = await ManipulateObject(data, sink, w, obj => s/*, - { - reason: trans.reason, - transformerSourceHandle: // TODO - }*/); - if (!result.anyHit) { - // this.config.Message({ - // Channel: Channel.Warning, - // Details: trans, - // Text: `Set directive with 'where' clause '${w}' was not used.` - // }); - } - data = result.result; - } // test for (const t of trans.test) { const doc = data.ReadObject(); diff --git a/src/autorest-core/lib/pipeline/pipeline.ts b/src/autorest-core/lib/pipeline/pipeline.ts index 1e0900e4f..e08254355 100644 --- a/src/autorest-core/lib/pipeline/pipeline.ts +++ b/src/autorest-core/lib/pipeline/pipeline.ts @@ -256,7 +256,6 @@ function BuildPipeline(config: ConfigurationView): { pipeline: { [name: string]: } export async function RunPipeline(configView: ConfigurationView, fileSystem: IFileSystem): Promise { - // built-in plugins const plugins: { [name: string]: PipelinePlugin } = { "identity": CreatePluginIdentity(), @@ -288,7 +287,8 @@ export async function RunPipeline(configView: ConfigurationView, fileSystem: IFi // __status scope const startTime = Date.now(); (configView.Raw as any).__status = new Proxy({}, { - async get(_, key) { + get(_, key) { + if (key === "__info") return false; const expr = new Buffer(key.toString(), "base64").toString("ascii"); try { return FastStringify(safeEval(expr, { diff --git a/src/autorest-core/lib/pipeline/suppression.ts b/src/autorest-core/lib/pipeline/suppression.ts index 3aae6ef09..3d682f857 100644 --- a/src/autorest-core/lib/pipeline/suppression.ts +++ b/src/autorest-core/lib/pipeline/suppression.ts @@ -13,7 +13,7 @@ export class Suppressor { private suppressions: DirectiveView[]; public constructor(private config: ConfigurationView) { - this.suppressions = From(config.Directives).Where(x => [...x.suppress].length > 0).ToArray(); + this.suppressions = config.Directives.filter(x => [...x.suppress].length > 0); } private MatchesSourceFilter(document: string, path: JsonPath | undefined, supression: DirectiveView): boolean { diff --git a/src/autorest-core/lib/ref/uri.ts b/src/autorest-core/lib/ref/uri.ts index 307f267fe..75d48423e 100644 --- a/src/autorest-core/lib/ref/uri.ts +++ b/src/autorest-core/lib/ref/uri.ts @@ -122,10 +122,17 @@ export function GetFilenameWithoutExtension(uri: string): string { } export function ToRawDataUrl(uri: string): string { - // special URI handlers - // - GitHub - if (uri.startsWith("https://github")) { - uri = uri.replace(/^https?:\/\/(github.com)(\/[^\/]+\/[^\/]+\/)(blob|tree)\/(.*)/ig, "https://raw.githubusercontent.com$2$4"); + // special URI handlers (the 'if's shouldn't be necessary but provide some additional isolation in case there is anything wrong with one of the regexes) + // - GitHub repo + if (uri.startsWith("https://github.com")) { + uri = uri.replace(/^https?:\/\/(github.com)(\/[^\/]+\/[^\/]+\/)(blob|tree)\/(.*)$/ig, "https://raw.githubusercontent.com$2$4"); + } + // - GitHub gist + if (uri.startsWith("gist://")) { + uri = uri.replace(/^gist:\/\/([^\/]+\/[^\/]+)$/ig, "https://gist.githubusercontent.com/$1/raw/"); + } + if (uri.startsWith("https://gist.github.com")) { + uri = uri.replace(/^https?:\/\/gist.github.com\/([^\/]+\/[^\/]+)$/ig, "https://gist.githubusercontent.com/$1/raw/"); } return uri; @@ -203,7 +210,7 @@ function isAccessibleFile(localPath: string) { function FileUriToLocalPath(fileUri: string): string { const uri = parse(fileUri); if (!fileUri.startsWith("file:///")) { - throw new Error((!fileUri.startsWith("file://") + throw new Error(`Cannot write data to '${fileUri}'. ` + (!fileUri.startsWith("file://") ? `Protocol '${uri.protocol}' not supported for writing.` : `UNC paths not supported for writing.`) + " Make sure to specify a local, absolute path as target file/folder."); } diff --git a/src/autorest-core/lib/source-map/blaming.ts b/src/autorest-core/lib/source-map/blaming.ts index aa6ea7653..cb97fa095 100644 --- a/src/autorest-core/lib/source-map/blaming.ts +++ b/src/autorest-core/lib/source-map/blaming.ts @@ -17,10 +17,7 @@ export class BlameTree { const enhanced = TryDecodeEnhancedPositionFromName(position.name); if (enhanced !== undefined) { for (const blame of blames) { - blame.name = EncodeEnhancedPositionInName(blame.name, Object.assign( - {}, - enhanced, - TryDecodeEnhancedPositionFromName(blame.name) || {})); + blame.name = EncodeEnhancedPositionInName(blame.name, { ...enhanced, ...TryDecodeEnhancedPositionFromName(blame.name) }); } } diff --git a/src/autorest-core/resources/default-configuration.md b/src/autorest-core/resources/default-configuration.md index fbc19a447..e27aa4a30 100644 --- a/src/autorest-core/resources/default-configuration.md +++ b/src/autorest-core/resources/default-configuration.md @@ -194,3 +194,108 @@ On by default for backwards compatibility, but see https://github.com/Azure/auto ``` yaml client-side-validation: true ``` + +# Directives + +The built-in `transform` directive with its filters `from` and `where` are very powerful, but can become verbose and thus hard to reuse for common patterns (e.g. rename an operation). +Furthermore, they usually rely on precise data formats (e.g. where to find operations in the `code-model-v1`) and thus break once the data format changes. +We propose the following mechanism of declaring directives similar to macros, which allows capturing commonly used directives in a more high-level way. +Configuration files using these macros instead of "low-level" directives are robust against changes in the data format as the declaration in here will be adjusted accordingly. + +## How it works + +A declaration such as + +``` yaml false +declare-directive: + my-directive: >- + [ + { + transform: `some transformer, parameterized with '${JSON.stringify($)}'` + }, + { + from: "code-model-v1" + transform: `some other transformer, parameterized with '${JSON.stringify($)}'` + } + ] +``` + +can be used by naming it in a `directive` section: + +``` yaml false +directive: + - my-directive: # as a standalone, with an object as parameter + foo: bar + baz: 42 + - from: a + where: b + my-directive: 42 # together with other stuff, with a number as parameter +``` + +Each `directive` entry that names `my-directive` will be expanded with the whatever the declaration evaluates to, where `$` is substituted with the value provided to the directive when used. +If the declaration evaluates to an array, the directives are duplicated accordingly (this enables directive declarations that transform data on multiple stages). +In the above example, `directive` gets expanded to: + +``` yaml false +directive: + - transform: >- + some transformer, parameterized with '{ "foo": \"bar\", "baz": 42 }' + - from: code-model-v1 + transform: >- + some other transformer, parameterized with '{ "foo": \"bar\", "baz": 42 }' + - from: a + where: b + transform: >- + some transformer, parameterized with '42' + - from: a + where: b + transform: >- + some other transformer, parameterized with '42' +``` + +As can be seen in the last `directive`, `from` as specified originally was not overridden by `code-model-v1`, i.e. what was specified by the user is given higher priority. + + +## `set` + +Formerly implemented in the AutoRest core itself, `set` is now just syntactic sugar for `transform`. + +``` yaml +declare-directive: + set: >- + { transform: `return ${JSON.stringify($)}` } +``` + +## Operations + +### Selection + +Select operations by ID at different stages of the pipeline. + +``` yaml +declare-directive: + where-operation: >- + (() => { + switch ($context.from) { + case "code-model-v1": + return { from: "code-model-v1", where: `$.operations[*].methods[?(@.serializedName == ${JSON.stringify($)})]` }; + case "swagger-document": + default: + return { from: "swagger-document", where: `$.paths.*[?(@.operationId == ${JSON.stringify($)})]` }; + } + })() +``` + +## Removal + +Removes an operation by ID. + +``` yaml +declare-directive: + remove-operation: >- + { + from: 'swagger-document', + "where-operation": $, + transform: 'return undefined' + } +``` diff --git a/src/autorest-core/test/syntax-validation.ts b/src/autorest-core/test/syntax-validation.ts index 17ce8d124..04e8d73e8 100644 --- a/src/autorest-core/test/syntax-validation.ts +++ b/src/autorest-core/test/syntax-validation.ts @@ -31,7 +31,7 @@ import { Parse } from "../lib/parsing/literate-yaml"; return messages; } - @test async "syntax errors"() { + @test @timeout(10000) async "syntax errors"() { // good assert.strictEqual((await this.GetLoaderErrors("{ a: 3 }")).length, 0); assert.strictEqual((await this.GetLoaderErrors("a: 3")).length, 0);