/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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 System; using System.Net; using System.Threading; using Amazon.Util; namespace Amazon.StorageGateway.Util { /// /// Utilities for working with the AWS Storage Gateway service, such as /// requesting a running AWS Storage Gateway instances's activation key for /// registering a Storage Gateway server. /// public static class AmazonStorageGatewayUtil { private const string activationKeyName = "activationKey"; private const string locationHeaderName = "Location"; private const int defaultMaxRetries = 5; private const int defaultMaxBackoff = 30 * 1000; /// /// Sends a request to the AWS Storage Gateway server running at the /// specified address, and returns the activation key for that server. /// The default max retry count and max exponential backoff time will be /// used. /// /// The DNS name or IP address of a running AWS Storage Gateway /// The activation key required for some API calls to AWS Storage Gateway. /// Maximum default retry count is 5 attempts, with exponential backoff up to a max of 30 seconds. public static string GetActivationKey(string gatewayAddress) { return GetActivationKey(gatewayAddress, defaultMaxRetries, defaultMaxBackoff); } /// /// Sends a request to the AWS Storage Gateway server running at the /// specified address, and returns the activation key for that server. /// The default max retry count and max exponential backoff time will be /// used. /// /// The DNS name or IP address of a running AWS Storage Gateway /// The region in which the gateway will be activated. /// The activation key required for some API calls to AWS Storage Gateway. /// Maximum default retry count is 5 attempts, with exponential backoff up to a max of 30 seconds. public static string GetActivationKey(string gatewayAddress, RegionEndpoint activationRegion) { return GetActivationKey(gatewayAddress, activationRegion, defaultMaxRetries, defaultMaxBackoff); } /// /// Sends a request to the AWS Storage Gateway server running at the /// specified address, and returns the activation key for that server. /// /// The DNS name or IP address of a running AWS Storage Gateway /// The maximum number of retries to attempt on failure /// The maximum backoff time, in milliseconds, for retry attempts. Backoff times between retries rise exponentially until they hit this ceiling. /// The activation key required for some API calls to AWS Storage Gateway. public static string GetActivationKey(string gatewayAddress, int maxRetries, int maxBackoff) { return GetActivationKey(gatewayAddress, null, maxRetries, maxBackoff); } /// /// Sends a request to the AWS Storage Gateway server running at the /// specified address, and returns the activation key for that server. /// /// The DNS name or IP address of a running AWS Storage Gateway /// The region in which the gateway will be activated. /// The maximum number of retries to attempt on failure /// The maximum backoff time, in milliseconds, for retry attempts. Backoff times between retries rise exponentially until they hit this ceiling. /// The activation key required for some API calls to AWS Storage Gateway. public static string GetActivationKey(string gatewayAddress, RegionEndpoint activationRegion, int maxRetries, int maxBackoff) { if (maxRetries <= 1) maxRetries = defaultMaxRetries; if (maxBackoff <= 0) maxBackoff = defaultMaxBackoff; int retries = 0; while (retries < maxRetries) { try { string uri = "http://" + gatewayAddress; if (activationRegion != null) uri = uri + "/?activationRegion=" + activationRegion.SystemName; string locationHeader = GetHeader(uri); var parameters = AWSSDKUtils.ParseQueryParameters(locationHeader); string activationKey; if (parameters.TryGetValue(activationKeyName, out activationKey) && !string.IsNullOrEmpty(activationKey)) return activationKey; throw new AmazonStorageGatewayException("Unable to get activation key from : " + uri); } catch (WebException) { retries++; if (retries == maxRetries) break; } int delay = (int)(Math.Pow(4, retries) * 100); delay = Math.Min(delay, maxBackoff); AWSSDKUtils.Sleep(delay); } throw new AmazonStorageGatewayException("Unable to get activation key; retries exhausted"); } private static string GetHeader(string url) { HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest; request.AllowAutoRedirect = false; var asyncResponse = request.BeginGetResponse(null, null); using (HttpWebResponse response = request.EndGetResponse(asyncResponse) as HttpWebResponse) { if (response == null) { throw new WebException("The Web Response for a successful request is null!", WebExceptionStatus.ProtocolError); } if (response.StatusCode != HttpStatusCode.Found) throw new AmazonStorageGatewayException( "Could not fetch activation key, received HTTP status code '" + response.StatusCode + "' expected '302'"); return response.Headers[locationHeaderName]; } } } }