-
Couldn't load subscription status.
- Fork 2.3k
Description
Describe the bug
A clear and concise description of what the bug is.
The feature flags used for experimental are defined here. This below example creates an setting static object with the feature flag name and default value.
public static final Setting<Boolean> IDENTITY_SETTING = Setting.boolSetting(IDENTITY, false, Property.NodeScope);
However, if the feature flag is not specified as an env variable or written in the yml file, the FeatureFlags.isEnabled method does not read the value from these static settings and instead sets to 'false' by default.
/**
* Used to test feature flags whose values are expected to be booleans.
* This method returns true if the value is "true" (case-insensitive),
* and false otherwise.
*/
public static boolean isEnabled(String featureFlagName) {
if ("true".equalsIgnoreCase(System.getProperty(featureFlagName))) {
// TODO: Remove the if condition once FeatureFlags are only supported via opensearch.yml
return true;
}
return settings != null && settings.getAsBoolean(featureFlagName, false);
}
Because these feature flag settings are never initialized / registered during node boostrap, it causes the difficulty when adding a static setting with the default value of true to keep the feature enabled but still gated behind the flag.
For example on node.java, if the default value on FeatureFlags.IDENTITY is set to true, the FeatureFlags.isEnabled will always return false.
final Settings settings = pluginsService.updatedSettings();
// Ensure to initialize Feature Flags via the settings from opensearch.yml
FeatureFlags.initializeFeatureFlags(settings);
final List<IdentityPlugin> identityPlugins = new ArrayList<>();
if (FeatureFlags.isEnabled(FeatureFlags.IDENTITY)) {
...
# this condition will never entered
}
To Reproduce
Steps to reproduce the behavior:
- Set any feature flag (for example IDENTITY_SETTING) default value to
truepublic static final Setting<Boolean> IDENTITY_SETTING = Setting.boolSetting(IDENTITY, false, Property.NodeScope); - Add logs around FeatureFlags.isEnabled method usage during node bootstrap
OpenSearch/server/src/main/java/org/opensearch/node/Node.java
Lines 467 to 473 in 8cfde6c
final Settings settings = pluginsService.updatedSettings(); // Ensure to initialize Feature Flags via the settings from opensearch.yml FeatureFlags.initializeFeatureFlags(settings); final List<IdentityPlugin> identityPlugins = new ArrayList<>(); if (FeatureFlags.isEnabled(FeatureFlags.IDENTITY)) {
# Example logging
logger.info("louis-feature-flag-test: " + FeatureFlags.IDENTITY + " value: " + settings.get(FeatureFlags.IDENTITY));
if (FeatureFlags.isEnabled(FeatureFlags.IDENTITY)) {
// If identity is enabled load plugins implementing the extension point
logger.info("Identity on so found plugins implementing: " + pluginsService.filterPlugins(IdentityPlugin.class).toString());
identityPlugins.addAll(pluginsService.filterPlugins(IdentityPlugin.class));
}
- Start cluster
./gradlew run --debug-server-jvm --info
- See error
[2023-08-25T12:46:29,937][INFO ][o.o.n.Node ] [runTask-0] louis-feature-flag-test: opensearch.experimental.feature.identity.enabled value: null
[2023-08-25T12:46:29,938][INFO ][o.o.n.Node ] [runTask-0] louis-feature-flag-test: opensearch.experimental.feature.extensions.enabled value: null
Expected behavior
A clear and concise description of what you expected to happen.
Some options here
- Disallow the use case of adding a static setting with the default value of 'true' in order to keep the feature enabled but still gated behind the flag: We could limit the feature flag's functionality by concealing the default_value during static setting construction. The default value is then set to always
false. On public doc and java doc, we should explictly mention that flags are required to be removed when you want to enable the feature. - FeatureFlags.isEnabled reads the setting object's real default_value.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status