You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@helix.apache.org by ki...@apache.org on 2012/10/25 01:14:57 UTC

[5/42] Refactoring the package names and removing jsql parser

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixAdmin.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixAdmin.java b/helix-core/src/main/java/org/apache/helix/HelixAdmin.java
new file mode 100644
index 0000000..2d6539a
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixAdmin.java
@@ -0,0 +1,387 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.helix.ConfigScope.ConfigScopeProperty;
+import org.apache.helix.model.ExternalView;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.StateModelDefinition;
+
+
+public interface HelixAdmin
+{
+  /**
+   * Get a list of clusters under "/"
+   * 
+   * @return
+   */
+  List<String> getClusters();
+
+  /**
+   * Get a list of instances under a cluster
+   * 
+   * @param clusterName
+   * @return
+   */
+  List<String> getInstancesInCluster(String clusterName);
+
+  /**
+   * Get instance configs
+   * 
+   * @param clusterName
+   * @param instanceName
+   * @return
+   */
+  InstanceConfig getInstanceConfig(String clusterName, String instanceName);
+
+  /**
+   * Get a list of resources in a cluster
+   * 
+   * @param clusterName
+   * @return
+   */
+  List<String> getResourcesInCluster(String clusterName);
+
+  /**
+   * Add a cluster
+   * 
+   * @param clusterName
+   * @param overwritePrevRecord
+   */
+  void addCluster(String clusterName, boolean overwritePrevRecord);
+
+  /**
+   * Add a cluster and also add this cluster as a resource group in the super cluster
+   * 
+   * @param clusterName
+   * @param grandCluster
+   */
+  void addClusterToGrandCluster(String clusterName, String grandCluster);
+
+  /**
+   * Add a resource to a cluster, using the default ideal state mode AUTO
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param numResources
+   * @param stateModelRef
+   */
+  void addResource(String clusterName,
+                   String resourceName,
+                   int numResources,
+                   String stateModelRef);
+
+  /**
+   * Add a resource to a cluster
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param numResources
+   * @param stateModelRef
+   * @param idealStateMode
+   */
+  void addResource(String clusterName,
+                   String resourceName,
+                   int numResources,
+                   String stateModelRef,
+                   String idealStateMode);
+
+  /**
+   * Add a resource to a cluster, using a bucket size > 1
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param numResources
+   * @param stateModelRef
+   * @param idealStateMode
+   * @param bucketSize
+   */
+  void addResource(String clusterName,
+                   String resourceName,
+                   int numResources,
+                   String stateModelRef,
+                   String idealStateMode,
+                   int bucketSize);
+
+  /**
+   * Add an instance to a cluster
+   * 
+   * @param clusterName
+   * @param instanceConfig
+   */
+  void addInstance(String clusterName, InstanceConfig instanceConfig);
+
+  /**
+   * Drop an instance from a cluster
+   * 
+   * @param clusterName
+   * @param instanceConfig
+   */
+  void dropInstance(String clusterName, InstanceConfig instanceConfig);
+
+  /**
+   * Get ideal state for a resource
+   * 
+   * @param clusterName
+   * @param dbName
+   * @return
+   */
+  IdealState getResourceIdealState(String clusterName, String dbName);
+
+  /**
+   * Set ideal state for a resource
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param idealState
+   */
+  void setResourceIdealState(String clusterName,
+                             String resourceName,
+                             IdealState idealState);
+
+  /**
+   * Disable or enable an instance
+   * 
+   * @param clusterName
+   * @param instanceName
+   * @param enabled
+   */
+  void enableInstance(String clusterName, String instanceName, boolean enabled);
+
+  /**
+   * Disable or enable a list of partitions on an instance
+   * 
+   * @param enabled
+   * @param clusterName
+   * @param instanceName
+   * @param resourceName
+   * @param partitionNames
+   */
+  void enablePartition(boolean enabled,
+                       String clusterName,
+                       String instanceName,
+                       String resourceName,
+                       List<String> partitionNames);
+
+  /**
+   * Disable or enable a cluster
+   * 
+   * @param clusterName
+   * @param enabled
+   */
+  void enableCluster(String clusterName, boolean enabled);
+
+  /**
+   * Reset a list of partitions in error state for an instance
+   * 
+   * The partitions are assume to be in error state and reset will bring them from error
+   * to initial state. An error to initial state transition is required for reset.
+   * 
+   * @param clusterName
+   * @param instanceName
+   * @param resourceName
+   * @param partitionNames
+   */
+  void resetPartition(String clusterName,
+                      String instanceName,
+                      String resourceName,
+                      List<String> partitionNames);
+
+  /**
+   * Reset all the partitions in error state for a list of instances
+   * 
+   * @param clusterName
+   * @param instanceNames
+   */
+  void resetInstance(String clusterName, List<String> instanceNames);
+
+  /**
+   * Reset all partitions in error state for a list of resources
+   * 
+   * @param clusterName
+   * @param resourceNames
+   */
+  void resetResource(String clusterName, List<String> resourceNames);
+
+  /**
+   * Add a state model definition
+   * 
+   * @param clusterName
+   * @param stateModelDef
+   * @param record
+   */
+  void addStateModelDef(String clusterName,
+                        String stateModelDef,
+                        StateModelDefinition record);
+
+  /**
+   * Drop a resource from a cluster
+   * 
+   * @param clusterName
+   * @param resourceName
+   */
+  void dropResource(String clusterName, String resourceName);
+
+  /**
+   * Add a statistics to a cluster
+   * 
+   * @param clusterName
+   * @param statName
+   */
+  void addStat(String clusterName, String statName);
+
+  /**
+   * Add an alert to a cluster
+   * 
+   * @param clusterName
+   * @param alertName
+   */
+  void addAlert(String clusterName, String alertName);
+
+  /**
+   * Drop a statistics from a cluster
+   * 
+   * @param clusterName
+   * @param statName
+   */
+  void dropStat(String clusterName, String statName);
+
+  /**
+   * Drop an alert from a cluster
+   * 
+   * @param clusterName
+   * @param alertName
+   */
+  void dropAlert(String clusterName, String alertName);
+
+  /**
+   * Get a list of state model definitions in a cluster
+   * 
+   * @param clusterName
+   * @return
+   */
+  List<String> getStateModelDefs(String clusterName);
+
+  /**
+   * Get a state model definition in a cluster
+   * 
+   * @param clusterName
+   * @param stateModelName
+   * @return
+   */
+  StateModelDefinition getStateModelDef(String clusterName, String stateModelName);
+
+  /**
+   * Get external view for a resource
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @return
+   */
+  ExternalView getResourceExternalView(String clusterName, String resourceName);
+
+  /**
+   * Drop a cluster
+   * 
+   * @param clusterName
+   */
+  void dropCluster(String clusterName);
+
+  /**
+   * Set configuration values
+   * 
+   * @param scope
+   * @param properties
+   */
+  void setConfig(ConfigScope scope, Map<String, String> properties);
+
+  /**
+   * Remove configuration values
+   * 
+   * @param scope
+   * @param keys
+   */
+  void removeConfig(ConfigScope scope, Set<String> keys);
+
+  /**
+   * Get configuration values
+   * 
+   * @param scope
+   * @param keys
+   * @return
+   */
+  Map<String, String> getConfig(ConfigScope scope, Set<String> keys);
+
+  /**
+   * Get configuration keys
+   * 
+   * @param scope
+   * @param clusterName
+   * @param keys
+   * @return
+   */
+  List<String> getConfigKeys(ConfigScopeProperty scope,
+                             String clusterName,
+                             String... keys);
+
+  /**
+   * Rebalance a resource in cluster
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param replica
+   * @param keyPrefix
+   */
+  void rebalance(String clusterName, String resourceName, int replica);
+
+  /**
+   * Add ideal state using a json format file
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param idealStateFile
+   * @throws IOException
+   */
+  void addIdealState(String clusterName, String resourceName, String idealStateFile) throws IOException;
+
+  /**
+   * Add state model definition using a json format file
+   * 
+   * @param clusterName
+   * @param resourceName
+   * @param idealStateFile
+   * @throws IOException
+   */
+  void addStateModelDef(String clusterName,
+                        String stateModelDefName,
+                        String stateModelDefFile) throws IOException;
+
+  /**
+   * Add a message contraint
+   * 
+   * @param constraintId
+   * @param constraints
+   */
+  void addMessageConstraint(String clusterName,
+                            String constraintId,
+                            Map<String, String> constraints);
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixConstants.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixConstants.java b/helix-core/src/main/java/org/apache/helix/HelixConstants.java
new file mode 100644
index 0000000..15547ff
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixConstants.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+public interface HelixConstants
+{
+  // ChangeType and PropertyType are the same; remove this
+  enum ChangeType
+  {
+    // @formatter:off
+    IDEAL_STATE,
+    CONFIG,
+    LIVE_INSTANCE,
+    CURRENT_STATE,
+    MESSAGE,
+    EXTERNAL_VIEW,
+    CONTROLLER,
+    MESSAGES_CONTROLLER,
+    HEALTH
+    // @formatter:on
+  }
+
+  enum StateModelToken
+  {
+    ANY_LIVEINSTANCE
+  }
+
+  enum ClusterConfigType
+  {
+    HELIX_DISABLE_PIPELINE_TRIGGERS
+  }
+
+  static final String DEFAULT_STATE_MODEL_FACTORY = "DEFAULT";
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java b/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
new file mode 100644
index 0000000..67a3ac1
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixDataAccessor.java
@@ -0,0 +1,161 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.List;
+import java.util.Map;
+
+import org.I0Itec.zkclient.DataUpdater;
+
+/**
+ * Interface used to interact with Helix Data Types like IdealState, Config,
+ * LiveInstance, Message, ExternalView etc PropertyKey represent the HelixData
+ * type. See {@link Builder} to get more information on building a propertyKey.
+ * 
+ * @author kgopalak
+ * 
+ */
+public interface HelixDataAccessor
+{
+  /**
+   * Create a helix property only if it does not exist.
+   * 
+   * @param key
+   * @param value
+   * @return true if creation was successful. False if already exists or if it
+   *         failed to create
+   */
+
+  <T extends HelixProperty> boolean createProperty(PropertyKey key, T value);
+
+  /**
+   * Set a property, overwrite if it exists and creates if not exists. This api
+   * assumes the node exists and only tries to update it only if the call fail
+   * it will create the node. So there is a performance cost if always ends up
+   * creating the node.
+   * 
+   * @param key
+   * @param value
+   * @true if the operation was successful
+   */
+  <T extends HelixProperty> boolean setProperty(PropertyKey key, T value);
+
+  /**
+   * Updates a property using newvalue.merge(oldvalue)
+   * 
+   * @param key
+   * @param value
+   * @return true if the update was successful
+   */
+  <T extends HelixProperty> boolean updateProperty(PropertyKey key, T value);
+
+  /**
+   * Return the property value, it must be refer to a single Helix Property. i.e
+   * PropertyKey.isLeaf() must return true.
+   * 
+   * @param key
+   * @return value, Null if absent or on error
+   */
+  <T extends HelixProperty> T getProperty(PropertyKey key);
+
+  /**
+   * Return a list of property values, each of which must be refer to a single Helix
+   * Property. Property may be bucketized.
+   * 
+   * @param keys
+   * @return
+   */
+  public <T extends HelixProperty> List<T> getProperty(List<PropertyKey> keys);
+
+  /**
+   * Removes the property
+   * 
+   * @param key
+   * @return true if removal was successful or node does not exist. false if the
+   *         node existed and failed to remove it
+   */
+  boolean removeProperty(PropertyKey key);
+
+  /**
+   * Return the child names for a property. PropertyKey needs to refer to a
+   * collection like instances, resources. PropertyKey.isLeaf must be false
+   * 
+   * @param type
+   * @return SubPropertyNames
+   */
+  List<String> getChildNames(PropertyKey key);
+
+  /**
+   * Get the child values for a property. PropertyKey needs to refer to just one
+   * level above the non leaf. PropertyKey.isCollection must be true.
+   * 
+   * @param type
+   * @return subPropertyValues
+   */
+  <T extends HelixProperty> List<T> getChildValues(PropertyKey key);
+
+  /**
+   * Same as getChildValues except that it converts list into a map using the id
+   * of the HelixProperty
+   * 
+   * @param key
+   * @return
+   */
+
+  <T extends HelixProperty> Map<String, T> getChildValuesMap(PropertyKey key);
+
+  /**
+   * Adds multiple children to a parent.
+   * 
+   * @param key
+   * @param children
+   * @return
+   */
+  <T extends HelixProperty> boolean[] createChildren(List<PropertyKey> keys,
+      List<T> children);
+
+  /**
+   * Sets multiple children under one parent
+   * 
+   * @param externalViews
+   * @param views
+   */
+  <T extends HelixProperty> boolean[] setChildren(List<PropertyKey> keys, List<T> children);
+  
+  /**
+   * Updates multiple children under one parent
+   * 
+   * @param externalViews
+   * @param views
+   */
+  <T extends HelixProperty> boolean[] updateChildren(List<String> paths,
+      List<DataUpdater<ZNRecord>> updaters,
+      int options);
+  
+  /**
+   * Get key builder for the accessor
+   * 
+   * @return
+   */
+  PropertyKey.Builder keyBuilder();
+
+  /**
+   * Get underlying base data accessor
+   * 
+   * @return
+   */
+  BaseDataAccessor<ZNRecord> getBaseDataAccessor();
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixException.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixException.java b/helix-core/src/main/java/org/apache/helix/HelixException.java
new file mode 100644
index 0000000..d9d9de0
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixException.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+
+public class HelixException extends RuntimeException
+{
+
+  public HelixException(String message)
+  {
+    super(message);
+  }
+
+  public HelixException(Throwable cause)
+  {
+    super(cause);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixManager.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixManager.java b/helix-core/src/main/java/org/apache/helix/HelixManager.java
new file mode 100644
index 0000000..a34ab8e
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixManager.java
@@ -0,0 +1,297 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.List;
+
+import org.apache.helix.controller.GenericHelixController;
+import org.apache.helix.healthcheck.ParticipantHealthReportCollector;
+import org.apache.helix.participant.HelixStateMachineEngine;
+import org.apache.helix.participant.StateMachineEngine;
+import org.apache.helix.spectator.RoutingTableProvider;
+import org.apache.helix.store.PropertyStore;
+import org.apache.helix.store.zk.ZkHelixPropertyStore;
+
+
+/**
+ * First class Object any process will interact with<br/>
+ * General flow <blockquote>
+ * 
+ * <pre>
+ * manager = HelixManagerFactory.getManagerFor<ROLE>(); ROLE can be participant, spectator or a controller<br/>
+ * manager.connect();
+ * manager.addSOMEListener();
+ * manager.start()
+ * After start is invoked the subsequent interactions will be via listener onChange callbacks
+ * There will be 3 scenarios for onChange callback, which can be determined using NotificationContext.type
+ * INIT -> will be invoked the first time the listener is added
+ * CALLBACK -> will be invoked due to datachange in the property value
+ * FINALIZE -> will be invoked when listener is removed or session expires
+ * manager.disconnect()
+ * </pre>
+ * 
+ * </blockquote> Default implementations available
+ * 
+ * @see HelixStateMachineEngine for participant
+ * @see RoutingTableProvider for spectator
+ * @see GenericHelixController for controller
+ * @author kgopalak
+ */
+public interface HelixManager
+{
+
+  /**
+   * Start participating in the cluster operations. All listeners will be
+   * initialized and will be notified for every cluster state change This method
+   * is not re-entrant. One cannot call this method twice.
+   * 
+   * @throws Exception
+   */
+  void connect() throws Exception;
+
+  /**
+   * Check if the connection is alive, code depending on cluster manager must
+   * always do this if( manager.isConnected()){ //custom code } This will
+   * prevent client in doing anything when its disconnected from the cluster.
+   * There is no need to invoke connect again if isConnected return false.
+   * 
+   * @return
+   */
+  boolean isConnected();
+
+  /**
+   * Disconnect from the cluster. All the listeners will be removed and
+   * disconnected from the server. Its important for the client to ensure that
+   * new manager instance is used when it wants to connect again.
+   */
+  void disconnect();
+
+  /**
+   * @see IdealStateChangeListener#onIdealStateChange(List, NotificationContext)
+   * @param listener
+   * @throws Exception
+   */
+  void addIdealStateChangeListener(IdealStateChangeListener listener)
+      throws Exception;
+
+  /**
+   * @see LiveInstanceChangeListener#onLiveInstanceChange(List,
+   *      NotificationContext)
+   * @param listener
+   */
+  void addLiveInstanceChangeListener(LiveInstanceChangeListener listener)
+      throws Exception;
+
+  /**
+   * @see ConfigChangeListener#onConfigChange(List, NotificationContext)
+   * @param listener
+   */
+  void addConfigChangeListener(ConfigChangeListener listener) throws Exception;
+
+  /**
+   * @see MessageListener#onMessage(String, List, NotificationContext)
+   * @param listener
+   * @param instanceName
+   */
+  void addMessageListener(MessageListener listener, String instanceName)
+      throws Exception;
+
+  /**
+   * @see CurrentStateChangeListener#onStateChange(String, List,
+   *      NotificationContext)
+   * @param listener
+   * @param instanceName
+   */
+
+  void addCurrentStateChangeListener(CurrentStateChangeListener listener,
+      String instanceName, String sessionId) throws Exception;
+
+  /**
+   * @see HealthStateChangeListener#onHealthChange(String, List,
+   *      NotificationContext)
+   * @param listener
+   * @param instanceName
+   */
+  void addHealthStateChangeListener(HealthStateChangeListener listener,
+      String instanceName) throws Exception;
+
+  /**
+   * @see ExternalViewChangeListener#onExternalViewChange(List,
+   *      NotificationContext)
+   * @param listener
+   */
+  void addExternalViewChangeListener(ExternalViewChangeListener listener)
+      throws Exception;
+
+  /**
+   * Add listener for controller change
+   * 
+   * Used in distributed cluster controller
+   */
+  void addControllerListener(ControllerChangeListener listener);
+
+  /**
+   * Removes the listener. If the same listener was used for multiple changes,
+   * all change notifications will be removed.<br/>
+   * This will invoke onChange method on the listener with
+   * NotificationContext.type set to FINALIZE. Listener can clean up its state.<br/>
+   * The data provided in this callback may not be reliable.<br/>
+   * When a session expires all listeners will be removed and re-added
+   * automatically. <br/>
+   * This provides the ability for listeners to either reset their state or do
+   * any cleanup tasks.<br/>
+   * 
+   * @param listener
+   * @return
+   */
+  boolean removeListener(Object listener);
+
+  /**
+   * Return the client to perform read/write operations on the cluster data
+   * store {@link getHelixDataAccessor() }
+   * 
+   * @return DataAccessor
+   */
+  @Deprecated
+  DataAccessor getDataAccessor();
+
+  /**
+   * Return the client to perform read/write operations on the cluster data
+   * store
+   * 
+   * @return ClusterDataAccessor
+   */
+  HelixDataAccessor getHelixDataAccessor();
+
+  /**
+   * Get config accessor
+   * 
+   * @return
+   */
+  ConfigAccessor getConfigAccessor();
+
+  /**
+   * Returns the cluster name associated with this cluster manager
+   * 
+   * @return
+   */
+  String getClusterName();
+
+  /**
+   * Returns the instanceName used to connect to the cluster
+   * 
+   * @return
+   */
+
+  String getInstanceName();
+
+  /**
+   * Get the sessionId associated with the connection to cluster data store.
+   */
+  String getSessionId();
+
+  /**
+   * The time stamp is always updated when a notification is received. This can
+   * be used to check if there was any new notification when previous
+   * notification was being processed. This is updated based on the
+   * notifications from listeners registered.
+   */
+  long getLastNotificationTime();
+
+  /**
+   * Provides admin interface to setup and modify cluster.
+   * 
+   * @return
+   */
+  HelixAdmin getClusterManagmentTool();
+
+  /**
+   * Provide get property store for a cluster
+   * 
+   * @param rootNamespace
+   * @param serializer
+   * @return
+   */
+  @Deprecated
+  PropertyStore<ZNRecord> getPropertyStore();
+  
+  /**
+   * Get property store
+   * 
+   * @return
+   */
+  ZkHelixPropertyStore<ZNRecord> getHelixPropertyStore();
+
+  /**
+   * Messaging service which can be used to send cluster wide messages.
+   * 
+   */
+  ClusterMessagingService getMessagingService();
+
+  /**
+   * Participant only component that periodically update participant health
+   * report to cluster manager server.
+   * 
+   */
+  ParticipantHealthReportCollector getHealthReportCollector();
+
+  /**
+   * Get cluster manager instance type
+   * 
+   * @return
+   */
+  InstanceType getInstanceType();
+
+  /**
+   * Get cluster manager version
+   * 
+   * @return the cluster manager version
+   */
+  String getVersion();
+
+  /**
+   * 
+   * @return the state machine engine
+   */
+  StateMachineEngine getStateMachineEngine();
+
+  /**
+   * Check if the cluster manager is the leader
+   * 
+   * @return true if this is a controller and a leader of the cluster
+   */
+  boolean isLeader();
+
+  /**
+   * start timer tasks when becomes leader
+   * 
+   */
+  void startTimerTasks();
+
+  /**
+   * stop timer tasks when becomes standby
+   * 
+   */
+  void stopTimerTasks();
+  
+  /**
+   * Add a callback that is invoked before cluster manager connects
+   * 
+   * @see PreConnectCallback#onPreConnect()
+   * @param callback
+   */
+  void addPreConnectCallback(PreConnectCallback callback);
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixManagerFactory.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixManagerFactory.java b/helix-core/src/main/java/org/apache/helix/HelixManagerFactory.java
new file mode 100644
index 0000000..9f05b2d
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixManagerFactory.java
@@ -0,0 +1,104 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+/**
+ * factory that creates cluster managers
+ *
+ * for zk-based cluster managers, the getZKXXX(..zkClient) that takes a zkClient parameter
+ *   are intended for session expiry test purpose
+ */
+import org.apache.helix.manager.file.DynamicFileHelixManager;
+import org.apache.helix.manager.file.StaticFileHelixManager;
+import org.apache.helix.manager.zk.ZKHelixManager;
+import org.apache.helix.store.file.FilePropertyStore;
+import org.apache.log4j.Logger;
+
+
+public final class HelixManagerFactory
+{
+  private static final Logger logger = Logger.getLogger(HelixManagerFactory.class);
+
+  /**
+   * Construct a zk-based cluster manager enforce all types (PARTICIPANT, CONTROLLER, and
+   * SPECTATOR to have a name
+   * 
+   * @param clusterName
+   * @param instanceName
+   * @param type
+   * @param zkAddr
+   * @return
+   * @throws Exception
+   */
+  public static HelixManager getZKHelixManager(String clusterName,
+                                               String instanceName,
+                                               InstanceType type,
+                                               String zkAddr) throws Exception
+  {
+    return new ZKHelixManager(clusterName, instanceName, type, zkAddr);
+  }
+
+  /**
+   * Construct a file-based cluster manager using a static cluster-view file the
+   * cluster-view file contains pre-computed state transition messages from initial
+   * OFFLINE states to ideal states
+   * 
+   * @param clusterName
+   * @param instanceName
+   * @param type
+   * @param clusterViewFile
+   * @return
+   * @throws Exception
+   */
+  @Deprecated
+  public static HelixManager getStaticFileHelixManager(String clusterName,
+                                                       String instanceName,
+                                                       InstanceType type,
+                                                       String clusterViewFile) throws Exception
+  {
+    if (type != InstanceType.PARTICIPANT)
+    {
+      throw new IllegalArgumentException("Static file-based cluster manager doesn't support type other than participant");
+    }
+    return new StaticFileHelixManager(clusterName, instanceName, type, clusterViewFile);
+  }
+
+  /**
+   * Construct a dynamic file-based cluster manager
+   * 
+   * @param clusterName
+   * @param instanceName
+   * @param type
+   * @param file
+   *          property store: all dynamic-file based participants/controller shall use the
+   *          same file property store to avoid race condition in updating files
+   * @return
+   * @throws Exception
+   */
+  @Deprecated
+  public static HelixManager getDynamicFileHelixManager(String clusterName,
+                                                        String instanceName,
+                                                        InstanceType type,
+                                                        FilePropertyStore<ZNRecord> store) throws Exception
+  {
+    if (type != InstanceType.PARTICIPANT && type != InstanceType.CONTROLLER)
+    {
+      throw new IllegalArgumentException("Dynamic file-based cluster manager doesn't support types other than participant and controller");
+    }
+
+    return new DynamicFileHelixManager(clusterName, instanceName, type, store);
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixProperty.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixProperty.java b/helix-core/src/main/java/org/apache/helix/HelixProperty.java
new file mode 100644
index 0000000..01689c5
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixProperty.java
@@ -0,0 +1,224 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A wrapper class for ZNRecord. Used as a base class for IdealState, CurrentState, etc.
+ */
+public class HelixProperty
+{
+  public enum HelixPropertyAttribute
+  {
+    BUCKET_SIZE,
+    GROUP_MESSAGE_MODE
+  }
+
+  protected final ZNRecord _record;
+
+  public HelixProperty(String id)
+  {
+    _record = new ZNRecord(id);
+  }
+
+  public HelixProperty(ZNRecord record)
+  {
+    _record = new ZNRecord(record);
+  }
+
+  public final String getId()
+  {
+    return _record.getId();
+  }
+
+  public final ZNRecord getRecord()
+  {
+    return _record;
+  }
+
+  public final void setDeltaList(List<ZNRecordDelta> deltaList)
+  {
+    _record.setDeltaList(deltaList);
+  }
+
+  @Override
+  public String toString()
+  {
+    return _record.toString();
+  }
+
+  public int getBucketSize()
+  {
+    String bucketSizeStr =
+        _record.getSimpleField(HelixPropertyAttribute.BUCKET_SIZE.toString());
+    int bucketSize = 0;
+    if (bucketSizeStr != null)
+    {
+      try
+      {
+        bucketSize = Integer.parseInt(bucketSizeStr);
+      }
+      catch (NumberFormatException e)
+      {
+        // OK
+      }
+    }
+    return bucketSize;
+  }
+
+  public void setBucketSize(int bucketSize)
+  {
+    if (bucketSize <= 0)
+      bucketSize = 0;
+
+    _record.setSimpleField(HelixPropertyAttribute.BUCKET_SIZE.toString(), "" + bucketSize);
+  }
+
+  /**
+   * static method that convert ZNRecord to an instance that subclasses HelixProperty
+   * 
+   * @param clazz
+   * @param record
+   * @return
+   */
+  public static <T extends HelixProperty> T convertToTypedInstance(Class<T> clazz,
+                                                                   ZNRecord record)
+  {
+    if (record == null)
+    {
+      return null;
+    }
+
+    try
+    {
+      Constructor<T> constructor = clazz.getConstructor(new Class[] { ZNRecord.class });
+      return constructor.newInstance(record);
+    }
+    catch (Exception e)
+    {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+    }
+
+    return null;
+  }
+
+  public static <T extends HelixProperty> List<T> convertToTypedList(Class<T> clazz,
+                                                                     Collection<ZNRecord> records)
+  {
+    if (records == null)
+    {
+      return null;
+    }
+
+    List<T> decorators = new ArrayList<T>();
+    for (ZNRecord record : records)
+    {
+      T decorator = HelixProperty.convertToTypedInstance(clazz, record);
+      if (decorator != null)
+      {
+        decorators.add(decorator);
+      }
+    }
+    return decorators;
+  }
+
+  public static <T extends HelixProperty> Map<String, T> convertListToMap(List<T> records)
+  {
+    if (records == null)
+    {
+      return Collections.emptyMap();
+    }
+
+    Map<String, T> decorators = new HashMap<String, T>();
+    for (T record : records)
+    {
+      decorators.put(record.getId(), record);
+    }
+    return decorators;
+  }
+
+  public static <T extends HelixProperty> List<ZNRecord> convertToList(List<T> typedInstances)
+  {
+    if (typedInstances == null)
+    {
+      return Collections.emptyList();
+    }
+
+    List<ZNRecord> records = new ArrayList<ZNRecord>();
+    for (T typedInstance : typedInstances)
+    {
+      records.add(typedInstance.getRecord());
+    }
+
+    return records;
+  }
+
+  public void setGroupMessageMode(boolean enable)
+  {
+    _record.setSimpleField(HelixPropertyAttribute.GROUP_MESSAGE_MODE.toString(), ""
+        + enable);
+  }
+
+  public boolean getGroupMessageMode()
+  {
+    String enableStr =
+        _record.getSimpleField(HelixPropertyAttribute.GROUP_MESSAGE_MODE.toString());
+    if (enableStr == null)
+    {
+      return false;
+    }
+
+    try
+    {
+      return Boolean.parseBoolean(enableStr.toLowerCase());
+    }
+    catch (Exception e)
+    {
+      return false;
+    }
+  }
+  
+  public boolean isValid()
+  {
+    return false;
+  }
+
+  @Override
+  public boolean equals(Object obj)
+  {
+    if (obj == null)
+    {
+      return false;
+    }
+    if (obj instanceof HelixProperty)
+    {
+      HelixProperty that = (HelixProperty) obj;
+      if (that.getRecord() != null)
+      {
+        return that.getRecord().equals(this.getRecord());
+      }
+    }
+    return false;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/HelixTimerTask.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/HelixTimerTask.java b/helix-core/src/main/java/org/apache/helix/HelixTimerTask.java
new file mode 100644
index 0000000..8cee808
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/HelixTimerTask.java
@@ -0,0 +1,33 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.TimerTask;
+
+public abstract class HelixTimerTask extends TimerTask
+{
+  /**
+   * Timer task starts
+   * 
+   */
+  public abstract void start();
+  
+  /**
+   * Timer task stops
+   * 
+   */
+  public abstract void stop();
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/IdealStateChangeListener.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/IdealStateChangeListener.java b/helix-core/src/main/java/org/apache/helix/IdealStateChangeListener.java
new file mode 100644
index 0000000..d8806cc
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/IdealStateChangeListener.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.List;
+
+import org.apache.helix.model.IdealState;
+
+
+public interface IdealStateChangeListener
+{
+
+  /**
+   * Invoed when ideal state changes
+   * 
+   * @param idealState
+   * @param changeContext
+   */
+  void onIdealStateChange(List<IdealState> idealState, NotificationContext changeContext);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/InstanceType.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/InstanceType.java b/helix-core/src/main/java/org/apache/helix/InstanceType.java
new file mode 100644
index 0000000..241304a
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/InstanceType.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+/**
+ * CONTROLLER:     cluster managing component is a controller
+ * PARTICIPANT:    participate in the cluster state changes
+ * SPECTATOR:      interested in the state changes in the cluster
+ * CONTROLLER_PARTICIPANT:
+ *  special participant that competes for the leader of CONTROLLER_CLUSTER
+ *  used in cluster controller of distributed mode {@HelixControllerMain}
+ *
+ */
+public enum InstanceType
+{
+  CONTROLLER,
+  PARTICIPANT,
+  SPECTATOR,
+  CONTROLLER_PARTICIPANT,
+  ADMINISTRATOR
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/LiveInstanceChangeListener.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/LiveInstanceChangeListener.java b/helix-core/src/main/java/org/apache/helix/LiveInstanceChangeListener.java
new file mode 100644
index 0000000..97513a4
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/LiveInstanceChangeListener.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.List;
+
+import org.apache.helix.model.LiveInstance;
+
+
+public interface LiveInstanceChangeListener
+{
+
+  /**
+   * Invoked when live instance changes
+   * 
+   * @param liveInstances
+   * @param changeContext
+   */
+  public void onLiveInstanceChange(List<LiveInstance> liveInstances,
+                                   NotificationContext changeContext);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/MessageListener.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/MessageListener.java b/helix-core/src/main/java/org/apache/helix/MessageListener.java
new file mode 100644
index 0000000..d8fb8c9
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/MessageListener.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.List;
+
+import org.apache.helix.model.Message;
+
+
+public interface MessageListener
+{
+
+  /**
+   * Invoked when message changes
+   * 
+   * @param instanceName
+   * @param messages
+   * @param changeContext
+   */
+  public void onMessage(String instanceName, List<Message> messages,
+      NotificationContext changeContext);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/NotificationContext.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/NotificationContext.java b/helix-core/src/main/java/org/apache/helix/NotificationContext.java
new file mode 100644
index 0000000..53a3417
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/NotificationContext.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class NotificationContext
+{
+  // keys used for object map
+  public static final String TASK_EXECUTOR_KEY = "TASK_EXECUTOR";
+  
+  private Map<String, Object> _map;
+
+  private HelixManager _manager;
+  private Type _type;
+  private String _pathChanged;
+  private String _eventName;
+
+  public String getEventName()
+  {
+    return _eventName;
+  }
+
+  public void setEventName(String eventName)
+  {
+    _eventName = eventName;
+  }
+
+  public NotificationContext(HelixManager manager)
+  {
+    _manager = manager;
+    _map = new HashMap<String, Object>();
+  }
+
+  public HelixManager getManager()
+  {
+    return _manager;
+  }
+
+  public Map<String, Object> getMap()
+  {
+    return _map;
+  }
+
+  public Type getType()
+  {
+    return _type;
+  }
+
+  public void setManager(HelixManager manager)
+  {
+    this._manager = manager;
+  }
+
+  public void add(String key, Object value)
+  {
+    _map.put(key, value);
+  }
+
+  public void setMap(Map<String, Object> map)
+  {
+    this._map = map;
+  }
+
+  public void setType(Type type)
+  {
+    this._type = type;
+  }
+
+  public Object get(String key)
+  {
+    return _map.get(key);
+  }
+
+  public enum Type
+  {
+    INIT, CALLBACK, FINALIZE
+  }
+
+  public String getPathChanged()
+  {
+    return _pathChanged;
+  }
+
+  public void setPathChanged(String pathChanged)
+  {
+    this._pathChanged = pathChanged;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/PreConnectCallback.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/PreConnectCallback.java b/helix-core/src/main/java/org/apache/helix/PreConnectCallback.java
new file mode 100644
index 0000000..f19a4fa
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/PreConnectCallback.java
@@ -0,0 +1,12 @@
+package org.apache.helix;
+
+public interface PreConnectCallback
+{
+  /**
+   * Callback function that is called by HelixManager before connected to zookeeper. If
+   * exception are thrown HelixManager will not connect and no live instance is created
+   * 
+   * @see ZkHelixManager#handleNewSessionAsParticipant()
+   */
+  public void onPreConnect();
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/PropertyKey.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/PropertyKey.java b/helix-core/src/main/java/org/apache/helix/PropertyKey.java
new file mode 100644
index 0000000..e1fd3db
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/PropertyKey.java
@@ -0,0 +1,553 @@
+package org.apache.helix;
+
+import static org.apache.helix.PropertyType.ALERTS;
+import static org.apache.helix.PropertyType.ALERT_HISTORY;
+import static org.apache.helix.PropertyType.ALERT_STATUS;
+import static org.apache.helix.PropertyType.CONFIGS;
+import static org.apache.helix.PropertyType.CONTROLLER;
+import static org.apache.helix.PropertyType.CURRENTSTATES;
+import static org.apache.helix.PropertyType.ERRORS;
+import static org.apache.helix.PropertyType.ERRORS_CONTROLLER;
+import static org.apache.helix.PropertyType.EXTERNALVIEW;
+import static org.apache.helix.PropertyType.HEALTHREPORT;
+import static org.apache.helix.PropertyType.HISTORY;
+import static org.apache.helix.PropertyType.IDEALSTATES;
+import static org.apache.helix.PropertyType.LEADER;
+import static org.apache.helix.PropertyType.LIVEINSTANCES;
+import static org.apache.helix.PropertyType.MESSAGES;
+import static org.apache.helix.PropertyType.MESSAGES_CONTROLLER;
+import static org.apache.helix.PropertyType.PAUSE;
+import static org.apache.helix.PropertyType.PERSISTENTSTATS;
+import static org.apache.helix.PropertyType.STATEMODELDEFS;
+import static org.apache.helix.PropertyType.STATUSUPDATES;
+import static org.apache.helix.PropertyType.STATUSUPDATES_CONTROLLER;
+
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.helix.ConfigScope.ConfigScopeProperty;
+import org.apache.helix.manager.zk.ZKHelixDataAccessor;
+import org.apache.helix.manager.zk.ZkBaseDataAccessor;
+import org.apache.helix.manager.zk.ZkClient;
+import org.apache.helix.model.AlertHistory;
+import org.apache.helix.model.AlertStatus;
+import org.apache.helix.model.Alerts;
+import org.apache.helix.model.ClusterConstraints;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.Error;
+import org.apache.helix.model.ExternalView;
+import org.apache.helix.model.HealthStat;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LeaderHistory;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.Message;
+import org.apache.helix.model.PauseSignal;
+import org.apache.helix.model.PersistentStats;
+import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.model.StatusUpdate;
+import org.apache.log4j.Logger;
+
+
+public class PropertyKey
+{
+  private static Logger          LOG = Logger.getLogger(PropertyKey.class);
+  public PropertyType            _type;
+  private final String[]         _params;
+  Class<? extends HelixProperty> _typeClazz;
+
+  public PropertyKey(PropertyType type,
+                     Class<? extends HelixProperty> typeClazz,
+                     String... params)
+  {
+    _type = type;
+    if (params == null || params.length == 0 || Arrays.asList(params).contains(null))
+    {
+      throw new IllegalArgumentException("params cannot be null");
+    }
+
+    _params = params;
+    _typeClazz = typeClazz;
+  }
+
+  @Override
+  public int hashCode()
+  {
+    return super.hashCode();
+  }
+
+  public String getPath()
+  {
+    String clusterName = _params[0];
+    String[] subKeys = Arrays.copyOfRange(_params, 1, _params.length);
+    String path = PropertyPathConfig.getPath(_type, clusterName, subKeys);
+    if (path == null)
+    {
+      LOG.error("Invalid property key with type:" + _type + "subKeys:"
+          + Arrays.toString(_params));
+    }
+    return path;
+  }
+
+  public static class Builder
+  {
+    private final String _clusterName;
+
+    public Builder(String clusterName)
+    {
+      _clusterName = clusterName;
+    }
+
+    public PropertyKey idealStates()
+    {
+      return new PropertyKey(IDEALSTATES, IdealState.class, _clusterName);
+    }
+
+    public PropertyKey idealStates(String resourceName)
+    {
+      return new PropertyKey(IDEALSTATES, IdealState.class, _clusterName, resourceName);
+    }
+
+    public PropertyKey stateModelDefs()
+    {
+      return new PropertyKey(STATEMODELDEFS, StateModelDefinition.class, _clusterName);
+    }
+
+    public PropertyKey stateModelDef(String stateModelName)
+    {
+      return new PropertyKey(STATEMODELDEFS,
+                             StateModelDefinition.class,
+                             _clusterName,
+                             stateModelName);
+    }
+
+    public PropertyKey clusterConfig()
+    {
+      return new PropertyKey(CONFIGS,
+                             null,
+                             _clusterName,
+                             ConfigScopeProperty.CLUSTER.toString());
+    }
+
+    public PropertyKey instanceConfigs()
+    {
+      return new PropertyKey(CONFIGS,
+                             InstanceConfig.class,
+                             _clusterName,
+                             ConfigScopeProperty.PARTICIPANT.toString());
+    }
+
+    public PropertyKey instanceConfig(String instanceName)
+    {
+      return new PropertyKey(CONFIGS,
+                             InstanceConfig.class,
+                             _clusterName,
+                             ConfigScopeProperty.PARTICIPANT.toString(),
+                             instanceName);
+    }
+
+    public PropertyKey resourceConfig(String resourceName)
+    {
+      return new PropertyKey(CONFIGS,
+                             null,
+                             _clusterName,
+                             ConfigScopeProperty.RESOURCE.toString(),
+                             resourceName);
+    }
+
+    public PropertyKey resourceConfig(String instanceName, String resourceName)
+    {
+      return new PropertyKey(CONFIGS,
+                             null,
+                             _clusterName,
+                             ConfigScopeProperty.RESOURCE.toString(),
+                             resourceName);
+    }
+
+    public PropertyKey partitionConfig(String resourceName, String partitionName)
+    {
+      return new PropertyKey(CONFIGS,
+                             null,
+                             _clusterName,
+                             ConfigScopeProperty.RESOURCE.toString(),
+                             resourceName);
+    }
+
+    public PropertyKey partitionConfig(String instanceName,
+                                       String resourceName,
+                                       String partitionName)
+    {
+      return new PropertyKey(CONFIGS,
+                             null,
+                             _clusterName,
+                             ConfigScopeProperty.RESOURCE.toString(),
+                             resourceName);
+    }
+
+    public PropertyKey constraints()
+    {
+      return new PropertyKey(CONFIGS,
+                             ClusterConstraints.class,
+                             _clusterName,
+                             ConfigScopeProperty.CONSTRAINT.toString());
+    }
+
+    public PropertyKey constraint(String constraintType)
+    {
+      return new PropertyKey(CONFIGS,
+                             ClusterConstraints.class,
+                             _clusterName,
+                             ConfigScopeProperty.CONSTRAINT.toString(),
+                             constraintType);
+    }
+
+    public PropertyKey liveInstances()
+    {
+      return new PropertyKey(LIVEINSTANCES, LiveInstance.class, _clusterName);
+    }
+
+    public PropertyKey liveInstance(String instanceName)
+    {
+      return new PropertyKey(LIVEINSTANCES,
+                             LiveInstance.class,
+                             _clusterName,
+                             instanceName);
+    }
+
+    public PropertyKey instances()
+    {
+      return new PropertyKey(CONFIGS, null, _clusterName);
+    }
+
+    public PropertyKey messages(String instanceName)
+    {
+      return new PropertyKey(MESSAGES, Message.class, _clusterName, instanceName);
+    }
+
+    public PropertyKey message(String instanceName, String messageId)
+    {
+      return new PropertyKey(MESSAGES,
+                             Message.class,
+                             _clusterName,
+                             instanceName,
+                             messageId);
+    }
+
+    public PropertyKey sessions(String instanceName)
+    {
+      return new PropertyKey(CURRENTSTATES,
+                             CurrentState.class,
+                             _clusterName,
+                             instanceName);
+    }
+
+    public PropertyKey currentStates(String instanceName, String sessionId)
+    {
+      return new PropertyKey(CURRENTSTATES,
+                             CurrentState.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId);
+    }
+
+    public PropertyKey currentState(String instanceName,
+                                    String sessionId,
+                                    String resourceName)
+    {
+      return new PropertyKey(CURRENTSTATES,
+                             CurrentState.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             resourceName);
+    }
+
+    public PropertyKey currentState(String instanceName,
+                                    String sessionId,
+                                    String resourceName,
+                                    String bucketName)
+    {
+      if (bucketName == null)
+      {
+        return new PropertyKey(CURRENTSTATES,
+                               CurrentState.class,
+                               _clusterName,
+                               instanceName,
+                               sessionId,
+                               resourceName);
+
+      }
+      else
+      {
+        return new PropertyKey(CURRENTSTATES,
+                               CurrentState.class,
+                               _clusterName,
+                               instanceName,
+                               sessionId,
+                               resourceName,
+                               bucketName);
+      }
+    }
+
+    // addEntry(PropertyType.STATUSUPDATES, 2,
+    // "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES");
+    // addEntry(PropertyType.STATUSUPDATES, 3,
+    // "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}");
+    // addEntry(PropertyType.STATUSUPDATES, 4,
+    // "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}/{subPath}");
+    // addEntry(PropertyType.STATUSUPDATES, 5,
+    // "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}/{subPath}/{recordName}");
+    public PropertyKey stateTransitionStatus(String instanceName,
+                                             String sessionId,
+                                             String resourceName,
+                                             String partitionName)
+    {
+      return new PropertyKey(STATUSUPDATES,
+                             StatusUpdate.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             resourceName,
+                             partitionName);
+    }
+
+    public PropertyKey stateTransitionStatus(String instanceName,
+                                             String sessionId,
+                                             String resourceName)
+    {
+      return new PropertyKey(STATUSUPDATES,
+                             StatusUpdate.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             resourceName);
+    }
+
+    public PropertyKey stateTransitionStatus(String instanceName, String sessionId)
+    {
+      return new PropertyKey(STATUSUPDATES,
+                             StatusUpdate.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId);
+    }
+
+    /**
+     * Used to get status update for a NON STATE TRANSITION type
+     * 
+     * @param instanceName
+     * @param sessionId
+     * @param msgType
+     * @param msgId
+     * @return
+     */
+    public PropertyKey taskStatus(String instanceName,
+                                  String sessionId,
+                                  String msgType,
+                                  String msgId)
+    {
+      return new PropertyKey(STATUSUPDATES,
+                             StatusUpdate.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             msgType,
+                             msgId);
+    }
+
+    public PropertyKey stateTransitionError(String instanceName,
+                                            String sessionId,
+                                            String resourceName,
+                                            String partitionName)
+    {
+      return new PropertyKey(ERRORS,
+                             Error.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             resourceName,
+                             partitionName);
+    }
+
+    public PropertyKey stateTransitionErrors(String instanceName,
+                                             String sessionId,
+                                             String resourceName)
+    {
+      return new PropertyKey(ERRORS,
+                             Error.class,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             resourceName);
+    }
+
+    /**
+     * Used to get status update for a NON STATE TRANSITION type
+     * 
+     * @param instanceName
+     * @param sessionId
+     * @param msgType
+     * @param msgId
+     * @return
+     */
+    public PropertyKey taskError(String instanceName,
+                                 String sessionId,
+                                 String msgType,
+                                 String msgId)
+    {
+      return new PropertyKey(ERRORS,
+                             null,
+                             _clusterName,
+                             instanceName,
+                             sessionId,
+                             msgType,
+                             msgId);
+    }
+
+    public PropertyKey externalViews()
+    {
+      return new PropertyKey(EXTERNALVIEW, ExternalView.class, _clusterName);
+    }
+
+    public PropertyKey externalView(String resourceName)
+    {
+      return new PropertyKey(EXTERNALVIEW, ExternalView.class, _clusterName, resourceName);
+    }
+
+    // * addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 4,
+    // *
+    // "/{clusterName}/CONTROLLER/STATUSUPDATES/{sessionId}/{subPath}/{recordName}"
+    // * ); addEntry(PropertyType.LEADER, 1,
+    // "/{clusterName}/CONTROLLER/LEADER");
+    // * addEntry(PropertyType.HISTORY, 1, "/{clusterName}/CONTROLLER/HISTORY");
+    // * addEntry(PropertyType.PAUSE, 1, "/{clusterName}/CONTROLLER/PAUSE");
+    // * addEntry(PropertyType.PERSISTENTSTATS, 1,
+    // * "/{clusterName}/CONTROLLER/PERSISTENTSTATS");
+    // addEntry(PropertyType.ALERTS,
+    // * 1, "/{clusterName}/CONTROLLER/ALERTS");
+    // addEntry(PropertyType.ALERT_STATUS,
+    // * 1, "/{clusterName}/CONTROLLER/ALERT_STATUS");
+    // * addEntry(PropertyType.ALERT_HISTORY, 1,
+    // * "/{clusterName}/CONTROLLER/ALERT_HISTORY"); // @formatter:on
+
+    public PropertyKey controller()
+    {
+      return new PropertyKey(CONTROLLER, null, _clusterName);
+    }
+
+    public PropertyKey controllerTaskErrors()
+    {
+      return new PropertyKey(ERRORS_CONTROLLER, StatusUpdate.class, _clusterName);
+    }
+
+    public PropertyKey controllerTaskError(String errorId)
+    {
+      return new PropertyKey(ERRORS_CONTROLLER, Error.class, _clusterName, errorId);
+    }
+
+    public PropertyKey controllerTaskStatuses(String subPath)
+    {
+      return new PropertyKey(STATUSUPDATES_CONTROLLER,
+                             StatusUpdate.class,
+                             _clusterName,
+                             subPath);
+    }
+
+    public PropertyKey controllerTaskStatus(String subPath, String recordName)
+    {
+      return new PropertyKey(STATUSUPDATES_CONTROLLER,
+                             StatusUpdate.class,
+                             _clusterName,
+                             subPath,
+                             recordName);
+    }
+
+    public PropertyKey controllerMessages()
+    {
+      return new PropertyKey(MESSAGES_CONTROLLER, Message.class, _clusterName);
+    }
+
+    public PropertyKey controllerMessage(String msgId)
+    {
+      return new PropertyKey(MESSAGES_CONTROLLER, Message.class, _clusterName, msgId);
+    }
+
+    public PropertyKey controllerLeaderHistory()
+    {
+      return new PropertyKey(HISTORY, LeaderHistory.class, _clusterName);
+    }
+
+    public PropertyKey controllerLeader()
+    {
+      return new PropertyKey(LEADER, LiveInstance.class, _clusterName);
+    }
+
+    public PropertyKey pause()
+    {
+      return new PropertyKey(PAUSE, PauseSignal.class, _clusterName);
+    }
+
+    public PropertyKey persistantStat()
+    {
+      return new PropertyKey(PERSISTENTSTATS, PersistentStats.class, _clusterName);
+    }
+
+    public PropertyKey alerts()
+    {
+      return new PropertyKey(ALERTS, Alerts.class, _clusterName);
+    }
+
+    public PropertyKey alertStatus()
+    {
+      return new PropertyKey(ALERT_STATUS, AlertStatus.class, _clusterName);
+    }
+
+    public PropertyKey alertHistory()
+    {
+      return new PropertyKey(ALERT_HISTORY, AlertHistory.class, _clusterName);
+    }
+
+    public PropertyKey healthReport(String instanceName, String id)
+    {
+      return new PropertyKey(HEALTHREPORT,
+                             HealthStat.class,
+                             _clusterName,
+                             instanceName,
+                             id);
+    }
+
+    public PropertyKey healthReports(String instanceName)
+    {
+      return new PropertyKey(HEALTHREPORT, HealthStat.class, _clusterName, instanceName);
+    }
+
+  }
+
+  public PropertyType getType()
+  {
+    return _type;
+  }
+
+  public String[] getParams()
+  {
+    return _params;
+  }
+
+  public Class<? extends HelixProperty> getTypeClass()
+  {
+    return _typeClazz;
+  }
+
+  public static void main(String[] args)
+  {
+    ZkClient zkClient = new ZkClient("localhost:2181");
+    zkClient.waitUntilConnected(10, TimeUnit.SECONDS);
+    BaseDataAccessor baseDataAccessor = new ZkBaseDataAccessor(zkClient);
+    HelixDataAccessor accessor =
+        new ZKHelixDataAccessor("test-cluster", baseDataAccessor);
+    Builder builder = new PropertyKey.Builder("test-cluster");
+    HelixProperty value = new IdealState("test-resource");
+    accessor.createProperty(builder.idealStates("test-resource"), value);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/PropertyPathConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/PropertyPathConfig.java b/helix-core/src/main/java/org/apache/helix/PropertyPathConfig.java
new file mode 100644
index 0000000..4cabfd1
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/PropertyPathConfig.java
@@ -0,0 +1,214 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+import static org.apache.helix.PropertyType.ALERTS;
+import static org.apache.helix.PropertyType.ALERT_STATUS;
+import static org.apache.helix.PropertyType.CONFIGS;
+import static org.apache.helix.PropertyType.CURRENTSTATES;
+import static org.apache.helix.PropertyType.EXTERNALVIEW;
+import static org.apache.helix.PropertyType.HEALTHREPORT;
+import static org.apache.helix.PropertyType.HISTORY;
+import static org.apache.helix.PropertyType.IDEALSTATES;
+import static org.apache.helix.PropertyType.LIVEINSTANCES;
+import static org.apache.helix.PropertyType.MESSAGES;
+import static org.apache.helix.PropertyType.PAUSE;
+import static org.apache.helix.PropertyType.STATEMODELDEFS;
+import static org.apache.helix.PropertyType.STATUSUPDATES;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.helix.model.AlertStatus;
+import org.apache.helix.model.Alerts;
+import org.apache.helix.model.CurrentState;
+import org.apache.helix.model.ExternalView;
+import org.apache.helix.model.HealthStat;
+import org.apache.helix.model.IdealState;
+import org.apache.helix.model.InstanceConfig;
+import org.apache.helix.model.LeaderHistory;
+import org.apache.helix.model.LiveInstance;
+import org.apache.helix.model.Message;
+import org.apache.helix.model.PauseSignal;
+import org.apache.helix.model.StateModelDefinition;
+import org.apache.helix.model.StatusUpdate;
+import org.apache.log4j.Logger;
+
+
+public class PropertyPathConfig
+{
+  private static Logger logger = Logger.getLogger(PropertyPathConfig.class);
+
+  static Map<PropertyType, Map<Integer, String>> templateMap = new HashMap<PropertyType, Map<Integer, String>>();
+  static Map<PropertyType, Class<? extends HelixProperty>> typeToClassMapping= new HashMap<PropertyType, Class<? extends HelixProperty>>();
+  static{
+    typeToClassMapping.put(LIVEINSTANCES, LiveInstance.class);
+    typeToClassMapping.put(IDEALSTATES, IdealState.class);
+    typeToClassMapping.put(CONFIGS, InstanceConfig.class);
+    typeToClassMapping.put(EXTERNALVIEW, ExternalView.class);
+    typeToClassMapping.put(STATEMODELDEFS, StateModelDefinition.class);
+    typeToClassMapping.put(MESSAGES, Message.class);
+    typeToClassMapping.put(CURRENTSTATES, CurrentState.class);
+    typeToClassMapping.put(STATUSUPDATES, StatusUpdate.class);
+    typeToClassMapping.put(HISTORY, LeaderHistory.class);
+    typeToClassMapping.put(HEALTHREPORT, HealthStat.class);
+    typeToClassMapping.put(ALERTS, Alerts.class);
+    typeToClassMapping.put(ALERT_STATUS, AlertStatus.class);
+    typeToClassMapping.put(PAUSE, PauseSignal.class);
+  }
+  static
+  {
+    // @formatter:off
+    addEntry(PropertyType.CONFIGS, 1, "/{clusterName}/CONFIGS");
+    addEntry(PropertyType.CONFIGS, 2, "/{clusterName}/CONFIGS/{scope}");
+    addEntry(PropertyType.CONFIGS, 3, "/{clusterName}/CONFIGS/{scope}/{scopeKey}");
+    // addEntry(PropertyType.CONFIGS,2,"/{clusterName}/CONFIGS/{instanceName}");
+    addEntry(PropertyType.LIVEINSTANCES, 1, "/{clusterName}/LIVEINSTANCES");
+    addEntry(PropertyType.LIVEINSTANCES, 2, "/{clusterName}/LIVEINSTANCES/{instanceName}");
+    addEntry(PropertyType.INSTANCES, 1, "/{clusterName}/INSTANCES");
+    addEntry(PropertyType.INSTANCES, 2, "/{clusterName}/INSTANCES/{instanceName}");
+    addEntry(PropertyType.IDEALSTATES, 1, "/{clusterName}/IDEALSTATES");
+    addEntry(PropertyType.IDEALSTATES, 2, "/{clusterName}/IDEALSTATES/{resourceName}");
+    addEntry(PropertyType.EXTERNALVIEW, 1, "/{clusterName}/EXTERNALVIEW");
+    addEntry(PropertyType.EXTERNALVIEW, 2, "/{clusterName}/EXTERNALVIEW/{resourceName}");
+    addEntry(PropertyType.STATEMODELDEFS, 1, "/{clusterName}/STATEMODELDEFS");
+    addEntry(PropertyType.STATEMODELDEFS, 2, "/{clusterName}/STATEMODELDEFS/{stateModelName}");
+    addEntry(PropertyType.CONTROLLER, 1, "/{clusterName}/CONTROLLER");
+    addEntry(PropertyType.PROPERTYSTORE, 1, "/{clusterName}/PROPERTYSTORE");
+    addEntry(PropertyType.HELIX_PROPERTYSTORE, 1, "/{clusterName}/HELIX_PROPERTYSTORE");
+
+    // INSTANCE
+    addEntry(PropertyType.MESSAGES, 2, "/{clusterName}/INSTANCES/{instanceName}/MESSAGES");
+    addEntry(PropertyType.MESSAGES, 3, "/{clusterName}/INSTANCES/{instanceName}/MESSAGES/{msgId}");
+    addEntry(PropertyType.CURRENTSTATES, 2, "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES");
+    addEntry(PropertyType.CURRENTSTATES, 3,
+        "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES/{sessionId}");
+    addEntry(PropertyType.CURRENTSTATES, 4,
+        "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES/{sessionId}/{resourceName}");
+    addEntry(PropertyType.CURRENTSTATES, 5,
+        "/{clusterName}/INSTANCES/{instanceName}/CURRENTSTATES/{sessionId}/{resourceName}/{bucketName}");
+    addEntry(PropertyType.STATUSUPDATES, 2, "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES");
+    addEntry(PropertyType.STATUSUPDATES, 3,
+        "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}");
+    addEntry(PropertyType.STATUSUPDATES, 4,
+        "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}/{subPath}");
+    addEntry(PropertyType.STATUSUPDATES, 5,
+        "/{clusterName}/INSTANCES/{instanceName}/STATUSUPDATES/{sessionId}/{subPath}/{recordName}");
+    addEntry(PropertyType.ERRORS, 2, "/{clusterName}/INSTANCES/{instanceName}/ERRORS");
+    addEntry(PropertyType.ERRORS, 3, "/{clusterName}/INSTANCES/{instanceName}/ERRORS/{sessionId}");
+    addEntry(PropertyType.ERRORS, 4,
+        "/{clusterName}/INSTANCES/{instanceName}/ERRORS/{sessionId}/{subPath}");
+    addEntry(PropertyType.ERRORS, 5,
+        "/{clusterName}/INSTANCES/{instanceName}/ERRORS/{sessionId}/{subPath}/{recordName}");
+    addEntry(PropertyType.HEALTHREPORT, 2, "/{clusterName}/INSTANCES/{instanceName}/HEALTHREPORT");
+    addEntry(PropertyType.HEALTHREPORT, 3,
+        "/{clusterName}/INSTANCES/{instanceName}/HEALTHREPORT/{reportName}");
+    // CONTROLLER
+    addEntry(PropertyType.MESSAGES_CONTROLLER, 1, "/{clusterName}/CONTROLLER/MESSAGES");
+    addEntry(PropertyType.MESSAGES_CONTROLLER, 2, "/{clusterName}/CONTROLLER/MESSAGES/{msgId}");
+    addEntry(PropertyType.ERRORS_CONTROLLER, 1, "/{clusterName}/CONTROLLER/ERRORS");
+    addEntry(PropertyType.ERRORS_CONTROLLER, 2, "/{clusterName}/CONTROLLER/ERRORS/{errorId}");
+    addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 1, "/{clusterName}/CONTROLLER/STATUSUPDATES");
+    addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 2,
+        "/{clusterName}/CONTROLLER/STATUSUPDATES/{subPath}");
+    addEntry(PropertyType.STATUSUPDATES_CONTROLLER, 3,
+        "/{clusterName}/CONTROLLER/STATUSUPDATES/{subPath}/{recordName}");
+    addEntry(PropertyType.LEADER, 1, "/{clusterName}/CONTROLLER/LEADER");
+    addEntry(PropertyType.HISTORY, 1, "/{clusterName}/CONTROLLER/HISTORY");
+    addEntry(PropertyType.PAUSE, 1, "/{clusterName}/CONTROLLER/PAUSE");
+    addEntry(PropertyType.PERSISTENTSTATS, 1, "/{clusterName}/CONTROLLER/PERSISTENTSTATS");
+    addEntry(PropertyType.ALERTS, 1, "/{clusterName}/CONTROLLER/ALERTS");
+    addEntry(PropertyType.ALERT_STATUS, 1, "/{clusterName}/CONTROLLER/ALERT_STATUS");
+    addEntry(PropertyType.ALERT_HISTORY, 1, "/{clusterName}/CONTROLLER/ALERT_HISTORY");
+    // @formatter:on
+
+  }
+  static Pattern pattern = Pattern.compile("(\\{.+?\\})");
+
+  private static void addEntry(PropertyType type, int numKeys, String template)
+  {
+    if (!templateMap.containsKey(type))
+    {
+      templateMap.put(type, new HashMap<Integer, String>());
+    }
+    logger.trace("Adding template for type:" + type.getType() + " arguments:" + numKeys
+        + " template:" + template);
+    templateMap.get(type).put(numKeys, template);
+  }
+
+  public static String getPath(PropertyType type, String clusterName, String... keys)
+  {
+    if (clusterName == null)
+    {
+      logger.warn("ClusterName can't be null for type:" + type);
+      return null;
+    }
+    if (keys == null)
+    {
+      keys = new String[] {};
+    }
+    String template = null;
+    if (templateMap.containsKey(type))
+    {
+      // keys.length+1 since we add clusterName
+      template = templateMap.get(type).get(keys.length + 1);
+    }
+
+    String result = null;
+
+    if (template != null)
+    {
+      result = template;
+      Matcher matcher = pattern.matcher(template);
+      int count = 0;
+      while (matcher.find())
+      {
+        count = count + 1;
+        String var = matcher.group();
+        if (count == 1)
+        {
+          result = result.replace(var, clusterName);
+        } else
+        {
+          result = result.replace(var, keys[count - 2]);
+        }
+      }
+    }
+    if (result == null || result.indexOf('{') > -1 || result.indexOf('}') > -1)
+    {
+      logger.warn("Unable to instantiate template:" + template + " using clusterName:"
+          + clusterName + " and keys:" + Arrays.toString(keys));
+    }
+    return result;
+  }
+  public static String getInstanceNameFromPath(String path)
+  {
+    // path structure
+    // /<cluster_name>/instances/<instance_name>/[currentStates/messages]
+    if (path.contains("/" + PropertyType.INSTANCES + "/"))
+    {
+      String[] split = path.split("\\/");
+      if (split.length > 3)
+      {
+        return split[3];
+      }
+    }
+    return null;
+  }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/437eb42e/helix-core/src/main/java/org/apache/helix/PropertyType.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/PropertyType.java b/helix-core/src/main/java/org/apache/helix/PropertyType.java
new file mode 100644
index 0000000..f709a9e
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/PropertyType.java
@@ -0,0 +1,193 @@
+/**
+ * Copyright (C) 2012 LinkedIn Inc <op...@linkedin.com>
+ *
+ * Licensed 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.helix;
+
+
+enum Type
+{
+  CLUSTER, INSTANCE, CONTROLLER, RESOURCE;
+}
+
+public enum PropertyType
+{
+
+  // @formatter:off
+  // CLUSTER PROPERTIES
+  CONFIGS(Type.CLUSTER, true, false, false, false, true),
+  LIVEINSTANCES(Type.CLUSTER, false, false, false, true, true),
+  INSTANCES(Type.CLUSTER, true, false),
+  IDEALSTATES(Type.CLUSTER, true, false, false, false, true),
+  EXTERNALVIEW(Type.CLUSTER, true, false),
+  STATEMODELDEFS(Type.CLUSTER, true, false, false, false, true),
+  CONTROLLER(Type.CLUSTER, true, false),
+  PROPERTYSTORE(Type.CLUSTER, true, false),
+  HELIX_PROPERTYSTORE(Type.CLUSTER, true, false),
+
+  // INSTANCE PROPERTIES
+  MESSAGES(Type.INSTANCE, true, true, true),
+  CURRENTSTATES(Type.INSTANCE, true, true, false, false, true),
+  STATUSUPDATES(Type.INSTANCE, true, true, false, false, false, true),
+  ERRORS(Type.INSTANCE, true, true),
+  HEALTHREPORT(Type.INSTANCE, true, false, false, false, false, true),
+
+  // CONTROLLER PROPERTY
+  LEADER(Type.CONTROLLER, false, false, true, true),
+  HISTORY(Type.CONTROLLER, true, true, true),
+  PAUSE(Type.CONTROLLER, true, false, true),
+  MESSAGES_CONTROLLER(Type.CONTROLLER, true, false, true),
+  STATUSUPDATES_CONTROLLER(Type.CONTROLLER, true, true, true),
+  ERRORS_CONTROLLER(Type.CONTROLLER, true, true, true),
+  PERSISTENTSTATS(Type.CONTROLLER, true, false, false, false),
+  ALERTS(Type.CONTROLLER, true, false, false, false),
+  ALERT_STATUS(Type.CONTROLLER, true, false, false, false),
+  ALERT_HISTORY(Type.CONTROLLER, true, false, false, false);
+
+  // @formatter:on
+
+  Type    type;
+  
+  boolean isPersistent;
+
+  boolean mergeOnUpdate;
+
+  boolean updateOnlyOnExists;
+
+  boolean createOnlyIfAbsent;
+
+  /**
+   * "isCached" defines whether the property is cached in data accessor if data is cached,
+   * then read from zk can be optimized
+   */
+  boolean isCached;
+
+  boolean usePropertyTransferServer;
+
+  private PropertyType(Type type, boolean isPersistent, boolean mergeOnUpdate)
+  {
+    this(type, isPersistent, mergeOnUpdate, false);
+  }
+
+  private PropertyType(Type type,
+                       boolean isPersistent,
+                       boolean mergeOnUpdate,
+                       boolean updateOnlyOnExists)
+  {
+    this(type, isPersistent, mergeOnUpdate, false, false);
+  }
+
+  private PropertyType(Type type,
+                       boolean isPersistent,
+                       boolean mergeOnUpdate,
+                       boolean updateOnlyOnExists,
+                       boolean createOnlyIfAbsent)
+  {
+    this(type, isPersistent, mergeOnUpdate, updateOnlyOnExists, createOnlyIfAbsent, false);
+  }
+
+  private PropertyType(Type type,
+                       boolean isPersistent,
+                       boolean mergeOnUpdate,
+                       boolean updateOnlyOnExists,
+                       boolean createOnlyIfAbsent,
+                       boolean isCached)
+  {
+    this(type,
+         isPersistent,
+         mergeOnUpdate,
+         updateOnlyOnExists,
+         createOnlyIfAbsent,
+         isCached,
+         false);
+  }
+
+  private PropertyType(Type type,
+                       boolean isPersistent,
+                       boolean mergeOnUpdate,
+                       boolean updateOnlyOnExists,
+                       boolean createOnlyIfAbsent,
+                       boolean isCached,
+                       boolean isAsyncWrite)
+  {
+    this.type = type;
+    this.isPersistent = isPersistent;
+    this.mergeOnUpdate = mergeOnUpdate;
+    this.updateOnlyOnExists = updateOnlyOnExists;
+    this.createOnlyIfAbsent = createOnlyIfAbsent;
+    this.isCached = isCached;
+    this.usePropertyTransferServer = isAsyncWrite;
+  }
+
+  public boolean isCreateOnlyIfAbsent()
+  {
+    return createOnlyIfAbsent;
+  }
+
+  public void setCreateIfAbsent(boolean createIfAbsent)
+  {
+    this.createOnlyIfAbsent = createIfAbsent;
+  }
+
+  public Type getType()
+  {
+    return type;
+  }
+
+  public void setType(Type type)
+  {
+    this.type = type;
+  }
+
+  public boolean isPersistent()
+  {
+    return isPersistent;
+  }
+
+  public void setPersistent(boolean isPersistent)
+  {
+    this.isPersistent = isPersistent;
+  }
+
+  public boolean isMergeOnUpdate()
+  {
+    return mergeOnUpdate;
+  }
+
+  public void setMergeOnUpdate(boolean mergeOnUpdate)
+  {
+    this.mergeOnUpdate = mergeOnUpdate;
+  }
+
+  public boolean isUpdateOnlyOnExists()
+  {
+    return updateOnlyOnExists;
+  }
+
+  public void setUpdateOnlyOnExists(boolean updateOnlyOnExists)
+  {
+    this.updateOnlyOnExists = updateOnlyOnExists;
+  }
+
+  public boolean isCached()
+  {
+    return isCached;
+  }
+
+  public boolean usePropertyTransferServer()
+  {
+    return usePropertyTransferServer;
+  }
+
+}