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 2013/12/11 00:41:15 UTC

git commit: Initial provisioning code

Updated Branches:
  refs/heads/helix-provisioning [created] c3aca96f1


Initial provisioning code


Project: http://git-wip-us.apache.org/repos/asf/incubator-helix/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-helix/commit/c3aca96f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-helix/tree/c3aca96f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-helix/diff/c3aca96f

Branch: refs/heads/helix-provisioning
Commit: c3aca96f1ca938edc483c853c361d5450612a558
Parents: 80fc2be
Author: Kishore Gopalakrishna <g....@gmail.com>
Authored: Tue Dec 10 15:41:01 2013 -0800
Committer: Kishore Gopalakrishna <g....@gmail.com>
Committed: Tue Dec 10 15:41:01 2013 -0800

----------------------------------------------------------------------
 .../apache/helix/api/config/ResourceConfig.java |   5 +
 .../controller/provisioner/ContainerId.java     |  30 +++++
 .../provisioner/ContainerProvider.java          |  15 +++
 .../provisioner/ContainerProviderFactory.java   |   5 +
 .../controller/provisioner/ContainerSpec.java   |  13 +++
 .../controller/provisioner/ContainerState.java  |   5 +
 .../provisioner/ParticipantContainer.java       |  13 +++
 .../controller/provisioner/Provisioner.java     |   9 ++
 .../provisioner/ProvisionerConfig.java          |   5 +
 .../provisioner/ProvisionerContext.java         |   5 +
 .../controller/provisioner/TargetProvider.java  |  24 ++++
 .../provisioner/TargetProviderInput.java        |  15 +++
 .../provisioner/TargetProviderResponse.java     |  52 +++++++++
 .../stages/ContainerProvisioningStage.java      | 110 +++++++++++++++++++
 14 files changed, 306 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/api/config/ResourceConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/api/config/ResourceConfig.java b/helix-core/src/main/java/org/apache/helix/api/config/ResourceConfig.java
index b148a49..0aedfaf 100644
--- a/helix-core/src/main/java/org/apache/helix/api/config/ResourceConfig.java
+++ b/helix-core/src/main/java/org/apache/helix/api/config/ResourceConfig.java
@@ -7,6 +7,7 @@ import org.apache.helix.api.Partition;
 import org.apache.helix.api.Scope;
 import org.apache.helix.api.id.PartitionId;
 import org.apache.helix.api.id.ResourceId;
+import org.apache.helix.controller.provisioner.ProvisionerConfig;
 import org.apache.helix.controller.rebalancer.config.RebalancerConfig;
 
 import com.google.common.collect.Sets;
@@ -366,4 +367,8 @@ public class ResourceConfig {
           _bucketSize, _batchMessageMode);
     }
   }
+
+  public ProvisionerConfig getProvisionerConfig() {
+    return null;
+  }
 }

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerId.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerId.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerId.java
new file mode 100644
index 0000000..49bc0fc
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerId.java
@@ -0,0 +1,30 @@
+package org.apache.helix.controller.provisioner;
+
+import org.apache.helix.api.id.Id;
+
+public class ContainerId extends Id {
+
+  String id;
+
+  private ContainerId(String containerId) {
+    this.id = containerId;
+  }
+
+  @Override
+  public String stringify() {
+    return id;
+  }
+
+  /**
+   * Get a concrete partition id
+   * @param partitionId string partition identifier
+   * @return PartitionId
+   */
+  public static ContainerId from(String containerId) {
+    if (containerId == null) {
+      return null;
+    }
+    return new ContainerId(containerId);
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProvider.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProvider.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProvider.java
new file mode 100644
index 0000000..2bc5aab
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProvider.java
@@ -0,0 +1,15 @@
+package org.apache.helix.controller.provisioner;
+
+
+public interface ContainerProvider {
+	
+	ContainerId allocateContainer(ContainerSpec spec);
+	
+	boolean deallocateContainer(ContainerId containerId);
+	
+	boolean startContainer(ContainerId containerId);
+	
+	boolean stopContainer(ContainerId containerId);
+	
+	ContainerState getContainerState(ContainerId  containerId); 
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProviderFactory.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProviderFactory.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProviderFactory.java
new file mode 100644
index 0000000..fd79317
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerProviderFactory.java
@@ -0,0 +1,5 @@
+package org.apache.helix.controller.provisioner;
+
+public class ContainerProviderFactory {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerSpec.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerSpec.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerSpec.java
new file mode 100644
index 0000000..6ca3fa0
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerSpec.java
@@ -0,0 +1,13 @@
+package org.apache.helix.controller.provisioner;
+
+public class ContainerSpec {
+  /**
+   * Some unique id representing the container.
+   */
+  ContainerId containerId;
+
+  public ContainerId getContainerId() {
+    return containerId;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerState.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerState.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerState.java
new file mode 100644
index 0000000..421ff3d
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ContainerState.java
@@ -0,0 +1,5 @@
+package org.apache.helix.controller.provisioner;
+
+public enum ContainerState {
+	ACQUIRE, CONNECTING, ACTIVE, TEARDOWN, FAILED, HALTED, FINALIZE
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ParticipantContainer.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ParticipantContainer.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ParticipantContainer.java
new file mode 100644
index 0000000..84b69e5
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ParticipantContainer.java
@@ -0,0 +1,13 @@
+package org.apache.helix.controller.provisioner;
+
+public class ParticipantContainer {
+
+  /**
+   * Id request by the target provider
+   */
+  String requestId;
+  
+  String allocatedId;
+  
+  
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/Provisioner.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/Provisioner.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/Provisioner.java
new file mode 100644
index 0000000..98c4f9b
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/Provisioner.java
@@ -0,0 +1,9 @@
+package org.apache.helix.controller.provisioner;
+
+
+public interface Provisioner extends ContainerProvider, TargetProvider{
+
+  
+
+ 
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerConfig.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerConfig.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerConfig.java
new file mode 100644
index 0000000..58c099f
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerConfig.java
@@ -0,0 +1,5 @@
+package org.apache.helix.controller.provisioner;
+
+public interface ProvisionerConfig {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerContext.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerContext.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerContext.java
new file mode 100644
index 0000000..f00042f
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/ProvisionerContext.java
@@ -0,0 +1,5 @@
+package org.apache.helix.controller.provisioner;
+
+public interface ProvisionerContext {
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProvider.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProvider.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProvider.java
new file mode 100644
index 0000000..82c7d3b
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProvider.java
@@ -0,0 +1,24 @@
+package org.apache.helix.controller.provisioner;
+
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.helix.HelixManager;
+import org.apache.helix.api.Cluster;
+import org.apache.helix.api.Participant;
+import org.apache.helix.api.id.ResourceId;
+
+public interface TargetProvider {
+
+  public void init(HelixManager helixManager);
+
+ /**
+  * @param cluster
+  * @param resourceId ResourceId name of the resource
+  * @param participants
+  * @return
+  */
+  TargetProviderResponse evaluateExistingContainers(Cluster cluster,ResourceId resourceId,
+      Collection<Participant> participants);
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderInput.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderInput.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderInput.java
new file mode 100644
index 0000000..064e422
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderInput.java
@@ -0,0 +1,15 @@
+package org.apache.helix.controller.provisioner;
+
+import java.util.List;
+
+import org.apache.helix.api.Participant;
+
+/**
+ * 
+ *
+ */
+public class TargetProviderInput {
+
+  List<ContainerSpec> containersToBeAcquired;
+  List<Participant> existingParticipants;
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderResponse.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderResponse.java b/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderResponse.java
new file mode 100644
index 0000000..ecd8a16
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/provisioner/TargetProviderResponse.java
@@ -0,0 +1,52 @@
+package org.apache.helix.controller.provisioner;
+
+import java.util.List;
+
+import org.apache.helix.api.Participant;
+
+public class TargetProviderResponse {
+  
+  List<ContainerSpec> containersToAcquire;
+
+  List<Participant> containersToRelease;
+
+  List<Participant> containersToStop;
+
+  List<Participant> containersToStart;
+
+  public List<ContainerSpec> getContainersToAcquire() {
+    return containersToAcquire;
+  }
+
+  public void setContainersToAcquire(List<ContainerSpec> containersToAcquire) {
+    this.containersToAcquire = containersToAcquire;
+  }
+
+  public List<Participant> getContainersToRelease() {
+    return containersToRelease;
+  }
+
+  public void setContainersToRelease(List<Participant> containersToRelease) {
+    this.containersToRelease = containersToRelease;
+  }
+
+  public List<Participant> getContainersToStop() {
+    return containersToStop;
+  }
+
+  public void setContainersToStop(List<Participant> containersToStop) {
+    this.containersToStop = containersToStop;
+  }
+
+  public List<Participant> getContainersToStart() {
+    return containersToStart;
+  }
+
+  public void setContainersToStart(List<Participant> containersToStart) {
+    this.containersToStart = containersToStart;
+  }
+
+
+  
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-helix/blob/c3aca96f/helix-core/src/main/java/org/apache/helix/controller/stages/ContainerProvisioningStage.java
----------------------------------------------------------------------
diff --git a/helix-core/src/main/java/org/apache/helix/controller/stages/ContainerProvisioningStage.java b/helix-core/src/main/java/org/apache/helix/controller/stages/ContainerProvisioningStage.java
new file mode 100644
index 0000000..a7ffc99
--- /dev/null
+++ b/helix-core/src/main/java/org/apache/helix/controller/stages/ContainerProvisioningStage.java
@@ -0,0 +1,110 @@
+package org.apache.helix.controller.stages;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.helix.HelixAdmin;
+import org.apache.helix.HelixManager;
+import org.apache.helix.api.Cluster;
+import org.apache.helix.api.Participant;
+import org.apache.helix.api.config.ResourceConfig;
+import org.apache.helix.api.id.ParticipantId;
+import org.apache.helix.api.id.ResourceId;
+import org.apache.helix.controller.pipeline.AbstractBaseStage;
+import org.apache.helix.controller.provisioner.ContainerId;
+import org.apache.helix.controller.provisioner.ContainerSpec;
+import org.apache.helix.controller.provisioner.Provisioner;
+import org.apache.helix.controller.provisioner.ProvisionerConfig;
+import org.apache.helix.controller.provisioner.TargetProvider;
+import org.apache.helix.controller.provisioner.TargetProviderResponse;
+import org.apache.helix.util.HelixUtil;
+
+/**
+ * This stage will manager the container allocation/deallocation needed for a
+ * specific resource.<br/>
+ * It does the following <br/>
+ * From the idealstate, it gets ContainerTargetProvider and ContainerProvider <br/>
+ * ContainerTargetProviderFactory will provide the number of containers needed
+ * for a resource <br/>
+ * ContainerProvider will provide the ability to allocate, deallocate, start,
+ * stop container <br/>
+ */
+public class ContainerProvisioningStage extends AbstractBaseStage {
+
+  Map<ResourceId, Provisioner> _provisionerMap = new HashMap<ResourceId, Provisioner>();
+
+  @Override
+  public void process(ClusterEvent event) throws Exception {
+    HelixManager helixManager = event.getAttribute("helixmanager");
+    Map<ResourceId, ResourceConfig> resourceMap =
+        event.getAttribute(AttributeName.RESOURCES.toString());
+    HelixAdmin helixAdmin = helixManager.getClusterManagmentTool();
+    for (ResourceId resourceId : resourceMap.keySet()) {
+      ResourceConfig resourceConfig = resourceMap.get(resourceId);
+      ProvisionerConfig provisionerConfig = resourceConfig.getProvisionerConfig();
+      if (provisionerConfig != null) {
+        Provisioner provisioner;
+        provisioner = _provisionerMap.get(resourceId);
+
+        if (provisioner == null) {
+          String provisionerClass = resourceConfig.getProvisionerClass();
+          provisioner =
+              (Provisioner) (HelixUtil.loadClass(getClass(), provisionerClass).newInstance());
+          _provisionerMap.put(resourceId, provisioner);
+        }
+
+        Cluster cluster = event.getAttribute("clusterDataCache");
+        Collection<Participant> participants = cluster.getParticipantMap().values();
+        
+        //Participants registered in helix
+        //Give those participants to targetprovider
+        //Provide the response that contains, new containerspecs, containers to be released, containers to be stopped
+        //call the respective provisioner to allocate and start the container. 
+        //Each container is then started its state is changed from any place.
+        //The target provider is given the state of container and asked for its new state. For each state there is a corresponding handler function.
+        
+        //TargetProvider should be stateless, given the state of cluster and existing participants it should return the same result
+        TargetProviderResponse response = provisioner.evaluateExistingContainers(cluster,resourceId, participants);
+        
+        //start new containers
+        for(Participant participant: response.getContainersToStart()){
+          String containerIdStr = participant.getUserConfig().getSimpleField("ContainerId");
+          ContainerId containerId = ContainerId.from(containerIdStr);
+          //create the helix participant and add it to cluster
+          provisioner.startContainer(containerId);
+        }
+        
+        //allocate new containers
+        for(ContainerSpec spec: response.getContainersToAcquire()){
+          //create a new Participant, attach the container spec
+          //create a helix_participant in ACQUIRING STATE
+          ContainerId containerId = provisioner.allocateContainer(spec);
+          //create the helix participant and add it to cluster
+          provisioner.startContainer(containerId);
+        }
+        
+        //release containers
+        for(Participant participant: response.getContainersToRelease()){
+          String containerIdStr = participant.getUserConfig().getSimpleField("ContainerId");
+          ContainerId containerId = ContainerId.from(containerIdStr);
+          //disable the node first
+          provisioner.stopContainer(containerId);
+          //this will change the container state
+          provisioner.deallocateContainer(containerId);
+          //remove the participant
+        }
+
+        //stop but dont remove
+        for(Participant participant: participants){
+          String containerIdStr = participant.getUserConfig().getSimpleField("ContainerId");
+          ContainerId containerId = ContainerId.from(containerIdStr);
+          provisioner.stopContainer(containerId);
+        }
+      }
+    }
+  }
+}