Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[release/8.0] Fix ConfigurationSchemaGenerator to use correct TimeSpan format #3342

Merged
merged 4 commits into from
Apr 5, 2024

Conversation

github-actions[bot]
Copy link
Contributor

@github-actions github-actions bot commented Apr 2, 2024

Backport of #3320 to release/8.0

/cc @eerhardt

Customer Impact

When setting TimeSpan values in appsettings.json, we are not writing the correct format in our Configuration JSON schema. We were using format: duration, which sounds like it is correct, but this format is:

"duration": New in draft 2019-09 A duration as defined by the ISO 8601 ABNF for "duration". For example, P3D expresses a duration of 3 days.

Which doesn't work with TimeSpan.

Testing

Existing tests pass, added new tests for the TimeSpan format Regex.

Risk

Very low. Changing the valid format for TimeSpan values won't affect anything else.

Microsoft Reviewers: Open in CodeFlow

eerhardt added 4 commits April 2, 2024 19:00
'duration' isn't an acceptable description of how to represent a TimeSpan. Instead use a custom regular expression to represent TimeSpan formats.
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-integrations Issues pertaining to Aspire Integrations packages label Apr 2, 2024
@eerhardt eerhardt requested review from sebastienros and radical April 2, 2024 23:21
@joperezr joperezr added the Servicing-consider Issue for next servicing release review label Apr 3, 2024
@@ -69,12 +69,12 @@
"properties": {
"Delay": {
"type": "string",
"format": "duration",
"pattern": "^-?(\\d{1,7}|((\\d{1,7}[\\.:])?(([01]?\\d|2[0-3]):[0-5]?\\d|([01]?\\d|2[0-3]):[0-5]?\\d:[0-5]?\\d)(\\.\\d{1,7})?))$",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you author this based on the spec (appears to be BNF) or is it copied from someplace?

and assuming https://datatracker.ietf.org/doc/html/rfc3339#appendix-A is the right place to look at, what does this correspond to -- "Duration" here?

Mentally translating that BNF into pattern is a bit taxing on my brain. I see you have a bunch of tests -- are there any other canonical tests for this patter we can borrow from somewhere?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I see it's documented in the code below. But still not sure which part of the spec it matches to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and assuming https://datatracker.ietf.org/doc/html/rfc3339#appendix-A is the right place to look at, what does this correspond to -- "Duration" here?

That is precisely the wrong place to look. We used to say format: duration which says:

A duration as defined by the ISO 8601 ABNF for "duration". For example, P3D expresses a duration of 3 days.

But this doesn't work with TimeSpan.Parse which is what the code is using.

did you author this based on the spec (appears to be BNF) or is it copied from someplace?

I authored it following the behavior of TimeSpan.Parse, which is what the code that is parsing the string uses. See:

https://github.com/dotnet/runtime/blob/c19d68e52c6d743c8f81ed9049e8c172ae461c99/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/ConfigurationBindingGenerator.Parser.cs#L302-L304

https://github.com/dotnet/runtime/blob/c19d68e52c6d743c8f81ed9049e8c172ae461c99/src/libraries/Microsoft.Extensions.Configuration.Binder/gen/Emitter/CoreBindingHelpers.cs#L620-L623

@@ -401,12 +401,21 @@ private void AppendTypeNodes(JsonObject propertyNode, TypeSpec propertyTypeSpec)
}
}

const string NegativeOption = @"-?";
const string DaysAlone = @"\d{1,7}";
const string DaysPrefixOption = @$"({DaysAlone}[\.:])?";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are the parentheses in all these pieces intended to capture? (I don't know where this regex is executed)

if not, they should ideally be noncapturing (?: .... ) or RegexOptions.ExplicitCapture passed. Although, if it's just doing IsMatch, we're probably smart enough to realize this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't intended to do a capture. They are intended to be groupings for alternations and loops.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can put the ?: into the parens, but it really hurts the readability of the Regex. (not that it is currently all that readable)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(I don't know where this regex is executed)

It is executed whenever someone wants to validate the JSON document against the schema. For example in JsonSchema.Net: https://github.com/gregsdennis/json-everything/blob/fd3ce0b98f1ee6fa7c0f4965281151efa5df7e57/JsonSchema/PatternKeyword.cs#L87 it just calls Regex.IsMatch.

Regex.IsMatch is smart enough to not do captures because they won't be used.

Copy link
Member

@DamianEdwards DamianEdwards left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving from bar POV

@eerhardt eerhardt added Servicing-approved Approved for servicing release and removed Servicing-consider Issue for next servicing release review labels Apr 4, 2024
@eerhardt eerhardt merged commit 3492247 into release/8.0 Apr 5, 2024
7 checks passed
@eerhardt eerhardt deleted the backport/pr-3320-to-release/8.0 branch April 5, 2024 00:51
@danmoseley danmoseley mentioned this pull request Apr 12, 2024
@github-actions github-actions bot locked and limited conversation to collaborators May 8, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-integrations Issues pertaining to Aspire Integrations packages Servicing-approved Approved for servicing release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants