Rename Vexer to Excititor
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
using Amazon;
|
||||
using Amazon.Runtime;
|
||||
using Amazon.S3;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Excititor.Export;
|
||||
|
||||
namespace StellaOps.Excititor.ArtifactStores.S3.Extensions;
|
||||
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddVexS3ArtifactClient(this IServiceCollection services, Action<S3ArtifactClientOptions> configure)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(configure);
|
||||
|
||||
services.Configure(configure);
|
||||
services.AddSingleton(CreateS3Client);
|
||||
services.AddSingleton<IS3ArtifactClient, S3ArtifactClient>();
|
||||
return services;
|
||||
}
|
||||
|
||||
private static IAmazonS3 CreateS3Client(IServiceProvider provider)
|
||||
{
|
||||
var options = provider.GetRequiredService<IOptions<S3ArtifactClientOptions>>().Value;
|
||||
var config = new AmazonS3Config
|
||||
{
|
||||
RegionEndpoint = RegionEndpoint.GetBySystemName(options.Region),
|
||||
ForcePathStyle = options.ForcePathStyle,
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(options.ServiceUrl))
|
||||
{
|
||||
config.ServiceURL = options.ServiceUrl;
|
||||
}
|
||||
|
||||
return new AmazonS3Client(config);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using Amazon.S3;
|
||||
using Amazon.S3.Model;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using StellaOps.Excititor.Export;
|
||||
|
||||
namespace StellaOps.Excititor.ArtifactStores.S3;
|
||||
|
||||
public sealed class S3ArtifactClientOptions
|
||||
{
|
||||
public string Region { get; set; } = "us-east-1";
|
||||
|
||||
public string? ServiceUrl { get; set; }
|
||||
= null;
|
||||
|
||||
public bool ForcePathStyle { get; set; }
|
||||
= true;
|
||||
}
|
||||
|
||||
public sealed class S3ArtifactClient : IS3ArtifactClient
|
||||
{
|
||||
private readonly IAmazonS3 _s3;
|
||||
private readonly ILogger<S3ArtifactClient> _logger;
|
||||
|
||||
public S3ArtifactClient(IAmazonS3 s3, ILogger<S3ArtifactClient> logger)
|
||||
{
|
||||
_s3 = s3 ?? throw new ArgumentNullException(nameof(s3));
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
}
|
||||
|
||||
public async Task<bool> ObjectExistsAsync(string bucketName, string key, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var metadata = await _s3.GetObjectMetadataAsync(bucketName, key, cancellationToken).ConfigureAwait(false);
|
||||
return metadata.HttpStatusCode == System.Net.HttpStatusCode.OK;
|
||||
}
|
||||
catch (AmazonS3Exception ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task PutObjectAsync(string bucketName, string key, Stream content, IDictionary<string, string> metadata, CancellationToken cancellationToken)
|
||||
{
|
||||
var request = new PutObjectRequest
|
||||
{
|
||||
BucketName = bucketName,
|
||||
Key = key,
|
||||
InputStream = content,
|
||||
AutoCloseStream = false,
|
||||
};
|
||||
|
||||
foreach (var kvp in metadata)
|
||||
{
|
||||
request.Metadata[kvp.Key] = kvp.Value;
|
||||
}
|
||||
|
||||
await _s3.PutObjectAsync(request, cancellationToken).ConfigureAwait(false);
|
||||
_logger.LogDebug("Uploaded object {Bucket}/{Key}", bucketName, key);
|
||||
}
|
||||
|
||||
public async Task<Stream?> GetObjectAsync(string bucketName, string key, CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
var response = await _s3.GetObjectAsync(bucketName, key, cancellationToken).ConfigureAwait(false);
|
||||
var buffer = new MemoryStream();
|
||||
await response.ResponseStream.CopyToAsync(buffer, cancellationToken).ConfigureAwait(false);
|
||||
buffer.Position = 0;
|
||||
return buffer;
|
||||
}
|
||||
catch (AmazonS3Exception ex) when (ex.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
{
|
||||
_logger.LogDebug("Object {Bucket}/{Key} not found", bucketName, key);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DeleteObjectAsync(string bucketName, string key, CancellationToken cancellationToken)
|
||||
{
|
||||
await _s3.DeleteObjectAsync(bucketName, key, cancellationToken).ConfigureAwait(false);
|
||||
_logger.LogDebug("Deleted object {Bucket}/{Key}", bucketName, key);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AWSSDK.S3" Version="3.7.305.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Excititor.Export\StellaOps.Excititor.Export.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user