-
Notifications
You must be signed in to change notification settings - Fork 428
feat/OAK-12253 : add a mechanism to override FT defaults via system property #2947
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
base: trunk
Are you sure you want to change the base?
Changes from all commits
1e210a2
98b38ac
336e897
502a6cb
089193f
fd03ba9
1f772a2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -22,8 +22,11 @@ | |||||
| import java.util.Collections; | ||||||
| import java.util.concurrent.atomic.AtomicBoolean; | ||||||
|
|
||||||
| import org.apache.jackrabbit.oak.commons.properties.SystemPropertySupplier; | ||||||
| import org.apache.jackrabbit.oak.spi.whiteboard.Registration; | ||||||
| import org.apache.jackrabbit.oak.spi.whiteboard.Whiteboard; | ||||||
| import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | ||||||
|
|
||||||
| /** | ||||||
| * A feature toggle to control new functionality. The default state of a feature | ||||||
|
|
@@ -34,12 +37,20 @@ | |||||
| * involves registering a feature toggle on the {@link Whiteboard} and | ||||||
| * potentially comes with some overhead (e.g. when the whiteboard is based on | ||||||
| * OSGi). Therefore, client code should not create a new feature, check the | ||||||
| * state and then immediately release/close it again. Instead a feature should | ||||||
| * state and then immediately release/close it again. Instead, a feature should | ||||||
| * be acquired initially, checked at runtime whenever needed and finally | ||||||
| * released when the client component is destroyed. | ||||||
| * <p> | ||||||
| * The default state of {@code false} can be overridden by a system property | ||||||
| * using {@linkplain #newFeatureWithSystemPropertyDefault(String, Whiteboard)}, | ||||||
| * in which case The property name is derived from the toggle name. This helps to quickly verify | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
| * a new feature. For a toggle named {@code "foo"}, the system property name is | ||||||
| * {@code oak-feature.foo}. | ||||||
| */ | ||||||
| public final class Feature implements Closeable { | ||||||
|
|
||||||
| private static final Logger LOG = LoggerFactory.getLogger(Feature.class); | ||||||
|
|
||||||
| private final AtomicBoolean value; | ||||||
|
|
||||||
| private final Registration registration; | ||||||
|
|
@@ -49,6 +60,16 @@ | |||||
| this.registration = registration; | ||||||
| } | ||||||
|
|
||||||
| private static Feature internalNewFeatureWithSystemPropertyDefault(String name, Whiteboard whiteboard, boolean withSysPropDefault) { | ||||||
| // by default the initial value is false, but it can be overridden by a system property | ||||||
| AtomicBoolean value = withSysPropDefault ? new AtomicBoolean( | ||||||
| SystemPropertySupplier.create("oak-feature." + name, false). | ||||||
|
Check failure on line 66 in oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
|
||||||
| loggingTo(LOG).get()) : new AtomicBoolean(); | ||||||
| FeatureToggle adapter = new FeatureToggle(name, value); | ||||||
| return new Feature(value, whiteboard.register( | ||||||
| FeatureToggle.class, adapter, Collections.emptyMap())); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Creates a new {@link Feature} with the given name and registers the | ||||||
| * corresponding {@link FeatureToggle} on the {@link Whiteboard}. | ||||||
|
|
@@ -60,10 +81,15 @@ | |||||
| * @return the feature toggle. | ||||||
| */ | ||||||
| public static Feature newFeature(String name, Whiteboard whiteboard) { | ||||||
| AtomicBoolean value = new AtomicBoolean(); | ||||||
| FeatureToggle adapter = new FeatureToggle(name, value); | ||||||
| return new Feature(value, whiteboard.register( | ||||||
| FeatureToggle.class, adapter, Collections.emptyMap())); | ||||||
| return internalNewFeatureWithSystemPropertyDefault(name, whiteboard, false); | ||||||
| } | ||||||
|
|
||||||
| /** | ||||||
| * Same as {@linkplain #newFeature(String, Whiteboard)}, but with the initial state provided | ||||||
| * by a system property, named based on the feature's name. | ||||||
| */ | ||||||
| public static Feature newFeatureWithSystemPropertyDefault(String name, Whiteboard whiteboard) { | ||||||
| return internalNewFeatureWithSystemPropertyDefault(name, whiteboard, true); | ||||||
|
Check failure on line 92 in oak-core-spi/src/main/java/org/apache/jackrabbit/oak/spi/toggle/Feature.java
|
||||||
| } | ||||||
|
|
||||||
| /** | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,7 @@ | |
| import org.junit.Test; | ||
|
|
||
| import static org.apache.jackrabbit.oak.spi.toggle.Feature.newFeature; | ||
| import static org.apache.jackrabbit.oak.spi.toggle.Feature.newFeatureWithSystemPropertyDefault; | ||
| import static org.hamcrest.CoreMatchers.hasItems; | ||
| import static org.hamcrest.Matchers.empty; | ||
| import static org.hamcrest.core.Is.is; | ||
|
|
@@ -50,6 +51,28 @@ public void disabledByDefault() { | |
| } | ||
| } | ||
|
|
||
| @Test | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional (for local consideration only — not pushing code): /**
* SystemPropertySupplier uses {@link Boolean#valueOf(String)} for boolean props: only
* {@code "true"} (case-insensitive) enables the toggle; values like {@code "yes"} or
* {@code "garbage"} are treated as {@code false}, not as a parse error.
*/
@Test
public void defaultOverriddenWithNonTrueValueStaysDisabled() {
String sysPropName = "oak-feature.my.toggle";
for (String value : new String[] {"garbage", "yes", "1", "on", ""}) {
System.setProperty(sysPropName, value);
try (Feature feature = newFeatureWithSystemPropertyDefault("my.toggle", whiteboard)) {
assertFalse("property value '" + value + "' must not enable the toggle", feature.isEnabled());
} finally {
System.clearProperty(sysPropName);
}
}
} |
||
| public void defaultOverriddenAsTrue() { | ||
| String sysPropName = "oak-feature.my.toggle"; | ||
| System.setProperty(sysPropName, "true"); | ||
| try (Feature feature = newFeatureWithSystemPropertyDefault("my.toggle", whiteboard)) { | ||
| assertTrue(feature.isEnabled()); | ||
| } finally { | ||
| System.clearProperty(sysPropName); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void defaultOverriddenAsFalse() { | ||
| String sysPropName = "oak-feature.my.toggle"; | ||
| System.setProperty(sysPropName, "false"); | ||
| try (Feature feature = newFeatureWithSystemPropertyDefault("my.toggle", whiteboard)) { | ||
| assertFalse(feature.isEnabled()); | ||
| } finally { | ||
| System.clearProperty(sysPropName); | ||
| } | ||
| } | ||
|
|
||
| @Test | ||
| public void register() { | ||
| try (Feature feature = newFeature("my.toggle", whiteboard)) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.