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);
+        }
+    }
 }

Reply via email to