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

Allow specifying optional config section with YAML configuration #14847

Closed
hrstoyanov opened this issue Feb 5, 2021 · 23 comments · Fixed by #14955 or #17073
Closed

Allow specifying optional config section with YAML configuration #14847

hrstoyanov opened this issue Feb 5, 2021 · 23 comments · Fixed by #14955 or #17073
Labels
area/config kind/enhancement New feature or request
Milestone

Comments

@hrstoyanov
Copy link

hrstoyanov commented Feb 5, 2021

Describe the bug
See here
Expected behavior
Optional configuration sections should be allowed with Quarkus YAML config.

Actual behavior
I know of no way of specifying optional section with YAML config.

To Reproduce
Unpack this project
issue_optional_config.zip
and follow the instruction here

@hrstoyanov hrstoyanov added the kind/bug Something isn't working label Feb 5, 2021
@ghost ghost added the triage/needs-triage label Feb 5, 2021
@hrstoyanov
Copy link
Author

@geoand

@geoand geoand added kind/enhancement New feature or request and removed kind/bug Something isn't working labels Feb 5, 2021
@geoand geoand changed the title [Quarkus 1.11.1] No way to specify optional config section with YAML configuration Allow specifying optional config section with YAML configuration Feb 5, 2021
@hrstoyanov
Copy link
Author

hrstoyanov commented Feb 5, 2021

@geoand thanks for looking into this issue, any chance this gets fixed in 1.11.x? if I use JSON, would that work?

@geoand
Copy link
Contributor

geoand commented Feb 5, 2021

Most likely yes, but I can't make any guarantee on which micro it will be in.

@geoand
Copy link
Contributor

geoand commented Feb 5, 2021

I took a look at this and actually I am not sure I want to go through with it.

The reason is because the semantics of having the config section be Optional are a little hazy.
Say you make the sectional Optional, then under what conditional does rhe method return a value? When at least one property is set, when all properties are set?
If you go with the first option (which on the face of it seems the most reasonable), what happens when you invoke a method of that sub section that does not return an Optional but whose property has not been set?
It just seems to me to be weird to deal with a consistent and non suprising way... I assume that if we do do this, then whatever way it's done, some folks will be surprised by its behavior.

@hrstoyanov
Copy link
Author

hrstoyanov commented Feb 6, 2021

@geoand
Not sure why it is confusing - if an optional section is partially populated, extracting values from non-existing fields should result in default value for the type, or depending on any additional field annotations?

Take a look at this example:

sql_proxy:
  name: proxyname
  server:
    mssql:
      //server: localhost - missing
      //user: john - missing
      //password: changeme - missing
      port: 1143
      ...
 interface MSSQLConfig {
        @ConfigProperty(name = "server")  String server();
        @ConfigProperty(name = "user", defaultValue="smith")  String user();
        @ConfigProperty(name = "password")  @NotBlank String password();
        @ConfigProperty(name = "port") int port();
}
public interface ServerConfig {
    @ConfigProperty(name = "mssql") Optional<MSSQLConfig> mssql();
}

I would expect this:

   Optional<MSSQLConfig> optionalMSSQL = ServerConfig.msssql();

   assert optionalMSSQL.isPresent(); //Case 1. Because the section itself  exists! Otherwise - the optional should be empty/not present.
   MSSQLConfig mssql = optional.get();  // ... could potentially be NULL
   String server = mssql.server(); //Case 2. This is OK, we default to NULL, if missing, since it is not required.
   String user = mssql.user(); //Case 3. This is OK, we default to "smith", if missing.
   String password = mssql.password(); //Case 4. Runtime exception, since value is required and missing. 
   int port = mssql.port(); //Case 5. This is OK, we default to 0, if missing. Or maybe Integer.NaN?

What else is a developer to do without optional sections? How would you deal with the case where you want to make MSSQL section optional, so you can have ORACLE and PostGress as alternatives ?

@geoand
Copy link
Contributor

geoand commented Feb 6, 2021

I explained why I think it's confusing, I don't think there is much point in reiterating it.

You mention the default value for the subsections, but what would happen if there is no default value?

The best I can do is give it some thought and get back to you, but I'll be honest, I don't think I'll implement this.

@geoand
Copy link
Contributor

geoand commented Feb 6, 2021

Another complication is that in MP Config which is used at the lowest level for configuration, there is no support for multi level configuration - as one uses in YAML - so that means that all configuration options are mapped to a flat property structure.
This really complicates things from a YAML point of view.
Unfortunately we can't do much at the moment, but it's certainly a design choice that needs to be reevaluated in the future

@geoand
Copy link
Contributor

geoand commented Feb 8, 2021

After taking another look at this, I stand by my initial assement. Once we have a redesign of MP Config based on what I mention above, we can have another look at this

@hrstoyanov
Copy link
Author

i tried several hacks this weekend, but nothing worked.. Dumping MPConfig, will have to create my own parser.

Feel free to close this issue.

@geoand
Copy link
Contributor

geoand commented Feb 8, 2021

I won't close it as it's a valid feature request. I will gladly implement it once MP Config has the appropriate architecture in place that will allow me to do so.

@hrstoyanov
Copy link
Author

thanks. i appreciate it.

@geoand
Copy link
Contributor

geoand commented Feb 8, 2021

You bet!

@radcortez
Copy link
Member

radcortez commented Feb 9, 2021

@hrstoyanov please check this: smallrye/smallrye-config@b6f6fba. Is this what you are looking for?

I believe that PR will provide the missing pieces to support YAML mapping properly. Please, provide me your most complicated mapping and I'll add it as a test case :)

@hrstoyanov
Copy link
Author

hrstoyanov commented Feb 13, 2021

Would check it this weekend! And TOML (I have not forgotten!) ... You guys rock!

@radcortez
Copy link
Member

radcortez commented Feb 19, 2021

This is now supported with SmallRye Config @ConfigMapping, so I will consider there is an option to support the expected behaviour (even if it requires to use a different API).

Moving forward, we may replace or use as a backend implementation the SR @ConfigMapping in the Quarkus @ConfigProperties.

@hrstoyanov if you disagree, please reopen.

@radcortez radcortez linked a pull request Feb 19, 2021 that will close this issue
@radcortez radcortez added this to the 1.13 - master milestone Feb 19, 2021
@radcortez
Copy link
Member

Here is some documentation as well:
https://smallrye.io/docs/smallrye-config/mapping/mapping.html

@hrstoyanov
Copy link
Author

@radcortez radcortez reopened this Apr 19, 2021
@radcortez
Copy link
Member

Reopened due to some additional issues found in the implementation.

@geoand
Copy link
Contributor

geoand commented Apr 20, 2021

What are the additional implementation issues?

@radcortez
Copy link
Member

This is in SR ConfigMapping. We have an issue where when we have defaults set with the annotation at the same level for collection types, the defaults are not being applied properly.

@geoand
Copy link
Contributor

geoand commented Apr 20, 2021

Understood, thanks

@radcortez
Copy link
Member

@hrstoyanov this will be fixed with smallrye/smallrye-config#550.

@hrstoyanov
Copy link
Author

Thanks @radcortez , will test as soon as itis available in the maven repo!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/config kind/enhancement New feature or request
Projects
None yet
3 participants