Skip to content

Commit

Permalink
Fix bug with custom client request id generation (Azure#1104)
Browse files Browse the repository at this point in the history
* Fix bug with custom client request id generation

  - Fix bug where parameter grouping broke custom client
    request id generation.

* Add tests and regenerated expected

* Fix static analysis errors

  - Fix string.Format missing CultureInfo.CurrentCulture.
  - ProcessClientRequestIdExtension check serviceClient for null.
  • Loading branch information
matthchr authored and tbombach committed Jun 2, 2016
1 parent 26e44ad commit 88a5f61
Show file tree
Hide file tree
Showing 43 changed files with 1,017 additions and 75 deletions.
22 changes: 22 additions & 0 deletions AutoRest/Generators/CSharp/Azure.CSharp.Tests/AcceptanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,28 @@ public void CustomNamedRequestIdTest()
}
}

[Fact]
public void CustomNamedRequestIdParameterGroupingTest()
{
SwaggerSpecRunner.RunTests(
SwaggerPath("azure-special-properties.json"), ExpectedPath("AzureSpecials"), generator: "Azure.CSharp");

const string validSubscription = "1234-5678-9012-3456";
const string expectedRequestId = "9C4D50EE-2D56-4CD3-8152-34347DC9F2B0";

using (var client = new AutoRestAzureSpecialParametersTestClient(Fixture.Uri,
new TokenCredentials(validSubscription, Guid.NewGuid().ToString())))
{
var group = new HeaderCustomNamedRequestIdParamGroupingParameters()
{
FooClientRequestId = expectedRequestId
};
IAzureOperationResponse response = client.Header.CustomNamedRequestIdParamGroupingWithHttpMessagesAsync(group).Result;

Assert.Equal("123", response.RequestId);
}
}

[Fact]
public void DurationTests()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,5 +216,172 @@ internal HeaderOperations(AutoRestAzureSpecialParametersTestClient client)
return _result;
}

/// <summary>
/// Send foo-client-request-id = 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0 in the
/// header of the request, via a parameter group
/// </summary>
/// <param name='headerCustomNamedRequestIdParamGroupingParameters'>
/// Additional parameters for the operation
/// </param>
/// <param name='customHeaders'>
/// Headers that will be added to request.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
/// <return>
/// A response object containing the response body and response headers.
/// </return>
public async Task<AzureOperationHeaderResponse<HeaderCustomNamedRequestIdParamGroupingHeaders>> CustomNamedRequestIdParamGroupingWithHttpMessagesAsync(HeaderCustomNamedRequestIdParamGroupingParameters headerCustomNamedRequestIdParamGroupingParameters, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
{
if (headerCustomNamedRequestIdParamGroupingParameters == null)
{
throw new ValidationException(ValidationRules.CannotBeNull, "headerCustomNamedRequestIdParamGroupingParameters");
}
if (headerCustomNamedRequestIdParamGroupingParameters != null)
{
headerCustomNamedRequestIdParamGroupingParameters.Validate();
}
string fooClientRequestId = default(string);
if (headerCustomNamedRequestIdParamGroupingParameters != null)
{
fooClientRequestId = headerCustomNamedRequestIdParamGroupingParameters.FooClientRequestId;
}
// Tracing
bool _shouldTrace = ServiceClientTracing.IsEnabled;
string _invocationId = null;
if (_shouldTrace)
{
_invocationId = ServiceClientTracing.NextInvocationId.ToString();
Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("fooClientRequestId", fooClientRequestId);
tracingParameters.Add("cancellationToken", cancellationToken);
ServiceClientTracing.Enter(_invocationId, this, "CustomNamedRequestIdParamGrouping", tracingParameters);
}
// Construct URL
var _baseUrl = this.Client.BaseUri.AbsoluteUri;
var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "azurespecials/customNamedRequestIdParamGrouping").ToString();
List<string> _queryParameters = new List<string>();
if (_queryParameters.Count > 0)
{
_url += "?" + string.Join("&", _queryParameters);
}
// Create HTTP transport objects
HttpRequestMessage _httpRequest = new HttpRequestMessage();
HttpResponseMessage _httpResponse = null;
_httpRequest.Method = new HttpMethod("POST");
_httpRequest.RequestUri = new Uri(_url);
// Set Headers
if (this.Client.GenerateClientRequestId != null && this.Client.GenerateClientRequestId.Value)
{
_httpRequest.Headers.TryAddWithoutValidation("foo-client-request-id", Guid.NewGuid().ToString());
}
if (this.Client.AcceptLanguage != null)
{
if (_httpRequest.Headers.Contains("accept-language"))
{
_httpRequest.Headers.Remove("accept-language");
}
_httpRequest.Headers.TryAddWithoutValidation("accept-language", this.Client.AcceptLanguage);
}
if (fooClientRequestId != null)
{
if (_httpRequest.Headers.Contains("foo-client-request-id"))
{
_httpRequest.Headers.Remove("foo-client-request-id");
}
_httpRequest.Headers.TryAddWithoutValidation("foo-client-request-id", fooClientRequestId);
}
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;
// Set Credentials
if (this.Client.Credentials != null)
{
cancellationToken.ThrowIfCancellationRequested();
await this.Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
}
// Send Request
if (_shouldTrace)
{
ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
_httpResponse = await this.Client.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 ErrorException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
try
{
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
Error _errorBody = SafeJsonConvert.DeserializeObject<Error>(_responseContent, this.Client.DeserializationSettings);
if (_errorBody != null)
{
ex.Body = _errorBody;
}
}
catch (JsonException)
{
// Ignore the exception
}
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 AzureOperationHeaderResponse<HeaderCustomNamedRequestIdParamGroupingHeaders>();
_result.Request = _httpRequest;
_result.Response = _httpResponse;
if (_httpResponse.Headers.Contains("foo-request-id"))
{
_result.RequestId = _httpResponse.Headers.GetValues("foo-request-id").FirstOrDefault();
}
try
{
_result.Headers = _httpResponse.GetHeadersAsJson().ToObject<HeaderCustomNamedRequestIdParamGroupingHeaders>(JsonSerializer.Create(this.Client.DeserializationSettings));
}
catch (JsonException ex)
{
_httpRequest.Dispose();
if (_httpResponse != null)
{
_httpResponse.Dispose();
}
throw new SerializationException("Unable to deserialize the headers.", _httpResponse.GetHeadersAsJson().ToString(), ex);
}
if (_shouldTrace)
{
ServiceClientTracing.Exit(_invocationId, _result);
}
return _result;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,41 @@ public static HeaderCustomNamedRequestIdHeaders CustomNamedRequestId(this IHeade
}
}

/// <summary>
/// Send foo-client-request-id = 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0 in the
/// header of the request, via a parameter group
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
/// <param name='headerCustomNamedRequestIdParamGroupingParameters'>
/// Additional parameters for the operation
/// </param>
public static HeaderCustomNamedRequestIdParamGroupingHeaders CustomNamedRequestIdParamGrouping(this IHeaderOperations operations, HeaderCustomNamedRequestIdParamGroupingParameters headerCustomNamedRequestIdParamGroupingParameters)
{
return Task.Factory.StartNew(s => ((IHeaderOperations)s).CustomNamedRequestIdParamGroupingAsync(headerCustomNamedRequestIdParamGroupingParameters), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
}

/// <summary>
/// Send foo-client-request-id = 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0 in the
/// header of the request, via a parameter group
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
/// <param name='headerCustomNamedRequestIdParamGroupingParameters'>
/// Additional parameters for the operation
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
public static async Task<HeaderCustomNamedRequestIdParamGroupingHeaders> CustomNamedRequestIdParamGroupingAsync(this IHeaderOperations operations, HeaderCustomNamedRequestIdParamGroupingParameters headerCustomNamedRequestIdParamGroupingParameters, CancellationToken cancellationToken = default(CancellationToken))
{
using (var _result = await operations.CustomNamedRequestIdParamGroupingWithHttpMessagesAsync(headerCustomNamedRequestIdParamGroupingParameters, null, cancellationToken).ConfigureAwait(false))
{
return _result.Headers;
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,19 @@ public partial interface IHeaderOperations
/// Thrown when a required parameter is null
/// </exception>
Task<AzureOperationHeaderResponse<HeaderCustomNamedRequestIdHeaders>> CustomNamedRequestIdWithHttpMessagesAsync(string fooClientRequestId, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Send foo-client-request-id = 9C4D50EE-2D56-4CD3-8152-34347DC9F2B0
/// in the header of the request, via a parameter group
/// </summary>
/// <param name='headerCustomNamedRequestIdParamGroupingParameters'>
/// Additional parameters for the operation
/// </param>
/// <param name='customHeaders'>
/// The headers that will be added to request.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
Task<AzureOperationHeaderResponse<HeaderCustomNamedRequestIdParamGroupingHeaders>> CustomNamedRequestIdParamGroupingWithHttpMessagesAsync(HeaderCustomNamedRequestIdParamGroupingParameters headerCustomNamedRequestIdParamGroupingParameters, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.

namespace Fixtures.Azure.AcceptanceTestsAzureSpecials.Models
{
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using Microsoft.Rest.Azure;

/// <summary>
/// Defines headers for customNamedRequestIdParamGrouping operation.
/// </summary>
public partial class HeaderCustomNamedRequestIdParamGroupingHeaders
{
/// <summary>
/// Initializes a new instance of the
/// HeaderCustomNamedRequestIdParamGroupingHeaders class.
/// </summary>
public HeaderCustomNamedRequestIdParamGroupingHeaders() { }

/// <summary>
/// Initializes a new instance of the
/// HeaderCustomNamedRequestIdParamGroupingHeaders class.
/// </summary>
public HeaderCustomNamedRequestIdParamGroupingHeaders(string fooRequestId = default(string))
{
FooRequestId = fooRequestId;
}

/// <summary>
/// Gets or sets gets the foo-request-id.
/// </summary>
[JsonProperty(PropertyName = "foo-request-id")]
public string FooRequestId { get; set; }

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for
// license information.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.

namespace Fixtures.Azure.AcceptanceTestsAzureSpecials.Models
{
using System;
using System.Linq;
using System.Collections.Generic;
using Newtonsoft.Json;
using Microsoft.Rest;
using Microsoft.Rest.Serialization;
using Microsoft.Rest.Azure;

/// <summary>
/// Additional parameters for the header_customNamedRequestIdParamGrouping
/// operation.
/// </summary>
public partial class HeaderCustomNamedRequestIdParamGroupingParameters
{
/// <summary>
/// Initializes a new instance of the
/// HeaderCustomNamedRequestIdParamGroupingParameters class.
/// </summary>
public HeaderCustomNamedRequestIdParamGroupingParameters() { }

/// <summary>
/// Initializes a new instance of the
/// HeaderCustomNamedRequestIdParamGroupingParameters class.
/// </summary>
public HeaderCustomNamedRequestIdParamGroupingParameters(string fooClientRequestId)
{
FooClientRequestId = fooClientRequestId;
}

/// <summary>
/// Gets or sets the fooRequestId
/// </summary>
[JsonProperty(PropertyName = "")]
public string FooClientRequestId { get; set; }

/// <summary>
/// Validate the object. Throws ValidationException if validation fails.
/// </summary>
public virtual void Validate()
{
if (FooClientRequestId == null)
{
throw new ValidationException(ValidationRules.CannotBeNull, "FooClientRequestId");
}
}
}
}
Loading

0 comments on commit 88a5f61

Please sign in to comment.