Repository: stratos Updated Branches: refs/heads/master ead11b8ce -> cfbcf3d5b
adding seperate partition context for group and application network partition context Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/48545bd3 Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/48545bd3 Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/48545bd3 Branch: refs/heads/master Commit: 48545bd38c4726da3cd53355d9cc8a5076a0ace3 Parents: ead11b8 Author: reka <[email protected]> Authored: Fri Nov 28 09:45:40 2014 +0530 Committer: reka <[email protected]> Committed: Fri Nov 28 09:45:56 2014 +0530 ---------------------------------------------------------------------- ...ApplicationLevelNetworkPartitionContext.java | 101 +++ .../ClusterLevelNetworkPartitionContext.java | 2 +- .../GroupLevelNetworkPartitionContext.java | 201 +++++ .../autoscaler/GroupLevelPartitionContext.java | 738 +++++++++++++++++++ .../stratos/autoscaler/MemberStatsContext.java | 9 + .../autoscaler/NetworkPartitionContext.java | 189 +---- ...ntComponentLevelNetworkPartitionContext.java | 222 ------ .../algorithm/AutoscaleAlgorithm.java | 5 +- .../autoscaler/algorithm/OneAfterAnother.java | 5 +- .../autoscaler/algorithm/RoundRobin.java | 5 +- .../monitor/ParentComponentMonitor.java | 28 +- .../monitor/application/ApplicationMonitor.java | 33 +- .../autoscaler/monitor/group/GroupMonitor.java | 41 +- 13 files changed, 1121 insertions(+), 458 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ApplicationLevelNetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ApplicationLevelNetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ApplicationLevelNetworkPartitionContext.java new file mode 100644 index 0000000..cb400f8 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ApplicationLevelNetworkPartitionContext.java @@ -0,0 +1,101 @@ +/* + * 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. + */ +package org.apache.stratos.autoscaler; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; +import org.apache.stratos.messaging.domain.instance.context.ApplicationInstanceContext; +import org.apache.stratos.messaging.domain.instance.context.InstanceContext; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Holds runtime data of a network partition. + * + */ +public class ApplicationLevelNetworkPartitionContext extends NetworkPartitionContext implements Serializable { + private static final Log log = LogFactory.getLog(ApplicationLevelNetworkPartitionContext.class); + private final String id; + + //group instances kept inside a partition + private Map<String, ApplicationInstanceContext> instanceIdToInstanceContextMap; + + public ApplicationLevelNetworkPartitionContext(String id) { + this.id = id; + } + + public Map<String, ApplicationInstanceContext> getInstanceIdToInstanceContextMap() { + return instanceIdToInstanceContextMap; + } + + public void setInstanceIdToInstanceContextMap(Map<String, ApplicationInstanceContext> instanceIdToInstanceContextMap) { + this.instanceIdToInstanceContextMap = instanceIdToInstanceContextMap; + } + + public void addInstanceContext(ApplicationInstanceContext context) { + this.instanceIdToInstanceContextMap.put(context.getInstanceId(), context); + + } + + + public int hashCode() { + + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + return result; + + } + + public boolean equals(final Object obj) { + + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof ApplicationLevelNetworkPartitionContext)) { + return false; + } + final ApplicationLevelNetworkPartitionContext other = (ApplicationLevelNetworkPartitionContext) obj; + if (this.id == null) { + if (other.id != null) { + return false; + } + } else if (!this.id.equals(other.id)) { + return false; + } + return true; + } + + @Override + public String toString() { + return "ApplicationNetworkPartitionContext [id=" + id + "]"; + } + + public String getId() { + return id; + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ClusterLevelNetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ClusterLevelNetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ClusterLevelNetworkPartitionContext.java index 73f1bce..afe193e 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ClusterLevelNetworkPartitionContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ClusterLevelNetworkPartitionContext.java @@ -79,7 +79,7 @@ public class ClusterLevelNetworkPartitionContext extends NetworkPartitionContext public ClusterLevelNetworkPartitionContext(String id, String partitionAlgo, Partition[] partitions) { - super(id, partitionAlgo, partitions); + //super(id, partitionAlgo, partitions); this.id = id; this.partitionAlgorithm = partitionAlgo; if (partitions == null) { http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelNetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelNetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelNetworkPartitionContext.java new file mode 100644 index 0000000..fecca76 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelNetworkPartitionContext.java @@ -0,0 +1,201 @@ +/* + * 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. + */ +package org.apache.stratos.autoscaler; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Holds runtime data of a network partition. + * + */ +public class GroupLevelNetworkPartitionContext extends NetworkPartitionContext implements Serializable { + private static final Log log = LogFactory.getLog(GroupLevelNetworkPartitionContext.class); + private final String id; + private int scaleDownRequestsCount = 0; + private float averageRequestsServedPerInstance; + + private int minInstanceCount = 0, maxInstanceCount = 0; + private int requiredInstanceCountBasedOnStats; + private int requiredInstanceCountBasedOnDependencies; + + private final String partitionAlgorithm; + + private final Partition[] partitions; + + //details required for partition selection algorithms + private int currentPartitionIndex; + + //partitions of this network partition + private final Map<String, GroupLevelPartitionContext> partitionCtxts; + + public GroupLevelNetworkPartitionContext(String id, String partitionAlgo, Partition[] partitions) { + this.id = id; + this.partitionAlgorithm = partitionAlgo; + if (partitions == null) { + this.partitions = new Partition[0]; + } else { + this.partitions = Arrays.copyOf(partitions, partitions.length); + } + partitionCtxts = new HashMap<String, GroupLevelPartitionContext>(); + for (Partition partition : partitions) { + minInstanceCount += partition.getPartitionMin(); + maxInstanceCount += partition.getPartitionMax(); + } + requiredInstanceCountBasedOnStats = minInstanceCount; + requiredInstanceCountBasedOnDependencies = minInstanceCount; + + } + + public int getMinInstanceCount() { + return minInstanceCount; + } + + public void setMinInstanceCount(int minInstanceCount) { + this.minInstanceCount = minInstanceCount; + } + + public int getMaxInstanceCount() { + return maxInstanceCount; + } + + public void setMaxInstanceCount(int maxInstanceCount) { + this.maxInstanceCount = maxInstanceCount; + } + + public int hashCode() { + + final int prime = 31; + int result = 1; + result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); + return result; + + } + + public boolean equals(final Object obj) { + + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof GroupLevelNetworkPartitionContext)) { + return false; + } + final GroupLevelNetworkPartitionContext other = (GroupLevelNetworkPartitionContext) obj; + if (this.id == null) { + if (other.id != null) { + return false; + } + } else if (!this.id.equals(other.id)) { + return false; + } + return true; + } + + @Override + public String toString() { + return "NetworkPartitionContext [id=" + id + "partitionAlgorithm=" + partitionAlgorithm + ", minInstanceCount=" + + minInstanceCount + ", maxInstanceCount=" + maxInstanceCount + "]"; + } + + public int getCurrentPartitionIndex() { + return currentPartitionIndex; + } + + public void setCurrentPartitionIndex(int currentPartitionIndex) { + this.currentPartitionIndex = currentPartitionIndex; + } + + public String getId() { + return id; + } + + public Map<String, GroupLevelPartitionContext> getPartitionCtxts() { + return partitionCtxts; + } + + public GroupLevelPartitionContext getPartitionCtxt(String partitionId) { + return partitionCtxts.get(partitionId); + } + + public void addPartitionContext(GroupLevelPartitionContext partitionContext) { + partitionCtxts.put(partitionContext.getPartitionId(), partitionContext); + } + + public String getPartitionAlgorithm() { + return partitionAlgorithm; + } + + public Partition[] getPartitions() { + return partitions; + } + + public int getNonTerminatedMemberCountOfPartition(String partitionId) { + if (partitionCtxts.containsKey(partitionId)) { + return getPartitionCtxt(partitionId).getNonTerminatedInstanceCount(); + } + return 0; + } + + public int getActiveMemberCount(String currentPartitionId) { + if (partitionCtxts.containsKey(currentPartitionId)) { + return getPartitionCtxt(currentPartitionId).getActiveInstanceCount(); + } + return 0; + } + + public int getScaleDownRequestsCount() { + return scaleDownRequestsCount; + } + + public void resetScaleDownRequestsCount() { + this.scaleDownRequestsCount = 0; + } + + public void increaseScaleDownRequestsCount() { + this.scaleDownRequestsCount += 1; + } + + public float getRequiredInstanceCountBasedOnStats() { + return requiredInstanceCountBasedOnStats; + } + + public void setRequiredInstanceCountBasedOnStats(int requiredInstanceCountBasedOnStats) { + this.requiredInstanceCountBasedOnStats = requiredInstanceCountBasedOnStats; + } + + public int getRequiredInstanceCountBasedOnDependencies() { + return requiredInstanceCountBasedOnDependencies; + } + + public void setRequiredInstanceCountBasedOnDependencies(int requiredInstanceCountBasedOnDependencies) { + this.requiredInstanceCountBasedOnDependencies = requiredInstanceCountBasedOnDependencies; + } + + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelPartitionContext.java new file mode 100644 index 0000000..09a2783 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/GroupLevelPartitionContext.java @@ -0,0 +1,738 @@ +/* + * 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. + */ +package org.apache.stratos.autoscaler; + +import org.apache.commons.configuration.XMLConfiguration; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.util.ConfUtil; +import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; +import org.apache.stratos.common.constants.StratosConstants; +import org.apache.stratos.messaging.domain.instance.context.InstanceContext; + +import java.io.Serializable; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +/** + * This is an object that inserted to the rules engine. + * Holds information about a partition. + */ + +public class GroupLevelPartitionContext implements Serializable { + + private static final long serialVersionUID = -2920388667345980487L; + private static final Log log = LogFactory.getLog(GroupLevelPartitionContext.class); + private final int PENDING_MEMBER_FAILURE_THRESHOLD = 5; + private String partitionId; + private String serviceName; + private String networkPartitionId; + private Partition partition; + private int minimumInstanceCount = 0; + private int pendingInstancesFailureCount = 0; + // properties + private Properties properties; + + // 15 mints as the default + private long pendingInstanceExpiryTime = 900000; + // pending instances + private List<InstanceContext> pendingInstances; + + // 1 day as default + private long obsoltedInstanceExpiryTime = 1 * 24 * 60 * 60 * 1000; + + // 30 mints as default + private long terminationPendingInstanceExpiryTime = 1800000; + + // instances to be terminated + private Map<String, InstanceContext> obsoletedInstances; + + // active instances + private List<InstanceContext> activeInstances; + + // termination pending instances, instance is added to this when Autoscaler send grace fully shut down event + private List<InstanceContext> terminationPendingInstances; + + //instance id: time that instance is moved to termination pending status + private Map<String, Long> terminationPendingStartedTime; + + //Keep statistics come from CEP + private Map<String, MemberStatsContext> instanceStatsContexts; + + //group instances kept inside a partition + private Map<String, InstanceContext> instanceIdToInstanceContextMap; + + // for the use of tests + public GroupLevelPartitionContext(long instanceExpiryTime) { + + this.activeInstances = new ArrayList<InstanceContext>(); + this.terminationPendingInstances = new ArrayList<InstanceContext>(); + pendingInstanceExpiryTime = instanceExpiryTime; + } + + public GroupLevelPartitionContext(Partition partition) { + this.setPartition(partition); + this.minimumInstanceCount = partition.getPartitionMin(); + this.partitionId = partition.getId(); + this.pendingInstances = new ArrayList<InstanceContext>(); + this.activeInstances = new ArrayList<InstanceContext>(); + this.terminationPendingInstances = new ArrayList<InstanceContext>(); + this.obsoletedInstances = new ConcurrentHashMap<String, InstanceContext>(); + instanceStatsContexts = new ConcurrentHashMap<String, MemberStatsContext>(); + instanceIdToInstanceContextMap = new HashMap<String, InstanceContext>(); + + + terminationPendingStartedTime = new HashMap<String, Long>(); + // check if a different value has been set for expiryTime + XMLConfiguration conf = ConfUtil.getInstance(null).getConfiguration(); + pendingInstanceExpiryTime = conf.getLong(StratosConstants.PENDING_VM_MEMBER_EXPIRY_TIMEOUT, 900000); + obsoltedInstanceExpiryTime = conf.getLong(StratosConstants.OBSOLETED_VM_MEMBER_EXPIRY_TIMEOUT, 86400000); + if (log.isDebugEnabled()) { + log.debug("Instance expiry time is set to: " + pendingInstanceExpiryTime); + log.debug("Instance obsoleted expiry time is set to: " + obsoltedInstanceExpiryTime); + } + + /*FIXME Thread th = new Thread(new PendingInstanceWatcher(this)); + th.start(); + Thread th2 = new Thread(new ObsoletedInstanceWatcher(this)); + th2.start(); + Thread th3 = new Thread(new TerminationPendingInstanceWatcher(this)); + th3.start();*/ + } + + public long getTerminationPendingStartedTimeOfInstance(String instanceId) { + return terminationPendingStartedTime.get(instanceId); + } + + public Map<String, InstanceContext> getInstanceIdToInstanceContextMap() { + return instanceIdToInstanceContextMap; + } + + public void setInstanceIdToInstanceContextMap(Map<String, InstanceContext> instanceIdToInstanceContextMap) { + this.instanceIdToInstanceContextMap = instanceIdToInstanceContextMap; + } + + public void addInstanceContext(InstanceContext context) { + this.instanceIdToInstanceContextMap.put(context.getInstanceId(), context); + + } + + public List<InstanceContext> getPendingInstances() { + return pendingInstances; + } + + public void setPendingInstances(List<InstanceContext> pendingInstances) { + this.pendingInstances = pendingInstances; + } + + public int getActiveInstanceCount() { + return activeInstances.size(); + } + + public String getPartitionId() { + return partitionId; + } + + public void setPartitionId(String partitionId) { + this.partitionId = partitionId; + } + + public int getMinimumInstanceCount() { + return minimumInstanceCount; + } + + public void setMinimumInstanceCount(int minimumInstanceCount) { + this.minimumInstanceCount = minimumInstanceCount; + } + + public Partition getPartition() { + return partition; + } + + public void setPartition(Partition partition) { + this.partition = partition; + } + + public void addPendingInstance(InstanceContext ctxt) { + this.pendingInstances.add(ctxt); + } + + public boolean removePendingInstance(String id) { + if (id == null) { + return false; + } + synchronized (pendingInstances) { + for (Iterator<InstanceContext> iterator = pendingInstances.iterator(); iterator.hasNext(); ) { + InstanceContext pendingInstance = (InstanceContext) iterator.next(); + if (id.equals(pendingInstance.getInstanceId())) { + iterator.remove(); + return true; + } + + } + } + + return false; + } + + public void movePendingInstanceToActiveInstances(String instanceId) { + if (instanceId == null) { + return; + } + synchronized (pendingInstances) { + Iterator<InstanceContext> iterator = pendingInstances.listIterator(); + while (iterator.hasNext()) { + InstanceContext pendingInstance = iterator.next(); + if (pendingInstance == null) { + iterator.remove(); + continue; + } + if (instanceId.equals(pendingInstance.getInstanceId())) { + // instance is activated + // remove from pending list + iterator.remove(); + // add to the activated list + this.activeInstances.add(pendingInstance); + pendingInstancesFailureCount = 0; + if (log.isDebugEnabled()) { + log.debug(String.format("Instance is removed and added to the " + + "activated Instance list. [Instance Id] %s", instanceId)); + } + break; + } + } + } + } + + public boolean activeInstanceAvailable(String instanceId) { + for (InstanceContext activeInstance : activeInstances) { + if (instanceId.equals(activeInstance.getInstanceId())) { + return true; + } + } + return false; + } + + public boolean pendingInstanceAvailable(String instanceId) { + + for (InstanceContext pendingInstance : pendingInstances) { + if (instanceId.equals(pendingInstance.getInstanceId())) { + return true; + } + } + return false; + } + + public void moveActiveInstanceToTerminationPendingInstances(String instanceId) { + if (instanceId == null) { + return; + } + synchronized (activeInstances) { + Iterator<InstanceContext> iterator = activeInstances.listIterator(); + while (iterator.hasNext()) { + InstanceContext activeInstance = iterator.next(); + if (activeInstance == null) { + iterator.remove(); + continue; + } + if (instanceId.equals(activeInstance.getInstanceId())) { + // instance is activated + // remove from pending list + iterator.remove(); + // add to the activated list + this.terminationPendingInstances.add(activeInstance); + if (log.isDebugEnabled()) { + log.debug(String.format("Active instance is removed and added to the " + + "termination pending instance list. [Instance Id] %s", instanceId)); + } + break; + } + } + } + } + + /** + * Removes the {@link org.apache.stratos.messaging.domain.instance.context.InstanceContext} object mapping + * to the specified instance id from the specified InstanceContext collection + * + * @param iterator The {@link java.util.Iterator} for the collection containing + * {@link org.apache.stratos.messaging.domain.instance.context.InstanceContext} + * objects + * @param instanceId Instance Id {@link String} for the + * {@link org.apache.stratos.messaging.domain.instance.context.InstanceContext} + * to be removed + * @return {@link org.apache.stratos.messaging.domain.instance.context.InstanceContext} object if + * object found and removed, null if otherwise. + */ + private InstanceContext removeInstanceFrom(Iterator<InstanceContext> iterator, String instanceId) { + while (iterator.hasNext()) { + InstanceContext activeInstance = iterator.next(); + if (activeInstance == null) { + iterator.remove(); + continue; + } + if (instanceId.equals(activeInstance.getInstanceId())) { + iterator.remove(); + return activeInstance; + } + } + + return null; + } + + /** + * Check the instance lists for the provided instance ID and move the instance to the obsolete list + * + * @param ctxt The instance ID of the instance to search + *//* + public void moveInstanceToObsoleteList(String instanceId) { + if (instanceId == null) { + return; + } + + // check active instance list + Iterator<InstanceContext> activeInstanceIterator = activeInstances.listIterator(); + InstanceContext removedInstance = this.removeInstanceFrom(activeInstanceIterator, instanceId); + if (removedInstance != null) { + this.addObsoleteInstance(removedInstance); + removedInstance.setObsoleteInitTime(System.currentTimeMillis()); + if (log.isDebugEnabled()) { + log.debug(String.format("Active instance is removed and added to the " + + "obsolete instance list. [Instance Id] %s", instanceId)); + } + + return; + } + + // check pending instance list + Iterator<InstanceContext> pendingInstanceIterator = pendingInstances.listIterator(); + removedInstance = this.removeInstanceFrom(pendingInstanceIterator, instanceId); + if (removedInstance != null) { + this.addObsoleteInstance(removedInstance); + removedInstance.setObsoleteInitTime(System.currentTimeMillis()); + if (log.isDebugEnabled()) { + log.debug(String.format("Pending instance is removed and added to the " + + "obsolete instance list. [Instance Id] %s", instanceId)); + } + + return; + } + + // check termination pending instance list + Iterator<InstanceContext> terminationPendingInstancesIterator = terminationPendingInstances.listIterator(); + removedInstance = this.removeInstanceFrom(terminationPendingInstancesIterator, instanceId); + if (removedInstance != null) { + this.addObsoleteInstance(removedInstance); + removedInstance.setObsoleteInitTime(System.currentTimeMillis()); + if (log.isDebugEnabled()) { + log.debug(String.format("Termination Pending instance is removed and added to the " + + "obsolete instance list. [Instance Id] %s", instanceId)); + } + } + } +*/ + public void addActiveInstance(InstanceContext ctxt) { + this.activeInstances.add(ctxt); + } + + public void removeActiveInstance(InstanceContext ctxt) { + this.activeInstances.remove(ctxt); + } + + public boolean removeTerminationPendingInstance(String instanceId) { + boolean terminationPendingInstanceAvailable = false; + synchronized (terminationPendingInstances) { + for (InstanceContext instanceContext : terminationPendingInstances) { + if (instanceContext.getInstanceId().equals(instanceId)) { + terminationPendingInstanceAvailable = true; + terminationPendingInstances.remove(instanceContext); + break; + } + } + } + return terminationPendingInstanceAvailable; + } + + public long getObsoltedInstanceExpiryTime() { + return obsoltedInstanceExpiryTime; + } + + public void setObsoltedInstanceExpiryTime(long obsoltedInstanceExpiryTime) { + this.obsoltedInstanceExpiryTime = obsoltedInstanceExpiryTime; + } + + public void addObsoleteInstance(InstanceContext ctxt) { + this.obsoletedInstances.put(ctxt.getInstanceId(), ctxt); + } + + public boolean removeObsoleteInstance(String instanceId) { + if (this.obsoletedInstances.remove(instanceId) == null) { + return false; + } + return true; + } + + public long getPendingInstanceExpiryTime() { + return pendingInstanceExpiryTime; + } + + public void setPendingInstanceExpiryTime(long pendingInstanceExpiryTime) { + this.pendingInstanceExpiryTime = pendingInstanceExpiryTime; + } + + public Map<String, InstanceContext> getObsoletedInstances() { + return obsoletedInstances; + } + + public void setObsoletedInstances(Map<String, InstanceContext> obsoletedInstances) { + this.obsoletedInstances = obsoletedInstances; + } + + public String getNetworkPartitionId() { + return networkPartitionId; + } + + public void setNetworkPartitionId(String networkPartitionId) { + this.networkPartitionId = networkPartitionId; + } + + public Map<String, MemberStatsContext> getInstanceStatsContexts() { + return instanceStatsContexts; + } + + public MemberStatsContext getInstanceStatsContext(String instanceId) { + return instanceStatsContexts.get(instanceId); + } + + public void addInstanceStatsContext(MemberStatsContext ctxt) { + this.instanceStatsContexts.put(ctxt.getInstanceId(), ctxt); + } + + public void removeInstanceStatsContext(String instanceId) { + this.instanceStatsContexts.remove(instanceId); + } + + public MemberStatsContext getPartitionCtxt(String id) { + return this.instanceStatsContexts.get(id); + } + + public Properties getProperties() { + return properties; + } + +// public boolean instanceExist(String instanceId) { +// return instanceStatsContexts.containsKey(instanceId); +// } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public String getServiceName() { + return serviceName; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public List<InstanceContext> getTerminationPendingInstances() { + return terminationPendingInstances; + } + + public void setTerminationPendingInstances(List<InstanceContext> terminationPendingInstances) { + this.terminationPendingInstances = terminationPendingInstances; + } + + public int getTotalInstanceCount() { + + return activeInstances.size() + pendingInstances.size() + terminationPendingInstances.size(); + } + + public int getNonTerminatedInstanceCount() { + return activeInstances.size() + pendingInstances.size(); + } + + public List<InstanceContext> getActiveInstances() { + return activeInstances; + } + + public void setActiveInstances(List<InstanceContext> activeInstances) { + this.activeInstances = activeInstances; + } + + public boolean removeActiveInstanceById(String instanceId) { + boolean removeActiveInstance = false; + synchronized (activeInstances) { + Iterator<InstanceContext> iterator = activeInstances.listIterator(); + while (iterator.hasNext()) { + InstanceContext instanceContext = iterator.next(); + if (instanceId.equals(instanceContext.getInstanceId())) { + iterator.remove(); + removeActiveInstance = true; + + break; + } + } + } + return removeActiveInstance; + } + + public boolean activeInstanceExist(String instanceId) { + + for (InstanceContext instanceContext : activeInstances) { + if (instanceId.equals(instanceContext.getInstanceId())) { + return true; + } + } + return false; + } + + public int getAllInstanceForTerminationCount() { + int count = activeInstances.size() + pendingInstances.size() + terminationPendingInstances.size(); + if (log.isDebugEnabled()) { + log.debug("PartitionContext:getAllInstanceForTerminationCount:size:" + count); + } + return count; + } + + // Map<String, InstanceStatsContext> getInstanceStatsContexts().keySet() + public Set<String> getAllInstanceForTermination() { + + List<InstanceContext> merged = new ArrayList<InstanceContext>(); + + + merged.addAll(activeInstances); + merged.addAll(pendingInstances); + merged.addAll(terminationPendingInstances); + + Set<String> results = new HashSet<String>(merged.size()); + + for (InstanceContext ctx : merged) { + results.add(ctx.getInstanceId()); + } + + + if (log.isDebugEnabled()) { + log.debug("PartitionContext:getAllInstanceForTermination:size:" + results.size()); + } + + //InstanceContext x = new InstanceContext(); + //x.getInstanceId() + + return results; + } + + public void movePendingTerminationInstanceToObsoleteInstances(String instanceId) { + + log.info("Starting the moving of termination pending to obsolete for [instance] " + instanceId); + if (instanceId == null) { + return; + } + Iterator<InstanceContext> iterator = terminationPendingInstances.listIterator(); + while (iterator.hasNext()) { + InstanceContext terminationPendingInstance = iterator.next(); + if (terminationPendingInstance == null) { + iterator.remove(); + continue; + } + if (instanceId.equals(terminationPendingInstance.getInstanceId())) { + + log.info("Found termination pending instance and trying to move [instance] " + instanceId + " to obsolete list"); + // instance is pending termination + // remove from pending termination list + iterator.remove(); + // add to the obsolete list + this.obsoletedInstances.put(instanceId, terminationPendingInstance); + + terminationPendingStartedTime.put(instanceId, System.currentTimeMillis()); + + if (log.isDebugEnabled()) { + log.debug(String.format("Termination pending instance is removed and added to the " + + "obsolete instance list. [Instance Id] %s", instanceId)); + } + break; + } + } + } + + public InstanceContext getPendingTerminationInstance(String instanceId) { + for (InstanceContext instanceContext : terminationPendingInstances) { + if (instanceId.equals(instanceContext.getInstanceId())) { + return instanceContext; + } + } + return null; + } + + public long getTerminationPendingInstanceExpiryTime() { + return terminationPendingInstanceExpiryTime; + } + + public void movePendingInstanceToObsoleteInstances(String instanceId) { + if (instanceId == null) { + return; + } + Iterator<InstanceContext> iterator = pendingInstances.listIterator(); + while (iterator.hasNext()) { + InstanceContext pendingInstance = iterator.next(); + if (pendingInstance == null) { + iterator.remove(); + continue; + } + if (instanceId.equals(pendingInstance.getInstanceId())) { + + // remove from pending list + iterator.remove(); + // add to the obsolete list + this.obsoletedInstances.put(instanceId, pendingInstance); + if (log.isDebugEnabled()) { + log.debug(String.format("Pending instance is removed and added to the " + + "obsolete instance list. [Instance Id] %s", instanceId)); + } + break; + } + } + + } + + /*private class PendingInstanceWatcher implements Runnable { + private ParentComponentLevelPartitionContext ctxt; + + public PendingInstanceWatcher(ParentComponentLevelPartitionContext ctxt) { + this.ctxt = ctxt; + } + + @Override + public void run() { + + while (true) { + long expiryTime = ctxt.getPendingInstanceExpiryTime(); + List<InstanceContext> pendingInstances = ctxt.getPendingInstances(); + + synchronized (pendingInstances) { + Iterator<InstanceContext> iterator = pendingInstances.listIterator(); + while ( iterator.hasNext()) { + InstanceContext pendingInstance = iterator.next(); + + if (pendingInstance == null) { + continue; + } + long pendingTime = System.currentTimeMillis() - pendingInstance.getInitTime(); + if (pendingTime >= expiryTime) { + + + iterator.remove(); + log.info("Pending state of instance: " + pendingInstance.getInstanceId() + + " is expired. " + "Adding as an obsoleted instance."); + // instance should be terminated + ctxt.addObsoleteInstance(pendingInstance); + pendingInstancesFailureCount++; + if( pendingInstancesFailureCount > PENDING_MEMBER_FAILURE_THRESHOLD){ + setPendingInstanceExpiryTime(expiryTime * 2);//Doubles the expiry time after the threshold of failure exceeded + //TODO Implement an alerting system: STRATOS-369 + } + } + } + } + + try { + // TODO find a constant + Thread.sleep(15000); + } catch (InterruptedException ignore) { + } + } + } + + } +*/ + /*private class ObsoletedInstanceWatcher implements Runnable { + private ParentComponentLevelPartitionContext ctxt; + + public ObsoletedInstanceWatcher(ParentComponentLevelPartitionContext ctxt) { + this.ctxt = ctxt; + } + + @Override + public void run() { + while (true) { + long obsoltedInstanceExpiryTime = ctxt.getObsoltedInstanceExpiryTime(); + Map<String, InstanceContext> obsoletedInstances = ctxt.getObsoletedInstances(); + + Iterator<Entry<String, InstanceContext>> iterator = obsoletedInstances.entrySet().iterator(); + while (iterator.hasNext()) { + Entry<String, InstanceContext> pairs = iterator.next(); + InstanceContext obsoleteInstance = (InstanceContext) pairs.getValue(); + if (obsoleteInstance == null) { + continue; + } + long obsoleteTime = System.currentTimeMillis() - obsoleteInstance.getInitTime(); + if (obsoleteTime >= obsoltedInstanceExpiryTime) { + iterator.remove(); + } + } + try { + // TODO find a constant + Thread.sleep(15000); + } catch (InterruptedException ignore) { + } + } + } + }*/ + + /** + * This thread is responsible for moving instance to obsolete list if pending termination timeout happens + */ + private class TerminationPendingInstanceWatcher implements Runnable { + private GroupLevelPartitionContext ctxt; + + public TerminationPendingInstanceWatcher(GroupLevelPartitionContext ctxt) { + this.ctxt = ctxt; + } + + @Override + public void run() { + + while (true) { + long terminationPendingInstanceExpiryTime = ctxt.getTerminationPendingInstanceExpiryTime(); + + Iterator<InstanceContext> iterator = ctxt.getTerminationPendingInstances().listIterator(); + while (iterator.hasNext()) { + + InstanceContext terminationPendingInstance = iterator.next(); + if (terminationPendingInstance == null) { + continue; + } + long terminationPendingTime = System.currentTimeMillis() + - ctxt.getTerminationPendingStartedTimeOfInstance(terminationPendingInstance.getInstanceId()); + if (terminationPendingTime >= terminationPendingInstanceExpiryTime) { + log.info("Moving [instance] " + terminationPendingInstance.getInstanceId() + partitionId); + iterator.remove(); + obsoletedInstances.put(terminationPendingInstance.getInstanceId(), terminationPendingInstance); + } + } + try { + // TODO find a constant + Thread.sleep(15000); + } catch (InterruptedException ignore) { + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/MemberStatsContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/MemberStatsContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/MemberStatsContext.java index 84e8854..14f9a12 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/MemberStatsContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/MemberStatsContext.java @@ -30,6 +30,7 @@ public class MemberStatsContext { private LoadAverage loadAverage; private MemoryConsumption memoryConsumption; private String memberId; + private String instanceId; public MemberStatsContext(String memberId) { this.memberId = memberId; @@ -100,4 +101,12 @@ public class MemberStatsContext { public float getSecondDerivativeOfMemoryConsumption() { return memoryConsumption.getSecondDerivative(); } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/NetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/NetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/NetworkPartitionContext.java index 9ca60ca..d2eb676 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/NetworkPartitionContext.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/NetworkPartitionContext.java @@ -20,197 +20,10 @@ package org.apache.stratos.autoscaler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; -import org.apache.stratos.messaging.domain.instance.context.InstanceContext; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; /** * This will keep track of network partition level information. */ public abstract class NetworkPartitionContext { - private static final Log log = LogFactory.getLog(ParentComponentLevelNetworkPartitionContext.class); - private final String id; - private int scaleDownRequestsCount = 0; - private float averageRequestsServedPerInstance; - - private int minInstanceCount = 0, maxInstanceCount = 0; - private int requiredInstanceCountBasedOnStats; - private int requiredInstanceCountBasedOnDependencies; - - private Map<String, InstanceContext> instanceIdToInstanceContextMap; - - - private final String partitionAlgorithm; - - private final Partition[] partitions; - - //details required for partition selection algorithms - private int currentPartitionIndex; - - //partitions of this network partition - private final Map<String, ClusterLevelPartitionContext> partitionCtxts; - - public NetworkPartitionContext(String id, String partitionAlgo, Partition[] partitions) { - - super(); - this.id = id; - this.partitionAlgorithm = partitionAlgo; - if (partitions == null) { - this.partitions = new Partition[0]; - } else { - this.partitions = Arrays.copyOf(partitions, partitions.length); - } - partitionCtxts = new HashMap<String, ClusterLevelPartitionContext>(); - for (Partition partition : partitions) { - minInstanceCount += partition.getPartitionMin(); - maxInstanceCount += partition.getPartitionMax(); - } - requiredInstanceCountBasedOnStats = minInstanceCount; - requiredInstanceCountBasedOnDependencies = minInstanceCount; - instanceIdToInstanceContextMap = new HashMap<String, InstanceContext>(); - - } - - public int getMinInstanceCount() { - return minInstanceCount; - } - - public void setMinInstanceCount(int minInstanceCount) { - this.minInstanceCount = minInstanceCount; - } - - public int getMaxInstanceCount() { - return maxInstanceCount; - } - - public void setMaxInstanceCount(int maxInstanceCount) { - this.maxInstanceCount = maxInstanceCount; - } - - public int hashCode() { - - final int prime = 31; - int result = 1; - result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); - return result; - - } - - public boolean equals(final Object obj) { - - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ParentComponentLevelNetworkPartitionContext)) { - return false; - } - final ParentComponentLevelNetworkPartitionContext other = (ParentComponentLevelNetworkPartitionContext) obj; - if (this.id == null) { - if (this.id != null) { - return false; - } - } else if (!this.id.equals(this.id)) { - return false; - } - return true; - } - - @Override - public String toString() { - return "NetworkPartitionContext [id=" + id + "partitionAlgorithm=" + partitionAlgorithm + ", minInstanceCount=" + - minInstanceCount + ", maxInstanceCount=" + maxInstanceCount + "]"; - } - - public int getCurrentPartitionIndex() { - return currentPartitionIndex; - } - - public void setCurrentPartitionIndex(int currentPartitionIndex) { - this.currentPartitionIndex = currentPartitionIndex; - } - - public String getId() { - return id; - } - - public Map<String, ClusterLevelPartitionContext> getPartitionCtxts() { - return partitionCtxts; - } - - public ClusterLevelPartitionContext getPartitionCtxt(String partitionId) { - return partitionCtxts.get(partitionId); - } - - public void addPartitionContext(ClusterLevelPartitionContext clusterMonitorPartitionContext) { - partitionCtxts.put(clusterMonitorPartitionContext.getPartitionId(), clusterMonitorPartitionContext); - } - - public String getPartitionAlgorithm() { - return partitionAlgorithm; - } - - public Partition[] getPartitions() { - return partitions; - } - - public int getNonTerminatedMemberCountOfPartition(String partitionId) { - if (partitionCtxts.containsKey(partitionId)) { - return getPartitionCtxt(partitionId).getNonTerminatedMemberCount(); - } - return 0; - } - - public int getActiveMemberCount(String currentPartitionId) { - if (partitionCtxts.containsKey(currentPartitionId)) { - return getPartitionCtxt(currentPartitionId).getActiveMemberCount(); - } - return 0; - } - - public int getScaleDownRequestsCount() { - return scaleDownRequestsCount; - } - - public void resetScaleDownRequestsCount() { - this.scaleDownRequestsCount = 0; - } - - public void increaseScaleDownRequestsCount() { - this.scaleDownRequestsCount += 1; - } - - public float getRequiredInstanceCountBasedOnStats() { - return requiredInstanceCountBasedOnStats; - } - - public void setRequiredInstanceCountBasedOnStats(int requiredInstanceCountBasedOnStats) { - this.requiredInstanceCountBasedOnStats = requiredInstanceCountBasedOnStats; - } - - public int getRequiredInstanceCountBasedOnDependencies() { - return requiredInstanceCountBasedOnDependencies; - } - - public void setRequiredInstanceCountBasedOnDependencies(int requiredInstanceCountBasedOnDependencies) { - this.requiredInstanceCountBasedOnDependencies = requiredInstanceCountBasedOnDependencies; - } - - public Map<String, InstanceContext> getInstanceIdToInstanceContextMap() { - return instanceIdToInstanceContextMap; - } - - public void setInstanceIdToInstanceContextMap(Map<String, InstanceContext> instanceIdToInstanceContextMap) { - this.instanceIdToInstanceContextMap = instanceIdToInstanceContextMap; - } - - public void addInstanceContext(InstanceContext context) { - this.instanceIdToInstanceContextMap.put(context.getInstanceId(), context); - - } + private static final Log log = LogFactory.getLog(GroupLevelNetworkPartitionContext.class); } http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ParentComponentLevelNetworkPartitionContext.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ParentComponentLevelNetworkPartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ParentComponentLevelNetworkPartitionContext.java deleted file mode 100644 index d566c31..0000000 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/ParentComponentLevelNetworkPartitionContext.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * 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. - */ -package org.apache.stratos.autoscaler; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.policy.model.LoadAverage; -import org.apache.stratos.autoscaler.policy.model.MemoryConsumption; -import org.apache.stratos.autoscaler.policy.model.RequestsInFlight; -import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; -import org.apache.stratos.messaging.domain.instance.context.InstanceContext; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -/** - * Holds runtime data of a network partition. - * - */ -public class ParentComponentLevelNetworkPartitionContext extends NetworkPartitionContext implements Serializable { - private static final Log log = LogFactory.getLog(ParentComponentLevelNetworkPartitionContext.class); - private final String id; - private int scaleDownRequestsCount = 0; - private float averageRequestsServedPerInstance; - - private int minInstanceCount = 0, maxInstanceCount = 0; - private int requiredInstanceCountBasedOnStats; - private int requiredInstanceCountBasedOnDependencies; - - private Map<String, InstanceContext> instanceIdToInstanceContextMap; - - - private final String partitionAlgorithm; - - private final Partition[] partitions; - - //details required for partition selection algorithms - private int currentPartitionIndex; - - //partitions of this network partition - private final Map<String, ClusterLevelPartitionContext> partitionCtxts; - - public ParentComponentLevelNetworkPartitionContext(String id, String partitionAlgo, Partition[] partitions) { - - super(id, partitionAlgo, partitions); - this.id = id; - this.partitionAlgorithm = partitionAlgo; - if (partitions == null) { - this.partitions = new Partition[0]; - } else { - this.partitions = Arrays.copyOf(partitions, partitions.length); - } - partitionCtxts = new HashMap<String, ClusterLevelPartitionContext>(); - for (Partition partition : partitions) { - minInstanceCount += partition.getPartitionMin(); - maxInstanceCount += partition.getPartitionMax(); - } - requiredInstanceCountBasedOnStats = minInstanceCount; - requiredInstanceCountBasedOnDependencies = minInstanceCount; - instanceIdToInstanceContextMap = new HashMap<String, InstanceContext>(); - - } - - public int getMinInstanceCount() { - return minInstanceCount; - } - - public void setMinInstanceCount(int minInstanceCount) { - this.minInstanceCount = minInstanceCount; - } - - public int getMaxInstanceCount() { - return maxInstanceCount; - } - - public void setMaxInstanceCount(int maxInstanceCount) { - this.maxInstanceCount = maxInstanceCount; - } - - public int hashCode() { - - final int prime = 31; - int result = 1; - result = prime * result + ((this.id == null) ? 0 : this.id.hashCode()); - return result; - - } - - public boolean equals(final Object obj) { - - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof ParentComponentLevelNetworkPartitionContext)) { - return false; - } - final ParentComponentLevelNetworkPartitionContext other = (ParentComponentLevelNetworkPartitionContext) obj; - if (this.id == null) { - if (other.id != null) { - return false; - } - } else if (!this.id.equals(other.id)) { - return false; - } - return true; - } - - @Override - public String toString() { - return "NetworkPartitionContext [id=" + id + "partitionAlgorithm=" + partitionAlgorithm + ", minInstanceCount=" + - minInstanceCount + ", maxInstanceCount=" + maxInstanceCount + "]"; - } - - public int getCurrentPartitionIndex() { - return currentPartitionIndex; - } - - public void setCurrentPartitionIndex(int currentPartitionIndex) { - this.currentPartitionIndex = currentPartitionIndex; - } - - public String getId() { - return id; - } - - public Map<String, ClusterLevelPartitionContext> getPartitionCtxts() { - return partitionCtxts; - } - - public ClusterLevelPartitionContext getPartitionCtxt(String partitionId) { - return partitionCtxts.get(partitionId); - } - - public void addPartitionContext(ClusterLevelPartitionContext partitionContext) { - partitionCtxts.put(partitionContext.getPartitionId(), partitionContext); - } - - public String getPartitionAlgorithm() { - return partitionAlgorithm; - } - - public Partition[] getPartitions() { - return partitions; - } - - public int getNonTerminatedMemberCountOfPartition(String partitionId) { - if (partitionCtxts.containsKey(partitionId)) { - return getPartitionCtxt(partitionId).getNonTerminatedMemberCount(); - } - return 0; - } - - public int getActiveMemberCount(String currentPartitionId) { - if (partitionCtxts.containsKey(currentPartitionId)) { - return getPartitionCtxt(currentPartitionId).getActiveMemberCount(); - } - return 0; - } - - public int getScaleDownRequestsCount() { - return scaleDownRequestsCount; - } - - public void resetScaleDownRequestsCount() { - this.scaleDownRequestsCount = 0; - } - - public void increaseScaleDownRequestsCount() { - this.scaleDownRequestsCount += 1; - } - - public float getRequiredInstanceCountBasedOnStats() { - return requiredInstanceCountBasedOnStats; - } - - public void setRequiredInstanceCountBasedOnStats(int requiredInstanceCountBasedOnStats) { - this.requiredInstanceCountBasedOnStats = requiredInstanceCountBasedOnStats; - } - - public int getRequiredInstanceCountBasedOnDependencies() { - return requiredInstanceCountBasedOnDependencies; - } - - public void setRequiredInstanceCountBasedOnDependencies(int requiredInstanceCountBasedOnDependencies) { - this.requiredInstanceCountBasedOnDependencies = requiredInstanceCountBasedOnDependencies; - } - - public Map<String, InstanceContext> getInstanceIdToInstanceContextMap() { - return instanceIdToInstanceContextMap; - } - - public void setInstanceIdToInstanceContextMap(Map<String, InstanceContext> instanceIdToInstanceContextMap) { - this.instanceIdToInstanceContextMap = instanceIdToInstanceContextMap; - } - - public void addInstanceContext(InstanceContext context) { - this.instanceIdToInstanceContextMap.put(context.getInstanceId(), context); - - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/AutoscaleAlgorithm.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/AutoscaleAlgorithm.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/AutoscaleAlgorithm.java index c27cc1e..5e25aa9 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/AutoscaleAlgorithm.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/AutoscaleAlgorithm.java @@ -19,6 +19,7 @@ package org.apache.stratos.autoscaler.algorithm; +import org.apache.stratos.autoscaler.ClusterLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.NetworkPartitionContext; import org.apache.stratos.autoscaler.partition.PartitionGroup; import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; @@ -50,7 +51,7 @@ public interface AutoscaleAlgorithm { * @param clusterId Id of the cluster which need the {@link Partition} * @return {@link Partition} to scale up */ - public Partition getNextScaleUpPartition(NetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId); + public Partition getNextScaleUpPartition(ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId); /** @@ -59,5 +60,5 @@ public interface AutoscaleAlgorithm { * @param clusterId Id of the cluster which need the {@link Partition} * @return {@link Partition} to scale down */ - public Partition getNextScaleDownPartition(NetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId); + public Partition getNextScaleDownPartition(ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId); } http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/OneAfterAnother.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/OneAfterAnother.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/OneAfterAnother.java index afae0e8..540284f 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/OneAfterAnother.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/OneAfterAnother.java @@ -21,6 +21,7 @@ package org.apache.stratos.autoscaler.algorithm; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.ClusterLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.NetworkPartitionContext; import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; @@ -44,7 +45,7 @@ public class OneAfterAnother implements AutoscaleAlgorithm { private static final Log log = LogFactory.getLog(OneAfterAnother.class); - public Partition getNextScaleUpPartition(NetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId) { + public Partition getNextScaleUpPartition(ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId) { try { if (log.isDebugEnabled()) @@ -88,7 +89,7 @@ public class OneAfterAnother implements AutoscaleAlgorithm { return null; } - public Partition getNextScaleDownPartition(NetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId) { + public Partition getNextScaleDownPartition(ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId) { try { http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/RoundRobin.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/RoundRobin.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/RoundRobin.java index db24696..7a51f73 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/RoundRobin.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/algorithm/RoundRobin.java @@ -21,6 +21,7 @@ package org.apache.stratos.autoscaler.algorithm; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.ClusterLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.NetworkPartitionContext; import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; @@ -36,7 +37,7 @@ public class RoundRobin implements AutoscaleAlgorithm{ private static final Log log = LogFactory.getLog(RoundRobin.class); - public Partition getNextScaleUpPartition(NetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId){ + public Partition getNextScaleUpPartition(ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId){ try{ if (log.isDebugEnabled()) @@ -83,7 +84,7 @@ public class RoundRobin implements AutoscaleAlgorithm{ @Override - public Partition getNextScaleDownPartition(NetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId) { + public Partition getNextScaleDownPartition(ClusterLevelNetworkPartitionContext clusterLevelNetworkPartitionContext, String clusterId) { try{ if (log.isDebugEnabled()) log.debug(String.format("Searching for a partition to scale up [network partition] %s", http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ParentComponentMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ParentComponentMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ParentComponentMonitor.java index 1c563ee..efe639f 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ParentComponentMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ParentComponentMonitor.java @@ -21,8 +21,7 @@ package org.apache.stratos.autoscaler.monitor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.autoscaler.Constants; -import org.apache.stratos.autoscaler.ClusterLevelNetworkPartitionContext; -import org.apache.stratos.autoscaler.ParentComponentLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.GroupLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.algorithm.AutoscaleAlgorithm; import org.apache.stratos.autoscaler.algorithm.OneAfterAnother; import org.apache.stratos.autoscaler.algorithm.RoundRobin; @@ -67,15 +66,13 @@ public abstract class ParentComponentMonitor extends Monitor { protected List<String> inactiveMonitorsList; //terminating monitors list protected List<String> terminatingMonitorsList; - //network partition contexts - protected Map<String, ParentComponentLevelNetworkPartitionContext> networkPartitionCtxts; + public ParentComponentMonitor(ParentComponent component) throws DependencyBuilderException { aliasToActiveMonitorsMap = new HashMap<String, Monitor>(); inactiveMonitorsList = new ArrayList<String>(); terminatingMonitorsList = new ArrayList<String>(); - networkPartitionCtxts = new HashMap<String, ParentComponentLevelNetworkPartitionContext>(); //clusterIdToClusterMonitorsMap = new HashMap<String, AbstractClusterMonitor>(); this.id = component.getUniqueIdentifier(); //Building the startup dependencies for this monitor within the immediate children @@ -505,27 +502,6 @@ public abstract class ParentComponentMonitor extends Monitor { this.terminatingMonitorsList = terminatingMonitorsList; } - public Map<String, ParentComponentLevelNetworkPartitionContext> getNetworkPartitionCtxts() { - return networkPartitionCtxts; - } - - public void setNetworkPartitionCtxts(Map<String, ParentComponentLevelNetworkPartitionContext> networkPartitionCtxts) { - this.networkPartitionCtxts = networkPartitionCtxts; - } - - public void addNetworkPartitionContext(ParentComponentLevelNetworkPartitionContext clusterLevelNetworkPartitionContext) { - this.networkPartitionCtxts.put(clusterLevelNetworkPartitionContext.getId(), clusterLevelNetworkPartitionContext); - } - - public InstanceContext getInstanceContext(String instanceId) { - for(ParentComponentLevelNetworkPartitionContext context : this.networkPartitionCtxts.values()) { - if(context.getInstanceIdToInstanceContextMap().containsKey(instanceId)) { - return context.getInstanceIdToInstanceContextMap().get(instanceId); - } - } - return null; - } - private class MonitorAdder implements Runnable { private ApplicationChildContext context; private ParentComponentMonitor parent; http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java index 78cf8c2..9b466b8 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java @@ -20,7 +20,9 @@ package org.apache.stratos.autoscaler.monitor.application; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.ParentComponentLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.ApplicationLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.GroupLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.GroupLevelPartitionContext; import org.apache.stratos.autoscaler.applications.ApplicationHolder; import org.apache.stratos.autoscaler.applications.topic.ApplicationBuilder; import org.apache.stratos.autoscaler.exception.DependencyBuilderException; @@ -35,15 +37,14 @@ import org.apache.stratos.autoscaler.monitor.events.MonitorStatusEvent; import org.apache.stratos.autoscaler.partition.PartitionGroup; import org.apache.stratos.autoscaler.policy.PolicyManager; import org.apache.stratos.autoscaler.policy.model.DeploymentPolicy; +import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; import org.apache.stratos.messaging.domain.applications.Application; import org.apache.stratos.messaging.domain.applications.ApplicationStatus; import org.apache.stratos.messaging.domain.applications.GroupStatus; import org.apache.stratos.messaging.domain.topology.ClusterStatus; import org.apache.stratos.messaging.domain.topology.lifecycle.LifeCycleState; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; /** * ApplicationMonitor is to control the child monitors @@ -51,11 +52,16 @@ import java.util.List; public class ApplicationMonitor extends ParentComponentMonitor { private static final Log log = LogFactory.getLog(ApplicationMonitor.class); + //network partition contexts + private Map<String, ApplicationLevelNetworkPartitionContext> networkPartitionCtxts; + public ApplicationMonitor(Application application) throws DependencyBuilderException, TopologyInConsistentException { super(application); //setting the appId for the application this.appId = application.getUniqueIdentifier(); + networkPartitionCtxts = new HashMap<String, ApplicationLevelNetworkPartitionContext>(); + //starting the first set of dependencies from its children //TODO startMinimumDependencies(application); @@ -189,12 +195,12 @@ public class ApplicationMonitor extends ParentComponentMonitor { DeploymentPolicy deploymentPolicy = getDeploymentPolicy(application); String instanceId; for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { + ApplicationLevelNetworkPartitionContext context = + new ApplicationLevelNetworkPartitionContext(partitionGroup.getId()); instanceId = createApplicationInstance(application, partitionGroup.getId()); - ParentComponentLevelNetworkPartitionContext context = new ParentComponentLevelNetworkPartitionContext(partitionGroup.getId(), - partitionGroup.getPartitionAlgo(), - partitionGroup.getPartitions()); context.addInstanceContext(application.getInstanceContexts(instanceId)); - this.addNetworkPartitionContext(context); + + this.networkPartitionCtxts.put(context.getId(), context); instanceIds.add(instanceId); } @@ -239,4 +245,15 @@ public class ApplicationMonitor extends ParentComponentMonitor { return instanceId; } + public Map<String, ApplicationLevelNetworkPartitionContext> getNetworkPartitionCtxts() { + return networkPartitionCtxts; + } + + public void setNetworkPartitionCtxts(Map<String, ApplicationLevelNetworkPartitionContext> networkPartitionCtxts) { + this.networkPartitionCtxts = networkPartitionCtxts; + } + + public void addNetworkPartitionContext(ApplicationLevelNetworkPartitionContext clusterLevelNetworkPartitionContext) { + this.networkPartitionCtxts.put(clusterLevelNetworkPartitionContext.getId(), clusterLevelNetworkPartitionContext); + } } http://git-wip-us.apache.org/repos/asf/stratos/blob/48545bd3/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/group/GroupMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/group/GroupMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/group/GroupMonitor.java index 3a2498f..3fc78bb 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/group/GroupMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/group/GroupMonitor.java @@ -21,7 +21,7 @@ package org.apache.stratos.autoscaler.monitor.group; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.autoscaler.AutoscalerContext; -import org.apache.stratos.autoscaler.ParentComponentLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.GroupLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.algorithm.AutoscaleAlgorithm; import org.apache.stratos.autoscaler.applications.ApplicationHolder; import org.apache.stratos.autoscaler.applications.dependency.context.ApplicationChildContext; @@ -46,7 +46,9 @@ import org.apache.stratos.messaging.domain.topology.ClusterStatus; import org.apache.stratos.messaging.domain.topology.lifecycle.LifeCycleState; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * This is GroupMonitor to monitor the group which consists of @@ -56,6 +58,9 @@ public class GroupMonitor extends ParentComponentMonitor implements EventHandler private static final Log log = LogFactory.getLog(GroupMonitor.class); //whether groupScaling enabled or not private boolean groupScalingEnabled; + //network partition contexts + private Map<String, GroupLevelNetworkPartitionContext> networkPartitionCtxts; + /** * Constructor of GroupMonitor @@ -68,6 +73,8 @@ public class GroupMonitor extends ParentComponentMonitor implements EventHandler TopologyInConsistentException { super(group); this.appId = appId; + networkPartitionCtxts = new HashMap<String, GroupLevelNetworkPartitionContext>(); + //starting the minimum start able dependencies //startMinimumDependencies(group, parentInstanceId); } @@ -267,16 +274,24 @@ public class GroupMonitor extends ParentComponentMonitor implements EventHandler String instanceId; for(String parentInstanceId : parentInstanceIds) { - InstanceContext parentInstanceContext = this.parent.getInstanceContext(parentInstanceId); - ParentComponentLevelNetworkPartitionContext clusterLevelNetworkPartitionContext; + Application application = ApplicationHolder.getApplications().getApplication(this.appId); + InstanceContext parentInstanceContext; + if(this.id.equals(appId)) { + parentInstanceContext = application.getInstanceContexts(parentInstanceId); + } else { + Group group1 = application.getGroupRecursively(this.parent.getId()); + parentInstanceContext = group1.getInstanceContexts(parentInstanceId); + } + + GroupLevelNetworkPartitionContext groupLevelNetworkPartitionContext; if(this.networkPartitionCtxts.containsKey(parentInstanceContext)) { - clusterLevelNetworkPartitionContext = this.networkPartitionCtxts. + groupLevelNetworkPartitionContext = this.networkPartitionCtxts. get(parentInstanceContext.getNetworkPartitionId()); } else { - clusterLevelNetworkPartitionContext = new ParentComponentLevelNetworkPartitionContext( + groupLevelNetworkPartitionContext = new GroupLevelNetworkPartitionContext( parentInstanceContext.getNetworkPartitionId(), null, null); - this.addNetworkPartitionContext(clusterLevelNetworkPartitionContext); + this.addNetworkPartitionContext(groupLevelNetworkPartitionContext); } if(deploymentPolicyName != null) { @@ -286,7 +301,7 @@ public class GroupMonitor extends ParentComponentMonitor implements EventHandler getPartitionGroup(parentInstanceContext.getNetworkPartitionId()); AutoscaleAlgorithm algorithm = this.getAutoscaleAlgorithm(partitionGroup.getPartitionAlgo()); - Partition partition = algorithm.getNextScaleUpPartition(clusterLevelNetworkPartitionContext, this.id); + //Partition partition = algorithm.getNextScaleUpPartition(groupLevelNetworkPartitionContext, this.id); } instanceId = createGroupInstance(group, parentInstanceId); instanceIds.add(instanceId); @@ -312,4 +327,16 @@ public class GroupMonitor extends ParentComponentMonitor implements EventHandler instanceId, parentInstanceId); return instanceId; } + + public Map<String, GroupLevelNetworkPartitionContext> getNetworkPartitionCtxts() { + return networkPartitionCtxts; + } + + public void setNetworkPartitionCtxts(Map<String, GroupLevelNetworkPartitionContext> networkPartitionCtxts) { + this.networkPartitionCtxts = networkPartitionCtxts; + } + + public void addNetworkPartitionContext(GroupLevelNetworkPartitionContext clusterLevelNetworkPartitionContext) { + this.networkPartitionCtxts.put(clusterLevelNetworkPartitionContext.getId(), clusterLevelNetworkPartitionContext); + } }
