diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 682457d..7bcceca 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -3,14 +3,14 @@
"isRoot": true,
"tools": {
"swashbuckle.aspnetcore.cli": {
- "version": "9.0.1",
+ "version": "10.0.1",
"commands": [
"swagger"
],
"rollForward": false
},
"csharpier": {
- "version": "1.0.2",
+ "version": "1.2.1",
"commands": [
"csharpier"
],
diff --git a/Directory.Build.props b/Directory.Build.props
index 0230962..6b89139 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -5,7 +5,7 @@
enable
-
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/src/Api/Api.csproj b/src/Api/Api.csproj
index c6c95d2..d25956e 100644
--- a/src/Api/Api.csproj
+++ b/src/Api/Api.csproj
@@ -13,19 +13,19 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
+
+
+
diff --git a/src/Api/Authentication/PhaJwtAuthenticationHandler.cs b/src/Api/Authentication/PhaJwtAuthenticationHandler.cs
index f1831c8..803d65a 100644
--- a/src/Api/Authentication/PhaJwtAuthenticationHandler.cs
+++ b/src/Api/Authentication/PhaJwtAuthenticationHandler.cs
@@ -28,12 +28,10 @@ IOptions aclOptions
if (client == null)
return Task.CompletedTask;
- claimsIdentity.AddClaims(
- [
- .. client.Bcps.Select(ClaimTypes.CreateBcpClaim),
- .. client.ChedTypes.Select(ClaimTypes.CreateChedTypeClaim),
- ]
- );
+ claimsIdentity.AddClaims([
+ .. client.Bcps.Select(ClaimTypes.CreateBcpClaim),
+ .. client.ChedTypes.Select(ClaimTypes.CreateChedTypeClaim),
+ ]);
context.Principal = new ClaimsPrincipal(claimsIdentity);
diff --git a/src/Api/OpenApi/DescriptionSchemaFilter.cs b/src/Api/OpenApi/DescriptionSchemaFilter.cs
index 2487cbe..3246f8d 100644
--- a/src/Api/OpenApi/DescriptionSchemaFilter.cs
+++ b/src/Api/OpenApi/DescriptionSchemaFilter.cs
@@ -1,6 +1,6 @@
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Defra.PhaImportNotifications.Api.OpenApi;
@@ -8,7 +8,7 @@ namespace Defra.PhaImportNotifications.Api.OpenApi;
[ExcludeFromCodeCoverage]
public class DescriptionSchemaFilter : ISchemaFilter
{
- public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ public void Apply(IOpenApiSchema schema, SchemaFilterContext context)
{
if (context.ParameterInfo != null)
{
diff --git a/src/Api/OpenApi/ExampleValueSchemaFilter.cs b/src/Api/OpenApi/ExampleValueSchemaFilter.cs
index 057bd92..6a1c874 100644
--- a/src/Api/OpenApi/ExampleValueSchemaFilter.cs
+++ b/src/Api/OpenApi/ExampleValueSchemaFilter.cs
@@ -1,14 +1,16 @@
+using System.Text.Json.Nodes;
using Defra.PhaImportNotifications.Contracts;
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Defra.PhaImportNotifications.Api.OpenApi;
public class ExampleValueSchemaFilter : ISchemaFilter
{
- public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ public void Apply(IOpenApiSchema schema, SchemaFilterContext context)
{
+ var open = schema as OpenApiSchema;
+
var exampleValueAttributes =
context.MemberInfo?.GetCustomAttributes(false).OfType().ToList() ?? [];
@@ -20,9 +22,12 @@ public void Apply(OpenApiSchema schema, SchemaFilterContext context)
+ " underlying systems evolve. Consuming clients should cater for this possibility.";
var values = exampleValueAttributes.Select(a => a.Value).Where(v => !string.IsNullOrWhiteSpace(v));
+
+ open!.Enum ??= new List();
+
foreach (var value in values)
{
- schema.Enum.Add(new OpenApiString(value));
+ open.Enum.Add(value);
}
}
}
diff --git a/src/Api/OpenApi/TagsDocumentFilter.cs b/src/Api/OpenApi/TagsDocumentFilter.cs
index d29ad02..5f77138 100644
--- a/src/Api/OpenApi/TagsDocumentFilter.cs
+++ b/src/Api/OpenApi/TagsDocumentFilter.cs
@@ -1,5 +1,5 @@
-using Microsoft.OpenApi.Any;
-using Microsoft.OpenApi.Models;
+using System.Text.Json.Nodes;
+using Microsoft.OpenApi;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Defra.PhaImportNotifications.Api.OpenApi;
@@ -10,22 +10,23 @@ public class TagsDocumentFilter : IDocumentFilter
public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
{
- swaggerDoc.Extensions["tags"] = new OpenApiArray
+ var tag = swaggerDoc.Tags?.FirstOrDefault(t => t.Name == ImportNotificationsTag);
+ if (tag is not null)
{
- new OpenApiObject
- {
- ["name"] = new OpenApiString(ImportNotificationsTag),
- ["description"] = new OpenApiString("Get updated import notifications for a PHA"),
- },
- };
+ tag.Description = "Get updated import notifications for a PHA";
+ }
- swaggerDoc.Extensions["x-tagGroups"] = new OpenApiArray
- {
- new OpenApiObject
+ swaggerDoc.Extensions ??= new Dictionary();
+
+ swaggerDoc.Extensions["x-tagGroups"] = new JsonNodeExtension(
+ new JsonArray
{
- ["name"] = new OpenApiString("Endpoints"),
- ["tags"] = new OpenApiArray { new OpenApiString(ImportNotificationsTag) },
- },
- };
+ new JsonObject
+ {
+ ["name"] = "Endpoints",
+ ["tags"] = new JsonArray { ImportNotificationsTag },
+ },
+ }
+ );
}
}
diff --git a/src/Api/Program.cs b/src/Api/Program.cs
index 87d54f1..9c01283 100644
--- a/src/Api/Program.cs
+++ b/src/Api/Program.cs
@@ -16,7 +16,7 @@
using Microsoft.AspNetCore.WebUtilities;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
-using Microsoft.OpenApi.Models;
+using Microsoft.OpenApi;
using Serilog;
using Swashbuckle.AspNetCore.SwaggerGen;
@@ -114,18 +114,10 @@ static void ConfigureWebApplication(WebApplicationBuilder builder, string[] args
},
}
);
- c.AddSecurityRequirement(
- new OpenApiSecurityRequirement
- {
- {
- new OpenApiSecurityScheme
- {
- Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oAuth" },
- },
- []
- },
- }
- );
+ c.AddSecurityRequirement(document => new OpenApiSecurityRequirement
+ {
+ [new OpenApiSecuritySchemeReference("oAuth", document)] = [],
+ });
c.IncludeXmlComments(Assembly.GetExecutingAssembly());
c.IncludeXmlComments(typeof(ImportPreNotification).Assembly);
c.DocumentFilter();
diff --git a/src/Contracts/CommodityComplements.g.cs b/src/Contracts/CommodityComplements.g.cs
index e31d4b1..5e0b167 100644
--- a/src/Contracts/CommodityComplements.g.cs
+++ b/src/Contracts/CommodityComplements.g.cs
@@ -1,79 +1,79 @@
-#nullable enable
-using System.Text.Json.Serialization;
-using System.ComponentModel;
-
-namespace Defra.PhaImportNotifications.Contracts;
-public partial record CommodityComplements
-{
- [JsonPropertyName("uniqueComplementId")]
- [Description("UUID used to match commodityComplement to its complementParameter set. CHEDPP only")]
- public string? UniqueComplementId { get; init; }
-
- [JsonPropertyName("commodityDescription")]
- [Description("Description of the commodity")]
- public string? CommodityDescription { get; init; }
-
- [JsonPropertyName("commodityId")]
- [Description("The unique commodity ID")]
- public string? CommodityId { get; init; }
-
- [JsonPropertyName("complementId")]
- [Description("Identifier of complement chosen from speciesFamily,speciesClass and speciesType'. This is also used to link to the complementParameterSet")]
- public int? ComplementId { get; init; }
-
- [JsonPropertyName("complementName")]
- [Description("Represents the lowest granularity - either type, class, family or species name - for the commodity selected. This is also used to drive behaviour for EU Import journeys")]
- public string? ComplementName { get; init; }
-
- [JsonPropertyName("eppoCode")]
- [Description("EPPO Code related to plant commodities and wood packaging")]
- public string? EppoCode { get; init; }
-
- [JsonPropertyName("isWoodPackaging")]
- [Description("(Deprecated in IMTA-11832) Is this commodity wood packaging?")]
- public bool? IsWoodPackaging { get; init; }
-
- [JsonPropertyName("speciesId")]
- [Description("The species ID of the commodity that is imported. Not every commodity has a species ID. This is also used to link to the complementParameterSet. The species ID can change over time")]
- public string? SpeciesId { get; init; }
-
- [JsonPropertyName("speciesName")]
- [Description("Species name")]
- public string? SpeciesName { get; init; }
-
- [JsonPropertyName("speciesNomination")]
- [Description("Species nomination")]
- public string? SpeciesNomination { get; init; }
-
- [JsonPropertyName("speciesTypeName")]
- [Description("Species type name")]
- public string? SpeciesTypeName { get; init; }
-
- [JsonPropertyName("speciesType")]
- [Description("Species type identifier of commodity")]
- public string? SpeciesType { get; init; }
-
- [JsonPropertyName("speciesClassName")]
- [Description("Species class name")]
- public string? SpeciesClassName { get; init; }
-
- [JsonPropertyName("speciesClass")]
- [Description("Species class identifier of commodity")]
- public string? SpeciesClass { get; init; }
-
- [JsonPropertyName("speciesFamilyName")]
- [Description("Species family name of commodity")]
- public string? SpeciesFamilyName { get; init; }
-
- [JsonPropertyName("speciesFamily")]
- [Description("Species family identifier of commodity")]
- public string? SpeciesFamily { get; init; }
-
- [JsonPropertyName("speciesCommonName")]
- [Description("Species common name of commodity for IMP notification simple commodity selection")]
- public string? SpeciesCommonName { get; init; }
-
- [JsonPropertyName("isCdsMatched")]
- [Description("Has commodity been matched with corresponding CDS declaration")]
- public bool? IsCdsMatched { get; init; }
-}
+#nullable enable
+using System.Text.Json.Serialization;
+using System.ComponentModel;
+
+namespace Defra.PhaImportNotifications.Contracts;
+public partial record CommodityComplements
+{
+ [JsonPropertyName("uniqueComplementId")]
+ [Description("UUID used to match commodityComplement to its complementParameter set. CHEDPP only")]
+ public string? UniqueComplementId { get; init; }
+
+ [JsonPropertyName("commodityDescription")]
+ [Description("Description of the commodity")]
+ public string? CommodityDescription { get; init; }
+
+ [JsonPropertyName("commodityId")]
+ [Description("The unique commodity ID")]
+ public string? CommodityId { get; init; }
+
+ [JsonPropertyName("complementId")]
+ [Description("Identifier of complement chosen from speciesFamily,speciesClass and speciesType'. This is also used to link to the complementParameterSet")]
+ public int? ComplementId { get; init; }
+
+ [JsonPropertyName("complementName")]
+ [Description("Represents the lowest granularity - either type, class, family or species name - for the commodity selected. This is also used to drive behaviour for EU Import journeys")]
+ public string? ComplementName { get; init; }
+
+ [JsonPropertyName("eppoCode")]
+ [Description("EPPO Code related to plant commodities and wood packaging")]
+ public string? EppoCode { get; init; }
+
+ [JsonPropertyName("isWoodPackaging")]
+ [Description("(Deprecated in IMTA-11832) Is this commodity wood packaging?")]
+ public bool? IsWoodPackaging { get; init; }
+
+ [JsonPropertyName("speciesId")]
+ [Description("The species ID of the commodity that is imported. Not every commodity has a species ID. This is also used to link to the complementParameterSet. The species ID can change over time")]
+ public string? SpeciesId { get; init; }
+
+ [JsonPropertyName("speciesName")]
+ [Description("Species name")]
+ public string? SpeciesName { get; init; }
+
+ [JsonPropertyName("speciesNomination")]
+ [Description("Species nomination")]
+ public string? SpeciesNomination { get; init; }
+
+ [JsonPropertyName("speciesTypeName")]
+ [Description("Species type name")]
+ public string? SpeciesTypeName { get; init; }
+
+ [JsonPropertyName("speciesType")]
+ [Description("Species type identifier of commodity")]
+ public string? SpeciesType { get; init; }
+
+ [JsonPropertyName("speciesClassName")]
+ [Description("Species class name")]
+ public string? SpeciesClassName { get; init; }
+
+ [JsonPropertyName("speciesClass")]
+ [Description("Species class identifier of commodity")]
+ public string? SpeciesClass { get; init; }
+
+ [JsonPropertyName("speciesFamilyName")]
+ [Description("Species family name of commodity")]
+ public string? SpeciesFamilyName { get; init; }
+
+ [JsonPropertyName("speciesFamily")]
+ [Description("Species family identifier of commodity")]
+ public string? SpeciesFamily { get; init; }
+
+ [JsonPropertyName("speciesCommonName")]
+ [Description("Species common name of commodity for IMP notification simple commodity selection")]
+ public string? SpeciesCommonName { get; init; }
+
+ [JsonPropertyName("isCdsMatched")]
+ [Description("Has commodity been matched with corresponding CDS declaration")]
+ public bool? IsCdsMatched { get; init; }
+}
diff --git a/src/Contracts/ComplementParameterSets.g.cs b/src/Contracts/ComplementParameterSets.g.cs
index 91c4198..bfefa86 100644
--- a/src/Contracts/ComplementParameterSets.g.cs
+++ b/src/Contracts/ComplementParameterSets.g.cs
@@ -1,29 +1,29 @@
-#nullable enable
-using System.Text.Json.Serialization;
-using System.ComponentModel;
-
-namespace Defra.PhaImportNotifications.Contracts;
-public partial record ComplementParameterSets
-{
- [JsonPropertyName("uniqueComplementId")]
- [Description("UUID used to match commodityComplement to its complementParameter set. CHEDPP only")]
- public string? UniqueComplementId { get; init; }
-
- [JsonPropertyName("complementId")]
- public int? ComplementId { get; init; }
-
- [JsonPropertyName("speciesId")]
- public string? SpeciesId { get; init; }
-
- [JsonPropertyName("keyDataPair")]
- public List? KeyDataPair { get; init; }
-
- [JsonPropertyName("catchCertificates")]
- [JsonIgnore]
- [Description("Catch certificate details")]
- public List? CatchCertificates { get; init; }
-
- [JsonPropertyName("identifiers")]
- [Description("Data used to identify the complements inside an IMP consignment")]
- public List? Identifiers { get; init; }
-}
+#nullable enable
+using System.Text.Json.Serialization;
+using System.ComponentModel;
+
+namespace Defra.PhaImportNotifications.Contracts;
+public partial record ComplementParameterSets
+{
+ [JsonPropertyName("uniqueComplementId")]
+ [Description("UUID used to match commodityComplement to its complementParameter set. CHEDPP only")]
+ public string? UniqueComplementId { get; init; }
+
+ [JsonPropertyName("complementId")]
+ public int? ComplementId { get; init; }
+
+ [JsonPropertyName("speciesId")]
+ public string? SpeciesId { get; init; }
+
+ [JsonPropertyName("keyDataPair")]
+ public List? KeyDataPair { get; init; }
+
+ [JsonPropertyName("catchCertificates")]
+ [JsonIgnore]
+ [Description("Catch certificate details")]
+ public List? CatchCertificates { get; init; }
+
+ [JsonPropertyName("identifiers")]
+ [Description("Data used to identify the complements inside an IMP consignment")]
+ public List? Identifiers { get; init; }
+}
diff --git a/src/Contracts/ExternalError.g.cs b/src/Contracts/ExternalError.g.cs
index 6bdba91..ef9591f 100644
--- a/src/Contracts/ExternalError.g.cs
+++ b/src/Contracts/ExternalError.g.cs
@@ -1,22 +1,22 @@
-#nullable enable
-using System.Text.Json.Serialization;
-using System.ComponentModel;
-
-namespace Defra.PhaImportNotifications.Contracts;
-public partial record ExternalError
-{
- [JsonPropertyName("externalCorrelationId")]
- public string? ExternalCorrelationId { get; init; }
-
- [JsonPropertyName("sourceCorrelationId")]
- public string? SourceCorrelationId { get; init; }
-
- [JsonPropertyName("externalVersion")]
- public int? ExternalVersion { get; init; }
-
- [JsonPropertyName("messageSentAt")]
- public required DateTime MessageSentAt { get; init; }
-
- [JsonPropertyName("errors")]
- public List? Errors { get; init; }
-}
+#nullable enable
+using System.Text.Json.Serialization;
+using System.ComponentModel;
+
+namespace Defra.PhaImportNotifications.Contracts;
+public partial record ExternalError
+{
+ [JsonPropertyName("externalCorrelationId")]
+ public string? ExternalCorrelationId { get; init; }
+
+ [JsonPropertyName("sourceCorrelationId")]
+ public string? SourceCorrelationId { get; init; }
+
+ [JsonPropertyName("externalVersion")]
+ public int? ExternalVersion { get; init; }
+
+ [JsonPropertyName("messageSentAt")]
+ public required DateTime MessageSentAt { get; init; }
+
+ [JsonPropertyName("errors")]
+ public List? Errors { get; init; }
+}
diff --git a/src/Contracts/ImportPreNotificationUpdateResponse.g.cs b/src/Contracts/ImportPreNotificationUpdateResponse.g.cs
index 016b88b..1e9d415 100644
--- a/src/Contracts/ImportPreNotificationUpdateResponse.g.cs
+++ b/src/Contracts/ImportPreNotificationUpdateResponse.g.cs
@@ -1,13 +1,13 @@
-#nullable enable
-using System.Text.Json.Serialization;
-using System.ComponentModel;
-
-namespace Defra.PhaImportNotifications.Contracts;
-public partial record ImportPreNotificationUpdateResponse
-{
- [JsonPropertyName("referenceNumber")]
- public required string ReferenceNumber { get; init; }
-
- [JsonPropertyName("updated")]
- public required DateTime Updated { get; init; }
-}
+#nullable enable
+using System.Text.Json.Serialization;
+using System.ComponentModel;
+
+namespace Defra.PhaImportNotifications.Contracts;
+public partial record ImportPreNotificationUpdateResponse
+{
+ [JsonPropertyName("referenceNumber")]
+ public required string ReferenceNumber { get; init; }
+
+ [JsonPropertyName("updated")]
+ public required DateTime Updated { get; init; }
+}
diff --git a/src/Contracts/ImportPreNotificationUpdatesResponse.g.cs b/src/Contracts/ImportPreNotificationUpdatesResponse.g.cs
index 3991b81..b3d8d98 100644
--- a/src/Contracts/ImportPreNotificationUpdatesResponse.g.cs
+++ b/src/Contracts/ImportPreNotificationUpdatesResponse.g.cs
@@ -1,19 +1,19 @@
-#nullable enable
-using System.Text.Json.Serialization;
-using System.ComponentModel;
-
-namespace Defra.PhaImportNotifications.Contracts;
-public partial record ImportPreNotificationUpdatesResponse
-{
- [JsonPropertyName("importPreNotificationUpdates")]
- public required List ImportPreNotificationUpdates { get; init; }
-
- [JsonPropertyName("total")]
- public required int Total { get; init; }
-
- [JsonPropertyName("page")]
- public required int Page { get; init; }
-
- [JsonPropertyName("pageSize")]
- public required int PageSize { get; init; }
-}
+#nullable enable
+using System.Text.Json.Serialization;
+using System.ComponentModel;
+
+namespace Defra.PhaImportNotifications.Contracts;
+public partial record ImportPreNotificationUpdatesResponse
+{
+ [JsonPropertyName("importPreNotificationUpdates")]
+ public required List ImportPreNotificationUpdates { get; init; }
+
+ [JsonPropertyName("total")]
+ public required int Total { get; init; }
+
+ [JsonPropertyName("page")]
+ public required int Page { get; init; }
+
+ [JsonPropertyName("pageSize")]
+ public required int PageSize { get; init; }
+}
diff --git a/tests/Api.Integration/OpenApi/OpenApiTests.Redoc_VerifyAsExpected.verified.txt b/tests/Api.Integration/OpenApi/OpenApiTests.Redoc_VerifyAsExpected.verified.txt
index dadfa17..5104874 100644
--- a/tests/Api.Integration/OpenApi/OpenApiTests.Redoc_VerifyAsExpected.verified.txt
+++ b/tests/Api.Integration/OpenApi/OpenApiTests.Redoc_VerifyAsExpected.verified.txt
@@ -12,6 +12,11 @@
StatusCode: OK,
ReasonPhrase: OK,
Headers: [
+ {
+ x-redoc-version: [
+ 2.5.2
+ ]
+ },
{
Cache-Control: [
max-age=604800, private
diff --git a/tests/PhaImportNotifcations.Tests.csproj b/tests/PhaImportNotifcations.Tests.csproj
index fe4da1c..5b16ac8 100644
--- a/tests/PhaImportNotifcations.Tests.csproj
+++ b/tests/PhaImportNotifcations.Tests.csproj
@@ -8,21 +8,21 @@
-
+
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
diff --git a/tools/SchemaToCSharp/SchemaToCSharp.csproj b/tools/SchemaToCSharp/SchemaToCSharp.csproj
index d7efe54..6c87b67 100644
--- a/tools/SchemaToCSharp/SchemaToCSharp.csproj
+++ b/tools/SchemaToCSharp/SchemaToCSharp.csproj
@@ -6,8 +6,8 @@
enable
-
-
-
+
+
+