handling child scaling event and max out event in group monitor
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/586ab74a Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/586ab74a Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/586ab74a Branch: refs/heads/master Commit: 586ab74a963f1fbc2aa97ca66be4a1f324ff46a6 Parents: b8ecae2 Author: reka <[email protected]> Authored: Tue Dec 16 15:31:08 2014 +0530 Committer: Udara Liyanage <[email protected]> Committed: Thu Dec 18 12:06:57 2014 +0530 ---------------------------------------------------------------------- .../context/group/GroupInstanceContext.java | 50 ++++- .../GroupLevelNetworkPartitionContext.java | 5 + .../monitor/component/GroupMonitor.java | 215 +++++++++++-------- 3 files changed, 177 insertions(+), 93 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/586ab74a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/group/GroupInstanceContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/group/GroupInstanceContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/group/GroupInstanceContext.java index 072fc04..c7cbbe6 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/group/GroupInstanceContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/group/GroupInstanceContext.java @@ -20,9 +20,13 @@ package org.apache.stratos.autoscaler.context.group; import org.apache.stratos.autoscaler.context.InstanceContext; import org.apache.stratos.autoscaler.context.partition.GroupLevelPartitionContext; +import org.apache.stratos.autoscaler.monitor.events.ScalingEvent; +import org.apache.stratos.autoscaler.monitor.events.ScalingOverMaxEvent; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * This will hold the group instance related info @@ -31,11 +35,16 @@ public class GroupInstanceContext extends InstanceContext { //partitions of this network partition private final List<GroupLevelPartitionContext> partitionCtxts; + //key=id of the child, value=ScalingEvent + private Map<String, ScalingEvent> idToScalingEvent; + //key=id of the child, value=MaxOutScalingEvent + private Map<String, ScalingOverMaxEvent> idToScalingOverMaxEvent; public GroupInstanceContext(String id) { super(id); partitionCtxts = new ArrayList<GroupLevelPartitionContext>(); - + setIdToScalingEvent(new HashMap<String, ScalingEvent>()); + setIdToScalingOverMaxEvent(new HashMap<String, ScalingOverMaxEvent>()); } public List<GroupLevelPartitionContext> getPartitionCtxts() { @@ -78,4 +87,43 @@ public class GroupInstanceContext extends InstanceContext { return 0; } + public Map<String, ScalingEvent> getIdToScalingEvent() { + return idToScalingEvent; + } + + public void setIdToScalingEvent(Map<String, ScalingEvent> idToScalingEvent) { + this.idToScalingEvent = idToScalingEvent; + } + + public Map<String, ScalingOverMaxEvent> getIdToScalingOverMaxEvent() { + return idToScalingOverMaxEvent; + } + + public void setIdToScalingOverMaxEvent(Map<String, ScalingOverMaxEvent> idToScalingOverMaxEvent) { + this.idToScalingOverMaxEvent = idToScalingOverMaxEvent; + } + + public void removeScalingEvent(String id) { + this.idToScalingEvent.remove(id); + } + + public void addScalingEvent(ScalingEvent scalingEvent) { + this.idToScalingEvent.put(scalingEvent.getId(), scalingEvent); + } + + public void removeScalingOverMaxEvent(String id) { + this.idToScalingOverMaxEvent.remove(id); + } + + public void addScalingOverMaxEvent(ScalingOverMaxEvent scalingOverMaxEvent) { + this.idToScalingOverMaxEvent.put(scalingOverMaxEvent.getId(), scalingOverMaxEvent); + } + + public boolean containsScalingEvent(String id) { + return this.idToScalingEvent.containsKey(id); + } + + public boolean containsScalingOverMaxEvent(String id) { + return this.idToScalingOverMaxEvent.containsKey(id); + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/586ab74a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/GroupLevelNetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/GroupLevelNetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/GroupLevelNetworkPartitionContext.java index d461258..52af38d 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/GroupLevelNetworkPartitionContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/partition/network/GroupLevelNetworkPartitionContext.java @@ -20,6 +20,7 @@ package org.apache.stratos.autoscaler.context.partition.network; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.context.InstanceContext; import org.apache.stratos.autoscaler.context.group.GroupInstanceContext; import org.apache.stratos.autoscaler.context.partition.GroupLevelPartitionContext; @@ -85,6 +86,10 @@ public class GroupLevelNetworkPartitionContext extends NetworkPartitionContext i } + public GroupInstanceContext getInstanceContext(String instanceId) { + return this.instanceIdToInstanceContextMap.get(instanceId); + } + public int getMinInstanceCount() { return minInstanceCount; } http://git-wip-us.apache.org/repos/asf/stratos/blob/586ab74a/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 6c487a7..500a0ff 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 @@ -48,7 +48,10 @@ import org.apache.stratos.messaging.domain.instance.Instance; import org.apache.stratos.messaging.domain.topology.ClusterStatus; import org.apache.stratos.messaging.domain.topology.lifecycle.LifeCycleState; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -60,22 +63,18 @@ import java.util.concurrent.TimeUnit; public class GroupMonitor extends ParentComponentMonitor implements Runnable { private static final Log log = LogFactory.getLog(GroupMonitor.class); + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); //has scaling dependents protected boolean hasScalingDependents; //Indicates whether groupScaling enabled or not private boolean groupScalingEnabled; //Network partition contexts private Map<String, GroupLevelNetworkPartitionContext> networkPartitionCtxts; - - private Map<String, ScalingEvent> mapScalingEvent; - //Indicates whether the monitor is destroyed or not private boolean isDestroyed; //Monitoring interval of the monitor private int monitoringIntervalMilliseconds = 60000; //TODO get this from config file - private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - /** * Constructor of GroupMonitor * @@ -90,50 +89,48 @@ public class GroupMonitor extends ParentComponentMonitor implements Runnable { this.appId = appId; networkPartitionCtxts = new HashMap<String, GroupLevelNetworkPartitionContext>(); this.hasScalingDependents = hasScalingDependents; - mapScalingEvent=new HashMap<String, ScalingEvent>(); - } + } @Override public void run() { try { - - if (log.isDebugEnabled()) { - log.debug("Group monitor is running : " + this.toString()); - } - monitor(); - } catch (Exception e) { - log.error("Group monitor failed : " + this.toString(), e); - } + if (log.isDebugEnabled()) { + log.debug("Group monitor is running : " + this.toString()); + } + monitor(); + } catch (Exception e) { + log.error("Group monitor failed : " + this.toString(), e); + } } - public void startScheduler() { - scheduler.scheduleAtFixedRate(this, 0, monitoringIntervalMilliseconds, TimeUnit.MILLISECONDS); - } + public void startScheduler() { + scheduler.scheduleAtFixedRate(this, 0, monitoringIntervalMilliseconds, TimeUnit.MILLISECONDS); + } - protected void stopScheduler() { - scheduler.shutdownNow(); + protected void stopScheduler() { + scheduler.shutdownNow(); } - public void monitor() { - - Runnable monitoringRunnable = new Runnable() { - @Override - public void run() { - float finalFactor = 1; - if (log.isInfoEnabled()) { - log.info("Group monitor is running====== : " + this.toString()); - } - - Collection<ScalingEvent> events = mapScalingEvent.values(); - for (ScalingEvent event : events) { - log.info("Monitor Scaling Event"+event.getId()); - } - //TODO : call the on demand group scaling - mapScalingEvent.clear(); - } - }; - monitoringRunnable.run(); - } + public void monitor() { + + Runnable monitoringRunnable = new Runnable() { + @Override + public void run() { + float finalFactor = 1; + if (log.isDebugEnabled()) { + log.debug("Group monitor is running====== : " + this.toString()); + } + + /*Collection<ScalingEvent> events = mapScalingEvent.values(); + for (ScalingEvent event : events) { + log.info("Monitor Scaling Event"+event.getId()); + } + //TODO : call the on demand group scaling + mapScalingEvent.clear();*/ + } + }; + monitoringRunnable.run(); + } /** * Will set the status of the monitor based on Topology Group status/child status like scaling @@ -165,7 +162,7 @@ public class GroupMonitor extends ParentComponentMonitor implements Runnable { GroupInstance context = group.getInstanceContexts(instanceId); // notify parent log.info("[Group] " + this.id + "is notifying the [parent] " + this.parent.getId() + - " [instance] " + context.getParentId()); + " [instance] " + context.getParentId()); MonitorStatusEventBuilder.handleGroupStatusEvent(this.parent, status, this.id, parentInstanceId); } @@ -297,56 +294,90 @@ public class GroupMonitor extends ParentComponentMonitor implements Runnable { } } - @Override - public void onChildScalingEvent(ScalingEvent scalingEvent) { - if (hasScalingDependents) { - //notify parent - parent.onChildScalingEvent(scalingEvent); - } - - if (log.isDebugEnabled()) { - log.debug("Child scaling event received to [group]: " + this.getId() - + ", [network partition]: " + scalingEvent.getNetworkPartitionId() - + ", [event] " + scalingEvent.getId() + ", [group instance] " + scalingEvent.getInstanceId()); - } - - //find the child context of this group, - //Notifying children, if this group has scaling dependencies - if (scalingDependencies != null && !scalingDependencies.isEmpty()) { - // has dependencies. Notify children - if (aliasToActiveMonitorsMap != null && !aliasToActiveMonitorsMap.values().isEmpty()) { - - for (ScalingDependentList scalingDependentList : scalingDependencies) { - - for (String scalingDependentListComponent : scalingDependentList - .getScalingDependentListComponents()) { - - if (scalingDependentListComponent.equals(scalingEvent.getId())) { - - for (String scalingDependentListComponentInSelectedList : - scalingDependentList.getScalingDependentListComponents()) { - - Monitor monitor = aliasToActiveMonitorsMap.get( - scalingDependentListComponentInSelectedList); - if (monitor instanceof GroupMonitor || - monitor instanceof VMClusterMonitor) { - monitor.onParentScalingEvent(scalingEvent); - } - } - break; - } - } - } - } - } - if (scalingEvent.getId().equals(appId)) { - mapScalingEvent.put(scalingEvent.getInstanceId(), scalingEvent); - } - } + @Override + public void onChildScalingEvent(ScalingEvent scalingEvent) { + if (hasScalingDependents) { + //notify parent + parent.onChildScalingEvent(scalingEvent); + } + + if (log.isDebugEnabled()) { + log.debug("Child scaling event received to [group]: " + this.getId() + + ", [network partition]: " + scalingEvent.getNetworkPartitionId() + + ", [event] " + scalingEvent.getId() + ", [group instance] " + scalingEvent.getInstanceId()); + } + + //find the child context of this group, + //Notifying children, if this group has scaling dependencies + if (scalingDependencies != null && !scalingDependencies.isEmpty()) { + // has dependencies. Notify children + if (aliasToActiveMonitorsMap != null && !aliasToActiveMonitorsMap.values().isEmpty()) { + + for (ScalingDependentList scalingDependentList : scalingDependencies) { + + for (String scalingDependentListComponent : scalingDependentList + .getScalingDependentListComponents()) { + + if (scalingDependentListComponent.equals(scalingEvent.getId())) { + + for (String scalingDependentListComponentInSelectedList : + scalingDependentList.getScalingDependentListComponents()) { + + Monitor monitor = aliasToActiveMonitorsMap.get( + scalingDependentListComponentInSelectedList); + if (monitor instanceof GroupMonitor || + monitor instanceof VMClusterMonitor) { + monitor.onParentScalingEvent(scalingEvent); + } + } + break; + } + } + } + } + } + + String networkPartitionId = scalingEvent.getNetworkPartitionId(); + String instanceId = scalingEvent.getInstanceId(); + String id = scalingEvent.getId(); + GroupLevelNetworkPartitionContext networkPartitionContext = + this.networkPartitionCtxts.get(networkPartitionId); + if (networkPartitionContext != null) { + GroupInstanceContext instanceContext = networkPartitionContext.getInstanceContext(instanceId); + if (instanceContext != null) { + if (instanceContext.containsScalingEvent(id)) { + instanceContext.removeScalingEvent(id); + instanceContext.addScalingEvent(scalingEvent); + } else { + instanceContext.addScalingEvent(scalingEvent); + } + } + } + } @Override public void onChildScalingOverMaxEvent(ScalingOverMaxEvent scalingOverMaxEvent) { - + //Checking whether this monitor has room to create new instances else + // notify the parent with max out + //TODO by drool or periodic monitor or here + + //adding the scaling over max event to group instance Context + String networkPartitionId = scalingOverMaxEvent.getNetworkPartitionId(); + String instanceId = scalingOverMaxEvent.getInstanceId(); + String id = scalingOverMaxEvent.getId(); + GroupLevelNetworkPartitionContext networkPartitionContext = + this.networkPartitionCtxts.get(networkPartitionId); + if (networkPartitionContext != null) { + GroupInstanceContext instanceContext = networkPartitionContext.getInstanceContext(instanceId); + if (instanceContext != null) { + if (instanceContext.containsScalingEvent(id)) { + instanceContext.removeScalingOverMaxEvent(id); + instanceContext.addScalingOverMaxEvent(scalingOverMaxEvent); + } else { + instanceContext.addScalingOverMaxEvent(scalingOverMaxEvent); + } + } + } } @Override @@ -755,9 +786,9 @@ public class GroupMonitor extends ParentComponentMonitor implements Runnable { int minInstances = this.networkPartitionCtxts.get(networkPartitionId). getMinInstanceCount(); //if terminated all the instances in this instances map should be in terminated state - if(noOfInstancesOfRequiredStatus == this.inactiveInstancesMap.size() && + if (noOfInstancesOfRequiredStatus == this.inactiveInstancesMap.size() && requiredStatus == GroupStatus.Terminated) { - return true; + return true; } else if (noOfInstancesOfRequiredStatus >= minInstances) { return true; } else { @@ -774,7 +805,7 @@ public class GroupMonitor extends ParentComponentMonitor implements Runnable { @Override public void destroy() { - //TODO to stop all the drools + stopScheduler(); } }
