-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(webAPI): Require UUIDv7 (#1032)
<!--- Provide a general summary of your changes in the Title above --> ## Description This adds a requirement for user-supplied IDs to be UUIDv7, and that the timestamp on these are in the past. While implementing this I stumbled over a bug where the old way of creating IDs meant they were sorted in the wrong order because GUIDs in .NET are little endian. (Sort by ID ascending would have the newest at the top, and oldest at the bottom) The idea with UUIDv7 is that the first 6 bytes is the timestamp of creation, and this helps us avoid a fragmented index There will only be appends on the index b-tree when creating new entities, and no inserts further up the index. If we were to allow old UUIDv4 for the legacy archive imports, the index would forever be fragmented and have a performance hit. We now require that all incoming IDs are V7 and big endian (this is the standard in most other languages) Sorting by ID ascending on f.ex. DialogID should now list out oldest at the top, and newest at the bottom. ## Related Issue(s) - #969 ## Verification - [ ] **Your** code builds clean without any errors or warnings - [ ] Manual testing done (required) - [ ] Relevant automated test added (if you find this hard, leave it and we'll help out) ## Documentation - [ ] Documentation is updated (either in `docs`-directory, Altinnpedia or a separate linked PR in [altinn-studio-docs.](https://github.com/Altinn/altinn-studio-docs), if applicable)
- Loading branch information
Showing
15 changed files
with
229 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
50 changes: 50 additions & 0 deletions
50
...porten.Application/Common/Extensions/FluentValidation/FluentValidationUuiDv7Extensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using Digdir.Domain.Dialogporten.Domain.Common; | ||
using FluentValidation; | ||
using FluentValidation.Validators; | ||
|
||
namespace Digdir.Domain.Dialogporten.Application.Common.Extensions.FluentValidation; | ||
|
||
public static class FluentValidationUuiDv7Extensions | ||
{ | ||
public static IRuleBuilderOptions<T, Guid?> IsValidUuidV7<T>(this IRuleBuilder<T, Guid?> ruleBuilder) | ||
=> ruleBuilder.SetValidator(new UuidV7TimestampIsInPastValidator<T>()); | ||
|
||
public static IRuleBuilderOptions<T, Guid?> UuidV7TimestampIsInPast<T>(this IRuleBuilder<T, Guid?> ruleBuilder) | ||
=> ruleBuilder.SetValidator(new IsValidUuidV7TimestampValidator<T>()); | ||
} | ||
|
||
internal sealed class UuidV7TimestampIsInPastValidator<T> : PropertyValidator<T, Guid?> | ||
{ | ||
public override bool IsValid(ValidationContext<T> context, Guid? value) | ||
=> value is null || UuidV7.IsValid(value.Value); | ||
|
||
public override string Name { get; } = "Uuid7Validator"; | ||
|
||
protected override string GetDefaultMessageTemplate(string errorCode) => | ||
"Invalid {PropertyName}. Expected big endian UUIDv7 format. Got '{PropertyValue}'. See [link TBD]."; | ||
} | ||
|
||
internal sealed class IsValidUuidV7TimestampValidator<T> : PropertyValidator<T, Guid?> | ||
{ | ||
public override bool IsValid(ValidationContext<T> context, Guid? value) | ||
{ | ||
if (value is null) | ||
{ | ||
return true; | ||
} | ||
|
||
if (!UuidV7.TryToDateTimeOffset(value.Value, out var date)) | ||
{ | ||
context.MessageFormatter.AppendArgument("date", "invalid date"); | ||
return false; | ||
} | ||
|
||
context.MessageFormatter.AppendArgument("date", date.ToString("o")); | ||
return date < DateTimeOffset.UtcNow; | ||
} | ||
|
||
public override string Name { get; } = "Uuid7TimestampValidator"; | ||
|
||
protected override string GetDefaultMessageTemplate(string errorCode) | ||
=> "Invalid {PropertyName}. Expected the unix timestamp portion of the UUIDv7 to be in the past. Extrapolated '{date}' from '{PropertyValue}'. See [link TBD]."; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.