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

API review of Steeltoe.Configuration #1008

Merged
merged 51 commits into from
Sep 29, 2022
Merged

Conversation

bart-vmware
Copy link
Member

@bart-vmware bart-vmware commented Sep 5, 2022

Description

This PR is the result of me reviewing the public API surface of the Steeltoe.Configuration namespace, based on this guidance. Notable changes:

  • Seal public types that don't seem (properly) designed for inheritance (please indicate where I'm wrong)
  • Replace optional parameters with overloads in publicly exposed methods
  • Add input validation (null checks) on the parameters of publicly exposed methods
  • Change publicly exposed fields into properties, unless they are constants
  • Naming changes to comply with .NET Naming Conventions and Capitalization Conventions guidance from Microsoft
  • Correct or add doc-comments, as far as I understand the purpose of things
  • Prefer exposing interfaces to (read-only) collections, unless impossible due to lack of support in System.Text.Json
  • Remove logic that is conditional to the full .NET Framework

To facilitate the process, I've made several changes that are scoped to the Steeltoe.Configuration projects:

Open questions:

  • I've left all public types public, because I can't determine whether they should be. Although I don't understand why most types are public in the first place. The odd thing is that types in Steeltoe.Extensions.Configuration.Kubernetes are an exception to this: most types are internal there. What's the intended visibility of the types in the Steeltoe.Configuration namespace? Should we consider pubternal anywhere? In hindsight, this should have been the first step in the API review process.
  • Why do we provide a custom command-line configuration provider, given that Microsoft.Extensions.Configuration.CommandLine.CommandLineConfigurationProvider is already provided by ASP.NET?
  • What's the point of providing a random value provider? And why is it not generating cryptographically strong values, but instead relies on the deterministic (thus insecure) random generator?
  • Should we remove '"Extensions" in the "Steeltoe.Extensions.Configuration" namespace? The reason Microsoft puts Extensions in the namespace is to distinguish them from the core .NET APIs. But that reasoning does not apply to Steeltoe, so I think we should drop it.
  • Using the term Abstract in type names is uncommon in the .NET world. The typical convention is to prefix or suffix with Base. Should we rename types such as AbstractOptions and AbstractServiceOptions accordingly?

Fixes #899.

Quality checklist

  • Your code complies with our Coding Style.
  • You've updated unit and/or integration tests for your change, where applicable.
  • You've updated documentation for your change, where applicable.
    If your change affects other repositories, such as Documentation, Samples and/or MainSite, add linked PRs here.
  • There's an open issue for the PR that you are making. If you'd like to propose a new feature or change, please open an issue to discuss the change or find an existing issue.
  • You've added required license files and/or file headers (explaining where the code came from with proper attribution), where code is copied from StackOverflow, a blog, or OSS.

@bart-vmware
Copy link
Member Author

bart-vmware commented Sep 5, 2022

/azp run Steeltoe.All

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@bart-vmware bart-vmware marked this pull request as ready for review September 5, 2022 09:45
@bart-vmware
Copy link
Member Author

/cc @ccheetham

@TimHess
Copy link
Member

TimHess commented Sep 21, 2022

@hananiel can you address this one:

Why do we provide a custom command-line configuration provider, given that Microsoft.Extensions.Configuration.CommandLine.CommandLineConfigurationProvider is already provided by ASP.NET?

If we are talking about the SpringBootCmdprovider, it expands Cmd Line '.' delimited configuration key/value pairs that start with "spring." to .NET compatible form. Specifically it helps Steeltoe stream apps play in Dataflow There are other use cases as well where this would be useful - where the platform uses a java friendly convention.

Given other use cases, should this feature be detached from the command line and/or move into Placeholder (since the purpose seems to align as another config transform)?

@bart-vmware
Copy link
Member Author

bart-vmware commented Sep 22, 2022

@hananiel can you address this one:

Why do we provide a custom command-line configuration provider, given that Microsoft.Extensions.Configuration.CommandLine.CommandLineConfigurationProvider is already provided by ASP.NET?

If we are talking about the SpringBootCmdprovider, it expands Cmd Line '.' delimited configuration key/value pairs that start with "spring." to .NET compatible form. Specifically it helps Steeltoe stream apps play in Dataflow There are other use cases as well where this would be useful - where the platform uses a java friendly convention.

Given other use cases, should this feature be detached from the command line and/or move into Placeholder (since the purpose seems to align as another config transform)?

Thanks for the clarification. I was mislead by the type name, thinking it would read command-line values. But what it actually does is rename already-loaded keys, regardless of where they came from. I understand this is a useful feature to keep. While it has functional parity with Placeholder, this implementation is a lot simpler, so I'd prefer to keep them separate. I'm trying to come up with a better name that reflects what it does, but can't think of any. The current name indicates its purpose, which is handling Spring Boot command-line key syntax conversion. We could clarify the documentation a bit, though:

- Configuration provider that expands command-line '.' delimited configuration key/value pairs that start with "spring." to .NET compatible form.
+ Configuration provider that expands '.' delimited configuration keys that start with "spring." (typically originating from Spring Boot command-line parameters) to .NET compatible form.

and:

- Initializes a new instance of the <see cref="SpringBootCommandLineProvider" /> class. The <see cref="Configuration" /> will be created from the <see cref="CommandLineConfigurationProvider" />.
+ Initializes a new instance of the <see cref="SpringBootCommandLineProvider" /> class. The <see cref="IConfiguration" /> is assumed to contain configuration keys originating from the <see cref="CommandLineConfigurationProvider" />.

@bart-vmware
Copy link
Member Author

This PR seems to be so much more than just an API review of the Steeltoe.Configuration components... the changes touch everywhere. So many of the changes seem to have nothing to do with the API surface area of the Configuration components ... and more to do with resharper/analyzer/coding related changes ....

We should probably rename this PR to reflect what it really is ...

I don't think that's fair. Aside from a few small things (such as making test classes sealed, intentionally in a separate commit so it can be glanced over quickly), nearly all changes stem from the guidance here. The subset of sonar rules turned on in this PR exclusively concerns public API surface. This is unrelated to Resharper/StyleCop or code quality, it is about the exposed signatures. And where they changed, I've updated unit tests accordingly. I'm aware that this PR is large, but I've tried very hard to produce commits that target a single purpose, to make code review as easy as possible.

At this point, I guess I'm kind of with Hananiel ... lets merge it and start to work with the changes and see what happens

I disagree, there are still quite some open questions we haven't explored, discussed and decided on. The most important one being: What should be public and what should not be? Based on the outcome, I expect more changes regarding optional parameters and overloads. Merging now would not fulfill the purpose of this PR, which is to rationalize the public API surface and confirm this is what we want to expose.

Reviewing which types should be public may not be as hard as it seems, assuming a basic understanding of the interaction between types. We have 7 projects, each containing 10-15 files on average. We no longer have multiple types per .cs file, so going over the files per project should be doable. Another approach is to look at the PublicAPI.Unshipped.txt files. At a high level: everything in Kubernetes is internal, except for extension methods. In the other projects, nearly everything is public. I'd like to propose to make everything internal everywhere, except for extension methods. From there, we can decide which changes need to be reverted because we intend to expose those types. Would that work?

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@bart-vmware
Copy link
Member Author

We've discussed the open questions in our team meeting and agreed to the following:

  • Public types: Make all types internal, except for extension methods. @bart-vmware
  • Random: Need to better understand its use cases first. @dtillman
  • Namespace: Remove "Extensions" from the namespace. @bart-vmware
  • Abstract: Drop in favor of Base prefix/suffix (investigate common patterns in BCL). @bart-vmware

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@sonarcloud
Copy link

sonarcloud bot commented Sep 28, 2022

SonarCloud Quality Gate failed.    Quality Gate failed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot E 3 Security Hotspots
Code Smell A 15 Code Smells

0.0% 0.0% Coverage
0.2% 0.2% Duplication

Copy link
Member

@TimHess TimHess left a comment

Choose a reason for hiding this comment

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

LGTM

@bart-vmware bart-vmware merged commit 8f3b2de into main Sep 29, 2022
@bart-vmware bart-vmware deleted the configuration-api-review branch September 29, 2022 13:48
@TimHess TimHess added this to the 4.0.0-alpha milestone Dec 5, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Review API Surface area in Steeltoe.Configuration
5 participants