Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor updates #194

Merged
merged 5 commits into from
Nov 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/IIIFPresentation/API/API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks.EntityFrameworkCore" Version="8.0.11" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.3" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using API.Features.Storage.Models;
using API.Helpers;
using API.Infrastructure.AWS;
using API.Infrastructure.IdGenerator;
using API.Infrastructure.Requests;
using API.Infrastructure.Validation;
using API.Settings;
Expand Down Expand Up @@ -36,7 +37,7 @@ public class CreateCollectionHandler(
PresentationContext dbContext,
ILogger<CreateCollectionHandler> logger,
IIIFS3Service iiifS3,
IIdGenerator idGenerator,
IdentityManager identityManager,
IPathGenerator pathGenerator,
IOptions<ApiSettings> options)
: IRequestHandler<CreateCollection, ModifyEntityResult<PresentationCollection, ModifyCollectionType>>
Expand Down Expand Up @@ -69,7 +70,7 @@ public async Task<ModifyEntityResult<PresentationCollection, ModifyCollectionTyp

try
{
id = await dbContext.Collections.GenerateUniqueIdAsync(request.CustomerId, idGenerator, cancellationToken);
id = await identityManager.GenerateUniqueId<Collection>(request.CustomerId, cancellationToken);
}
catch (ConstraintException ex)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
using System.Data;
using API.Auth;
using API.Converters;
using API.Features.Storage.Helpers;
using API.Helpers;
using API.Infrastructure.AWS;
using API.Infrastructure.IdGenerator;
using API.Infrastructure.Requests;
using Core;
using Core.IIIF;
Expand All @@ -15,7 +15,6 @@
using Repository;
using Repository.Helpers;
using DatabaseCollection = Models.Database.Collections;
using IIdGenerator = API.Infrastructure.IdGenerator.IIdGenerator;

namespace API.Features.Storage.Requests;

Expand All @@ -34,7 +33,7 @@ public class PostHierarchicalCollection(
public class PostHierarchicalCollectionHandler(
PresentationContext dbContext,
ILogger<PostHierarchicalCollectionHandler> logger,
IIdGenerator idGenerator,
IdentityManager identityManager,
IIIFS3Service iiifS3,
IPathGenerator pathGenerator)
: IRequestHandler<PostHierarchicalCollection, ModifyEntityResult<Collection, ModifyCollectionType>>
Expand Down Expand Up @@ -119,16 +118,14 @@ private static DatabaseCollection.Collection CreateDatabaseCollection(PostHierar

private async Task<string?> GenerateUniqueId(PostHierarchicalCollection request, CancellationToken cancellationToken)
{
string? id = null;
try
{
id = await dbContext.Collections.GenerateUniqueIdAsync(request.CustomerId, idGenerator, cancellationToken);
return await identityManager.GenerateUniqueId<DatabaseCollection.Collection>(request.CustomerId, cancellationToken);
}
catch (ConstraintException ex)
{
logger.LogError(ex, "An exception occured while generating a unique id");
return null;
}

return id;
}
}
41 changes: 1 addition & 40 deletions src/IIIFPresentation/API/Helpers/CollectionHelperX.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
using System.Data;
using API.Converters;
using API.Infrastructure.IdGenerator;
using Microsoft.EntityFrameworkCore;
using Models.Database;
using Models.Database.Collections;
using Models.Database.General;
using Models.Database.Collections;

namespace API.Helpers;

Expand All @@ -13,7 +7,6 @@ namespace API.Helpers;
/// </summary>
public static class CollectionHelperX
{
private const int MaxAttempts = 3;
private const string ManifestsSlug = "manifests";
private const string CollectionsSlug = "collections";

Expand All @@ -25,36 +18,4 @@ public static string GenerateETagCacheKey(this IHierarchyResource hierarchyResou

private static string GetSlug<T>(this T resource) where T : IHierarchyResource
=> resource is Manifest ? ManifestsSlug : CollectionsSlug;

[Obsolete("Use IdentityManager.GenerateUniqueId instead.")]
public static async Task<string> GenerateUniqueIdAsync<T>(this DbSet<T> entities,
int customerId, IIdGenerator idGenerator, CancellationToken cancellationToken = default)
where T : class, IIdentifiable
{
var isUnique = false;
var id = string.Empty;
var currentAttempt = 0;
var random = new Random();
var maxRandomValue = 25000;

while (!isUnique)
{
if (currentAttempt > MaxAttempts)
{
throw new ConstraintException("Max attempts to generate an identifier exceeded");
}

id = idGenerator.Generate([
customerId,
DateTime.UtcNow.Ticks,
random.Next(0, maxRandomValue)
]);

isUnique = !await entities.AnyAsync(e => e.Id == id && e.CustomerId == customerId, cancellationToken);

currentAttempt++;
}

return id;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ public class IdentityManager(
ILogger<IdentityManager> logger)
{
private const int MaxAttempts = 3;
private const int MaxRandomValue = 25000;

public async Task<string> GenerateUniqueId<T>(int customerId, CancellationToken cancellationToken = default)
where T : class, IIdentifiable
Expand Down Expand Up @@ -70,7 +69,7 @@ public async Task<IList<string>> GenerateUniqueIds<T>(int customerId, int count,

throw new ConstraintException("Max attempts to generate an identifier exceeded");
}

private string GenerateIdentity(int customerId, Random random)
=> idGenerator.Generate([customerId, DateTime.UtcNow.Ticks, random.Next(0, MaxRandomValue)]);
=> idGenerator.Generate([random.Next(0, int.MaxValue), DateTime.UtcNow.Ticks, customerId]);
}
13 changes: 5 additions & 8 deletions src/IIIFPresentation/API/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@
.AddHttpContextAccessor();
builder.Services.ConfigureMediatR();
builder.Services.ConfigureIdGenerator();
builder.Services.AddHealthChecks();
builder.Services
.AddHealthChecks()
.AddDbContextCheck<PresentationContext>("Database");
builder.Services.AddAws(builder.Configuration, builder.Environment, aws);
builder.Services.Configure<ForwardedHeadersOptions>(opts =>
{
Expand All @@ -84,17 +86,12 @@

IIIFPresentationContextConfiguration.TryRunMigrations(builder.Configuration, app.Logger);

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}

var rewriteOptions = new RewriteOptions()
.AddRedirect("(.*)/$", "$1");

app
.UseSwagger()
.UseSwaggerUI()
.UseRewriter(rewriteOptions)
.UseHttpsRedirection()
.UseAuthentication()
Expand Down
185 changes: 0 additions & 185 deletions src/IIIFPresentation/AWS.Tests/S3/Models/ObjectInBucketXTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,166 +25,6 @@ public void GetS3Uri_Key_Correct()
s3Uri.ToString().Should().Be("s3://my-bucket/key/for/item");
}

[Fact]
public void GetS3Uri_Regionalised_NoRegion_NoKey_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket");

var s3Uri = objectInBucket.GetS3Uri();

s3Uri.ToString().Should().Be("s3://my-bucket/");
}

[Fact]
public void GetS3Uri_Regionalised_NoRegion_Key_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", "key/for/item");

var s3Uri = objectInBucket.GetS3Uri();

s3Uri.ToString().Should().Be("s3://my-bucket/key/for/item");
}

[Fact]
public void GetS3Uri_Regionalised_Region_NoKey_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", region: "eu-west-1");

var s3Uri = objectInBucket.GetS3Uri();

s3Uri.ToString().Should().Be("s3://my-bucket/");
}

[Fact]
public void GetS3Uri_Regionalised_Region_Key_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", "key/for/item", "eu-west-1");

var s3Uri = objectInBucket.GetS3Uri();

s3Uri.ToString().Should().Be("s3://my-bucket/key/for/item");
}

[Fact]
public void GetLegacyS3Uri_NoKey_Correct()
{
var objectInBucket = new ObjectInBucket("my-bucket");

var s3Uri = objectInBucket.GetLegacyS3Uri("us-east-1");

s3Uri.ToString().Should().Be("s3://us-east-1/my-bucket/");
}

[Fact]
public void GetLegacyS3Uri_Key_Correct()
{
var objectInBucket = new ObjectInBucket("my-bucket", "key/for/item");

var s3Uri = objectInBucket.GetLegacyS3Uri("us-east-1");

s3Uri.ToString().Should().Be("s3://us-east-1/my-bucket/key/for/item");
}

[Fact]
public void GetLegacyS3Uri_Regionalised_NoRegion_NoKey_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket");

var s3Uri = objectInBucket.GetLegacyS3Uri("us-east-1");

s3Uri.ToString().Should().Be("s3://us-east-1/my-bucket/");
}

[Fact]
public void GetLegacyS3Uri_Regionalised_NoRegion_Key_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", "key/for/item");

var s3Uri = objectInBucket.GetLegacyS3Uri("us-east-1");

s3Uri.ToString().Should().Be("s3://us-east-1/my-bucket/key/for/item");
}

[Fact]
public void GetLegacyS3Uri_Regionalised_Region_NoKey_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", region: "eu-west-1");

var s3Uri = objectInBucket.GetLegacyS3Uri("us-east-1");

s3Uri.ToString().Should().Be("s3://eu-west-1/my-bucket/");
}

[Fact]
public void GetLegacyS3Uri_Regionalised_Region_Key_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", "key/for/item", "eu-west-1");

var s3Uri = objectInBucket.GetLegacyS3Uri("us-east-1");

s3Uri.ToString().Should().Be("s3://eu-west-1/my-bucket/key/for/item");
}

[Fact]
public void GetHttpUri_NoKey_Correct()
{
var objectInBucket = new ObjectInBucket("my-bucket");

var s3Uri = objectInBucket.GetHttpUri();

s3Uri.ToString().Should().Be("https://s3.amazonaws.com/my-bucket/");
}

[Fact]
public void GetHttpUri_Key_Correct()
{
var objectInBucket = new ObjectInBucket("my-bucket", "key/for/item");

var s3Uri = objectInBucket.GetHttpUri();

s3Uri.ToString().Should().Be("https://s3.amazonaws.com/my-bucket/key/for/item");
}

[Fact]
public void GetHttpUri_Regionalised_NoRegion_NoKey_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket");

var s3Uri = objectInBucket.GetHttpUri();

s3Uri.ToString().Should().Be("https://s3.amazonaws.com/my-bucket/");
}

[Fact]
public void GetHttpUri_Regionalised_NoRegion_Key_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", "key/for/item");

var s3Uri = objectInBucket.GetHttpUri();

s3Uri.ToString().Should().Be("https://s3.amazonaws.com/my-bucket/key/for/item");
}

[Fact]
public void GetHttpUri_Regionalised_Region_NoKey_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", region: "eu-west-1");

var s3Uri = objectInBucket.GetHttpUri();

s3Uri.ToString().Should().Be("https://my-bucket.s3.eu-west-1.amazonaws.com/");
}

[Fact]
public void GetHttpUri_Regionalised_Region_Key_Correct()
{
var objectInBucket = new RegionalisedObjectInBucket("my-bucket", "key/for/item", "eu-west-1");

var s3Uri = objectInBucket.GetHttpUri();

s3Uri.ToString().Should().Be("https://my-bucket.s3.eu-west-1.amazonaws.com/key/for/item");
}

[Theory]
[InlineData("bucket", "bucket", "key", "key", true)]
[InlineData("bucket", "bucket", null, null, true)]
Expand All @@ -203,29 +43,4 @@ public void EqualsOperator_Compares_Values(string b1, string b2, string k1, stri
(objectInBucket1 == objectInBucket2).Should().Be(expected);
(objectInBucket1 != objectInBucket2).Should().Be(!expected);
}

[Theory]
[InlineData("bucket", "bucket", "key", "key", "region", "region", true)]
[InlineData("bucket", "bucket", null, null, "region", "region", true)]
[InlineData("bucket", "bucket", "key", "key", null, null, true)]
[InlineData("bucket1", "bucket", "key", "key", "region", "region", false)]
[InlineData("bucket", "bucket1", "key", "key", "region", "region", false)]
[InlineData("bucket", "bucket", "key1", "key", "region", "region", false)]
[InlineData("bucket", "bucket", "key", "key1", "region", "region", false)]
[InlineData("bucket", "bucket", null, "key", "region", "region", false)]
[InlineData("bucket", "bucket", "key", null, "region", "region", false)]
[InlineData("bucket", "bucket", "key", "key", "region1", "region", false)]
[InlineData("bucket", "bucket", "key", "key", "region", "region1", false)]
[InlineData("bucket", "bucket", "key", "key", null, "region", false)]
[InlineData("bucket", "bucket", "key", "key", "region", null, false)]
public void RegionalisedEqualsOperator_Compares_Values(string b1, string b2, string k1, string k2, string r1,
string r2, bool expected)
{
var objectInBucket1 = new RegionalisedObjectInBucket(b1, k1, r1);
var objectInBucket2 = new RegionalisedObjectInBucket(b2, k2, r2);

objectInBucket1.Equals(objectInBucket2).Should().Be(expected);
(objectInBucket1 == objectInBucket2).Should().Be(expected);
(objectInBucket1 != objectInBucket2).Should().Be(!expected);
}
}
Loading
Loading