Repository: stratos Updated Branches: refs/heads/master 3a6d76c78 -> afbf95a04
supporting nested level group scaling with more than one level Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/afbf95a0 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/afbf95a0 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/afbf95a0 Branch: refs/heads/master Commit: afbf95a047f5af71ce6e627fa78ad7a25cd2910d Parents: 3a6d76c Author: reka <[email protected]> Authored: Fri Jun 19 15:45:27 2015 +0530 Committer: reka <[email protected]> Committed: Fri Jun 19 15:45:47 2015 +0530 ---------------------------------------------------------------------- .../network/NetworkPartitionContext.java | 5 +- .../ParentLevelNetworkPartitionContext.java | 69 ++++++++++++++ .../AutoscalerTopologyEventReceiver.java | 2 +- .../stratos/autoscaler/monitor/Monitor.java | 23 ++++- .../monitor/component/GroupMonitor.java | 95 +++++++++++--------- 5 files changed, 146 insertions(+), 48 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/afbf95a0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/NetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/NetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/NetworkPartitionContext.java index 563c415..4335f01 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/NetworkPartitionContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/NetworkPartitionContext.java @@ -23,6 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.stratos.autoscaler.context.InstanceContext; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; /** * This will keep track of network partition level information. @@ -32,12 +33,12 @@ public abstract class NetworkPartitionContext { //id of the network partition context protected final String id; //group instances kept inside a partition - private Map<String, InstanceContext> instanceIdToInstanceContextMap; + protected Map<String, InstanceContext> instanceIdToInstanceContextMap; private int pendingMembersFailureCount = 0; protected NetworkPartitionContext(String id) { this.id = id; - instanceIdToInstanceContextMap = new HashMap<String, InstanceContext>(); + instanceIdToInstanceContextMap = new ConcurrentHashMap<String, InstanceContext>(); } http://git-wip-us.apache.org/repos/asf/stratos/blob/afbf95a0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/ParentLevelNetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/ParentLevelNetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/ParentLevelNetworkPartitionContext.java index b119410..3367e7a 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/ParentLevelNetworkPartitionContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/ParentLevelNetworkPartitionContext.java @@ -27,6 +27,7 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; /** * Holds runtime data of a network partition. @@ -167,6 +168,16 @@ public class ParentLevelNetworkPartitionContext extends NetworkPartitionContext this.requiredInstanceCountBasedOnStats = requiredInstanceCountBasedOnStats; } + public List<InstanceContext> getInstanceIdToInstanceContextMap(String parentInstanceId) { + List<InstanceContext> instanceContexts = new ArrayList<InstanceContext>(); + for(InstanceContext instanceContext : instanceIdToInstanceContextMap.values()) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + return instanceContexts; + } + public int getRequiredInstanceCountBasedOnDependencies() { return requiredInstanceCountBasedOnDependencies; } @@ -208,6 +219,16 @@ public class ParentLevelNetworkPartitionContext extends NetworkPartitionContext return activeInstances; } + public List<InstanceContext> getActiveInstances(String parentInstanceId) { + List<InstanceContext> instanceContexts = new ArrayList<InstanceContext>(); + for(InstanceContext instanceContext : activeInstances) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + return instanceContexts; + } + public void setActiveInstances(List<InstanceContext> activeInstances) { this.activeInstances = activeInstances; } @@ -216,6 +237,16 @@ public class ParentLevelNetworkPartitionContext extends NetworkPartitionContext return pendingInstances; } + public List<InstanceContext> getPendingInstances(String parentInstanceId) { + List<InstanceContext> instanceContexts = new ArrayList<InstanceContext>(); + for(InstanceContext instanceContext : pendingInstances) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + return instanceContexts; + } + public void setPendingInstances(List<InstanceContext> pendingInstances) { this.pendingInstances = pendingInstances; } @@ -228,10 +259,31 @@ public class ParentLevelNetworkPartitionContext extends NetworkPartitionContext return this.pendingInstances.size(); } + public int getPendingInstancesCount(String parentInstanceId) { + List<InstanceContext> instanceContexts = new ArrayList<InstanceContext>(); + for(InstanceContext instanceContext : pendingInstances) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + return instanceContexts.size(); + } + + public int getActiveInstancesCount() { return this.activeInstances.size(); } + public int getActiveInstancesCount(String parentInstanceId) { + List<InstanceContext> instanceContexts = new ArrayList<InstanceContext>(); + for(InstanceContext instanceContext : activeInstances) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + return instanceContexts.size(); + } + public InstanceContext getActiveInstance(String instanceId) { for (InstanceContext instanceContext : activeInstances) { if (instanceId.equals(instanceContext.getId())) { @@ -339,6 +391,23 @@ public class ParentLevelNetworkPartitionContext extends NetworkPartitionContext return this.activeInstances.size() + this.pendingInstances.size(); } + public int getNonTerminatedInstancesCount(String parentInstanceId) { + List<InstanceContext> instanceContexts = new ArrayList<InstanceContext>(); + + for(InstanceContext instanceContext : activeInstances) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + + for(InstanceContext instanceContext : pendingInstances) { + if(instanceContext.getParentInstanceId().equals(parentInstanceId)) { + instanceContexts.add(instanceContext); + } + } + return instanceContexts.size(); + } + public List<InstanceContext> getTerminatingPending() { return terminatingPending; } http://git-wip-us.apache.org/repos/asf/stratos/blob/afbf95a0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/event/receiver/topology/AutoscalerTopologyEventReceiver.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/event/receiver/topology/AutoscalerTopologyEventReceiver.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/event/receiver/topology/AutoscalerTopologyEventReceiver.java index dd034cc..0ae4385 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/event/receiver/topology/AutoscalerTopologyEventReceiver.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/event/receiver/topology/AutoscalerTopologyEventReceiver.java @@ -322,7 +322,7 @@ public class AutoscalerTopologyEventReceiver { monitor.notifyParentMonitor(ClusterStatus.Terminated, instanceId); //Removing the instance and instanceContext ClusterInstance instance = (ClusterInstance) monitor.getInstance(instanceId); - ((ClusterContext) monitor.getClusterContext()). + monitor.getClusterContext(). getNetworkPartitionCtxt(instance.getNetworkPartitionId()). removeInstanceContext(instanceId); monitor.removeInstance(instanceId); http://git-wip-us.apache.org/repos/asf/stratos/blob/afbf95a0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java index 07d791f..e6560f2 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java @@ -21,10 +21,7 @@ package org.apache.stratos.autoscaler.monitor; import org.apache.stratos.autoscaler.monitor.component.ParentComponentMonitor; import org.apache.stratos.messaging.domain.instance.Instance; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Abstract class for the monitoring functionality in Autoscaler. @@ -170,6 +167,24 @@ public abstract class Monitor implements EventHandler, Runnable { } /** + * Return the instances count + * + * @return number of exiting instances + */ + public int getInstanceCount() { + return instanceIdToInstanceMap.size(); + } + + /** + * Return the instances + * + * @return exiting instances + */ + public Collection<Instance> getInstances() { + return instanceIdToInstanceMap.values(); + } + + /** * This will remove the instance * * @param instanceId instance id http://git-wip-us.apache.org/repos/asf/stratos/blob/afbf95a0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java index ab5d2a5..8f0fd6d 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java @@ -157,48 +157,57 @@ public class GroupMonitor extends ParentComponentMonitor { ParentLevelNetworkPartitionContext parentLevelNetworkPartitionContext = (ParentLevelNetworkPartitionContext) networkPartitionContext; - int nonTerminatedInstancesCount = parentLevelNetworkPartitionContext. - getNonTerminatedInstancesCount(); - int minInstances = parentLevelNetworkPartitionContext. - getMinInstanceCount(); - int maxInstances = parentLevelNetworkPartitionContext. - getMaxInstanceCount(); - int activeInstances = parentLevelNetworkPartitionContext.getActiveInstancesCount(); - if (nonTerminatedInstancesCount < minInstances) { - int instancesToBeCreated = minInstances - nonTerminatedInstancesCount; - for (int i = 0; i < instancesToBeCreated; i++) { - for (InstanceContext parentInstanceContext : parent. - getNetworkPartitionContext(parentLevelNetworkPartitionContext.getId()). - getInstanceIdToInstanceContextMap().values()) { - //keep on scale-up/scale-down only if the application is active - ApplicationMonitor appMonitor = AutoscalerContext.getInstance(). - getAppMonitor(appId); - int activeAppInstances = ((ParentLevelNetworkPartitionContext) appMonitor. - getNetworkPartitionContext(parentLevelNetworkPartitionContext.getId())). - getActiveInstancesCount(); - if (activeAppInstances > 0) { - //Creating new group instance based on the existing parent instances - createInstanceOnDemand(parentInstanceContext.getId()); + Collection<Instance> parentInstances = parent.getInstances(); + + for(Instance parentInstance : parentInstances) { + int nonTerminatedInstancesCount = parentLevelNetworkPartitionContext. + getNonTerminatedInstancesCount(parentInstance.getInstanceId()); + int minInstances = parentLevelNetworkPartitionContext. + getMinInstanceCount(); + int maxInstances = parentLevelNetworkPartitionContext. + getMaxInstanceCount(); + int activeInstances = parentLevelNetworkPartitionContext. + getActiveInstancesCount(parentInstance.getInstanceId()); + + if (nonTerminatedInstancesCount < minInstances) { + int instancesToBeCreated = minInstances - nonTerminatedInstancesCount; + for (int i = 0; i < instancesToBeCreated; i++) { + for (InstanceContext parentInstanceContext : parent. + getNetworkPartitionContext(parentLevelNetworkPartitionContext.getId()). + getInstanceIdToInstanceContextMap().values()) { + //keep on scale-up/scale-down only if the application is active + ApplicationMonitor appMonitor = AutoscalerContext.getInstance(). + getAppMonitor(appId); + int activeAppInstances = ((ParentLevelNetworkPartitionContext) appMonitor. + getNetworkPartitionContext(parentLevelNetworkPartitionContext.getId())). + getActiveInstancesCount(); + if (activeAppInstances > 0) { + //Creating new group instance based on the existing parent instances + createInstanceOnDemand(parentInstanceContext.getId()); + } } - } + } } - } - //If the active instances are higher than the max instances, - // the group instance has to get terminated - if (activeInstances > maxInstances) { - int instancesToBeTerminated = activeInstances - maxInstances; - Collection<InstanceContext> contexts = networkPartitionContext. - getInstanceIdToInstanceContextMap().values(); - List<InstanceContext> contextList = new ArrayList<InstanceContext>(contexts); - for (int i = 0; i < instancesToBeTerminated; i++) { - InstanceContext instanceContext = contextList.get(i); - //scale down only when extra instances found - handleScalingDownBeyondMin(instanceContext, - networkPartitionContext, true); + //If the active instances are higher than the max instances, + // the group instance has to get terminated + if (activeInstances > maxInstances) { + int instancesToBeTerminated = activeInstances - maxInstances; + List<InstanceContext> contexts = + ((ParentLevelNetworkPartitionContext)networkPartitionContext). + getInstanceIdToInstanceContextMap(parentInstance.getInstanceId()); + List<InstanceContext> contextList = new ArrayList<InstanceContext>(contexts); + for (int i = 0; i < instancesToBeTerminated; i++) { + InstanceContext instanceContext = contextList.get(i); + //scale down only when extra instances found + handleScalingDownBeyondMin(instanceContext, + networkPartitionContext, true); + } } } + + } } }; @@ -298,7 +307,8 @@ public class GroupMonitor extends ParentComponentMonitor { private void createGroupInstanceOnScaling(final NetworkPartitionContext networkPartitionContext, final String parentInstanceId) { if (groupScalingEnabled) { - if (((ParentLevelNetworkPartitionContext) networkPartitionContext).getPendingInstancesCount() == 0) { + if (((ParentLevelNetworkPartitionContext) networkPartitionContext). + getPendingInstancesCount(parentInstanceId) == 0) { //one of the child is loaded and max out. // Hence creating new group instance if (log.isDebugEnabled()) { @@ -571,7 +581,8 @@ public class GroupMonitor extends ParentComponentMonitor { float factor = scalingEvent.getFactor(); ParentLevelNetworkPartitionContext parentLevelNetworkPartitionContext = (ParentLevelNetworkPartitionContext) networkPartitionContext; - int currentInstances = parentLevelNetworkPartitionContext.getNonTerminatedInstancesCount(); + int currentInstances = parentLevelNetworkPartitionContext. + getNonTerminatedInstancesCount(parentInstanceId); float requiredInstances = factor * parentLevelNetworkPartitionContext.getMinInstanceCount(); int ceilingRequiredInstances = (int) Math.ceil(requiredInstances); if (ceilingRequiredInstances > currentInstances) { @@ -589,11 +600,12 @@ public class GroupMonitor extends ParentComponentMonitor { //have to scale down if (parentLevelNetworkPartitionContext.getPendingInstancesCount() != 0) { ApplicationBuilder.handleGroupTerminatingEvent(appId, this.id, - parentLevelNetworkPartitionContext.getPendingInstances().get(0).getId()); + parentLevelNetworkPartitionContext.getPendingInstances(parentInstanceId). + get(0).getId()); } else { List<InstanceContext> activeInstances = - parentLevelNetworkPartitionContext.getActiveInstances(); + parentLevelNetworkPartitionContext.getActiveInstances(parentInstanceId); ApplicationBuilder.handleGroupTerminatingEvent(appId, this.id, activeInstances.get(activeInstances.size() - 1).toString()); } @@ -939,7 +951,8 @@ public class GroupMonitor extends ParentComponentMonitor { } } else { //have to create one more instance - if (group.getInstanceContextCount() < groupMax) { + if (parentLevelNetworkPartitionContext.getNonTerminatedInstancesCount(parentInstanceId) + < groupMax) { //Check whether group level deployment policy is there String deploymentPolicyId = AutoscalerUtil.getDeploymentPolicyIdByAlias(appId, id); if(deploymentPolicyId != null) {
