From b03712d4257806b2317123cde78d65bf60ca4d7e Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Thu, 11 Apr 2024 15:01:21 +0100 Subject: [PATCH 01/11] initial commit adding db --- .../Assets/AssetApplicationMetadata.cs | 40 +++++++ .../DLCS.Repository/DlcsContext.cs | 10 ++ ...9_adding AssetApplicationMetadata table.cs | 49 +++++++++ .../Migrations/DlcsContextModelSnapshot.cs | 104 +++++++++++++----- 4 files changed, 175 insertions(+), 28 deletions(-) create mode 100644 src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs create mode 100644 src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs diff --git a/src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs b/src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs new file mode 100644 index 000000000..1960cbcc6 --- /dev/null +++ b/src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using DLCS.Core.Types; + +namespace DLCS.Model.Assets; + +public class AssetApplicationMetadata +{ + /// + /// Unique identifier + /// + public int Id { get; set; } + + /// + /// The image id for the attached asset + /// + public AssetId ImageId { get; set; } + + public Asset Asset { get; set; } + + /// + /// Identifier for the type of metadata + /// + public string MetadataType { get; set; } + + /// + /// JSON object of values for type + /// + public string MetadataValue { get; set; } + + /// + /// When the metadata was created. + /// + public DateTime Created { get; set; } + + /// + /// When the metadata was last modified. + /// + public DateTime Modified { get; set; } +} \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/DlcsContext.cs b/src/protagonist/DLCS.Repository/DlcsContext.cs index 2ffb974a0..f53671c6c 100644 --- a/src/protagonist/DLCS.Repository/DlcsContext.cs +++ b/src/protagonist/DLCS.Repository/DlcsContext.cs @@ -77,6 +77,7 @@ public DlcsContext(DbContextOptions options) public virtual DbSet DeliveryChannelPolicies { get; set; } public virtual DbSet ImageDeliveryChannels { get; set; } public virtual DbSet DefaultDeliveryChannels { get; set; } + public virtual DbSet AssetApplicationMetadata { get; set; } public virtual DbSet SignupLinks { get; set; } @@ -680,6 +681,15 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.Property(e => e.MediaType).IsRequired().HasMaxLength(255); }); + modelBuilder.Entity(entity => + { + entity.Property(e => e.ImageId).IsRequired().HasConversion( + aId => aId.ToString(), + id => AssetId.FromString(id)); + entity.Property(e => e.MetadataType).IsRequired(); + entity.Property(e => e.MetadataValue).IsRequired().HasColumnType("jsonb"); + }); + OnModelCreatingPartial(modelBuilder); } diff --git a/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs b/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs new file mode 100644 index 000000000..fa286ffc9 --- /dev/null +++ b/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs @@ -0,0 +1,49 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DLCS.Repository.Migrations +{ + public partial class addingAssetApplicationMetadatatable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AssetApplicationMetadata", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ImageId = table.Column(type: "text", nullable: false), + AssetId = table.Column(type: "character varying(500)", nullable: false), + MetadataType = table.Column(type: "text", nullable: false), + MetadataValue = table.Column(type: "jsonb", nullable: false), + Created = table.Column(type: "timestamp with time zone", nullable: false), + Modified = table.Column(type: "timestamp with time zone", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AssetApplicationMetadata", x => x.Id); + table.ForeignKey( + name: "FK_AssetApplicationMetadata_Images_AssetId", + column: x => x.AssetId, + principalTable: "Images", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AssetApplicationMetadata_AssetId", + table: "AssetApplicationMetadata", + column: "AssetId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AssetApplicationMetadata"); + } + } +} diff --git a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs index 8ca77e0ef..a5b4ded68 100644 --- a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs +++ b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs @@ -18,7 +18,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) #pragma warning disable 612, 618 modelBuilder .UseCollation("en_US.UTF-8") - .HasAnnotation("ProductVersion", "6.0.5") + .HasAnnotation("ProductVersion", "6.0.22") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "tablefunc"); @@ -182,6 +182,43 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Images", (string)null); }); + modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AssetId") + .IsRequired() + .HasColumnType("character varying(500)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("ImageId") + .IsRequired() + .HasColumnType("text"); + + b.Property("MetadataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MetadataValue") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AssetId"); + + b.ToTable("AssetApplicationMetadata"); + }); + modelBuilder.Entity("DLCS.Model.Assets.Batch", b => { b.Property("Id") @@ -214,7 +251,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "Customer", "Superseded", "Submitted" }, "IX_BatchTest"); - b.ToTable("Batches", (string)null); + b.ToTable("Batches"); }); modelBuilder.Entity("DLCS.Model.Assets.CustomHeaders.CustomHeader", b => @@ -249,7 +286,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "Customer", "Space" }, "IX_CustomHeaders_ByCustomerSpace"); - b.ToTable("CustomHeaders", (string)null); + b.ToTable("CustomHeaders"); }); modelBuilder.Entity("DLCS.Model.Assets.ImageDeliveryChannel", b => @@ -278,7 +315,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("ImageId"); - b.ToTable("ImageDeliveryChannels", (string)null); + b.ToTable("ImageDeliveryChannels"); }); modelBuilder.Entity("DLCS.Model.Assets.ImageLocation", b => @@ -357,7 +394,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("NamedQueries", (string)null); + b.ToTable("NamedQueries"); }); modelBuilder.Entity("DLCS.Model.Auth.Entities.AuthService", b => @@ -413,7 +450,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id", "Customer"); - b.ToTable("AuthServices", (string)null); + b.ToTable("AuthServices"); }); modelBuilder.Entity("DLCS.Model.Auth.Entities.Role", b => @@ -441,7 +478,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id", "Customer"); - b.ToTable("Roles", (string)null); + b.ToTable("Roles"); }); modelBuilder.Entity("DLCS.Model.Auth.Entities.RoleProvider", b => @@ -468,7 +505,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("RoleProviders", (string)null); + b.ToTable("RoleProviders"); }); modelBuilder.Entity("DLCS.Model.Customers.Customer", b => @@ -502,7 +539,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("Customers", (string)null); + b.ToTable("Customers"); }); modelBuilder.Entity("DLCS.Model.Customers.CustomerOriginStrategy", b => @@ -537,7 +574,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("CustomerOriginStrategies", (string)null); + b.ToTable("CustomerOriginStrategies"); }); modelBuilder.Entity("DLCS.Model.Customers.SignupLink", b => @@ -559,7 +596,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("SignupLinks", (string)null); + b.ToTable("SignupLinks"); }); modelBuilder.Entity("DLCS.Model.Customers.User", b => @@ -594,7 +631,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("Users", (string)null); + b.ToTable("Users"); }); modelBuilder.Entity("DLCS.Model.DeliveryChannels.DefaultDeliveryChannel", b => @@ -624,7 +661,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Customer", "Space", "MediaType", "DeliveryChannelPolicyId") .IsUnique(); - b.ToTable("DefaultDeliveryChannels", (string)null); + b.ToTable("DefaultDeliveryChannels"); }); modelBuilder.Entity("DLCS.Model.Policies.DeliveryChannelPolicy", b => @@ -668,7 +705,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("Customer", "Name", "Channel") .IsUnique(); - b.ToTable("DeliveryChannelPolicies", (string)null); + b.ToTable("DeliveryChannelPolicies"); }); modelBuilder.Entity("DLCS.Model.Policies.ImageOptimisationPolicy", b => @@ -695,7 +732,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id", "Customer"); - b.ToTable("ImageOptimisationPolicies", (string)null); + b.ToTable("ImageOptimisationPolicies"); b.HasData( new @@ -727,7 +764,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("OriginStrategies", (string)null); + b.ToTable("OriginStrategies"); }); modelBuilder.Entity("DLCS.Model.Policies.ThumbnailPolicy", b => @@ -748,7 +785,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("ThumbnailPolicies", (string)null); + b.ToTable("ThumbnailPolicies"); }); modelBuilder.Entity("DLCS.Model.Processing.Queue", b => @@ -767,7 +804,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Customer", "Name"); - b.ToTable("Queues", (string)null); + b.ToTable("Queues"); }); modelBuilder.Entity("DLCS.Model.Spaces.Space", b => @@ -813,7 +850,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id", "Customer") .HasName("Spaces_pkey"); - b.ToTable("Spaces", (string)null); + b.ToTable("Spaces"); }); modelBuilder.Entity("DLCS.Model.Storage.CustomerStorage", b => @@ -859,7 +896,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("StoragePolicies", (string)null); + b.ToTable("StoragePolicies"); }); modelBuilder.Entity("DLCS.Repository.Auth.AuthToken", b => @@ -905,7 +942,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex(new[] { "CookieId" }, "IX_AuthTokens_CookieId"); - b.ToTable("AuthTokens", (string)null); + b.ToTable("AuthTokens"); }); modelBuilder.Entity("DLCS.Repository.Auth.SessionUser", b => @@ -923,7 +960,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("SessionUsers", (string)null); + b.ToTable("SessionUsers"); }); modelBuilder.Entity("DLCS.Repository.Entities.ActivityGroup", b => @@ -941,7 +978,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Group"); - b.ToTable("ActivityGroups", (string)null); + b.ToTable("ActivityGroups"); }); modelBuilder.Entity("DLCS.Repository.Entities.CustomerImageServer", b => @@ -956,7 +993,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Customer"); - b.ToTable("CustomerImageServers", (string)null); + b.ToTable("CustomerImageServers"); }); modelBuilder.Entity("DLCS.Repository.Entities.EntityCounter", b => @@ -977,7 +1014,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Type", "Scope", "Customer"); - b.ToTable("EntityCounters", (string)null); + b.ToTable("EntityCounters"); }); modelBuilder.Entity("DLCS.Repository.Entities.ImageServer", b => @@ -992,7 +1029,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("ImageServers", (string)null); + b.ToTable("ImageServers"); }); modelBuilder.Entity("DLCS.Repository.Entities.InfoJsonTemplate", b => @@ -1008,7 +1045,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.ToTable("InfoJsonTemplates", (string)null); + b.ToTable("InfoJsonTemplates"); }); modelBuilder.Entity("DLCS.Repository.Entities.MetricThreshold", b => @@ -1029,7 +1066,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Name", "Metric"); - b.ToTable("MetricThresholds", (string)null); + b.ToTable("MetricThresholds"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => + { + b.HasOne("DLCS.Model.Assets.Asset", "Asset") + .WithMany() + .HasForeignKey("AssetId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Asset"); }); modelBuilder.Entity("DLCS.Model.Assets.ImageDeliveryChannel", b => From e515a8670af68c9bdbe65b501485ad9c36aa8cb5 Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Thu, 11 Apr 2024 15:03:45 +0100 Subject: [PATCH 02/11] add designer file --- ...AssetApplicationMetadata table.Designer.cs | 1127 +++++++++++++++++ 1 file changed, 1127 insertions(+) create mode 100644 src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs diff --git a/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs b/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs new file mode 100644 index 000000000..9a7db1b22 --- /dev/null +++ b/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs @@ -0,0 +1,1127 @@ +// +using System; +using DLCS.Repository; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DLCS.Repository.Migrations +{ + [DbContext(typeof(DlcsContext))] + [Migration("20240411134159_adding AssetApplicationMetadata table")] + partial class addingAssetApplicationMetadatatable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseCollation("en_US.UTF-8") + .HasAnnotation("ProductVersion", "6.0.22") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "tablefunc"); + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.HasSequence("batch_id_sequence") + .StartsAt(570185L) + .HasMin(1L) + .HasMax(9223372036854775807L); + + modelBuilder.Entity("DLCS.Model.Assets.Asset", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Batch") + .IsRequired() + .HasColumnType("integer"); + + b.Property("Created") + .IsRequired() + .HasColumnType("timestamp with time zone"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("DeliveryChannels") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Duration") + .IsRequired() + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasDefaultValueSql("0"); + + b.Property("Error") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)") + .HasDefaultValueSql("NULL::character varying"); + + b.Property("Family") + .ValueGeneratedOnAdd() + .HasColumnType("char(1)") + .HasDefaultValueSql("'I'::\"char\""); + + b.Property("Finished") + .HasColumnType("timestamp with time zone"); + + b.Property("Height") + .IsRequired() + .HasColumnType("integer"); + + b.Property("ImageOptimisationPolicy") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValueSql("'fast-lossy'::character varying"); + + b.Property("Ingesting") + .IsRequired() + .HasColumnType("boolean"); + + b.Property("MaxUnauthorised") + .IsRequired() + .HasColumnType("integer"); + + b.Property("MediaType") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(100) + .HasColumnType("character varying(100)") + .HasDefaultValueSql("'image/jp2'::character varying"); + + b.Property("NotForDelivery") + .HasColumnType("boolean"); + + b.Property("NumberReference1") + .IsRequired() + .HasColumnType("integer"); + + b.Property("NumberReference2") + .IsRequired() + .HasColumnType("integer"); + + b.Property("NumberReference3") + .IsRequired() + .HasColumnType("integer"); + + b.Property("Origin") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("PreservedUri") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Reference1") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Reference2") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Reference3") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Roles") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Space") + .HasColumnType("integer"); + + b.Property("Tags") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ThumbnailPolicy") + .IsRequired() + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValueSql("'original'::character varying"); + + b.Property("Width") + .IsRequired() + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "Batch" }, "IX_ImagesByBatch"); + + b.HasIndex(new[] { "Id", "Customer", "Space" }, "IX_ImagesByCustomerSpace"); + + b.HasIndex(new[] { "Id", "Customer", "Error", "Batch" }, "IX_ImagesByErrors") + .HasFilter("((\"Error\" IS NOT NULL) AND ((\"Error\")::text <> ''::text))"); + + b.HasIndex(new[] { "Reference1" }, "IX_ImagesByReference1"); + + b.HasIndex(new[] { "Reference2" }, "IX_ImagesByReference2"); + + b.HasIndex(new[] { "Reference3" }, "IX_ImagesByReference3"); + + b.HasIndex(new[] { "Customer", "Space" }, "IX_ImagesBySpace"); + + b.ToTable("Images", (string)null); + }); + + modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AssetId") + .IsRequired() + .HasColumnType("character varying(500)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("ImageId") + .IsRequired() + .HasColumnType("text"); + + b.Property("MetadataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MetadataValue") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AssetId"); + + b.ToTable("AssetApplicationMetadata"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.Batch", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasDefaultValueSql("nextval('batch_id_sequence'::regclass)"); + + b.Property("Completed") + .HasColumnType("integer"); + + b.Property("Count") + .HasColumnType("integer"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Errors") + .HasColumnType("integer"); + + b.Property("Finished") + .HasColumnType("timestamp with time zone"); + + b.Property("Submitted") + .HasColumnType("timestamp with time zone"); + + b.Property("Superseded") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "Customer", "Superseded", "Submitted" }, "IX_BatchTest"); + + b.ToTable("Batches"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.CustomHeaders.CustomHeader", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Key") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Role") + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValueSql("NULL::character varying"); + + b.Property("Space") + .HasColumnType("integer"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "Customer", "Space" }, "IX_CustomHeaders_ByCustomerSpace"); + + b.ToTable("CustomHeaders"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.ImageDeliveryChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasMaxLength(100) + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Channel") + .IsRequired() + .HasColumnType("text"); + + b.Property("DeliveryChannelPolicyId") + .HasColumnType("integer"); + + b.Property("ImageId") + .IsRequired() + .HasColumnType("character varying(500)"); + + b.HasKey("Id"); + + b.HasIndex("DeliveryChannelPolicyId"); + + b.HasIndex("ImageId"); + + b.ToTable("ImageDeliveryChannels"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.ImageLocation", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Nas") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("S3") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Id"); + + b.ToTable("ImageLocation", (string)null); + }); + + modelBuilder.Entity("DLCS.Model.Assets.ImageStorage", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Space") + .HasColumnType("integer"); + + b.Property("CheckingInProgress") + .HasColumnType("boolean"); + + b.Property("LastChecked") + .HasColumnType("timestamp with time zone"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.Property("ThumbnailSize") + .HasColumnType("bigint"); + + b.HasKey("Id", "Customer", "Space"); + + b.HasIndex(new[] { "Customer", "Space", "Id" }, "IX_ImageStorageByCustomerSpace"); + + b.ToTable("ImageStorage", (string)null); + }); + + modelBuilder.Entity("DLCS.Model.Assets.NamedQueries.NamedQuery", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Global") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Template") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.ToTable("NamedQueries"); + }); + + modelBuilder.Entity("DLCS.Model.Auth.Entities.AuthService", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("CallToAction") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("ChildAuthService") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Description") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Label") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(250) + .HasColumnType("character varying(250)"); + + b.Property("PageDescription") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("PageLabel") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Profile") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("RoleProvider") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Ttl") + .HasColumnType("integer") + .HasColumnName("TTL"); + + b.HasKey("Id", "Customer"); + + b.ToTable("AuthServices"); + }); + + modelBuilder.Entity("DLCS.Model.Auth.Entities.Role", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Aliases") + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("AuthService") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Id", "Customer"); + + b.ToTable("Roles"); + }); + + modelBuilder.Entity("DLCS.Model.Auth.Entities.RoleProvider", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("AuthService") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Configuration") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Credentials") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("RoleProviders"); + }); + + modelBuilder.Entity("DLCS.Model.Customers.Customer", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("AcceptedAgreement") + .HasColumnType("boolean"); + + b.Property("Administrator") + .HasColumnType("boolean"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Keys") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Id"); + + b.ToTable("Customers"); + }); + + modelBuilder.Entity("DLCS.Model.Customers.CustomerOriginStrategy", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Credentials") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Optimised") + .HasColumnType("boolean"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Regex") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Strategy") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Id"); + + b.ToTable("CustomerOriginStrategies"); + }); + + modelBuilder.Entity("DLCS.Model.Customers.SignupLink", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("CustomerId") + .HasColumnType("integer"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("Note") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("SignupLinks"); + }); + + modelBuilder.Entity("DLCS.Model.Customers.User", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Enabled") + .HasColumnType("boolean"); + + b.Property("EncryptedPassword") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Roles") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("DLCS.Model.DeliveryChannels.DefaultDeliveryChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("DeliveryChannelPolicyId") + .HasColumnType("integer"); + + b.Property("MediaType") + .IsRequired() + .HasMaxLength(255) + .HasColumnType("character varying(255)"); + + b.Property("Space") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("DeliveryChannelPolicyId"); + + b.HasIndex("Customer", "Space", "MediaType", "DeliveryChannelPolicyId") + .IsUnique(); + + b.ToTable("DefaultDeliveryChannels"); + }); + + modelBuilder.Entity("DLCS.Model.Policies.DeliveryChannelPolicy", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Channel") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("PolicyData") + .HasColumnType("text"); + + b.Property("System") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("Customer", "Name", "Channel") + .IsUnique(); + + b.ToTable("DeliveryChannelPolicies"); + }); + + modelBuilder.Entity("DLCS.Model.Policies.ImageOptimisationPolicy", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Global") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("TechnicalDetails") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id", "Customer"); + + b.ToTable("ImageOptimisationPolicies"); + + b.HasData( + new + { + Id = "none", + Customer = 1, + Global = true, + Name = "No optimisation/transcoding", + TechnicalDetails = "no-op" + }, + new + { + Id = "use-original", + Customer = 1, + Global = true, + Name = "Use original for image-server", + TechnicalDetails = "use-original" + }); + }); + + modelBuilder.Entity("DLCS.Model.Policies.OriginStrategy", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("RequiresCredentials") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("OriginStrategies"); + }); + + modelBuilder.Entity("DLCS.Model.Policies.ThumbnailPolicy", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Sizes") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.HasKey("Id"); + + b.ToTable("ThumbnailPolicies"); + }); + + modelBuilder.Entity("DLCS.Model.Processing.Queue", b => + { + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Name") + .ValueGeneratedOnAdd() + .HasMaxLength(500) + .HasColumnType("character varying(500)") + .HasDefaultValueSql("'default'::character varying"); + + b.Property("Size") + .HasColumnType("integer"); + + b.HasKey("Customer", "Name"); + + b.ToTable("Queues"); + }); + + modelBuilder.Entity("DLCS.Model.Spaces.Space", b => + { + b.Property("Id") + .HasColumnType("integer"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("ImageBucket") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Keep") + .HasColumnType("boolean"); + + b.Property("MaxUnauthorised") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Roles") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Tags") + .IsRequired() + .HasMaxLength(1000) + .HasColumnType("character varying(1000)"); + + b.Property("Transform") + .HasColumnType("boolean"); + + b.HasKey("Id", "Customer") + .HasName("Spaces_pkey"); + + b.ToTable("Spaces"); + }); + + modelBuilder.Entity("DLCS.Model.Storage.CustomerStorage", b => + { + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Space") + .HasColumnType("integer"); + + b.Property("LastCalculated") + .HasColumnType("timestamp with time zone"); + + b.Property("NumberOfStoredImages") + .HasColumnType("bigint"); + + b.Property("StoragePolicy") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("TotalSizeOfStoredImages") + .HasColumnType("bigint"); + + b.Property("TotalSizeOfThumbnails") + .HasColumnType("bigint"); + + b.HasKey("Customer", "Space"); + + b.ToTable("CustomerStorage", (string)null); + }); + + modelBuilder.Entity("DLCS.Model.Storage.StoragePolicy", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("MaximumNumberOfStoredImages") + .HasColumnType("bigint"); + + b.Property("MaximumTotalSizeOfStoredImages") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.ToTable("StoragePolicies"); + }); + + modelBuilder.Entity("DLCS.Repository.Auth.AuthToken", b => + { + b.Property("Id") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("BearerToken") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("CookieId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Expires") + .HasColumnType("timestamp with time zone"); + + b.Property("LastChecked") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionUserId") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Ttl") + .HasColumnType("integer") + .HasColumnName("TTL"); + + b.HasKey("Id"); + + b.HasIndex(new[] { "BearerToken" }, "IX_AuthTokens_BearerToken"); + + b.HasIndex(new[] { "CookieId" }, "IX_AuthTokens_CookieId"); + + b.ToTable("AuthTokens"); + }); + + modelBuilder.Entity("DLCS.Repository.Auth.SessionUser", b => + { + b.Property("Id") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("Roles") + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.HasKey("Id"); + + b.ToTable("SessionUsers"); + }); + + modelBuilder.Entity("DLCS.Repository.Entities.ActivityGroup", b => + { + b.Property("Group") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Inhabitant") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Since") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Group"); + + b.ToTable("ActivityGroups"); + }); + + modelBuilder.Entity("DLCS.Repository.Entities.CustomerImageServer", b => + { + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("ImageServer") + .IsRequired() + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Customer"); + + b.ToTable("CustomerImageServers"); + }); + + modelBuilder.Entity("DLCS.Repository.Entities.EntityCounter", b => + { + b.Property("Type") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Scope") + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Customer") + .HasColumnType("integer"); + + b.Property("Next") + .HasColumnType("bigint"); + + b.HasKey("Type", "Scope", "Customer"); + + b.ToTable("EntityCounters"); + }); + + modelBuilder.Entity("DLCS.Repository.Entities.ImageServer", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("InfoJsonTemplate") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.HasKey("Id"); + + b.ToTable("ImageServers"); + }); + + modelBuilder.Entity("DLCS.Repository.Entities.InfoJsonTemplate", b => + { + b.Property("Id") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Template") + .IsRequired() + .HasMaxLength(4000) + .HasColumnType("character varying(4000)"); + + b.HasKey("Id"); + + b.ToTable("InfoJsonTemplates"); + }); + + modelBuilder.Entity("DLCS.Repository.Entities.MetricThreshold", b => + { + b.Property("Name") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Metric") + .HasMaxLength(500) + .HasColumnType("character varying(500)"); + + b.Property("Lower") + .HasColumnType("bigint"); + + b.Property("Upper") + .HasColumnType("bigint"); + + b.HasKey("Name", "Metric"); + + b.ToTable("MetricThresholds"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => + { + b.HasOne("DLCS.Model.Assets.Asset", "Asset") + .WithMany() + .HasForeignKey("AssetId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Asset"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.ImageDeliveryChannel", b => + { + b.HasOne("DLCS.Model.Policies.DeliveryChannelPolicy", "DeliveryChannelPolicy") + .WithMany("ImageDeliveryChannels") + .HasForeignKey("DeliveryChannelPolicyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DLCS.Model.Assets.Asset", "Asset") + .WithMany("ImageDeliveryChannels") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Asset"); + + b.Navigation("DeliveryChannelPolicy"); + }); + + modelBuilder.Entity("DLCS.Model.DeliveryChannels.DefaultDeliveryChannel", b => + { + b.HasOne("DLCS.Model.Policies.DeliveryChannelPolicy", "DeliveryChannelPolicy") + .WithMany() + .HasForeignKey("DeliveryChannelPolicyId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("DeliveryChannelPolicy"); + }); + + modelBuilder.Entity("DLCS.Model.Assets.Asset", b => + { + b.Navigation("ImageDeliveryChannels"); + }); + + modelBuilder.Entity("DLCS.Model.Policies.DeliveryChannelPolicy", b => + { + b.Navigation("ImageDeliveryChannels"); + }); +#pragma warning restore 612, 618 + } + } +} From 8d15f27e805fef0e79b3eee5685ab1d9392c3ec3 Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Thu, 11 Apr 2024 17:52:52 +0100 Subject: [PATCH 03/11] update to add thumb creator work --- src/protagonist/DLCS.Model/Assets/Asset.cs | 6 ++ .../AssetApplicationMetadata.cs | 3 +- .../Metadata/AssetApplicationMetadataKeys.cs | 8 ++ .../IAssetApplicationMetadataRepository.cs | 15 +++ .../AssetApplicationMetadataRepository.cs | 34 +++++++ .../Assets/Thumbs/ThumbsManager.cs | 19 +++- .../DLCS.Repository/DlcsContext.cs | 6 ++ ...ssetApplicationMetadata table.Designer.cs} | 97 +++++++++---------- ..._adding AssetApplicationMetadata table.cs} | 13 ++- .../Migrations/DlcsContextModelSnapshot.cs | 95 +++++++++--------- .../Ingest/Image/ThumbCreatorTests.cs | 5 +- .../Infrastructure/ServiceCollectionX.cs | 5 +- .../Engine/Ingest/Image/ThumbCreator.cs | 4 +- .../Reorganising/ThumbReorganiserTests.cs | 5 +- .../Infrastructure/ServiceCollectionX.cs | 2 + .../Thumbs/Reorganising/ThumbReorganiser.cs | 4 +- 16 files changed, 208 insertions(+), 113 deletions(-) rename src/protagonist/DLCS.Model/Assets/{ => Metadata}/AssetApplicationMetadata.cs (93%) create mode 100644 src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs create mode 100644 src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs create mode 100644 src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs rename src/protagonist/DLCS.Repository/Migrations/{20240411134159_adding AssetApplicationMetadata table.Designer.cs => 20240411144218_adding AssetApplicationMetadata table.Designer.cs} (96%) rename src/protagonist/DLCS.Repository/Migrations/{20240411134159_adding AssetApplicationMetadata table.cs => 20240411144218_adding AssetApplicationMetadata table.cs} (80%) diff --git a/src/protagonist/DLCS.Model/Assets/Asset.cs b/src/protagonist/DLCS.Model/Assets/Asset.cs index a1a8456ef..e8959938f 100644 --- a/src/protagonist/DLCS.Model/Assets/Asset.cs +++ b/src/protagonist/DLCS.Model/Assets/Asset.cs @@ -4,6 +4,7 @@ using System.Linq; using DLCS.Core.Collections; using DLCS.Core.Types; +using DLCS.Model.Assets.Metadata; namespace DLCS.Model.Assets; @@ -99,6 +100,11 @@ public IEnumerable TagsList /// A list of image delivery channels attached to this asset /// public ICollection ImageDeliveryChannels { get; set; } + + /// + /// A list of metadata attached to this asset + /// + public ICollection AssetApplicationMetadata { get; set; } public Asset() { diff --git a/src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs similarity index 93% rename from src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs rename to src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs index 1960cbcc6..fee75efc3 100644 --- a/src/protagonist/DLCS.Model/Assets/AssetApplicationMetadata.cs +++ b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs @@ -1,8 +1,7 @@ using System; -using System.Collections.Generic; using DLCS.Core.Types; -namespace DLCS.Model.Assets; +namespace DLCS.Model.Assets.Metadata; public class AssetApplicationMetadata { diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs new file mode 100644 index 000000000..f85815eaa --- /dev/null +++ b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs @@ -0,0 +1,8 @@ +using System.Dynamic; + +namespace DLCS.Model.Assets.Metadata; + +public static class AssetApplicationMetadataKeys +{ + public const string ThumbnailPolicy = "ThumbnailPolicy"; +} \ No newline at end of file diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs new file mode 100644 index 000000000..a0f4a4570 --- /dev/null +++ b/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using DLCS.Core.Types; + +namespace DLCS.Model.Assets.Metadata; + +public interface IAssetApplicationMetadataRepository +{ + public Task> GetThumbnailSizes(AssetId assetId); + + public Task AddApplicationMetadata( + AssetApplicationMetadata metadata, + CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs new file mode 100644 index 000000000..bc5ff2ff3 --- /dev/null +++ b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs @@ -0,0 +1,34 @@ +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using DLCS.Core.Types; +using DLCS.Model.Assets.Metadata; + +namespace DLCS.Repository.Assets; + +public class AssetApplicationMetadataRepository : IAssetApplicationMetadataRepository +{ + private readonly DlcsContext dlcsContext; + + public AssetApplicationMetadataRepository(DlcsContext dlcsContext) + { + this.dlcsContext = dlcsContext; + } + + public async Task> GetThumbnailSizes(AssetId assetId) + { + + + return new List(); + } + + public async Task AddApplicationMetadata( + AssetApplicationMetadata metadata, + CancellationToken cancellationToken = default) + { + var databaseMetadata= await dlcsContext.AssetApplicationMetadata.AddAsync(metadata, cancellationToken); + await dlcsContext.SaveChangesAsync(cancellationToken); + + return databaseMetadata.Entity; + } +} \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs b/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs index c241572ed..14f13b2d9 100644 --- a/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs +++ b/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs @@ -1,7 +1,9 @@ +using System; using System.Threading.Tasks; using DLCS.AWS.S3; using DLCS.Core.Types; using DLCS.Model.Assets; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Policies; using IIIF; using Newtonsoft.Json; @@ -15,14 +17,17 @@ public abstract class ThumbsManager { protected readonly IBucketWriter BucketWriter; protected readonly IStorageKeyGenerator StorageKeyGenerator; + protected readonly IAssetApplicationMetadataRepository AssetApplicationMetadataRepository; public ThumbsManager( IBucketWriter bucketWriter, - IStorageKeyGenerator storageKeyGenerator + IStorageKeyGenerator storageKeyGenerator, + IAssetApplicationMetadataRepository assetApplicationMetadataRepository ) { BucketWriter = bucketWriter; StorageKeyGenerator = storageKeyGenerator; + AssetApplicationMetadataRepository = assetApplicationMetadataRepository; } protected static Size GetMaxAvailableThumb(Asset asset, ThumbnailPolicy policy) @@ -33,8 +38,18 @@ protected static Size GetMaxAvailableThumb(Asset asset, ThumbnailPolicy policy) protected async Task CreateSizesJson(AssetId assetId, ThumbnailSizes thumbnailSizes) { + var serializedThumbnailSizes = JsonConvert.SerializeObject(thumbnailSizes); var sizesDest = StorageKeyGenerator.GetThumbsSizesJsonLocation(assetId); - await BucketWriter.WriteToBucket(sizesDest, JsonConvert.SerializeObject(thumbnailSizes), + await BucketWriter.WriteToBucket(sizesDest, serializedThumbnailSizes, "application/json"); + await AssetApplicationMetadataRepository.AddApplicationMetadata(new AssetApplicationMetadata() + { + ImageId = assetId, + MetadataType = AssetApplicationMetadataKeys.ThumbnailPolicy, + MetadataValue = serializedThumbnailSizes, + Created = DateTime.UtcNow, + Modified = DateTime.UtcNow + }); + } } \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/DlcsContext.cs b/src/protagonist/DLCS.Repository/DlcsContext.cs index f53671c6c..fbd2c5f94 100644 --- a/src/protagonist/DLCS.Repository/DlcsContext.cs +++ b/src/protagonist/DLCS.Repository/DlcsContext.cs @@ -9,6 +9,7 @@ using DLCS.Core.Types; using DLCS.Model.Assets; using DLCS.Model.Assets.CustomHeaders; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Assets.NamedQueries; using DLCS.Model.Auth.Entities; using DLCS.Model.Customers; @@ -683,11 +684,16 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { + entity.Property(e => e.Id).HasMaxLength(100); entity.Property(e => e.ImageId).IsRequired().HasConversion( aId => aId.ToString(), id => AssetId.FromString(id)); entity.Property(e => e.MetadataType).IsRequired(); entity.Property(e => e.MetadataValue).IsRequired().HasColumnType("jsonb"); + + entity.HasOne(e => e.Asset) + .WithMany(e => e.AssetApplicationMetadata) + .HasForeignKey(e => e.ImageId); }); OnModelCreatingPartial(modelBuilder); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs b/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.Designer.cs similarity index 96% rename from src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs rename to src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.Designer.cs index 9a7db1b22..446daf367 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.Designer.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.Designer.cs @@ -12,7 +12,7 @@ namespace DLCS.Repository.Migrations { [DbContext(typeof(DlcsContext))] - [Migration("20240411134159_adding AssetApplicationMetadata table")] + [Migration("20240411144218_adding AssetApplicationMetadata table")] partial class addingAssetApplicationMetadatatable { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -184,43 +184,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("Images", (string)null); }); - modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AssetId") - .IsRequired() - .HasColumnType("character varying(500)"); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - - b.Property("ImageId") - .IsRequired() - .HasColumnType("text"); - - b.Property("MetadataType") - .IsRequired() - .HasColumnType("text"); - - b.Property("MetadataValue") - .IsRequired() - .HasColumnType("jsonb"); - - b.Property("Modified") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.HasIndex("AssetId"); - - b.ToTable("AssetApplicationMetadata"); - }); - modelBuilder.Entity("DLCS.Model.Assets.Batch", b => { b.Property("Id") @@ -372,6 +335,40 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("ImageStorage", (string)null); }); + modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasMaxLength(100) + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("ImageId") + .IsRequired() + .HasColumnType("character varying(500)"); + + b.Property("MetadataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MetadataValue") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("AssetApplicationMetadata"); + }); + modelBuilder.Entity("DLCS.Model.Assets.NamedQueries.NamedQuery", b => { b.Property("Id") @@ -1071,17 +1068,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.ToTable("MetricThresholds"); }); - modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => - { - b.HasOne("DLCS.Model.Assets.Asset", "Asset") - .WithMany() - .HasForeignKey("AssetId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Asset"); - }); - modelBuilder.Entity("DLCS.Model.Assets.ImageDeliveryChannel", b => { b.HasOne("DLCS.Model.Policies.DeliveryChannelPolicy", "DeliveryChannelPolicy") @@ -1101,6 +1087,17 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("DeliveryChannelPolicy"); }); + modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => + { + b.HasOne("DLCS.Model.Assets.Asset", "Asset") + .WithMany("AssetApplicationMetadata") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Asset"); + }); + modelBuilder.Entity("DLCS.Model.DeliveryChannels.DefaultDeliveryChannel", b => { b.HasOne("DLCS.Model.Policies.DeliveryChannelPolicy", "DeliveryChannelPolicy") @@ -1114,6 +1111,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("DLCS.Model.Assets.Asset", b => { + b.Navigation("AssetApplicationMetadata"); + b.Navigation("ImageDeliveryChannels"); }); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs b/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.cs similarity index 80% rename from src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs rename to src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.cs index fa286ffc9..0a0e2de03 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240411134159_adding AssetApplicationMetadata table.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.cs @@ -14,10 +14,9 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "AssetApplicationMetadata", columns: table => new { - Id = table.Column(type: "integer", nullable: false) + Id = table.Column(type: "integer", maxLength: 100, nullable: false) .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - ImageId = table.Column(type: "text", nullable: false), - AssetId = table.Column(type: "character varying(500)", nullable: false), + ImageId = table.Column(type: "character varying(500)", nullable: false), MetadataType = table.Column(type: "text", nullable: false), MetadataValue = table.Column(type: "jsonb", nullable: false), Created = table.Column(type: "timestamp with time zone", nullable: false), @@ -27,17 +26,17 @@ protected override void Up(MigrationBuilder migrationBuilder) { table.PrimaryKey("PK_AssetApplicationMetadata", x => x.Id); table.ForeignKey( - name: "FK_AssetApplicationMetadata_Images_AssetId", - column: x => x.AssetId, + name: "FK_AssetApplicationMetadata_Images_ImageId", + column: x => x.ImageId, principalTable: "Images", principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); migrationBuilder.CreateIndex( - name: "IX_AssetApplicationMetadata_AssetId", + name: "IX_AssetApplicationMetadata_ImageId", table: "AssetApplicationMetadata", - column: "AssetId"); + column: "ImageId"); } protected override void Down(MigrationBuilder migrationBuilder) diff --git a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs index a5b4ded68..6a9266a67 100644 --- a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs +++ b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs @@ -182,43 +182,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("Images", (string)null); }); - modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("AssetId") - .IsRequired() - .HasColumnType("character varying(500)"); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - - b.Property("ImageId") - .IsRequired() - .HasColumnType("text"); - - b.Property("MetadataType") - .IsRequired() - .HasColumnType("text"); - - b.Property("MetadataValue") - .IsRequired() - .HasColumnType("jsonb"); - - b.Property("Modified") - .HasColumnType("timestamp with time zone"); - - b.HasKey("Id"); - - b.HasIndex("AssetId"); - - b.ToTable("AssetApplicationMetadata"); - }); - modelBuilder.Entity("DLCS.Model.Assets.Batch", b => { b.Property("Id") @@ -370,6 +333,40 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("ImageStorage", (string)null); }); + modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasMaxLength(100) + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Created") + .HasColumnType("timestamp with time zone"); + + b.Property("ImageId") + .IsRequired() + .HasColumnType("character varying(500)"); + + b.Property("MetadataType") + .IsRequired() + .HasColumnType("text"); + + b.Property("MetadataValue") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Modified") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("AssetApplicationMetadata"); + }); + modelBuilder.Entity("DLCS.Model.Assets.NamedQueries.NamedQuery", b => { b.Property("Id") @@ -1069,17 +1066,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("MetricThresholds"); }); - modelBuilder.Entity("DLCS.Model.Assets.AssetApplicationMetadata", b => - { - b.HasOne("DLCS.Model.Assets.Asset", "Asset") - .WithMany() - .HasForeignKey("AssetId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.Navigation("Asset"); - }); - modelBuilder.Entity("DLCS.Model.Assets.ImageDeliveryChannel", b => { b.HasOne("DLCS.Model.Policies.DeliveryChannelPolicy", "DeliveryChannelPolicy") @@ -1099,6 +1085,17 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("DeliveryChannelPolicy"); }); + modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => + { + b.HasOne("DLCS.Model.Assets.Asset", "Asset") + .WithMany("AssetApplicationMetadata") + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Asset"); + }); + modelBuilder.Entity("DLCS.Model.DeliveryChannels.DefaultDeliveryChannel", b => { b.HasOne("DLCS.Model.Policies.DeliveryChannelPolicy", "DeliveryChannelPolicy") @@ -1112,6 +1109,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("DLCS.Model.Assets.Asset", b => { + b.Navigation("AssetApplicationMetadata"); + b.Navigation("ImageDeliveryChannels"); }); diff --git a/src/protagonist/Engine.Tests/Ingest/Image/ThumbCreatorTests.cs b/src/protagonist/Engine.Tests/Ingest/Image/ThumbCreatorTests.cs index 456945d65..ba8f83456 100644 --- a/src/protagonist/Engine.Tests/Ingest/Image/ThumbCreatorTests.cs +++ b/src/protagonist/Engine.Tests/Ingest/Image/ThumbCreatorTests.cs @@ -3,6 +3,7 @@ using DLCS.AWS.S3.Models; using DLCS.Core.Types; using DLCS.Model.Assets; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Policies; using Engine.Ingest.Image; using FakeItEasy; @@ -16,6 +17,7 @@ public class ThumbCreatorTests private readonly TestBucketWriter bucketWriter; private readonly IStorageKeyGenerator storageKeyGenerator; private readonly ThumbCreator sut; + private readonly IAssetApplicationMetadataRepository assetApplicationMetadataRepository; private readonly List thumbsDeliveryChannel = new() { new ImageDeliveryChannel() @@ -29,6 +31,7 @@ public ThumbCreatorTests() { bucketWriter = new TestBucketWriter(); storageKeyGenerator = A.Fake(); + assetApplicationMetadataRepository = A.Fake(); A.CallTo(() => storageKeyGenerator.GetLargestThumbnailLocation(A._)) .ReturnsLazily((AssetId assetId) => new ObjectInBucket("thumbs-bucket", $"{assetId}/low.jpg")); @@ -41,7 +44,7 @@ public ThumbCreatorTests() return new ObjectInBucket("thumbs-bucket", $"{assetId}/{authSlug}/{size}.jpg"); }); - sut = new ThumbCreator(bucketWriter, storageKeyGenerator, new NullLogger()); + sut = new ThumbCreator(bucketWriter, storageKeyGenerator, assetApplicationMetadataRepository,new NullLogger()); } [Fact] diff --git a/src/protagonist/Engine/Infrastructure/ServiceCollectionX.cs b/src/protagonist/Engine/Infrastructure/ServiceCollectionX.cs index f6ea085e2..f994356af 100644 --- a/src/protagonist/Engine/Infrastructure/ServiceCollectionX.cs +++ b/src/protagonist/Engine/Infrastructure/ServiceCollectionX.cs @@ -4,12 +4,14 @@ using DLCS.AWS.SQS; using DLCS.Core.Caching; using DLCS.Core.FileSystem; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Auth; using DLCS.Model.Customers; using DLCS.Model.Policies; using DLCS.Model.Processing; using DLCS.Model.Storage; using DLCS.Repository; +using DLCS.Repository.Assets; using DLCS.Repository.Auth; using DLCS.Repository.Customers; using DLCS.Repository.Policies; @@ -86,7 +88,7 @@ public static IServiceCollection AddAssetIngestion(this IServiceCollection servi .AddScoped() .AddScoped() .AddScoped() - .AddSingleton() + .AddScoped() .AddScoped() .AddSingleton() .AddSingleton() @@ -135,6 +137,7 @@ public static IServiceCollection AddDataAccess(this IServiceCollection services, .AddSingleton() .AddScoped() .AddScoped() + .AddScoped() .AddDlcsContext(configuration); /// diff --git a/src/protagonist/Engine/Ingest/Image/ThumbCreator.cs b/src/protagonist/Engine/Ingest/Image/ThumbCreator.cs index 688e2e7f4..9cc80b387 100644 --- a/src/protagonist/Engine/Ingest/Image/ThumbCreator.cs +++ b/src/protagonist/Engine/Ingest/Image/ThumbCreator.cs @@ -3,6 +3,7 @@ using DLCS.Core.Threading; using DLCS.Core.Types; using DLCS.Model.Assets; +using DLCS.Model.Assets.Metadata; using DLCS.Repository.Assets; using DLCS.Repository.Assets.Thumbs; using IIIF; @@ -17,7 +18,8 @@ public class ThumbCreator : ThumbsManager, IThumbCreator public ThumbCreator( IBucketWriter bucketWriter, IStorageKeyGenerator storageKeyGenerator, - ILogger logger) : base(bucketWriter, storageKeyGenerator) + IAssetApplicationMetadataRepository assetApplicationMetadataRepository, + ILogger logger) : base(bucketWriter, storageKeyGenerator, assetApplicationMetadataRepository) { this.logger = logger; } diff --git a/src/protagonist/Thumbs.Tests/Reorganising/ThumbReorganiserTests.cs b/src/protagonist/Thumbs.Tests/Reorganising/ThumbReorganiserTests.cs index 9fbaeeee9..6e7c1d750 100644 --- a/src/protagonist/Thumbs.Tests/Reorganising/ThumbReorganiserTests.cs +++ b/src/protagonist/Thumbs.Tests/Reorganising/ThumbReorganiserTests.cs @@ -3,6 +3,7 @@ using DLCS.AWS.Settings; using DLCS.Core.Types; using DLCS.Model.Assets; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Assets.Thumbs; using DLCS.Model.Policies; using FakeItEasy; @@ -20,6 +21,7 @@ public class ThumbReorganiserTests private readonly IPolicyRepository thumbPolicyRepository; private readonly ThumbReorganiser sut; private readonly IBucketWriter bucketWriter; + private readonly IAssetApplicationMetadataRepository assetApplicationMetadataRepository; public ThumbReorganiserTests() { @@ -27,10 +29,11 @@ public ThumbReorganiserTests() bucketWriter = A.Fake(); assetRepository = A.Fake(); thumbPolicyRepository = A.Fake(); + assetApplicationMetadataRepository = A.Fake(); IStorageKeyGenerator storageKeyGenerator = new S3StorageKeyGenerator( Options.Create(new AWSSettings { S3 = new S3Settings { ThumbsBucket = "the-bucket" } })); sut = new ThumbReorganiser(bucketReader, bucketWriter, new NullLogger(), assetRepository, - thumbPolicyRepository, storageKeyGenerator); + thumbPolicyRepository, assetApplicationMetadataRepository, storageKeyGenerator); } [Fact] diff --git a/src/protagonist/Thumbs/Infrastructure/ServiceCollectionX.cs b/src/protagonist/Thumbs/Infrastructure/ServiceCollectionX.cs index 233c14fb5..ff694c272 100644 --- a/src/protagonist/Thumbs/Infrastructure/ServiceCollectionX.cs +++ b/src/protagonist/Thumbs/Infrastructure/ServiceCollectionX.cs @@ -1,6 +1,7 @@ using DLCS.AWS.Configuration; using DLCS.AWS.S3; using DLCS.Model.Assets; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Policies; using DLCS.Repository.Assets; using DLCS.Repository.Policies; @@ -30,6 +31,7 @@ public static IServiceCollection AddThumbnailHandling(this IServiceCollection se Log.Information("Thumbs supports reorganising thumbs"); services .AddSingleton() + .AddScoped() .AddSingleton() .AddSingleton(provider => ActivatorUtilities.CreateInstance( diff --git a/src/protagonist/Thumbs/Reorganising/ThumbReorganiser.cs b/src/protagonist/Thumbs/Reorganising/ThumbReorganiser.cs index 60984064c..587cf1273 100644 --- a/src/protagonist/Thumbs/Reorganising/ThumbReorganiser.cs +++ b/src/protagonist/Thumbs/Reorganising/ThumbReorganiser.cs @@ -8,6 +8,7 @@ using DLCS.Core.Threading; using DLCS.Core.Types; using DLCS.Model.Assets; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Assets.Thumbs; using DLCS.Model.Policies; using DLCS.Repository.Assets; @@ -35,7 +36,8 @@ public class ThumbReorganiser : ThumbsManager, IThumbReorganiser ILogger logger, IAssetRepository assetRepository, IThumbnailPolicyRepository policyRepository, - IStorageKeyGenerator storageKeyGenerator) : base(bucketWriter, storageKeyGenerator) + IAssetApplicationMetadataRepository assetApplicationMetadataRepository, + IStorageKeyGenerator storageKeyGenerator) : base(bucketWriter, storageKeyGenerator, assetApplicationMetadataRepository) { this.bucketReader = bucketReader; this.logger = logger; From dfe006dd12099134f6b328ffe69281f7483f555e Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Fri, 12 Apr 2024 15:24:20 +0100 Subject: [PATCH 04/11] adding tests plus updated context --- .../Metadata/AssetApplicationMetadata.cs | 5 -- .../Metadata/AssetApplicationMetadataKeys.cs | 8 -- .../Metadata/AssetApplicationMetadataTypes.cs | 6 ++ .../IAssetApplicationMetadataRepository.cs | 9 +- ...AssetApplicationMetadataRepositoryTests.cs | 82 +++++++++++++++++++ .../AssetApplicationMetadataRepository.cs | 36 +++++--- .../Assets/Thumbs/ThumbsManager.cs | 12 +-- .../DLCS.Repository/DlcsContext.cs | 2 +- ...ssetApplicationMetadata table.Designer.cs} | 21 ++--- ..._adding AssetApplicationMetadata table.cs} | 10 +-- .../Migrations/DlcsContextModelSnapshot.cs | 19 +---- .../Integration/DatabaseTestDataPopulation.cs | 13 +++ 12 files changed, 141 insertions(+), 82 deletions(-) delete mode 100644 src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs create mode 100644 src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs create mode 100644 src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs rename src/protagonist/DLCS.Repository/Migrations/{20240411144218_adding AssetApplicationMetadata table.Designer.cs => 20240412090855_adding AssetApplicationMetadata table.Designer.cs} (96%) rename src/protagonist/DLCS.Repository/Migrations/{20240411144218_adding AssetApplicationMetadata table.cs => 20240412090855_adding AssetApplicationMetadata table.cs} (75%) diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs index fee75efc3..8376b0720 100644 --- a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs +++ b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs @@ -5,11 +5,6 @@ namespace DLCS.Model.Assets.Metadata; public class AssetApplicationMetadata { - /// - /// Unique identifier - /// - public int Id { get; set; } - /// /// The image id for the attached asset /// diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs deleted file mode 100644 index f85815eaa..000000000 --- a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataKeys.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Dynamic; - -namespace DLCS.Model.Assets.Metadata; - -public static class AssetApplicationMetadataKeys -{ - public const string ThumbnailPolicy = "ThumbnailPolicy"; -} \ No newline at end of file diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs new file mode 100644 index 000000000..a5abc0c3a --- /dev/null +++ b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs @@ -0,0 +1,6 @@ +namespace DLCS.Model.Assets.Metadata; + +public static class AssetApplicationMetadataTypes +{ + public const string ThumbnailPolicy = "ThumbnailPolicy"; +} \ No newline at end of file diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs index a0f4a4570..aaf0d5e61 100644 --- a/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs +++ b/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Threading; +using System.Threading; using System.Threading.Tasks; using DLCS.Core.Types; @@ -7,9 +6,7 @@ namespace DLCS.Model.Assets.Metadata; public interface IAssetApplicationMetadataRepository { - public Task> GetThumbnailSizes(AssetId assetId); - - public Task AddApplicationMetadata( - AssetApplicationMetadata metadata, + public Task UpsertApplicationMetadata( + AssetId assetId, string metadataType, string metadataValue, CancellationToken cancellationToken = default); } \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs new file mode 100644 index 000000000..69bdb60c6 --- /dev/null +++ b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs @@ -0,0 +1,82 @@ +using System; +using DLCS.Core.Types; +using DLCS.Model.Assets.Metadata; +using DLCS.Repository.Assets; +using Microsoft.EntityFrameworkCore; +using Test.Helpers.Integration; + +namespace DLCS.Repository.Tests.Assets; + +[Trait("Category", "Database")] +[Collection(DatabaseCollection.CollectionName)] +public class AssetApplicationMetadataRepositoryTests +{ + private readonly DlcsContext dbContext; + private readonly AssetApplicationMetadataRepository sut; + + public AssetApplicationMetadataRepositoryTests(DlcsDatabaseFixture dbFixture) + { + dbContext = dbFixture.DbContext; + sut = new AssetApplicationMetadataRepository(dbFixture.DbContext); + + dbFixture.CleanUp(); + dbContext.Images.AddTestAsset(AssetId.FromString("99/1/1"), ref1: "foobar"); + dbContext.SaveChanges(); + } + + [Fact] + public async Task UpsertApplicationMetadata_AddsMetadata_WhenCalledWithNew() + { + // Arrange + var assetId = AssetId.FromString("99/1/1"); + var metadataValue = "{\"a\": [], \"o\": [[75, 100], [150, 200], [300, 400], [769, 1024]]}"; + + // Act + var metadata = await sut.UpsertApplicationMetadata(assetId, + AssetApplicationMetadataTypes.ThumbnailPolicy, metadataValue); + + var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => + x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbnailPolicy); + + // Assert + metadata.Should().NotBeNull(); + metaDataFromDatabase.Should().NotBeNull(); + metaDataFromDatabase.MetadataValue.Should().Be(metadataValue); + } + + [Fact] + public async Task UpsertApplicationMetadata_UpdatesMetadata_WhenCalledWithUpdated() + { + // Arrange + var assetId = AssetId.FromString("99/1/1"); + await sut.UpsertApplicationMetadata(assetId, + AssetApplicationMetadataTypes.ThumbnailPolicy, "{\"a\": [], \"o\": []}"); + var newMetadataValue = "{\"a\": [], \"o\": [[75, 100], [150, 200], [300, 400], [769, 1024]]}"; + + // Act + var metadata = await sut.UpsertApplicationMetadata(assetId, + AssetApplicationMetadataTypes.ThumbnailPolicy, newMetadataValue); + var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => + x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbnailPolicy); + + // Assert + metadata.Should().NotBeNull(); + metaDataFromDatabase.Should().NotBeNull(); + metaDataFromDatabase.MetadataValue.Should().Be(newMetadataValue); + } + + [Fact] + public async Task UpsertApplicationMetadata_ThrowsException_WhenCalledWithInvalidJson() + { + // Arrange + var assetId = AssetId.FromString("99/1/1"); + var metadataValue = "not json"; + + // Act + Func action = async () => await sut.UpsertApplicationMetadata(assetId, + AssetApplicationMetadataTypes.ThumbnailPolicy, metadataValue); + + // Assert + await action.Should().ThrowAsync(); + } +} \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs index bc5ff2ff3..97de551fc 100644 --- a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs +++ b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs @@ -1,8 +1,9 @@ -using System.Collections.Generic; +using System; using System.Threading; using System.Threading.Tasks; using DLCS.Core.Types; using DLCS.Model.Assets.Metadata; +using Microsoft.EntityFrameworkCore; namespace DLCS.Repository.Assets; @@ -14,21 +15,32 @@ public AssetApplicationMetadataRepository(DlcsContext dlcsContext) { this.dlcsContext = dlcsContext; } - - public async Task> GetThumbnailSizes(AssetId assetId) - { - - - return new List(); - } - public async Task AddApplicationMetadata( - AssetApplicationMetadata metadata, + public async Task UpsertApplicationMetadata(AssetId assetId, string metadataType, string metadataValue, CancellationToken cancellationToken = default) { - var databaseMetadata= await dlcsContext.AssetApplicationMetadata.AddAsync(metadata, cancellationToken); - await dlcsContext.SaveChangesAsync(cancellationToken); + var addedMetadata = await dlcsContext.AssetApplicationMetadata.FirstOrDefaultAsync(e => + e.ImageId == assetId && e.MetadataType == metadataType, cancellationToken); + if (addedMetadata is not null) + { + addedMetadata.MetadataValue = metadataValue; + addedMetadata.Modified = DateTime.UtcNow; + await dlcsContext.AssetApplicationMetadata.SingleUpdateAsync(addedMetadata, cancellationToken); + await dlcsContext.SaveChangesAsync(cancellationToken); + return addedMetadata; + } + + var databaseMetadata= await dlcsContext.AssetApplicationMetadata.AddAsync(new AssetApplicationMetadata() + { + ImageId = assetId, + MetadataType = metadataType, + MetadataValue = metadataValue, + Created = DateTime.UtcNow, + Modified = DateTime.UtcNow + }, cancellationToken); + + await dlcsContext.SaveChangesAsync(cancellationToken); return databaseMetadata.Entity; } } \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs b/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs index 14f13b2d9..f917d6aef 100644 --- a/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs +++ b/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using DLCS.AWS.S3; using DLCS.Core.Types; @@ -42,14 +41,7 @@ protected async Task CreateSizesJson(AssetId assetId, ThumbnailSizes thumbnailSi var sizesDest = StorageKeyGenerator.GetThumbsSizesJsonLocation(assetId); await BucketWriter.WriteToBucket(sizesDest, serializedThumbnailSizes, "application/json"); - await AssetApplicationMetadataRepository.AddApplicationMetadata(new AssetApplicationMetadata() - { - ImageId = assetId, - MetadataType = AssetApplicationMetadataKeys.ThumbnailPolicy, - MetadataValue = serializedThumbnailSizes, - Created = DateTime.UtcNow, - Modified = DateTime.UtcNow - }); - + await AssetApplicationMetadataRepository.UpsertApplicationMetadata(assetId, + AssetApplicationMetadataTypes.ThumbnailPolicy, serializedThumbnailSizes); } } \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository/DlcsContext.cs b/src/protagonist/DLCS.Repository/DlcsContext.cs index fbd2c5f94..7a4964278 100644 --- a/src/protagonist/DLCS.Repository/DlcsContext.cs +++ b/src/protagonist/DLCS.Repository/DlcsContext.cs @@ -684,7 +684,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.Property(e => e.Id).HasMaxLength(100); + entity.HasKey(e => new { e.ImageId, e.MetadataType }); entity.Property(e => e.ImageId).IsRequired().HasConversion( aId => aId.ToString(), id => AssetId.FromString(id)); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.Designer.cs b/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.Designer.cs similarity index 96% rename from src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.Designer.cs rename to src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.Designer.cs index 446daf367..c75878250 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.Designer.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.Designer.cs @@ -12,7 +12,7 @@ namespace DLCS.Repository.Migrations { [DbContext(typeof(DlcsContext))] - [Migration("20240411144218_adding AssetApplicationMetadata table")] + [Migration("20240412090855_adding AssetApplicationMetadata table")] partial class addingAssetApplicationMetadatatable { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -337,24 +337,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasMaxLength(100) - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - b.Property("ImageId") - .IsRequired() .HasColumnType("character varying(500)"); b.Property("MetadataType") - .IsRequired() .HasColumnType("text"); + b.Property("Created") + .HasColumnType("timestamp with time zone"); + b.Property("MetadataValue") .IsRequired() .HasColumnType("jsonb"); @@ -362,9 +353,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Modified") .HasColumnType("timestamp with time zone"); - b.HasKey("Id"); - - b.HasIndex("ImageId"); + b.HasKey("ImageId", "MetadataType"); b.ToTable("AssetApplicationMetadata"); }); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.cs b/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.cs similarity index 75% rename from src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.cs rename to src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.cs index 0a0e2de03..e765cc195 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240411144218_adding AssetApplicationMetadata table.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.cs @@ -1,6 +1,5 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #nullable disable @@ -14,8 +13,6 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "AssetApplicationMetadata", columns: table => new { - Id = table.Column(type: "integer", maxLength: 100, nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), ImageId = table.Column(type: "character varying(500)", nullable: false), MetadataType = table.Column(type: "text", nullable: false), MetadataValue = table.Column(type: "jsonb", nullable: false), @@ -24,7 +21,7 @@ protected override void Up(MigrationBuilder migrationBuilder) }, constraints: table => { - table.PrimaryKey("PK_AssetApplicationMetadata", x => x.Id); + table.PrimaryKey("PK_AssetApplicationMetadata", x => new { x.ImageId, x.MetadataType }); table.ForeignKey( name: "FK_AssetApplicationMetadata_Images_ImageId", column: x => x.ImageId, @@ -32,11 +29,6 @@ protected override void Up(MigrationBuilder migrationBuilder) principalColumn: "Id", onDelete: ReferentialAction.Cascade); }); - - migrationBuilder.CreateIndex( - name: "IX_AssetApplicationMetadata_ImageId", - table: "AssetApplicationMetadata", - column: "ImageId"); } protected override void Down(MigrationBuilder migrationBuilder) diff --git a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs index 6a9266a67..0b6996467 100644 --- a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs +++ b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs @@ -335,24 +335,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasMaxLength(100) - .HasColumnType("integer"); - - NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); - - b.Property("Created") - .HasColumnType("timestamp with time zone"); - b.Property("ImageId") - .IsRequired() .HasColumnType("character varying(500)"); b.Property("MetadataType") - .IsRequired() .HasColumnType("text"); + b.Property("Created") + .HasColumnType("timestamp with time zone"); + b.Property("MetadataValue") .IsRequired() .HasColumnType("jsonb"); @@ -360,9 +351,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Modified") .HasColumnType("timestamp with time zone"); - b.HasKey("Id"); - - b.HasIndex("ImageId"); + b.HasKey("ImageId", "MetadataType"); b.ToTable("AssetApplicationMetadata"); }); diff --git a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs index 27c0f47fe..4c1f34ac2 100644 --- a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs +++ b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs @@ -5,6 +5,7 @@ using DLCS.Core.Types; using DLCS.Model.Assets; using DLCS.Model.Assets.CustomHeaders; +using DLCS.Model.Assets.Metadata; using DLCS.Model.Assets.NamedQueries; using DLCS.Model.Customers; using DLCS.Model.DeliveryChannels; @@ -183,4 +184,16 @@ public static class DatabaseTestDataPopulation TotalSizeOfStoredImages = sizeOfStored, TotalSizeOfThumbnails = sizeOfThumbs }); + + public static ValueTask> AddAssetApplicationMetadata( + this DbSet assetApplicationMetadata, AssetId assetId, + string metadataType, string metadataValue) + => assetApplicationMetadata.AddAsync(new AssetApplicationMetadata() + { + ImageId = assetId, + MetadataType = metadataType, + MetadataValue = metadataValue, + Created = DateTime.UtcNow, + Modified = DateTime.UtcNow + }); } \ No newline at end of file From aad9d5868ad04e4bf173b59611909ec368cbd5ba Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Fri, 12 Apr 2024 15:48:37 +0100 Subject: [PATCH 05/11] updating additional tests --- .../Engine.Tests/Integration/ImageIngestTests.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs b/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs index cfc6af37e..822d17de8 100644 --- a/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs +++ b/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs @@ -202,6 +202,9 @@ public async Task IngestAsset_Success_HttpOrigin_AllOpen() var storage = await dbContext.ImageStorages.SingleAsync(a => a.Id == assetId); storage.Size.Should().BeGreaterThan(0); + + var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.ImageId == assetId); + policyData.MetadataValue.Should().Be("{\"a\": [], \"o\": [[1024, 1024], [400, 400], [200, 200], [100, 100]]}"); } [Fact] @@ -250,6 +253,9 @@ public async Task IngestAsset_Success_OnLargerReingest() var storage = await dbContext.ImageStorages.SingleAsync(a => a.Id == assetId); storage.Size.Should().NotBe(950); + + var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.ImageId == assetId); + policyData.MetadataValue.Should().Be("{\"a\": [], \"o\": [[1024, 1024], [400, 400], [200, 200], [100, 100]]}"); } [Fact] @@ -300,6 +306,9 @@ public async Task IngestAsset_Success_ChangesMediaTypeToContentType_WhenCalledWi var storage = await dbContext.ImageStorages.SingleAsync(a => a.Id == assetId); storage.Size.Should().BeGreaterThan(0); + + var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.ImageId == assetId); + policyData.MetadataValue.Should().Be("{\"a\": [], \"o\": [[1024, 1024], [400, 400], [200, 200], [100, 100]]}"); } [Fact] From 38511e8c903acefd1cf95c10f558c6178876cd6f Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Fri, 12 Apr 2024 16:05:36 +0100 Subject: [PATCH 06/11] refactoring name --- .../Assets/Metadata/AssetApplicationMetadataTypes.cs | 2 +- .../AssetApplicationMetadataRepositoryTests.cs | 12 ++++++------ .../DLCS.Repository/Assets/Thumbs/ThumbsManager.cs | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs index a5abc0c3a..44b635fd4 100644 --- a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs +++ b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadataTypes.cs @@ -2,5 +2,5 @@ public static class AssetApplicationMetadataTypes { - public const string ThumbnailPolicy = "ThumbnailPolicy"; + public const string ThumbSizes = "ThumbSizes"; } \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs index 69bdb60c6..73d6a552b 100644 --- a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs +++ b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs @@ -33,10 +33,10 @@ public async Task UpsertApplicationMetadata_AddsMetadata_WhenCalledWithNew() // Act var metadata = await sut.UpsertApplicationMetadata(assetId, - AssetApplicationMetadataTypes.ThumbnailPolicy, metadataValue); + AssetApplicationMetadataTypes.ThumbSizes, metadataValue); var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => - x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbnailPolicy); + x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); // Assert metadata.Should().NotBeNull(); @@ -50,14 +50,14 @@ public async Task UpsertApplicationMetadata_UpdatesMetadata_WhenCalledWithUpdate // Arrange var assetId = AssetId.FromString("99/1/1"); await sut.UpsertApplicationMetadata(assetId, - AssetApplicationMetadataTypes.ThumbnailPolicy, "{\"a\": [], \"o\": []}"); + AssetApplicationMetadataTypes.ThumbSizes, "{\"a\": [], \"o\": []}"); var newMetadataValue = "{\"a\": [], \"o\": [[75, 100], [150, 200], [300, 400], [769, 1024]]}"; // Act var metadata = await sut.UpsertApplicationMetadata(assetId, - AssetApplicationMetadataTypes.ThumbnailPolicy, newMetadataValue); + AssetApplicationMetadataTypes.ThumbSizes, newMetadataValue); var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => - x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbnailPolicy); + x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); // Assert metadata.Should().NotBeNull(); @@ -74,7 +74,7 @@ public async Task UpsertApplicationMetadata_ThrowsException_WhenCalledWithInvali // Act Func action = async () => await sut.UpsertApplicationMetadata(assetId, - AssetApplicationMetadataTypes.ThumbnailPolicy, metadataValue); + AssetApplicationMetadataTypes.ThumbSizes, metadataValue); // Assert await action.Should().ThrowAsync(); diff --git a/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs b/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs index f917d6aef..5cd26c42d 100644 --- a/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs +++ b/src/protagonist/DLCS.Repository/Assets/Thumbs/ThumbsManager.cs @@ -42,6 +42,6 @@ protected async Task CreateSizesJson(AssetId assetId, ThumbnailSizes thumbnailSi await BucketWriter.WriteToBucket(sizesDest, serializedThumbnailSizes, "application/json"); await AssetApplicationMetadataRepository.UpsertApplicationMetadata(assetId, - AssetApplicationMetadataTypes.ThumbnailPolicy, serializedThumbnailSizes); + AssetApplicationMetadataTypes.ThumbSizes, serializedThumbnailSizes); } } \ No newline at end of file From 3b71241e2f25af4c1d5dcb22262602060372d05b Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Fri, 12 Apr 2024 17:15:35 +0100 Subject: [PATCH 07/11] updates before code review --- .../Assets/Metadata/AssetApplicationMetadata.cs | 6 +++--- .../Assets/AssetApplicationMetadataRepositoryTests.cs | 4 ++-- .../Assets/AssetApplicationMetadataRepository.cs | 4 ++-- src/protagonist/DLCS.Repository/DlcsContext.cs | 6 +++--- ...854_adding AssetApplicationMetadata table.Designer.cs} | 8 ++++---- ...240412152854_adding AssetApplicationMetadata table.cs} | 8 ++++---- .../Migrations/DlcsContextModelSnapshot.cs | 6 +++--- .../Engine.Tests/Integration/ImageIngestTests.cs | 6 +++--- .../Integration/DatabaseTestDataPopulation.cs | 2 +- 9 files changed, 25 insertions(+), 25 deletions(-) rename src/protagonist/DLCS.Repository/Migrations/{20240412090855_adding AssetApplicationMetadata table.Designer.cs => 20240412152854_adding AssetApplicationMetadata table.Designer.cs} (96%) rename src/protagonist/DLCS.Repository/Migrations/{20240412090855_adding AssetApplicationMetadata table.cs => 20240412152854_adding AssetApplicationMetadata table.cs} (87%) diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs index 8376b0720..140f2892f 100644 --- a/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs +++ b/src/protagonist/DLCS.Model/Assets/Metadata/AssetApplicationMetadata.cs @@ -8,7 +8,7 @@ public class AssetApplicationMetadata /// /// The image id for the attached asset /// - public AssetId ImageId { get; set; } + public AssetId AssetId { get; set; } public Asset Asset { get; set; } @@ -23,12 +23,12 @@ public class AssetApplicationMetadata public string MetadataValue { get; set; } /// - /// When the metadata was created. + /// When the metadata was created /// public DateTime Created { get; set; } /// - /// When the metadata was last modified. + /// When the metadata was last modified /// public DateTime Modified { get; set; } } \ No newline at end of file diff --git a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs index 73d6a552b..b0823f3ac 100644 --- a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs +++ b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs @@ -36,7 +36,7 @@ public async Task UpsertApplicationMetadata_AddsMetadata_WhenCalledWithNew() AssetApplicationMetadataTypes.ThumbSizes, metadataValue); var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => - x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); + x.AssetId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); // Assert metadata.Should().NotBeNull(); @@ -57,7 +57,7 @@ public async Task UpsertApplicationMetadata_UpdatesMetadata_WhenCalledWithUpdate var metadata = await sut.UpsertApplicationMetadata(assetId, AssetApplicationMetadataTypes.ThumbSizes, newMetadataValue); var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => - x.ImageId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); + x.AssetId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); // Assert metadata.Should().NotBeNull(); diff --git a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs index 97de551fc..a58232491 100644 --- a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs +++ b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs @@ -20,7 +20,7 @@ public AssetApplicationMetadataRepository(DlcsContext dlcsContext) CancellationToken cancellationToken = default) { var addedMetadata = await dlcsContext.AssetApplicationMetadata.FirstOrDefaultAsync(e => - e.ImageId == assetId && e.MetadataType == metadataType, cancellationToken); + e.AssetId == assetId && e.MetadataType == metadataType, cancellationToken); if (addedMetadata is not null) { @@ -33,7 +33,7 @@ public AssetApplicationMetadataRepository(DlcsContext dlcsContext) var databaseMetadata= await dlcsContext.AssetApplicationMetadata.AddAsync(new AssetApplicationMetadata() { - ImageId = assetId, + AssetId = assetId, MetadataType = metadataType, MetadataValue = metadataValue, Created = DateTime.UtcNow, diff --git a/src/protagonist/DLCS.Repository/DlcsContext.cs b/src/protagonist/DLCS.Repository/DlcsContext.cs index 7a4964278..023f8e5ef 100644 --- a/src/protagonist/DLCS.Repository/DlcsContext.cs +++ b/src/protagonist/DLCS.Repository/DlcsContext.cs @@ -684,8 +684,8 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasKey(e => new { e.ImageId, e.MetadataType }); - entity.Property(e => e.ImageId).IsRequired().HasConversion( + entity.HasKey(e => new { ImageId = e.AssetId, e.MetadataType }); + entity.Property(e => e.AssetId).IsRequired().HasConversion( aId => aId.ToString(), id => AssetId.FromString(id)); entity.Property(e => e.MetadataType).IsRequired(); @@ -693,7 +693,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.HasOne(e => e.Asset) .WithMany(e => e.AssetApplicationMetadata) - .HasForeignKey(e => e.ImageId); + .HasForeignKey(e => e.AssetId); }); OnModelCreatingPartial(modelBuilder); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.Designer.cs b/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.Designer.cs similarity index 96% rename from src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.Designer.cs rename to src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.Designer.cs index c75878250..424d2baef 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.Designer.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.Designer.cs @@ -12,7 +12,7 @@ namespace DLCS.Repository.Migrations { [DbContext(typeof(DlcsContext))] - [Migration("20240412090855_adding AssetApplicationMetadata table")] + [Migration("20240412152854_adding AssetApplicationMetadata table")] partial class addingAssetApplicationMetadatatable { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -337,7 +337,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => { - b.Property("ImageId") + b.Property("AssetId") .HasColumnType("character varying(500)"); b.Property("MetadataType") @@ -353,7 +353,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Property("Modified") .HasColumnType("timestamp with time zone"); - b.HasKey("ImageId", "MetadataType"); + b.HasKey("AssetId", "MetadataType"); b.ToTable("AssetApplicationMetadata"); }); @@ -1080,7 +1080,7 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) { b.HasOne("DLCS.Model.Assets.Asset", "Asset") .WithMany("AssetApplicationMetadata") - .HasForeignKey("ImageId") + .HasForeignKey("AssetId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.cs b/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.cs similarity index 87% rename from src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.cs rename to src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.cs index e765cc195..a4903c930 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240412090855_adding AssetApplicationMetadata table.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.cs @@ -13,7 +13,7 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "AssetApplicationMetadata", columns: table => new { - ImageId = table.Column(type: "character varying(500)", nullable: false), + AssetId = table.Column(type: "character varying(500)", nullable: false), MetadataType = table.Column(type: "text", nullable: false), MetadataValue = table.Column(type: "jsonb", nullable: false), Created = table.Column(type: "timestamp with time zone", nullable: false), @@ -21,10 +21,10 @@ protected override void Up(MigrationBuilder migrationBuilder) }, constraints: table => { - table.PrimaryKey("PK_AssetApplicationMetadata", x => new { x.ImageId, x.MetadataType }); + table.PrimaryKey("PK_AssetApplicationMetadata", x => new { x.AssetId, x.MetadataType }); table.ForeignKey( - name: "FK_AssetApplicationMetadata_Images_ImageId", - column: x => x.ImageId, + name: "FK_AssetApplicationMetadata_Images_AssetId", + column: x => x.AssetId, principalTable: "Images", principalColumn: "Id", onDelete: ReferentialAction.Cascade); diff --git a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs index 0b6996467..1eabfa3f8 100644 --- a/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs +++ b/src/protagonist/DLCS.Repository/Migrations/DlcsContextModelSnapshot.cs @@ -335,7 +335,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("DLCS.Model.Assets.Metadata.AssetApplicationMetadata", b => { - b.Property("ImageId") + b.Property("AssetId") .HasColumnType("character varying(500)"); b.Property("MetadataType") @@ -351,7 +351,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Modified") .HasColumnType("timestamp with time zone"); - b.HasKey("ImageId", "MetadataType"); + b.HasKey("AssetId", "MetadataType"); b.ToTable("AssetApplicationMetadata"); }); @@ -1078,7 +1078,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.HasOne("DLCS.Model.Assets.Asset", "Asset") .WithMany("AssetApplicationMetadata") - .HasForeignKey("ImageId") + .HasForeignKey("AssetId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); diff --git a/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs b/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs index 822d17de8..bbb7f2d81 100644 --- a/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs +++ b/src/protagonist/Engine.Tests/Integration/ImageIngestTests.cs @@ -203,7 +203,7 @@ public async Task IngestAsset_Success_HttpOrigin_AllOpen() var storage = await dbContext.ImageStorages.SingleAsync(a => a.Id == assetId); storage.Size.Should().BeGreaterThan(0); - var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.ImageId == assetId); + var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.AssetId == assetId); policyData.MetadataValue.Should().Be("{\"a\": [], \"o\": [[1024, 1024], [400, 400], [200, 200], [100, 100]]}"); } @@ -254,7 +254,7 @@ public async Task IngestAsset_Success_OnLargerReingest() var storage = await dbContext.ImageStorages.SingleAsync(a => a.Id == assetId); storage.Size.Should().NotBe(950); - var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.ImageId == assetId); + var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.AssetId == assetId); policyData.MetadataValue.Should().Be("{\"a\": [], \"o\": [[1024, 1024], [400, 400], [200, 200], [100, 100]]}"); } @@ -307,7 +307,7 @@ public async Task IngestAsset_Success_ChangesMediaTypeToContentType_WhenCalledWi var storage = await dbContext.ImageStorages.SingleAsync(a => a.Id == assetId); storage.Size.Should().BeGreaterThan(0); - var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.ImageId == assetId); + var policyData = await dbContext.AssetApplicationMetadata.SingleAsync(a => a.AssetId == assetId); policyData.MetadataValue.Should().Be("{\"a\": [], \"o\": [[1024, 1024], [400, 400], [200, 200], [100, 100]]}"); } diff --git a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs index 4c1f34ac2..d475bb880 100644 --- a/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs +++ b/src/protagonist/Test.Helpers/Integration/DatabaseTestDataPopulation.cs @@ -190,7 +190,7 @@ public static class DatabaseTestDataPopulation string metadataType, string metadataValue) => assetApplicationMetadata.AddAsync(new AssetApplicationMetadata() { - ImageId = assetId, + AssetId = assetId, MetadataType = metadataType, MetadataValue = metadataValue, Created = DateTime.UtcNow, From e2d5f1879b2920bff8162bc2807ebcdeeaf47e30 Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Fri, 12 Apr 2024 17:21:03 +0100 Subject: [PATCH 08/11] add comment --- .../Metadata/IAssetApplicationMetadataRepository.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs index aaf0d5e61..9b4c2f56d 100644 --- a/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs +++ b/src/protagonist/DLCS.Model/Assets/Metadata/IAssetApplicationMetadataRepository.cs @@ -6,6 +6,14 @@ namespace DLCS.Model.Assets.Metadata; public interface IAssetApplicationMetadataRepository { + /// + /// Upserts asset application metadata into the table + /// + /// The asset id this metadata will relate to + /// The type of metadata to create + /// The value of this metadata + /// A cancellation token + /// A copy of the metadata that has been put into the database public Task UpsertApplicationMetadata( AssetId assetId, string metadataType, string metadataValue, CancellationToken cancellationToken = default); From 06c86fbb5cc34f1b2fb2041fa86b30ca794717a6 Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Mon, 15 Apr 2024 09:46:59 +0100 Subject: [PATCH 09/11] remove redundant assignment --- src/protagonist/DLCS.Repository/DlcsContext.cs | 2 +- ...415082950_adding AssetApplicationMetadata table.Designer.cs} | 2 +- ... => 20240415082950_adding AssetApplicationMetadata table.cs} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename src/protagonist/DLCS.Repository/Migrations/{20240412152854_adding AssetApplicationMetadata table.Designer.cs => 20240415082950_adding AssetApplicationMetadata table.Designer.cs} (97%) rename src/protagonist/DLCS.Repository/Migrations/{20240412152854_adding AssetApplicationMetadata table.cs => 20240415082950_adding AssetApplicationMetadata table.cs} (100%) diff --git a/src/protagonist/DLCS.Repository/DlcsContext.cs b/src/protagonist/DLCS.Repository/DlcsContext.cs index 023f8e5ef..3f0a85948 100644 --- a/src/protagonist/DLCS.Repository/DlcsContext.cs +++ b/src/protagonist/DLCS.Repository/DlcsContext.cs @@ -684,7 +684,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasKey(e => new { ImageId = e.AssetId, e.MetadataType }); + entity.HasKey(e => new { e.AssetId, e.MetadataType }); entity.Property(e => e.AssetId).IsRequired().HasConversion( aId => aId.ToString(), id => AssetId.FromString(id)); diff --git a/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.Designer.cs b/src/protagonist/DLCS.Repository/Migrations/20240415082950_adding AssetApplicationMetadata table.Designer.cs similarity index 97% rename from src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.Designer.cs rename to src/protagonist/DLCS.Repository/Migrations/20240415082950_adding AssetApplicationMetadata table.Designer.cs index 424d2baef..f9a5884bf 100644 --- a/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.Designer.cs +++ b/src/protagonist/DLCS.Repository/Migrations/20240415082950_adding AssetApplicationMetadata table.Designer.cs @@ -12,7 +12,7 @@ namespace DLCS.Repository.Migrations { [DbContext(typeof(DlcsContext))] - [Migration("20240412152854_adding AssetApplicationMetadata table")] + [Migration("20240415082950_adding AssetApplicationMetadata table")] partial class addingAssetApplicationMetadatatable { protected override void BuildTargetModel(ModelBuilder modelBuilder) diff --git a/src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.cs b/src/protagonist/DLCS.Repository/Migrations/20240415082950_adding AssetApplicationMetadata table.cs similarity index 100% rename from src/protagonist/DLCS.Repository/Migrations/20240412152854_adding AssetApplicationMetadata table.cs rename to src/protagonist/DLCS.Repository/Migrations/20240415082950_adding AssetApplicationMetadata table.cs From d016ee753d83f3ec48d3aa4ca587c254f6081090 Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Mon, 15 Apr 2024 11:13:50 +0100 Subject: [PATCH 10/11] remove redundant update --- .../Assets/AssetApplicationMetadataRepositoryTests.cs | 10 ++++++++-- .../Assets/AssetApplicationMetadataRepository.cs | 11 ++++++----- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs index b0823f3ac..d3073e4ed 100644 --- a/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs +++ b/src/protagonist/DLCS.Repository.Tests/Assets/AssetApplicationMetadataRepositoryTests.cs @@ -13,11 +13,17 @@ public class AssetApplicationMetadataRepositoryTests { private readonly DlcsContext dbContext; private readonly AssetApplicationMetadataRepository sut; + private readonly DlcsContext contextForTests; public AssetApplicationMetadataRepositoryTests(DlcsDatabaseFixture dbFixture) { dbContext = dbFixture.DbContext; - sut = new AssetApplicationMetadataRepository(dbFixture.DbContext); + + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseNpgsql(dbFixture.ConnectionString); + contextForTests = new DlcsContext(optionsBuilder.Options); + + sut = new AssetApplicationMetadataRepository(contextForTests); dbFixture.CleanUp(); dbContext.Images.AddTestAsset(AssetId.FromString("99/1/1"), ref1: "foobar"); @@ -56,7 +62,7 @@ public async Task UpsertApplicationMetadata_UpdatesMetadata_WhenCalledWithUpdate // Act var metadata = await sut.UpsertApplicationMetadata(assetId, AssetApplicationMetadataTypes.ThumbSizes, newMetadataValue); - var metaDataFromDatabase = await dbContext.AssetApplicationMetadata.FirstAsync(x => + var metaDataFromDatabase = await contextForTests.AssetApplicationMetadata.FirstAsync(x => x.AssetId == assetId && x.MetadataType == AssetApplicationMetadataTypes.ThumbSizes); // Assert diff --git a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs index a58232491..bce3d1296 100644 --- a/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs +++ b/src/protagonist/DLCS.Repository/Assets/AssetApplicationMetadataRepository.cs @@ -26,21 +26,22 @@ public AssetApplicationMetadataRepository(DlcsContext dlcsContext) { addedMetadata.MetadataValue = metadataValue; addedMetadata.Modified = DateTime.UtcNow; - await dlcsContext.AssetApplicationMetadata.SingleUpdateAsync(addedMetadata, cancellationToken); await dlcsContext.SaveChangesAsync(cancellationToken); return addedMetadata; } - - var databaseMetadata= await dlcsContext.AssetApplicationMetadata.AddAsync(new AssetApplicationMetadata() + + var assetApplicationMetadata = new AssetApplicationMetadata() { AssetId = assetId, MetadataType = metadataType, MetadataValue = metadataValue, Created = DateTime.UtcNow, Modified = DateTime.UtcNow - }, cancellationToken); + }; + + await dlcsContext.AssetApplicationMetadata.AddAsync(assetApplicationMetadata, cancellationToken); await dlcsContext.SaveChangesAsync(cancellationToken); - return databaseMetadata.Entity; + return assetApplicationMetadata; } } \ No newline at end of file From 64844acee72deff76c61b148b8ed497aca49d3a4 Mon Sep 17 00:00:00 2001 From: "jack.lewis" Date: Mon, 15 Apr 2024 13:22:56 +0100 Subject: [PATCH 11/11] updating thumbs --- src/protagonist/Engine/appsettings.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/protagonist/Engine/appsettings.json b/src/protagonist/Engine/appsettings.json index 371bcc1ba..41df280f0 100644 --- a/src/protagonist/Engine/appsettings.json +++ b/src/protagonist/Engine/appsettings.json @@ -37,11 +37,11 @@ "DeliveryChannelMappings": { "video-mp4-720p": "System preset: Generic 720p", "audio-mp3-128": "System preset: Audio MP3 - 128k" - }, - "ImageIngest": { - "DefaultThumbs": [ - "!100,100", "!200,200", "!400,400", "!1024,1024" - ] } + }, + "ImageIngest": { + "DefaultThumbs": [ + "!100,100", "!200,200", "!400,400", "!1024,1024" + ] } }