/*******************************************************************************
* Copyright 2008-2012 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.
* *****************************************************************************
* __ _ _ ___
* ( )( \/\/ )/ __)
* /__\ \ / \__ \
* (_)(_) \/\/ (___/
*
* AWS SDK for .NET
*
*/
using Amazon.Internal;
using Amazon.Runtime.Internal.Auth;
using System;
using System.Collections.Generic;
using System.Globalization;
#if UNITY
using UnityEngine;
using Amazon.Runtime.Internal;
#endif
namespace Amazon
{
///
/// This class contains region information used to lazily compute the service endpoints. The static constants representing the
/// regions can be used while constructing the AWS client instead of looking up the exact endpoint URL.
///
public partial class RegionEndpoint
{
#region Statics
private static Dictionary _hashBySystemName = new Dictionary(StringComparer.OrdinalIgnoreCase);
///
/// The US East (Virginia) endpoint.
///
public static readonly RegionEndpoint USEast1 = GetEndpoint("us-east-1", "US East (Virginia)");
///
/// The US East (Virginia) regional endpoint.
///
private static readonly RegionEndpoint USEast1Regional = GetEndpoint("us-east-1-regional", "US East (Virginia) regional");
///
/// The US East (Ohio) endpoint.
///
public static readonly RegionEndpoint USEast2 = GetEndpoint("us-east-2", "US East (Ohio)");
///
/// The US West (N. California) endpoint.
///
public static readonly RegionEndpoint USWest1 = GetEndpoint("us-west-1", "US West (N. California)");
///
/// The US West (Oregon) endpoint.
///
public static readonly RegionEndpoint USWest2 = GetEndpoint("us-west-2", "US West (Oregon)");
///
/// The EU North (Stockholm) endpoint.
///
public static readonly RegionEndpoint EUNorth1 = GetEndpoint("eu-north-1", "EU North (Stockholm)");
///
/// The EU West (Ireland) endpoint.
///
public static readonly RegionEndpoint EUWest1 = GetEndpoint("eu-west-1", "EU West (Ireland)");
///
/// The EU West (London) endpoint.
///
public static readonly RegionEndpoint EUWest2 = GetEndpoint("eu-west-2", "EU West (London)");
///
/// The EU West (Paris) endpoint.
///
public static readonly RegionEndpoint EUWest3 = GetEndpoint("eu-west-3", "EU West (Paris)");
///
/// The EU Central (Frankfurt) endpoint.
///
public static readonly RegionEndpoint EUCentral1 = GetEndpoint("eu-central-1", "EU Central (Frankfurt)");
///
/// The Asia Pacific (Hong Kong) endpoint.
///
public static readonly RegionEndpoint APEast1 = GetEndpoint("ap-east-1", "Asia Pacific (Hong Kong)");
///
/// The Asia Pacific (Tokyo) endpoint.
///
public static readonly RegionEndpoint APNortheast1 = GetEndpoint("ap-northeast-1", "Asia Pacific (Tokyo)");
///
/// The Asia Pacific (Seoul) endpoint.
///
public static readonly RegionEndpoint APNortheast2 = GetEndpoint("ap-northeast-2", "Asia Pacific (Seoul)");
///
/// The Asia Pacific (Osaka-Local) endpoint.
///
public static readonly RegionEndpoint APNortheast3 = GetEndpoint("ap-northeast-3", "Asia Pacific (Osaka-Local)");
///
/// The Asia Pacific (Mumbai) endpoint.
///
public static readonly RegionEndpoint APSouth1 = GetEndpoint("ap-south-1", "Asia Pacific (Mumbai)");
///
/// The Asia Pacific (Singapore) endpoint.
///
public static readonly RegionEndpoint APSoutheast1 = GetEndpoint("ap-southeast-1", "Asia Pacific (Singapore)");
///
/// The Asia Pacific (Sydney) endpoint.
///
public static readonly RegionEndpoint APSoutheast2 = GetEndpoint("ap-southeast-2", "Asia Pacific (Sydney)");
///
/// The South America (Sao Paulo) endpoint.
///
public static readonly RegionEndpoint SAEast1 = GetEndpoint("sa-east-1", "South America (Sao Paulo)");
///
/// The US GovCloud East (Virginia) endpoint.
///
public static readonly RegionEndpoint USGovCloudEast1 = GetEndpoint("us-gov-east-1", "US GovCloud East (Virginia)");
///
/// The US GovCloud West (Oregon) endpoint.
///
public static readonly RegionEndpoint USGovCloudWest1 = GetEndpoint("us-gov-west-1", "US GovCloud West (Oregon)");
///
/// The China (Beijing) endpoint.
///
public static readonly RegionEndpoint CNNorth1 = GetEndpoint("cn-north-1", "China (Beijing)");
///
/// The China (Ningxia) endpoint.
///
public static readonly RegionEndpoint CNNorthWest1 = GetEndpoint("cn-northwest-1", "China (Ningxia)");
///
/// The Canada (Central) endpoint.
///
public static readonly RegionEndpoint CACentral1 = GetEndpoint("ca-central-1", "Canada (Central)");
///
/// The Middle East (Bahrain) endpoint.
///
public static readonly RegionEndpoint MESouth1 = GetEndpoint("me-south-1", "Middle East (Bahrain)");
///
/// Represents the endpoint overridding rules in the endpoints.json
/// Is used to map private region (ie us-east-1-regional) to public regions (us-east-1)
/// For signing purposes.
///
private static Dictionary _hashRegionEndpointOverride = new Dictionary() {
{ USEast1Regional, USEast1 }
};
///
/// Enumerate through all the regions.
///
public static IEnumerable EnumerableAllRegions
{
get
{
List list = new List();
foreach (IRegionEndpoint endpoint in RegionEndpointProvider.AllRegionEndpoints)
{
list.Add(GetEndpoint(endpoint.RegionName, endpoint.DisplayName));
}
return list;
}
}
///
/// Gets the region based on its system name like "us-west-1"
///
/// The system name of the service like "us-west-1"
///
public static RegionEndpoint GetBySystemName(string systemName)
{
return GetEndpoint(systemName, null);
}
///
/// Gets the region endpoint override if exists
///
/// The region endpoint to find the possible override for
///
public static RegionEndpoint GetRegionEndpointOverride(RegionEndpoint regionEndpoint)
{
return _hashRegionEndpointOverride.ContainsKey(regionEndpoint) ? _hashRegionEndpointOverride[regionEndpoint] : null;
}
private static RegionEndpoint GetEndpoint(string systemName, string displayName)
{
RegionEndpoint regionEndpoint = null;
if (displayName == null)
{
lock (_hashBySystemName)
{
if (_hashBySystemName.TryGetValue(systemName, out regionEndpoint))
return regionEndpoint;
}
// GetRegionEndpoint will always return a non-null value. If the the region(systemName) is unknown,
// the providers will create a fallback instance that will generate an endpoint to the best
// of its knowledge.
displayName = RegionEndpointProvider.GetRegionEndpoint(systemName).DisplayName;
}
lock (_hashBySystemName)
{
if (_hashBySystemName.TryGetValue(systemName, out regionEndpoint))
return regionEndpoint;
regionEndpoint = new RegionEndpoint(systemName, displayName);
_hashBySystemName.Add(regionEndpoint.SystemName, regionEndpoint);
}
return regionEndpoint;
}
private static IRegionEndpointProvider _regionEndpointProvider;
private static IRegionEndpointProvider RegionEndpointProvider
{
get
{
if (_regionEndpointProvider == null)
{
// If the existing customer provided the endpoints.json file via
// , it's in v2 format. We we will create
// a v2 provider which does a fall through during LoadEndpointDefinitions()
// and loads from the override file provided by the user.
//
// Else, we are loading from the assembly resource. In which case we use the
// latest provider.
//
// It's actually a bug that _regionEndpointProvider is a static member variable
// since the IEndpointProvider should respect the AWSConfigs.EndpointDefinition
// _at_ the time of the service client instantiation. However, since this is
// the existing behavior with v2 endpoint file format, we will preserve this behavior as is.
if (!string.IsNullOrEmpty(AWSConfigs.EndpointDefinition))
{
_regionEndpointProvider = new RegionEndpointProviderV2();
}
else
{
_regionEndpointProvider = new RegionEndpointProviderV3();
}
}
return _regionEndpointProvider;
}
}
#endregion
private RegionEndpoint(string systemName, string displayName)
{
this.SystemName = systemName;
this.DisplayName = displayName;
}
///
/// Gets the system name of a region.
///
public string SystemName
{
get;
private set;
}
///
/// Gets the display name of a region.
///
public string DisplayName
{
get;
private set;
}
///
/// Gets the partition name the region is in. For example for us-east-1 the partition name is aws. For cn-northwest-1 the partition name is aws-cn.
///
public string PartitionName
{
get
{
var regionEndpointV3 = this.InternedRegionEndpoint as RegionEndpointV3;
return regionEndpointV3?.PartitionName;
}
}
///
/// Gets the dns suffix for the region endpoints in a partition. For example the aws partition's suffix is amazonaws.com. The aws-cn partition's suffix is amazonaws.com.cn.
///
public string PartitionDnsSuffix
{
get
{
var regionEndpointV3 = this.InternedRegionEndpoint as RegionEndpointV3;
return regionEndpointV3?.PartitionDnsSuffix;
}
}
private IRegionEndpoint InternedRegionEndpoint
{
get
{
return RegionEndpointProvider.GetRegionEndpoint(SystemName);
}
}
///
/// Gets the endpoint for a service in a region.
///
///
/// The services system name. Service system names can be obtained from the
/// RegionEndpointServiceName member of the ClientConfig-derived class for the service.
///
///
/// For forwards compatibility, if the service being requested for isn't known in the region, this method
/// will generate an endpoint using the AWS endpoint heuristics. In this case, it is not guaranteed the
/// endpoint will point to a valid service endpoint.
///
///
public Endpoint GetEndpointForService(string serviceName)
{
return GetEndpointForService(serviceName, false);
}
///
/// Gets the endpoint for a service in a region, optionally selecting a dualstack compatible endpoint.
///
///
/// The services system name. Service system names can be obtained from the
/// RegionEndpointServiceName member of the ClientConfig-derived class for the service.
///
///
/// If true a dualstack endpoint is returned. It is the user's responsibility to verify that the given service
/// supports a dualstack endpoint for the region.
///
///
/// For forwards compatibility, if the service being requested for isn't known in the region, this method
/// will generate an endpoint using the AWS endpoint heuristics. In this case, it is not guaranteed the
/// endpoint will point to a valid service endpoint.
///
///
public Endpoint GetEndpointForService(string serviceName, bool dualStack)
{
return InternedRegionEndpoint.GetEndpointForService(serviceName, dualStack);
}
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0} ({1})", this.DisplayName, this.SystemName);
}
///
/// This class defines an endpoints hostname and which protocols it supports.
///
public class Endpoint
{
internal Endpoint(string hostname, string authregion, string signatureVersionOverride)
{
this.Hostname = hostname;
this.AuthRegion = authregion;
this.SignatureVersionOverride = signatureVersionOverride;
}
///
/// Gets the hostname for the service.
///
public string Hostname
{
get;
private set;
}
///
/// The authentication region to be used in request signing.
///
public string AuthRegion
{
get;
private set;
}
public override string ToString()
{
return this.Hostname;
}
///
/// This property is only set for S3 endpoints. For all other services this property returns null.
/// For S3 endpoints, if the endpoint supports signature version 2 this property will be "2", otherwise it will be "4".
///
public string SignatureVersionOverride
{
get;
private set;
}
}
}
}