Feature-enablement: init from brooklyn properties
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ce168285 Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ce168285 Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ce168285 Branch: refs/heads/master Commit: ce168285ff8c71f460701e5d818c58c343dae64a Parents: c06a229 Author: Aled Sage <[email protected]> Authored: Thu Jan 8 21:19:31 2015 +0000 Committer: Aled Sage <[email protected]> Committed: Wed Jan 14 22:38:08 2015 +0000 ---------------------------------------------------------------------- .../internal/BrooklynFeatureEnablement.java | 47 ++++++++++++++++---- .../internal/LocalManagementContext.java | 10 ++++- .../internal/BrooklynFeatureEnablementTest.java | 27 +++++++++++ 3 files changed, 74 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ce168285/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java b/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java index 9946ac7..7ecd7cd 100644 --- a/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java +++ b/core/src/main/java/brooklyn/internal/BrooklynFeatureEnablement.java @@ -23,6 +23,7 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import brooklyn.config.BrooklynProperties; import brooklyn.internal.storage.BrooklynStorage; import brooklyn.management.ha.HighAvailabilityMode; import brooklyn.util.internal.ssh.ShellTool; @@ -43,27 +44,29 @@ public class BrooklynFeatureEnablement { private static final Logger LOG = LoggerFactory.getLogger(BrooklynFeatureEnablement.class); - public static final String FEATURE_POLICY_PERSISTENCE_PROPERTY = "brooklyn.experimental.feature.policyPersistence"; + public static final String FEATURE_PROPERTY_PREFIX = "brooklyn.experimental.feature"; - public static final String FEATURE_ENRICHER_PERSISTENCE_PROPERTY = "brooklyn.experimental.feature.enricherPersistence"; + public static final String FEATURE_POLICY_PERSISTENCE_PROPERTY = FEATURE_PROPERTY_PREFIX+".policyPersistence"; + + public static final String FEATURE_ENRICHER_PERSISTENCE_PROPERTY = FEATURE_PROPERTY_PREFIX+".enricherPersistence"; - public static final String FEATURE_FEED_PERSISTENCE_PROPERTY = "brooklyn.experimental.feature.feedPersistence"; + public static final String FEATURE_FEED_PERSISTENCE_PROPERTY = FEATURE_PROPERTY_PREFIX+".feedPersistence"; /** whether feeds are automatically registered when set on entities, so that they are persisted */ - public static final String FEATURE_FEED_REGISTRATION_PROPERTY = "brooklyn.experimental.feature.feedRegistration"; + public static final String FEATURE_FEED_REGISTRATION_PROPERTY = FEATURE_PROPERTY_PREFIX+".feedRegistration"; - public static final String FEATURE_CATALOG_PERSISTENCE_PROPERTY = "brooklyn.experimental.feature.catalogPersistence"; + public static final String FEATURE_CATALOG_PERSISTENCE_PROPERTY = FEATURE_PROPERTY_PREFIX+".catalogPersistence"; /** whether the default standby mode is {@link HighAvailabilityMode#HOT_STANDBY} or falling back to the traditional * {@link HighAvailabilityMode#STANDBY} */ - public static final String FEATURE_DEFAULT_STANDBY_IS_HOT_PROPERTY = "brooklyn.experimental.feature.defaultStandbyIsHot"; + public static final String FEATURE_DEFAULT_STANDBY_IS_HOT_PROPERTY = FEATURE_PROPERTY_PREFIX+".defaultStandbyIsHot"; /** whether to attempt to use {@link BrooklynStorage} (datagrid) as a backing store for data; * note this is <b>not</b> compatible with {@link #FEATURE_DEFAULT_STANDBY_IS_HOT_PROPERTY} * which uses a blob/file store and a larger-granularity rebind process than was intended with the datagrid */ /* not sure if we still even need this? now the rebind/read-only feature reloads on demand from the persistence store; * the data-grid backing */ - public static final String FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE = "brooklyn.experimental.feature.useBrooklynLiveObjectsDatagridStorage"; + public static final String FEATURE_USE_BROOKLYN_LIVE_OBJECTS_DATAGRID_STORAGE = FEATURE_PROPERTY_PREFIX+".useBrooklynLiveObjectsDatagridStorage"; /** * Renaming threads can really helps with debugging etc; however it's a massive performance hit (2x) @@ -91,7 +94,7 @@ public class BrooklynFeatureEnablement { * If this feature is disabled, then even if the {@link ShellTool#PROP_EXEC_ASYNC} is configured it * will still use the classic ssh approach. */ - public static final String FEATURE_SSH_ASYNC_EXEC = "brooklyn.experimental.feature.ssh.asyncExec"; + public static final String FEATURE_SSH_ASYNC_EXEC = FEATURE_PROPERTY_PREFIX+".ssh.asyncExec"; private static final Map<String, Boolean> FEATURE_ENABLEMENTS = Maps.newLinkedHashMap(); @@ -118,6 +121,34 @@ public class BrooklynFeatureEnablement { setDefaults(); } + /** + * Initialises the feature-enablement from brooklyn properties. For each + * property, prefer a system-property if present; otherwise use the value + * from brooklyn properties. + */ + public static void init(BrooklynProperties props) { + boolean changed = false; + for (Map.Entry<String, Object> entry : props.asMapWithStringKeys().entrySet()) { + String property = entry.getKey(); + if (property.startsWith(FEATURE_PROPERTY_PREFIX)) { + if (!FEATURE_ENABLEMENTS.containsKey(property)) { + Object rawVal = System.getProperty(property); + if (rawVal == null) { + rawVal = entry.getValue(); + } + boolean val = Boolean.parseBoolean(""+rawVal); + FEATURE_ENABLEMENTS.put(property, val); + + changed = true; + LOG.debug("Init feature enablement of "+property+" set to "+val); + } + } + } + if (!changed) { + LOG.debug("Init feature enablement did nothing, as no settings in brooklyn properties"); + } + } + public static boolean isEnabled(String property) { synchronized (MUTEX) { if (!FEATURE_ENABLEMENTS.containsKey(property)) { http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ce168285/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java b/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java index 257e1f6..202e4a6 100644 --- a/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java +++ b/core/src/main/java/brooklyn/management/internal/LocalManagementContext.java @@ -44,6 +44,7 @@ import brooklyn.entity.effector.Effectors; import brooklyn.entity.proxying.InternalEntityFactory; import brooklyn.entity.proxying.InternalLocationFactory; import brooklyn.entity.proxying.InternalPolicyFactory; +import brooklyn.internal.BrooklynFeatureEnablement; import brooklyn.internal.storage.DataGridFactory; import brooklyn.location.Location; import brooklyn.management.AccessController; @@ -171,16 +172,19 @@ public class LocalManagementContext extends AbstractManagementContext { public LocalManagementContext(Builder builder, Map<String, Object> brooklynAdditionalProperties, DataGridFactory datagridFactory) { super(builder.build(), datagridFactory); + + checkNotNull(configMap, "brooklynProperties"); + // TODO in a persisted world the planeId may be injected this.managementPlaneId = Strings.makeRandomId(8); - this.managementNodeId = Strings.makeRandomId(8); - checkNotNull(configMap, "brooklynProperties"); this.builder = builder; this.brooklynAdditionalProperties = brooklynAdditionalProperties; if (brooklynAdditionalProperties != null) configMap.addFromMap(brooklynAdditionalProperties); + BrooklynFeatureEnablement.init(configMap); + this.locationManager = new LocalLocationManager(this); this.accessManager = new LocalAccessManager(); this.usageManager = new LocalUsageManager(this); @@ -385,6 +389,8 @@ public class LocalManagementContext extends AbstractManagementContext { clearLocationRegistry(); + BrooklynFeatureEnablement.init(configMap); + // Notify listeners that properties have been reloaded for (PropertiesReloadListener listener : reloadListeners) { listener.reloaded(); http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ce168285/core/src/test/java/brooklyn/internal/BrooklynFeatureEnablementTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/brooklyn/internal/BrooklynFeatureEnablementTest.java b/core/src/test/java/brooklyn/internal/BrooklynFeatureEnablementTest.java index 38b9ee5..ea0fed6 100644 --- a/core/src/test/java/brooklyn/internal/BrooklynFeatureEnablementTest.java +++ b/core/src/test/java/brooklyn/internal/BrooklynFeatureEnablementTest.java @@ -25,6 +25,8 @@ import static org.testng.Assert.assertTrue; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import brooklyn.config.BrooklynProperties; + public class BrooklynFeatureEnablementTest { @BeforeMethod(alwaysRun=true) @@ -88,4 +90,29 @@ public class BrooklynFeatureEnablementTest { System.clearProperty(featureProperty); } } + + @Test + public void testCanSetDefaultWhichIsIgnoredIfBrooklynProps() throws Exception { + String featureProperty = "brooklyn.experimental.feature.testCanSetDefaultWhichIsIgnoredIfBrooklynProps"; + BrooklynProperties props = BrooklynProperties.Factory.newEmpty(); + props.put(featureProperty, false); + BrooklynFeatureEnablement.init(props); + BrooklynFeatureEnablement.setDefault(featureProperty, true); + assertFalse(BrooklynFeatureEnablement.isEnabled(featureProperty)); + } + + @Test + public void testPrefersSysPropOverBrooklynProps() throws Exception { + String featureProperty = "brooklyn.experimental.feature.testPrefersSysPropOverBrooklynProps"; + BrooklynProperties props = BrooklynProperties.Factory.newEmpty(); + props.put(featureProperty, false); + System.setProperty(featureProperty, "true"); + try { + BrooklynFeatureEnablement.init(props); + BrooklynFeatureEnablement.setDefault(featureProperty, true); + assertTrue(BrooklynFeatureEnablement.isEnabled(featureProperty)); + } finally { + System.clearProperty(featureProperty); + } + } }
