Connected config gathering to CloudStack

Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/49cd4fa3
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/49cd4fa3
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/49cd4fa3

Branch: refs/heads/master
Commit: 49cd4fa380dcea548b50987ddf15c38031615f4e
Parents: 90cfca0
Author: Alex Huang <alex.hu...@citrix.com>
Authored: Tue Aug 6 11:03:38 2013 -0700
Committer: Alex Huang <alex.hu...@citrix.com>
Committed: Wed Aug 7 16:41:04 2013 -0700

----------------------------------------------------------------------
 .../apache/cloudstack/config/Configuration.java | 63 ++++++++++++++++++--
 .../com/cloud/cluster/ClusterManagerImpl.java   |  4 +-
 .../cluster/ClusterServiceServletAdapter.java   |  2 +-
 .../framework/config/ConfigDepot.java           |  2 +
 .../framework/config/ConfigDepotAdmin.java      |  7 +++
 .../framework/config/ConfigDepotImpl.java       | 29 ++++++++-
 .../cloudstack/framework/config/ConfigKey.java  | 12 ++--
 .../framework/config/Configurable.java          |  8 +++
 .../framework/config/ConfigurationVO.java       |  2 +-
 .../framework/config/ScopedConfigValue.java     | 43 +++++++++++++
 .../cloud/agent/manager/AgentManagerImpl.java   | 13 ++--
 .../manager/ClusteredAgentManagerImpl.java      |  8 +--
 .../cloud/server/ConfigurationServerImpl.java   |  4 ++
 13 files changed, 166 insertions(+), 31 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/api/src/org/apache/cloudstack/config/Configuration.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/config/Configuration.java 
b/api/src/org/apache/cloudstack/config/Configuration.java
index 8657832..97cc8c4 100644
--- a/api/src/org/apache/cloudstack/config/Configuration.java
+++ b/api/src/org/apache/cloudstack/config/Configuration.java
@@ -16,18 +16,69 @@
 // under the License.
 package org.apache.cloudstack.config;
 
+import java.util.Date;
+
+/**
+ * Configuration represents one global configuration parameter for CloudStack.
+ * Its scope should indicate whether this parameter can be set at different
+ * organization levels in CloudStack.
+ *
+ */
 public interface Configuration {
 
-    public String getCategory();
+    /**
+     * @return Category of the parameter.
+     */
+    String getCategory();
+
+    /**
+     * @return Server instance that uses this parameter.
+     */
+    String getInstance();
+
+    /**
+     * @return Component that introduced this parameter.
+     */
+    String getComponent();
+
+    /**
+     * @return Name of the parameter.
+     */
+    String getName();
 
-    public String getInstance();
+    /**
+     * @return Value set by the administrator.  Defaults to the defaultValue.
+     */
+    String getValue();
 
-    public String getComponent();
+    /**
+     * @return Description of the value and the range of the value.
+     */
+    String getDescription();
 
-    public String getName();
+    /**
+     * @return Default value for this parameter.  Cannot be null.
+     */
+    String getDefaultValue();
 
-    public String getValue();
+    /**
+     * @return Scope for the parameter.  Null indicates that this parameter is
+     * always global.  A non-null value indicates that this parameter can be
+     * set at a certain organization level.
+     */
+    String getScope();
 
-    public String getDescription();
+    /**
+     * @return can the configuration parameter be changed without restarting 
the server.
+     */
+    boolean isDynamic();
 
+    /**
+     * @return The date this VO was updated by the components.  Note that this 
is not
+     * a date for when an administrator updates the value.  This is when the 
system
+     * updated this value.  By searching on this field gives you all the config
+     * parameters that have changed in an upgrade.  Null value indicates that 
this
+     * parameter is no longer used and can be deleted.
+     */
+    Date getUpdated();
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
----------------------------------------------------------------------
diff --git a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java 
b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
index 046a1dc..41b619c 100644
--- a/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
+++ b/framework/cluster/src/com/cloud/cluster/ClusterManagerImpl.java
@@ -1028,9 +1028,9 @@ public class ClusterManagerImpl extends ManagerBase 
implements ClusterManager {
     }
 
     protected final ConfigKey<Integer> HeartBeatInterval = new 
ConfigKey<Integer>(Integer.class, "cluster.heartbeat.interval", 
"management-server",
-            "1500", "Interval to check for the heart beat between management 
server nodes", false, "Seconds");
+            "1500", "Interval to check for the heart beat between management 
server nodes", false);
     protected final ConfigKey<Integer> HeartBeatThreshold = new 
ConfigKey<Integer>(Integer.class, "cluster.heartbeat.threshold", 
"management-server",
-            "150000", "Threshold before self-fence the management server", 
true, "Seconds");
+            "150000", "Threshold before self-fence the management server", 
true);
     
     @Override
     public boolean configure(String name, Map<String, Object> params) throws 
ConfigurationException {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java
----------------------------------------------------------------------
diff --git 
a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java 
b/framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java
index fc86e4d..87e92f5 100644
--- a/framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java
+++ b/framework/cluster/src/com/cloud/cluster/ClusterServiceServletAdapter.java
@@ -126,7 +126,7 @@ public class ClusterServiceServletAdapter extends 
AdapterBase implements Cluster
     }
     
     private final ConfigKey<Integer> ClusterMessageTimeOut = new 
ConfigKey<Integer>(Integer.class, "cluster.message.timeout.seconds", "Advance", 
"300",
-            "Time (in seconds) to wait before a inter-management server 
message post times out.", true, "Seconds");
+            "Time (in seconds) to wait before a inter-management server 
message post times out.", true);
 
     private void init() throws ConfigurationException {
        if(_mshostDao != null)

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java
index e2c1305..98363f3 100644
--- 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java
+++ 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepot.java
@@ -22,4 +22,6 @@ package org.apache.cloudstack.framework.config;
  */
 public interface ConfigDepot {
     <T> ConfigValue<T> get(ConfigKey<T> key);
+    
+    <T> ScopedConfigValue<T> getScopedValue(ConfigKey<T> key);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
index 8dac77f..b4d3773 100644
--- 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
+++ 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotAdmin.java
@@ -23,6 +23,13 @@ import java.util.List;
  *
  */
 public interface ConfigDepotAdmin {
+    /**
+     * Create configurations if there are new config parameters.
+     * Update configurations if the parameter settings have been changed.
+     * All configurations that have been updated/created will have the same 
timestamp in the updated field.
+     * All previous configurations that should be obsolete will have a null 
updated field.
+     * @see Configuration
+     */
     void populateConfigurations();
 
     List<String> getComponentsInDepot();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotImpl.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotImpl.java
 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotImpl.java
index 42b4ab6..df79d9d 100644
--- 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotImpl.java
+++ 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigDepotImpl.java
@@ -27,7 +27,25 @@ import 
org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import com.cloud.utils.db.EntityManager;
 
 /**
- * DepotImpl implements the ConfigDepot interface
+ * ConfigDepotImpl implements the ConfigDepot and ConfigDepotAdmin interface.
+ * Its functionalities include:
+ *   - Control how dynamic config values are cached and refreshed.
+ *   - Control how scoped config values are stored.
+ *   - Gather all of the Configurable interfaces and insert their config
+ *     variables into the config table.
+ *   - Hide the data source where configs are stored and retrieved.
+ * 
+ * When dealing with this class, we must be very careful on cluster situations.
+ *
+ * TODO:
+ *   - Move the rest of the changes to the config table to here.
+ *   - Implement ScopedConfigValue
+ *   - Move the code to set scoped configuration values to here.
+ *   - Add the code to mark the rows in configuration table without
+ *     the corresponding keys to be null.
+ *   - Move all of the configurations to using ConfigDepot
+ *   - Completely eliminate Config.java
+ *   - Figure out the correct categories.
  *
  */
 class ConfigDepotImpl implements ConfigDepot, ConfigDepotAdmin {
@@ -49,6 +67,13 @@ class ConfigDepotImpl implements ConfigDepot, 
ConfigDepotAdmin {
     }
     
     @Override
+    public <T> ScopedConfigValue<T> getScopedValue(ConfigKey<T> config) {
+        assert (config.scope() != null) : "Did you notice the configuration 
you're trying to retrieve is not scoped?";
+        return new ScopedConfigValue<T>(_entityMgr, config);
+    }
+
+
+    @Override
     public void populateConfigurations() {
         Date date = new Date();
         for (Configurable configurable : _configurables) {
@@ -70,8 +95,6 @@ class ConfigDepotImpl implements ConfigDepot, 
ConfigDepotAdmin {
                     }
                 }
             }
-
-            // TODO: Missing code to remove the updated field if the a 
configurationVO's name cannot be found any more.
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java
index f47d302..cef226c 100644
--- a/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java
+++ b/framework/config/src/org/apache/cloudstack/framework/config/ConfigKey.java
@@ -16,14 +16,12 @@
 // under the License.
 package org.apache.cloudstack.framework.config;
 
+import com.cloud.org.Grouping;
+
 /**
  * ConfigKey supplants the original Config.java.  It is just a class
  * declaration where others can declare their config variables.
  * 
- * TODO: This class should be moved to a framework project where the gathering
- *       of these configuration keys should be done by a config server.  I
- *       don't have time yet to do this.  Ask me about it if you want to work
- *       in this area.  Right now, we'll just work with the actual names.
  */
 public class ConfigKey<T> {
     
@@ -49,7 +47,7 @@ public class ConfigKey<T> {
         return _description;
     }
 
-    public String scope() {
+    public Class<? extends Grouping> scope() {
         return _scope;
     }
 
@@ -66,11 +64,11 @@ public class ConfigKey<T> {
     private final String _name;
     private final String _defaultValue;
     private final String _description;
-    private final String _scope; // Parameter can be at different levels 
(Zone/cluster/pool/account), by default every parameter is at global
+    private final Class<? extends Grouping> _scope; // Parameter can be at 
different levels (Zone/cluster/pool/account), by default every parameter is at 
global
     private final boolean _isDynamic;
 
     public ConfigKey(Class<T> type, String name, String category, String 
defaultValue, String description, boolean isDynamic,
-            String scope) {
+            Class<? extends Grouping> scope) {
         _category = category;
         _type = type;
         _name = name;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/Configurable.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/Configurable.java 
b/framework/config/src/org/apache/cloudstack/framework/config/Configurable.java
index 8dc5af9..f99e8a1 100644
--- 
a/framework/config/src/org/apache/cloudstack/framework/config/Configurable.java
+++ 
b/framework/config/src/org/apache/cloudstack/framework/config/Configurable.java
@@ -16,6 +16,14 @@
 // under the License.
 package org.apache.cloudstack.framework.config;
 
+/**
+ * Configurable can be implemented by components to insert their own
+ * configuration keys.
+ * 
+ * CloudStack will gather all of these configurations at startup and insert
+ * them into the configuration table.
+ *
+ */
 public interface Configurable {
 
     String getConfigComponentName();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/ConfigurationVO.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigurationVO.java
 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigurationVO.java
index a21ccbc..ad2b582 100644
--- 
a/framework/config/src/org/apache/cloudstack/framework/config/ConfigurationVO.java
+++ 
b/framework/config/src/org/apache/cloudstack/framework/config/ConfigurationVO.java
@@ -80,7 +80,7 @@ public class ConfigurationVO implements Configuration {
         this(key.category(), "DEFAULT", component, key.key(), 
key.defaultValue(), key.description());
         defaultValue = key.defaultValue();
         dynamic = key.isDynamic();
-        scope = key.scope();
+        scope = key.scope().getName();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/framework/config/src/org/apache/cloudstack/framework/config/ScopedConfigValue.java
----------------------------------------------------------------------
diff --git 
a/framework/config/src/org/apache/cloudstack/framework/config/ScopedConfigValue.java
 
b/framework/config/src/org/apache/cloudstack/framework/config/ScopedConfigValue.java
new file mode 100644
index 0000000..4631521
--- /dev/null
+++ 
b/framework/config/src/org/apache/cloudstack/framework/config/ScopedConfigValue.java
@@ -0,0 +1,43 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.framework.config;
+
+import com.cloud.dc.DataCenter;
+import com.cloud.dc.Pod;
+import com.cloud.org.Cluster;
+import com.cloud.org.Grouping;
+import com.cloud.utils.db.EntityManager;
+
+public class ScopedConfigValue<T> extends ConfigValue<T> {
+    public T getValueForScope(long scopeId) {
+        // TODO: In order to complete this the details for zone, pod, cluster
+        // needs to have interfaces.  Then you can use the EntityManager to
+        // retrieve those information.
+        Class<? extends Grouping> scope = _config.scope();
+        if (scope == DataCenter.class) {
+        } else if (scope == Pod.class) {
+
+        } else if (scope == Cluster.class) {
+
+        }
+        return null;
+    }
+    
+    protected ScopedConfigValue(EntityManager entityMgr, ConfigKey<T> key) {
+        super(entityMgr, key);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/server/src/com/cloud/agent/manager/AgentManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/agent/manager/AgentManagerImpl.java 
b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
index 690c96e..01c2137 100755
--- a/server/src/com/cloud/agent/manager/AgentManagerImpl.java
+++ b/server/src/com/cloud/agent/manager/AgentManagerImpl.java
@@ -179,17 +179,16 @@ public class AgentManagerImpl extends ManagerBase 
implements AgentManager, Handl
     protected ConfigDepot _configDepot;
 
     protected final ConfigKey<Integer> Workers = new 
ConfigKey<Integer>(Integer.class, "workers", "Advance", "5",
-            "Number of worker threads handling remote agent connections.", 
false, "5-Max Thread Limit");
-    protected final ConfigKey<Integer> Port = new 
ConfigKey<Integer>(Integer.class, "port", "Advance", "8250", "Port to listen on 
for remote agent connections.", false,
-            "Usable port range");
+            "Number of worker threads handling remote agent connections.", 
false);
+    protected final ConfigKey<Integer> Port = new 
ConfigKey<Integer>(Integer.class, "port", "Advance", "8250", "Port to listen on 
for remote agent connections.", false);
     protected final ConfigKey<Integer> PingInterval = new 
ConfigKey<Integer>(Integer.class, "ping.interval", "Advance", "60",
-            "Interval to send application level pings to make sure the 
connection is still working", false, "Seconds");
+            "Interval to send application level pings to make sure the 
connection is still working", false);
     protected final ConfigKey<Float> PingTimeout = new 
ConfigKey<Float>(Float.class, "ping.timeout", "Advance", "2.5",
-            "Multiplier to ping.interval before announcing an agent has timed 
out", true, null);
+            "Multiplier to ping.interval before announcing an agent has timed 
out", true);
     protected final ConfigKey<Integer> Wait = new 
ConfigKey<Integer>(Integer.class, "wait", "Advance", "1800",
-            "Time in seconds to wait for control commands to return", true, 
"Seconds");
+            "Time in seconds to wait for control commands to return", true);
     protected final ConfigKey<Integer> AlertWait = new 
ConfigKey<Integer>(Integer.class, "alert.wait", "Advance", "1800",
-            "Seconds to wait before alerting on a disconnected agent", true, 
"Seconds");
+            "Seconds to wait before alerting on a disconnected agent", true);
     protected final ConfigKey<Integer> DirectAgentLoadSize = new 
ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advance", "16",
             "The number of direct agents to load each time", false, null);
     protected final ConfigKey<Integer> DirectAgentPoolSize = new 
ConfigKey<Integer>(Integer.class, "direct.agent.pool.size", "Advance", "500",

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java 
b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
index 506e640..742d798 100755
--- a/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
+++ b/server/src/com/cloud/agent/manager/ClusteredAgentManagerImpl.java
@@ -134,13 +134,13 @@ public class ClusteredAgentManagerImpl extends 
AgentManagerImpl implements Clust
     }
 
     protected final ConfigKey<Boolean> EnableLB = new 
ConfigKey<Boolean>(Boolean.class, "agent.lb.enabled", "Advanced", "false",
-            "Enable agent load balancing between management server nodes", 
true, "True/False");
+            "Enable agent load balancing between management server nodes", 
true);
     protected final ConfigKey<Double> ConnectedAgentThreshold = new 
ConfigKey<Double>(Double.class, "agent.load.threshold", "Advanced", "0.7",
-            "What percentage of the agents can be held by one management 
server before load balancing happens", true, "0-1");
+            "What percentage of the agents can be held by one management 
server before load balancing happens", true);
     protected final ConfigKey<Integer> LoadSize = new 
ConfigKey<Integer>(Integer.class, "direct.agent.load.size", "Advanced", "16",
-            "How many agents to connect to in each round", true, "");
+            "How many agents to connect to in each round", true);
     protected final ConfigKey<Integer> ScanInterval = new 
ConfigKey<Integer>(Integer.class, "direct.agent.scan.interval", "Advanced", 
"90",
-            "Interval between scans to load agents", false, "Seconds");
+            "Interval between scans to load agents", false);
     
 
     protected ConfigValue<Boolean> _agentLBEnabled;

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/49cd4fa3/server/src/com/cloud/server/ConfigurationServerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java 
b/server/src/com/cloud/server/ConfigurationServerImpl.java
index 98290f6..bc9b23d 100755
--- a/server/src/com/cloud/server/ConfigurationServerImpl.java
+++ b/server/src/com/cloud/server/ConfigurationServerImpl.java
@@ -46,6 +46,7 @@ import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.FileUtils;
 import org.apache.log4j.Logger;
 
+import org.apache.cloudstack.framework.config.ConfigDepotAdmin;
 import org.apache.cloudstack.framework.config.ConfigurationVO;
 import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
 import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
@@ -142,6 +143,8 @@ public class ConfigurationServerImpl extends ManagerBase 
implements Configuratio
     @Inject private ClusterDetailsDao _clusterDetailsDao;
     @Inject private StoragePoolDetailsDao _storagePoolDetailsDao;
     @Inject private AccountDetailsDao _accountDetailsDao;
+    @Inject
+    protected ConfigDepotAdmin _configDepotAdmin;
 
     public ConfigurationServerImpl() {
        setRunLevel(ComponentLifecycle.RUN_LEVEL_FRAMEWORK_BOOTSTRAP);
@@ -153,6 +156,7 @@ public class ConfigurationServerImpl extends ManagerBase 
implements Configuratio
 
                try {
                        persistDefaultValues();
+            _configDepotAdmin.populateConfigurations();
                } catch (InternalErrorException e) {
                        throw new RuntimeException("Unhandled configuration 
exception", e);
                }

Reply via email to