/*
* MinIO .NET Library for Amazon S3 Compatible Cloud Storage, (C) 2017 MinIO, Inc.
*
* 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 System.Collections.Concurrent;
using System.Net;
using System.Xml.Linq;
using Minio.Helper;
namespace Minio;
///
/// A singleton bucket/region cache map.
///
public sealed class BucketRegionCache
{
private static readonly Lazy lazy = new(() => new BucketRegionCache());
private readonly ConcurrentDictionary regionMap;
private BucketRegionCache()
{
regionMap = new ConcurrentDictionary(StringComparer.Ordinal);
}
public static BucketRegionCache Instance => lazy.Value;
///
/// Returns AWS region for given bucket name.
///
///
///
public string Region(string bucketName)
{
_ = regionMap.TryGetValue(bucketName, out var value);
return value ?? "us-east-1";
}
///
/// Adds bucket name and its region to BucketRegionCache.
///
///
///
public void Add(string bucketName, string region)
{
_ = regionMap.TryAdd(bucketName, region);
}
///
/// Removes region cache of the bucket if any.
///
///
public void Remove(string bucketName)
{
_ = regionMap.TryRemove(bucketName, out _);
}
///
/// Returns true if given bucket name is in the map else false.
///
///
///
public bool Exists(string bucketName)
{
_ = regionMap.TryGetValue(bucketName, out var value);
return !string.Equals(value, null, StringComparison.OrdinalIgnoreCase);
}
///
/// Updates Region cache for given bucket.
///
///
///
internal static async Task Update(IMinioClient client, string bucketName)
{
string region = null;
if (!string.Equals(bucketName, null, StringComparison.OrdinalIgnoreCase) && client.Config.AccessKey is not null
&& client.Config.SecretKey is not null && !Instance.Exists(bucketName))
{
string location = null;
var path = Utils.UrlEncode(bucketName);
// Initialize client
var requestUrl = RequestUtil.MakeTargetURL(client.Config.BaseUrl, client.Config.Secure);
var requestBuilder = new HttpRequestMessageBuilder(HttpMethod.Get, requestUrl, path);
requestBuilder.AddQueryParameter("location", "");
using var response =
await client.ExecuteTaskAsync(client.ResponseErrorHandlers, requestBuilder).ConfigureAwait(false);
if (response is not null && HttpStatusCode.OK.Equals(response.StatusCode))
{
var root = XDocument.Parse(response.Content);
location = root.Root.Value;
}
if (string.IsNullOrEmpty(location))
{
region = "us-east-1";
}
else
{
// eu-west-1 can be sometimes 'EU'.
if (string.Equals(location, "EU", StringComparison.OrdinalIgnoreCase))
region = "eu-west-1";
else
region = location;
}
// Add the new location.
Instance.Add(bucketName, region);
}
return region;
}
}