Updated Branches:
  refs/heads/master d2abc0e27 -> 6e48383ef

moved out user dispsersing deployment planner


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

Branch: refs/heads/master
Commit: 6e48383ef8f9f44c0076277c90ff2d3e882926b7
Parents: 04b92c9
Author: Alex Huang <[email protected]>
Authored: Wed Jun 20 16:03:04 2012 -0700
Committer: Alex Huang <[email protected]>
Committed: Wed Jun 20 16:08:51 2012 -0700

----------------------------------------------------------------------
 .../deployment-planners/user-dispersing/.classpath |   10 +
 .../deployment-planners/user-dispersing/.project   |   17 ++
 .../.settings/org.eclipse.jdt.core.prefs           |   12 +
 .../deployment-planners/user-dispersing/build.xml  |  128 +++++++++
 .../com/cloud/deploy/UserDispersingPlanner.java    |  215 +++++++++++++++
 5 files changed, 382 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e48383e/plugins/deployment-planners/user-dispersing/.classpath
----------------------------------------------------------------------
diff --git a/plugins/deployment-planners/user-dispersing/.classpath 
b/plugins/deployment-planners/user-dispersing/.classpath
new file mode 100755
index 0000000..a246f5e
--- /dev/null
+++ b/plugins/deployment-planners/user-dispersing/.classpath
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+       <classpathentry kind="src" path="src"/>
+       <classpathentry kind="con" 
path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
+       <classpathentry combineaccessrules="false" kind="src" path="/api"/>
+       <classpathentry combineaccessrules="false" kind="src" path="/core"/>
+       <classpathentry combineaccessrules="false" kind="src" path="/server"/>
+       <classpathentry combineaccessrules="false" kind="src" path="/utils"/>
+       <classpathentry kind="output" path="bin"/>
+</classpath>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e48383e/plugins/deployment-planners/user-dispersing/.project
----------------------------------------------------------------------
diff --git a/plugins/deployment-planners/user-dispersing/.project 
b/plugins/deployment-planners/user-dispersing/.project
new file mode 100755
index 0000000..d9b2d40
--- /dev/null
+++ b/plugins/deployment-planners/user-dispersing/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+       <name>user-dispersing</name>
+       <comment></comment>
+       <projects>
+       </projects>
+       <buildSpec>
+               <buildCommand>
+                       <name>org.eclipse.jdt.core.javabuilder</name>
+                       <arguments>
+                       </arguments>
+               </buildCommand>
+       </buildSpec>
+       <natures>
+               <nature>org.eclipse.jdt.core.javanature</nature>
+       </natures>
+</projectDescription>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e48383e/plugins/deployment-planners/user-dispersing/.settings/org.eclipse.jdt.core.prefs
----------------------------------------------------------------------
diff --git 
a/plugins/deployment-planners/user-dispersing/.settings/org.eclipse.jdt.core.prefs
 
b/plugins/deployment-planners/user-dispersing/.settings/org.eclipse.jdt.core.prefs
new file mode 100755
index 0000000..d0ee7df
--- /dev/null
+++ 
b/plugins/deployment-planners/user-dispersing/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
+#Tue Jun 19 15:34:37 PDT 2012
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.7
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.7

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e48383e/plugins/deployment-planners/user-dispersing/build.xml
----------------------------------------------------------------------
diff --git a/plugins/deployment-planners/user-dispersing/build.xml 
b/plugins/deployment-planners/user-dispersing/build.xml
new file mode 100755
index 0000000..ba72332
--- /dev/null
+++ b/plugins/deployment-planners/user-dispersing/build.xml
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+
+
+<project name="Cloud Stack User Dispersing Deployment Planner" default="help" 
basedir=".">
+  <description>
+               Cloud Stack ant build file
+    </description>
+
+  <dirname property="dp-user-dispersing.base.dir" file="${ant.file.Cloud Stack 
User Dispersing Deployment Planner}/"/>
+  <!-- This directory must be set -->
+  <property name="top.dir" location="${dp-user-dispersing.base.dir}/../../.."/>
+  <property name="build.dir" location="${top.dir}/build"/>
+       
+       <echo message="build.dir=${build.dir}; top.dir=${top.dir}; 
dp-user-dispersing.base.dir=${dp-user-dispersing.base.dir}"/>
+
+  <!-- Import anything that the user wants to set-->
+  <!-- Import properties files and environment variables here -->
+
+  <property environment="env" />
+
+  <condition property="build-cloud.properties.file" 
value="${build.dir}/override/build-cloud.properties" 
else="${build.dir}/build-cloud.properties">
+    <available file="${build.dir}/override/build-cloud.properties" />
+  </condition>
+
+  <condition property="cloud.properties.file" 
value="${build.dir}/override/cloud.properties" 
else="${build.dir}/cloud.properties">
+    <available file="${build.dir}/override/cloud.properties" />
+  </condition>
+
+  <condition property="override.file" 
value="${build.dir}/override/replace.properties" 
else="${build.dir}/replace.properties">
+    <available file="${build.dir}/override/replace.properties" />
+  </condition>
+
+  <echo message="Using build parameters from ${build-cloud.properties.file}" />
+  <property file="${build-cloud.properties.file}" />
+
+  <echo message="Using company info from ${cloud.properties.file}" />
+  <property file="${cloud.properties.file}" />
+
+  <echo message="Using override file from ${override.file}" />
+  <property file="${override.file}" />
+
+  <property file="${build.dir}/build.number" />
+
+  <!-- In case these didn't get defined in the build-cloud.properties -->
+  <property name="branding.name" value="default" />
+  <property name="deprecation" value="off" />
+  <property name="target.compat.version" value="1.6" />
+  <property name="source.compat.version" value="1.6" />
+  <property name="debug" value="true" />
+  <property name="debuglevel" value="lines,source"/>
+
+  <echo message="target.dir=${target.dir}; top.dir=${top.dir}"/>
+  <!-- directories for build and distribution -->
+  <property name="target.dir" location="${top.dir}/target" />
+  <property name="classes.dir" location="${target.dir}/classes" />
+  <property name="jar.dir" location="${target.dir}/jar" />
+  <property name="dep.cache.dir" location="${target.dir}/dep-cache" />
+  <property name="build.log" location="${target.dir}/ant_verbose.txt" />
+
+  <property name="deps.dir" location="${top.dir}/deps" />
+  
+  <property name="dp-user-dispersing.jar" value="cloud-dp-user-dispersing.jar" 
/>
+  <property name="dp-user-dispersing-scripts.dir" 
location="${dp-user-dispersing.base.dir}/scripts" />
+       
+  <import file="${build.dir}/build-common.xml"/>
+
+  <echo message="target.dir=${target.dir}; top.dir=${top.dir}"/>
+       
+  <!-- This section needs to be replaced by some kind of dependency library-->
+  <path id="deps.classpath">
+    <!--filelist files="${deps.classpath}" /-->
+    <fileset dir="${deps.dir}" erroronmissingdir="false">
+      <include name="*.jar" />
+    </fileset>
+  </path>
+       
+  <path id="cloudstack.classpath">
+       <fileset dir="${jar.dir}">
+         <include name="*.jar"/>
+    </fileset>
+  </path>
+       
+  <path id="dp-user-dispersing.classpath">
+       <path refid="deps.classpath"/>
+       <path refid="cloudstack.classpath"/>
+  </path>
+       
+  <!-- This section needs to be replaced by some kind of dependency library-->
+       
+       
+  <target name="init" description="Initialize binaries directory">
+       <mkdir dir="${classes.dir}/${dp-user-dispersing.jar}"/>
+       <mkdir dir="${jar.dir}"/>
+  </target>
+       
+  <target name="compile-dp-user-dispersing" depends="init" 
description="Compile dp-user-dispersing">
+    <compile-java jar.name="${dp-user-dispersing.jar}" 
top.dir="${dp-user-dispersing.base.dir}" 
classpath="dp-user-dispersing.classpath" />
+  </target>
+       
+  <target name="help" description="help">
+    <echo level="info" message="This is the build file for 
dp-user-dispersing"/>
+    <echo level="info" message="You can do a build by doing ant build or clean 
by ant clean" />
+  </target>
+
+  <target name="clean-dp-user-dispersing">
+    <delete dir="${classes.dir}/${dp-user-dispersing.jar}"/>
+  </target>
+       
+  <target name="build" depends="compile-dp-user-dispersing"/>
+  <target name="clean" depends="clean-dp-user-dispersing"/>
+       
+</project>

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/6e48383e/plugins/deployment-planners/user-dispersing/src/com/cloud/deploy/UserDispersingPlanner.java
----------------------------------------------------------------------
diff --git 
a/plugins/deployment-planners/user-dispersing/src/com/cloud/deploy/UserDispersingPlanner.java
 
b/plugins/deployment-planners/user-dispersing/src/com/cloud/deploy/UserDispersingPlanner.java
new file mode 100755
index 0000000..dcad1e7
--- /dev/null
+++ 
b/plugins/deployment-planners/user-dispersing/src/com/cloud/deploy/UserDispersingPlanner.java
@@ -0,0 +1,215 @@
+// Copyright 2012 Citrix Systems, Inc. Licensed under the
+// Apache License, Version 2.0 (the "License"); you may not use this
+// file except in compliance with the License.  Citrix Systems, Inc.
+// reserves all rights not expressly granted by 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.
+// 
+// Automatically generated by addcopyright.py at 04/03/2012
+package com.cloud.deploy;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.ejb.Local;
+import javax.naming.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import com.cloud.configuration.Config;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
+import com.cloud.utils.NumbersUtil;
+import com.cloud.utils.Pair;
+import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachineProfile;
+
+@Local(value=DeploymentPlanner.class)
+public class UserDispersingPlanner extends FirstFitPlanner implements 
DeploymentPlanner {
+
+    private static final Logger s_logger = 
Logger.getLogger(UserDispersingPlanner.class);
+    
+    /**
+     * This method should reorder the given list of Cluster Ids by applying 
any necessary heuristic 
+     * for this planner
+     * For UserDispersingPlanner we need to order the clusters by considering 
the number of VMs for this account
+     * @return List<Long> ordered list of Cluster Ids
+     */
+    @Override
+    protected List<Long> reorderClusters(long id, boolean isZone, 
Pair<List<Long>, Map<Long, Double>> clusterCapacityInfo, 
VirtualMachineProfile<? extends VirtualMachine> vmProfile, DeploymentPlan plan){
+        List<Long> clusterIdsByCapacity = clusterCapacityInfo.first();
+        if(vmProfile.getOwner() == null){
+            return clusterIdsByCapacity;
+        }
+        long accountId = vmProfile.getOwner().getAccountId(); 
+        Pair<List<Long>, Map<Long, Double>> clusterIdsVmCountInfo = 
listClustersByUserDispersion(id, isZone, accountId);
+
+        //now we have 2 cluster lists - one ordered by capacity and the other 
by number of VMs for this account
+        //need to apply weights to these to find the correct ordering to follow
+        
+        if(_userDispersionWeight == 1.0f){
+            List<Long> clusterIds = clusterIdsVmCountInfo.first();
+            clusterIds.retainAll(clusterIdsByCapacity);
+            return clusterIds;
+        }else{
+            //apply weights to the two lists
+            return orderByApplyingWeights(clusterCapacityInfo, 
clusterIdsVmCountInfo, accountId);
+         }
+        
+        
+    }
+    
+    /**
+     * This method should reorder the given list of Pod Ids by applying any 
necessary heuristic 
+     * for this planner
+     * For UserDispersingPlanner we need to order the pods by considering the 
number of VMs for this account
+     * @return List<Long> ordered list of Pod Ids
+     */
+    @Override
+    protected List<Long> reorderPods(Pair<List<Long>, Map<Long, Double>> 
podCapacityInfo, VirtualMachineProfile<? extends VirtualMachine> vmProfile, 
DeploymentPlan plan){
+        List<Long> podIdsByCapacity = podCapacityInfo.first();
+        if(vmProfile.getOwner() == null){
+            return podIdsByCapacity;
+        }
+        long accountId = vmProfile.getOwner().getAccountId(); 
+        
+        Pair<List<Long>, Map<Long, Double>> podIdsVmCountInfo = 
listPodsByUserDispersion(plan.getDataCenterId(), accountId);
+
+        //now we have 2 pod lists - one ordered by capacity and the other by 
number of VMs for this account
+        //need to apply weights to these to find the correct ordering to follow
+        
+        if(_userDispersionWeight == 1.0f){
+            List<Long> podIds = podIdsVmCountInfo.first();
+            podIds.retainAll(podIdsByCapacity);
+            return podIds;
+        }else{
+            //apply weights to the two lists
+            return orderByApplyingWeights(podCapacityInfo, podIdsVmCountInfo, 
accountId);
+         }
+        
+    }
+
+    protected Pair<List<Long>, Map<Long, Double>> 
listClustersByUserDispersion(long id, boolean isZone, long accountId){
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Applying Userdispersion heuristic to clusters for 
account: "+ accountId);
+        }
+        Pair<List<Long>, Map<Long, Double>> clusterIdsVmCountInfo;
+        if(isZone){
+            clusterIdsVmCountInfo = 
_vmInstanceDao.listClusterIdsInZoneByVmCount(id, accountId);
+        }else{
+            clusterIdsVmCountInfo = 
_vmInstanceDao.listClusterIdsInPodByVmCount(id, accountId);
+        }
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("List of clusters in ascending order of number of 
VMs: "+ clusterIdsVmCountInfo.first());
+        }
+        return clusterIdsVmCountInfo;
+    }
+    
+    protected Pair<List<Long>, Map<Long, Double>> 
listPodsByUserDispersion(long dataCenterId, long accountId) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Applying Userdispersion heuristic to pods for 
account: "+ accountId);
+        }
+        Pair<List<Long>, Map<Long, Double>> podIdsVmCountInfo = 
_vmInstanceDao.listPodIdsInZoneByVmCount(dataCenterId, accountId);
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("List of pods in ascending order of number of VMs: 
"+ podIdsVmCountInfo.first());
+        }
+        
+        return podIdsVmCountInfo;
+    }
+    
+    
+    private List<Long> orderByApplyingWeights(Pair<List<Long>, Map<Long, 
Double>> capacityInfo, Pair<List<Long>, Map<Long, Double>> vmCountInfo, long 
accountId){
+        List<Long> capacityOrderedIds = capacityInfo.first();
+        List<Long> vmCountOrderedIds = vmCountInfo.first();
+        Map<Long, Double> capacityMap = capacityInfo.second();
+        Map<Long, Double> vmCountMap = vmCountInfo.second();
+
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Capacity Id list: "+ capacityOrderedIds + " , 
capacityMap:"+capacityMap);
+        }        
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Vm Count Id list: "+ vmCountOrderedIds + " , 
vmCountMap:"+vmCountMap);
+        }        
+
+        
+        List<Long> idsReorderedByWeights = new ArrayList<Long>();
+        float capacityWeight = (1.0f -_userDispersionWeight);
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Applying userDispersionWeight: "+ 
_userDispersionWeight);
+        }        
+        //normalize the vmCountMap
+        LinkedHashMap<Long, Double> normalisedVmCountIdMap= new 
LinkedHashMap<Long, Double>();
+        
+        Long totalVmsOfAccount = 
_vmInstanceDao.countRunningByAccount(accountId);
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Total VMs for account: "+ totalVmsOfAccount);
+        }            
+        for(Long id : vmCountOrderedIds){
+            Double normalisedCount = vmCountMap.get(id) / totalVmsOfAccount;
+            normalisedVmCountIdMap.put(id, normalisedCount);
+        }
+        
+        //consider only those ids that are in capacity map.
+        
+        SortedMap<Double, List<Long>> sortedMap= new TreeMap<Double, 
List<Long>>();
+        for(Long id : capacityOrderedIds){
+            Double weightedCapacityValue = capacityMap.get(id) * 
capacityWeight;
+            Double weightedVmCountValue = normalisedVmCountIdMap.get(id) * 
_userDispersionWeight;
+            Double totalWeight = weightedCapacityValue + weightedVmCountValue;
+            if(sortedMap.containsKey(totalWeight)){
+                List<Long> idList = sortedMap.get(totalWeight);
+                idList.add(id);
+                sortedMap.put(totalWeight, idList);
+            }else{
+                List<Long> idList = new ArrayList<Long>();
+                idList.add(id);
+                sortedMap.put(totalWeight, idList);
+            }
+        }
+        
+        for(List<Long> idList : sortedMap.values()){
+            idsReorderedByWeights.addAll(idList);
+        }
+        
+        if (s_logger.isTraceEnabled()) {
+            s_logger.trace("Reordered Id list: "+ idsReorderedByWeights);
+        }        
+        
+        return idsReorderedByWeights;
+    }
+    
+
+    @Override
+    public boolean canHandle(VirtualMachineProfile<? extends VirtualMachine> 
vm, DeploymentPlan plan, ExcludeList avoid) {
+        if(vm.getHypervisorType() != HypervisorType.BareMetal){
+            //check the allocation strategy
+            if (_allocationAlgorithm != null && 
_allocationAlgorithm.equals(AllocationAlgorithm.userdispersing.toString())) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    float _userDispersionWeight;
+
+    
+    @Override
+    public boolean configure(String name, Map<String, Object> params) throws 
ConfigurationException {
+        super.configure(name, params);
+        
+        String weight = 
_configDao.getValue(Config.VmUserDispersionWeight.key());
+        _userDispersionWeight = NumbersUtil.parseFloat(weight, 1.0f);
+        
+
+        return true;
+    }    
+
+}

Reply via email to