src/Network/Common/NetworkClient.cs (153 lines of code) (raw):

// ---------------------------------------------------------------------------------- // // Copyright Microsoft Corporation // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ---------------------------------------------------------------------------------- using Microsoft.Azure.Commands.Common.Authentication; using Microsoft.Azure.Commands.Common.Authentication.Abstractions; using Microsoft.Azure.Commands.Common.Authentication.Abstractions.Interfaces; using Microsoft.Azure.Commands.Common.Authentication.Models; using Microsoft.Azure.Management.Internal.Network.Version2017_03_01; using Microsoft.Azure.Management.Internal.Network.Version2017_03_01.Models; using Microsoft.Rest; using Microsoft.Rest.Azure; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Microsoft.Azure.Management.Internal.Network.Common { public partial class NetworkClient { public INetworkManagementClient NetworkManagementClient { get; set; } public Action<string> VerboseLogger { get; set; } public Action<string> ErrorLogger { get; set; } public Action<string> WarningLogger { get; set; } public NetworkClient(IAzureContext context): this(AzureSession.Instance.ClientFactory.CreateArmClient<NetworkManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager)) { } public NetworkClient(IAzureContext context, ICmdletContext cmdletContext) : this(AzureSession.Instance.ClientFactory.CreateArmClient<NetworkManagementClient>(context, AzureEnvironment.Endpoint.ResourceManager, cmdletContext)) { } public NetworkClient(INetworkManagementClient NetworkManagementClient) { this.NetworkManagementClient = NetworkManagementClient; } public NetworkClient() { } public string Generatevpnclientpackage(string resourceGroupName, string virtualNetworkGatewayName, VpnClientParameters parameters) { return Task.Factory.StartNew(() => GeneratevpnclientpackageAsync(resourceGroupName, virtualNetworkGatewayName, parameters)).Unwrap().GetAwaiter().GetResult(); } public async Task<string> GeneratevpnclientpackageAsync(string resourceGroupName, string virtualNetworkGatewayName, VpnClientParameters parameters, CancellationToken cancellationToken = default(CancellationToken)) { AzureOperationResponse<string> result = await this.GeneratevpnclientpackageWithHttpMessagesAsync(resourceGroupName, virtualNetworkGatewayName, parameters, null, cancellationToken).ConfigureAwait(false); return result.Body; } /// <summary> /// The Generatevpnclientpackage operation generates Vpn client package for /// P2S client of the virtual network gateway in the specified resource group /// through Network resource provider. /// </summary> /// <param name='resourceGroupName'> /// The name of the resource group. /// </param> /// <param name='virtualNetworkGatewayName'> /// The name of the virtual network gateway. /// </param> /// <param name='parameters'> /// Parameters supplied to the Begin Generating Virtual Network Gateway Vpn /// client package operation through Network resource provider. /// </param> /// <param name='customHeaders'> /// Headers that will be added to request. /// </param> /// <param name='cancellationToken'> /// The cancellation token. /// </param> public async Task<AzureOperationResponse<string>> GeneratevpnclientpackageWithHttpMessagesAsync(string resourceGroupName, string virtualNetworkGatewayName, VpnClientParameters parameters, Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken)) { #region 1. Send Async request to generate vpn client package // 1. Send Async request to generate vpn client package string baseUrl = NetworkManagementClient.BaseUri.ToString(); string apiVersion = "2016-12-01"; if (resourceGroupName == null) { throw new ValidationException(ValidationRules.CannotBeNull, "resourceGroupName"); } if (virtualNetworkGatewayName == null) { throw new ValidationException(ValidationRules.CannotBeNull, "virtualNetworkGatewayName"); } if (parameters == null) { throw new ValidationException(ValidationRules.CannotBeNull, "parameters"); } // Construct URL var url = new Uri(new Uri(baseUrl + (baseUrl.EndsWith("/") ? "" : "/")), "subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/" + "providers/Microsoft.Network/virtualnetworkgateways/{virtualNetworkGatewayName}/generatevpnclientpackage").ToString(); url = url.Replace("{resourceGroupName}", Uri.EscapeDataString(resourceGroupName)); url = url.Replace("{virtualNetworkGatewayName}", Uri.EscapeDataString(virtualNetworkGatewayName)); url = url.Replace("{subscriptionId}", Uri.EscapeDataString(NetworkManagementClient.SubscriptionId)); url += "?" + string.Join("&", string.Format("api-version={0}", Uri.EscapeDataString(apiVersion))); // Create HTTP transport objects HttpRequestMessage httpRequest = new HttpRequestMessage(); httpRequest.Method = new HttpMethod("POST"); httpRequest.RequestUri = new Uri(url); // Set Headers httpRequest.Headers.TryAddWithoutValidation("x-ms-client-request-id", Guid.NewGuid().ToString()); // Serialize Request string requestContent = JsonConvert.SerializeObject(parameters, NetworkManagementClient.SerializationSettings); httpRequest.Content = new StringContent(requestContent, Encoding.UTF8); httpRequest.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json; charset=utf-8"); // Set Credentials if (NetworkManagementClient.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await NetworkManagementClient.Credentials.ProcessHttpRequestAsync(httpRequest, cancellationToken).ConfigureAwait(false); } // Send Request cancellationToken.ThrowIfCancellationRequested(); var client = this.NetworkManagementClient as NetworkManagementClient; HttpClient httpClient = client.HttpClient; HttpResponseMessage httpResponse = await httpClient.SendAsync(httpRequest, cancellationToken).ConfigureAwait(false); HttpStatusCode statusCode = httpResponse.StatusCode; cancellationToken.ThrowIfCancellationRequested(); if ((int)statusCode != 202) { string responseContent = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); throw new Exception(string.Format("Get-AzVpnClientPackage Operation returned an invalid status code '{0}' with Exception:{1}", statusCode, string.IsNullOrEmpty(responseContent) ? "NotAvailable" : responseContent)); } // Create Result var result = new AzureOperationResponse<string>(); result.Request = httpRequest; result.Response = httpResponse; string locationResultsUrl = string.Empty; // Retrieve the location from LocationUri if (httpResponse.Headers.Contains("Location")) { locationResultsUrl = httpResponse.Headers.GetValues("Location").FirstOrDefault(); } else { throw new Exception(string.Format("Get-AzVpnClientPackage Operation Failed as no valid Location header received in response!")); } if (string.IsNullOrEmpty(locationResultsUrl)) { throw new Exception(string.Format("Get-AzVpnClientPackage Operation Failed as no valid Location header value received in response!")); } #endregion #region 2. Wait for Async operation to succeed and then Get the content i.e. VPN Client package Url from locationResults //Microsoft.WindowsAzure.Commands.Utilities.Common.TestMockSupport.Delay(60000); // 2. Wait for Async operation to succeed DateTime startTime = DateTime.UtcNow; DateTime giveUpAt = DateTime.UtcNow.AddMinutes(3); // Send the Get locationResults request for operaitonId till either we get StatusCode 200 or it time outs (3 minutes in this case) while (true) { HttpRequestMessage newHttpRequest = new HttpRequestMessage(); newHttpRequest.Method = new HttpMethod("GET"); newHttpRequest.RequestUri = new Uri(locationResultsUrl); if (NetworkManagementClient.Credentials != null) { cancellationToken.ThrowIfCancellationRequested(); await NetworkManagementClient.Credentials.ProcessHttpRequestAsync(newHttpRequest, cancellationToken).ConfigureAwait(false); } HttpResponseMessage newHttpResponse = await httpClient.SendAsync(newHttpRequest, cancellationToken).ConfigureAwait(false); if ((int)newHttpResponse.StatusCode != 200) { if (DateTime.UtcNow > giveUpAt) { string newResponseContent = await newHttpResponse.Content.ReadAsStringAsync().ConfigureAwait(false); throw new Exception(string.Format("Get-AzVpnClientPackage Operation returned an invalid status code '{0}' with Exception:{1} while retrieving " + "the Vpnclient PackageUrl!", newHttpResponse.StatusCode, string.IsNullOrEmpty(newResponseContent) ? "NotAvailable" : newResponseContent)); } else { // Wait for 15 seconds before retrying Microsoft.WindowsAzure.Commands.Utilities.Common.TestMockSupport.Delay(15000); } } else { // Get the content i.e.VPN Client package Url from locationResults result.Body = newHttpResponse.Content.ReadAsStringAsync().Result; return result; } } #endregion } } }