-
Notifications
You must be signed in to change notification settings - Fork 967
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
Split out a helper method for parsing only application overrides #708
Conversation
Hi @bbaldino, Thank you for your contribution! We really value the time you've taken to put this together. Before we proceed with reviewing this pull request, please sign the Lightbend Contributors License Agreement: |
For a specific use case, this PR allows me to do:
|
d315fb2
to
09e2d57
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! Re: your questions,
- Yeah there are various overloads for everything on ConfigFactory and it's a bit annoying (and also hard to get right). The precedent from
defaultApplication
would be to have one that takes no options and one that takes just a class loader; following that pattern seems reasonable to me. - notes inline, I think use the ensureClassLoader method
- I think throwing is right, it's better than silently falling back to application.conf (would be pretty hard to debug why my -Dconfig.whatever was being ignored in that case). Also, it keeps the current behavior, which is nice if in doubt.
@@ -8,7 +8,7 @@ | |||
|
|||
import java.io.File; | |||
import java.io.Reader; | |||
import java.net.URL; | |||
import java.net.*; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My memory isn't 100% but I think the codebase may mostly avoid wildcard imports
@@ -1090,6 +1090,63 @@ public static Config parseResourcesAnySyntax(String resourceBasename) { | |||
return parseResourcesAnySyntax(resourceBasename, ConfigParseOptions.defaults()); | |||
} | |||
|
|||
/** | |||
* Parse only any application overrides (those specified by config.{resource,file,url}), returning |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The word "override" already has a different meaning for ConfigFactory.defaultOverrides
so I wonder what else we could call this ... the README uses the word "replacement" perhaps? parseApplicationReplacement
?
if (loader == null) | ||
throw new ConfigException.BugOrBroken( | ||
"ClassLoader should have been set here; bug in ConfigFactory. " | ||
+ "(You can probably work around this bug by passing in a class loader or calling currentThread().setContextClassLoader() though.)"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should probably follow the pattern in the rest of ConfigFactory and call ensureClassLoader
rather than expecting it to be already set. The assertion here was because ConfigFactory is supposed to be the only caller of the strategy and it always does the ensureClassLoader. So here you can use ensureClassLoader which already throws if it can't find a loader.
specified += 1; | ||
|
||
if (specified == 0) { | ||
return ConfigImpl.emptyConfig("TODO: what to put here? Should something else be returned?"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe use Java 8 Optional ... ? I don't know what current best practice is around that, I haven't Java'd in a few years. I think there is a difference here between "something was specified and it was empty" and "nothing was specified."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This sounds good. Other option would be to return null I guess, but the way Optional
allows orElseGet
in DefaultConfigLoadingStrategy
is nice, so will use Optional
.
specified += 1; | ||
|
||
if (specified == 0) { | ||
Config overrideConfig = ConfigFactory.parseApplicationOverride(parseOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we rename to replacement
or something I'd carry it through variable names and terminology in comments
|
||
if (specified == 0) { | ||
Config overrideConfig = ConfigFactory.parseApplicationOverride(parseOptions); | ||
if (overrideConfig.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with optional it could be orElseGet(() -> ConfigFactory.parseResourcesAnySyntax("application", parseOptions))
maybe
config/src/main/main.iml
Outdated
@@ -0,0 +1,11 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should .gitignore these probably and remove from the PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤦 Will remove this.
Thanks for the comments, @havocp ! I think I addressed everything. One unfortunate thing I found about the
But it's not terrible. Is there some kind of static |
Yep there's a One other thought here is to add |
(for since tags, there are some existing examples I believe to copy) |
Ah, great.
Done. 👍 |
Thanks! |
*/ | ||
public static java.util.Optional<Config> parseApplicationReplacement(ConfigParseOptions parseOptions) { | ||
ensureClassLoader(parseOptions, "parseApplicationReplacement"); | ||
ClassLoader loader = parseOptions.getClassLoader(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, oops - I didn't catch this before merging, but ensureClassLoader returns the new options, doesn't modify the original options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops. I can open a follow up fix PR today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this PR broke backward compatibility. We have been using version 1.4.0 and it was possible to override any config options by using
After switching to version 1.4.1 this stopped working and now we must use I know that this is against the docs but it worked, so in such case you broke backward comaptibility. |
My bad, this isn't this PR but this commit - this should be pointed out in Version Notes. |
I found a workaround but I need to test it
|
This came out of a discussion in gitter with @havocp. I had a need to be able to write a custom Config load which would allow an override (via
-Dconfig.*
) but also fallback toapplication.conf
, even if an override were present. Previously the logic to parse overrides existed only inDefaultConfigLoadingStrategy#parseApplicationConfig
, which would replace any application resource with the-Dconfig.*
file. This PR moves the logic for parsing the overrides into a separate helper method, which is now used byDefaultConfigLoadingStrategy#parseApplicationConfig
but can be used elsewhere as well.A few questions on things that may need changing:
ConfigParseOptions
) toparseApplicationOverride
acceptable? There should probably be another version which takes no arguments and passesConfigParseOptions.defaults()
.ConfigImpl.emptyConfig
in the case where no override was specified? This requires an origin description and I wasn't sure what would be best to put there, maybe there's a better object to return.ConfigFactory#parseApplicationOverride
acceptable (in the case where no override files were given). Maybe it's better to return empty here as well?