-
Notifications
You must be signed in to change notification settings - Fork 122
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
Possibility to nullify config used in ConfigMapping #1291
Comments
In Quarkus you could wrap the mapping in a CDI Bean and use the annotations @IfBuildProperty(name = "please.enable", stringValue = "yes")
@ApplicationScoped
public class MyMappingBean {
@Inject
MyMapping myMapping;
}
@ConfigMapping(prefix = "my.mapping")
public interface MyMapping {
String value();
} Would this work for you? Another option is to use a SmallRyeConfigBuilderCustomizer and directly control which mappings are available in smallrye-config/implementation/src/main/java/io/smallrye/config/SmallRyeConfigBuilder.java Lines 830 to 832 in fc6de87
smallrye-config/implementation/src/main/java/io/smallrye/config/ConfigMappingContext.java Lines 47 to 62 in cd2e20d
|
I am using quarkus, and I cannot use build time stuff, as I cannot start supporting X builds with X different combinations of feature enablement. Another thing is that when let say feature X is enabled, a ConfigSourceFactory loads other configs that fills the config mapping (+ user stuff configs), hence why when feature gets disabled, the ConfigMapping becomes partially filled, and complains about the missing stuff. That's why my idea was to wrap all the configs in an optional, like in the example repo, and have a way to sort of mark them all as empty, so the config looks "ok" i.e. optional is empty, and feature.enabled=false. |
In relation to #845 I wonder if there could be something like this;
and a api sort of Unsure how that work work for quarkus/cdi cases though.. |
The customizer is SmallRye Config only, so it would work independently of Quarkus.
This may not be a good idea. We use the declared types to determine the behaviour of the mapping. CDI would be a problem, because you cannot use Also, when a declaration is reused in a tree as: @ConfigMapping(optional = true)
interface OptionalMapping {
}
@ConfigMapping
interface NonOptionalMapping {
OptionalMapping optionalMapping();
Optional<OptionalMapping> optionalMappingAsOptional();
} This looks a bit weird to me. Would the type declaration override the annotation or we have to validate that you always wrap the mapping in an |
Thanks for your answer.
I actually missed that from your previous message. That seems like it could be a really good solution, but as you mentioned if I do not have access to the raw config even, I cannot really know if a certain feature is available or not. When you said some hook in ConfigMappingContext.java I am not sure what it actually means though, does it mean it could be a way to get the config? A change in SR Config? about the optional I said above;
Agree, no idea on that. I was naively thinking about something like Instance and use something like
it does look weird. and I do not exactly know how it work work in a fully logical way. My goal is just to prevent half-provided config to break the app, i.e. make a half present optional be simply sort of ignored even if some configSource provides some values. From what I understand and read, looks like the customizer is quite close of being able to make this work, and actually ignore configMappings. |
Yes, that does not exist now. We would need to add it. How is the configuration to enable / disable is defined? Is it the user that provides the configuration? Or it is some other logic that sets that configuration to enable / disable? Couldn't that logic be written in the customizer to add / remove mappings? |
It's a little convoluted but let me try to explain my flow; 1- there are features, feature can be enabled/disabled via a My goal is that if the user wants to temporarily disable a feature he can jsut change the env var to featureX.disabled=false. Without bothering removing his extra featureX.customizaions="XXX". so when ready it can just be toggled back to true. Currently if the feature is toggled FALSE, the ConfigSourceFactory will skip getting the config for that service, and the extra params that remain in a user conf will fill some of the things in the Optional (see linked project in OP) then startup will fail, until the user redeploys by commenting all the FeatureX properties in its env var. Its not the end of the world obviously, but it would be nice to not have the risk of a feature changing because params were not reapplied properly, besides the basic enabled true false. Basically having a single feature flag, and not 1+ whatever is manually configured and/or overridden |
Can you only enable / disable from env var? |
Yes, some are by default to "true" in the application.properties. Some needs to be toggled via env var. |
Ok, for now, you can use the same validation trick we discussed in Quarkus. Create your customizer and internally, create a new With the config, you can now query for the expected configuration and add / remove mappings from the original builder. The downside is that you create some additional objects (and read the sources multiple times), but it is usually fast and maybe good enough until we have a proper solution. |
I tried the above and unfortunately I cannot remove the Customizer. I tried a little something like this public class CustomConfigBuilder implements SmallRyeConfigBuilderCustomizer {
@Override
public void configBuilder(SmallRyeConfigBuilder builder) {
var test = builder.isAddDiscoveredCustomizers();
var conf = builder.build();
boolean isEnabled = conf.getValue("feature.enabled", boolean.class);
builder.withMappingIgnore("feature");
}
} compare to other the customizer does not have a |
I tried a bit more by modifying SR Config without much success;; changes in SR config end code looks like this; public void configBuilder(SmallRyeConfigBuilder builder) {
log.error("xxxxxxxx I AM HERE xxxxxxx ");
var conf = builder.setAddDiscoveredCustomizers(false).withCustomizerIgnore(this).build();
builder.setAddDiscoveredCustomizers(true);
boolean isEnabled = conf.getValue("feature.enabled", boolean.class);
if (!isEnabled) {
builder.withMappingIgnore("feature.**");
}
} I am using logs
|
This heavily relates to; #845
I have some ConfigMapping that are feature related. Those feature are enabled/disabled via .enabled=[true|false]
those ConfigMapping are used "lazily" in ApplicationScoped bean that are using Instance<> and LookupIfProperty() mechanism in quarkus.
I wish that if the enabled flag is false, all of
feature.**.*
get nullified to I don't have a startup error. I do not know / want to specify manually all the configs to be nullyfied, nor I want to force people to go and remove all their feature related config, they should just toggle the enabled/disable so they don't have to fully reconfigure the feature.I tried using an interceptor, but it does not work, as the ConfigMapping does not "load" values "/ usees interceptor..
but in soft the logic I had taht I would kike somehow to apply to the config mapping is the following;
Hope it is somewhat clear, I have created a little app here https://github.com/manofthepeace/opt-configmapping to show the structure, with a super simple mapping, in my app the config are far more complex with lots of nesting.
Obviously the above interceptor is wrong for the job, but its what I would like to achieve in a nutshell. Options welcome :) thanks
The text was updated successfully, but these errors were encountered: