/*
* 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 Amazon.Runtime.Endpoints;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using ThirdParty.Json.LitJson;
namespace Amazon.Runtime.Internal.Endpoints.StandardLibrary
{
///
/// Internal implementation of partition related data.
/// Used by standard library functions to access partition related data.
///
public partial class Partition : PropertyBag
{
///
/// Partition Name
///
public string name
{
get { return (string)this["name"]; }
set { this["name"] = value; }
}
///
/// Partition DNS suffix
///
public string dnsSuffix
{
get { return (string)this["dnsSuffix"]; }
set { this["dnsSuffix"] = value; }
}
///
/// Partition IPv6 DNS suffix
///
public string dualStackDnsSuffix
{
get { return (string)this["dualStackDnsSuffix"]; }
set { this["dualStackDnsSuffix"] = value; }
}
///
/// Partition supports FIPS
///
public bool supportsFIPS
{
get { return (bool)this["supportsFIPS"]; }
set { this["supportsFIPS"] = value; }
}
///
/// Partition supports IPv6
///
public bool supportsDualStack
{
get { return (bool)this["supportsDualStack"]; }
set { this["supportsDualStack"] = value; }
}
///
/// Builds Partition from PartitionAttributesShape
///
internal static Partition FromPartitionData(PartitionAttributesShape data)
{
return new Partition
{
name = data.name,
dnsSuffix = data.dnsSuffix,
dualStackDnsSuffix = data.dualStackDnsSuffix,
supportsFIPS = data.supportsFIPS,
supportsDualStack = data.supportsDualStack
};
}
private static readonly ReaderWriterLockSlim _locker = new ReaderWriterLockSlim();
private static Dictionary _partitionsByRegionName = new Dictionary();
private static Dictionary _partitionsByRegex = new Dictionary();
private static PartitionAttributesShape _defaultPartition;
///
/// Override partitions data from json file
///
public static void LoadPartitions(string partitionsFile)
{
if (!File.Exists(partitionsFile))
{
throw new AmazonClientException($"Can't find partitions file: {partitionsFile}");
}
_locker.EnterWriteLock();
try
{
var json = File.ReadAllText(partitionsFile);
var partitions = JsonMapper.ToObject(json);
_partitionsByRegionName.Clear();
_partitionsByRegex.Clear();
_defaultPartition = null;
foreach (var partition in partitions.partitions)
{
if (partition.id == "aws")
{
_defaultPartition = partition.outputs;
}
_partitionsByRegex.Add(partition.regionRegex, partition.outputs);
foreach (var region in partition.regions.Keys)
{
_partitionsByRegionName.Add(region, partition.outputs);
}
}
}
finally
{
_locker.ExitWriteLock();
}
}
internal static Partition GetPartitionByRegion(string region)
{
_locker.EnterReadLock();
try
{
PartitionAttributesShape partition;
// direct match
if (_partitionsByRegionName.TryGetValue(region, out partition))
{
return FromPartitionData(partition);
}
// regex match
foreach (var regex in _partitionsByRegex.Keys)
{
if (Regex.IsMatch(region, regex))
{
return FromPartitionData(_partitionsByRegex[regex]);
}
}
return FromPartitionData(_defaultPartition);
}
finally
{
_locker.ExitReadLock();
}
}
}
}