Repository: stratos Updated Branches: refs/heads/master dd1be219e -> e99025469
http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java new file mode 100644 index 0000000..dacb654 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java @@ -0,0 +1,645 @@ +/* + * 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.monitor.component; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.Constants; +import org.apache.stratos.autoscaler.algorithm.AutoscaleAlgorithm; +import org.apache.stratos.autoscaler.algorithm.OneAfterAnother; +import org.apache.stratos.autoscaler.algorithm.RoundRobin; +import org.apache.stratos.autoscaler.applications.ApplicationHolder; +import org.apache.stratos.autoscaler.applications.dependency.DependencyBuilder; +import org.apache.stratos.autoscaler.applications.dependency.DependencyTree; +import org.apache.stratos.autoscaler.applications.dependency.context.ApplicationChildContext; +import org.apache.stratos.autoscaler.applications.dependency.context.ClusterChildContext; +import org.apache.stratos.autoscaler.applications.dependency.context.GroupChildContext; +import org.apache.stratos.autoscaler.applications.topic.ApplicationBuilder; +import org.apache.stratos.autoscaler.event.publisher.ClusterStatusEventPublisher; +import org.apache.stratos.autoscaler.exception.application.DependencyBuilderException; +import org.apache.stratos.autoscaler.exception.application.ParentMonitorNotFoundException; +import org.apache.stratos.autoscaler.exception.application.TopologyInConsistentException; +import org.apache.stratos.autoscaler.exception.partition.PartitionValidationException; +import org.apache.stratos.autoscaler.exception.policy.PolicyValidationException; +import org.apache.stratos.autoscaler.monitor.Monitor; +import org.apache.stratos.autoscaler.monitor.MonitorFactory; +import org.apache.stratos.autoscaler.monitor.cluster.AbstractClusterMonitor; +import org.apache.stratos.autoscaler.monitor.events.builder.MonitorStatusEventBuilder; +import org.apache.stratos.autoscaler.status.processor.StatusChecker; +import org.apache.stratos.messaging.domain.applications.GroupStatus; +import org.apache.stratos.messaging.domain.applications.ParentComponent; +import org.apache.stratos.messaging.domain.instance.Instance; +import org.apache.stratos.messaging.domain.topology.ClusterStatus; +import org.apache.stratos.messaging.message.receiver.topology.TopologyManager; + +import java.util.*; + +/** + * Monitor is to monitor it's child monitors and + * control them according to the dependencies respectively. + */ +public abstract class ParentComponentMonitor extends Monitor { + private static final Log log = LogFactory.getLog(ParentComponentMonitor.class); + + //The monitors dependency tree with all the start-able/kill-able dependencies + protected DependencyTree startupDependencyTree; + //The monitors dependency tree with all the scaling dependencies + protected DependencyTree scalingDependencyTree; + //monitors map, key=GroupAlias/clusterId and value=GroupMonitor/AbstractClusterMonitor + protected Map<String, Monitor> aliasToActiveMonitorsMap; + //monitors map, stopped monitors + protected List<String> inactiveMonitorsList; + //terminating monitors list + protected List<String> terminatingMonitorsList; + + public ParentComponentMonitor(ParentComponent component) throws DependencyBuilderException { + aliasToActiveMonitorsMap = new HashMap<String, Monitor>(); + inactiveMonitorsList = new ArrayList<String>(); + terminatingMonitorsList = new ArrayList<String>(); + //clusterIdToClusterMonitorsMap = new HashMap<String, AbstractClusterMonitor>(); + this.id = component.getUniqueIdentifier(); + //Building the startup dependencies for this monitor within the immediate children + startupDependencyTree = DependencyBuilder.getInstance().buildDependency(component); + //Building the scaling dependencies for this monitor within the immediate children + scalingDependencyTree = DependencyBuilder.getInstance().buildDependency(component); + } + + /** + * This will start the parallel dependencies at once from the top level. + * it will get invoked when the monitor starts up only. + */ + public void startDependency(ParentComponent component, List<String> instanceIds) throws TopologyInConsistentException { + //start the first dependency + List<ApplicationChildContext> applicationContexts = this.startupDependencyTree. + getStarAbleDependencies(); + startDependency(applicationContexts, instanceIds); + + } + + /** + * This will start the parallel dependencies at once from the top level. + * it will get invoked when the monitor starts up only. + */ + public void startDependency(ParentComponent component, String instanceId) + throws TopologyInConsistentException, + ParentMonitorNotFoundException { + //start the first dependency + List<ApplicationChildContext> applicationContexts = this.startupDependencyTree. + getStarAbleDependencies(); + startDependency(applicationContexts, instanceId); + + } + + /** + * This will start the parallel dependencies at once from the top level. + * it will get invoked when the monitor starts up only. + */ + public void startDependency(ParentComponent component) throws TopologyInConsistentException { + //start the first dependency + List<ApplicationChildContext> applicationContexts = this.startupDependencyTree. + getStarAbleDependencies(); + Collection<Instance> contexts = component.getInstanceIdToInstanceContextMap().values(); + //traversing through all the Instance context and start them + List<String> instanceIds = new ArrayList<String>(); + for (Instance context : contexts) { + instanceIds.add(context.getInstanceId()); + } + startDependency(applicationContexts, instanceIds); + } + + /** + * This will get invoked based on the activation event of its one of the child + * + * @param id alias/clusterId of which receive the activated event + */ + public boolean startDependency(String id, String instanceId) throws TopologyInConsistentException { + List<ApplicationChildContext> applicationContexts = this.startupDependencyTree + .getStarAbleDependencies(id); + List<String> instanceIds = new ArrayList<String>(); + instanceIds.add(instanceId); + return startDependency(applicationContexts, instanceIds); + } + + public boolean startAllChildrenDependency(ParentComponent component, String instanceId) throws TopologyInConsistentException { + /*List<ApplicationChildContext> applicationContexts = this.startupDependencyTree + .findAllChildrenOfAppContext(id);*/ + return false;//startDependency(applicationContexts, instanceId); + } + + /** + * This will start the parallel dependencies at once from the top level + * by traversing to find the terminated dependencies. + * it will get invoked when start a child monitor on termination of a sub tree + */ + public void startDependencyOnTermination() throws TopologyInConsistentException { + //start the first dependency which went to terminated + List<ApplicationChildContext> applicationContexts = this.startupDependencyTree. + getStarAbleDependenciesByTermination(); + //FIXME to create new instanceIds + //startDependency(applicationContexts, null); + + } + + + /** + * To start the dependency of the given application contexts + * + * @param applicationContexts the found applicationContexts to be started + */ + private boolean startDependency(List<ApplicationChildContext> applicationContexts, List<String> instanceIds) { + if (applicationContexts != null && applicationContexts.isEmpty()) { + //all the groups/clusters have been started and waiting for activation + log.info("There is no child found for the [group]: " + this.id); + return false; + + } + for (ApplicationChildContext context : applicationContexts) { + if (log.isDebugEnabled()) { + log.debug("Dependency check for the Group " + context.getId() + " started"); + } + if (!this.aliasToActiveMonitorsMap.containsKey(context.getId())) { + //to avoid if it is already started + startMonitor(this, context, instanceIds); + } else { + //starting a new instance of the child + Monitor monitor = aliasToActiveMonitorsMap.get(context.getId()); + for (String instanceId : instanceIds) { + if (context instanceof ClusterChildContext) { + MonitorStatusEventBuilder.notifyChildCluster(monitor, ClusterStatus.Created, instanceId); + } else if (context instanceof GroupChildContext) { + MonitorStatusEventBuilder.notifyChildGroup(monitor, GroupStatus.Created, instanceId); + } + } + + } + } + + return true; + + } + + /** + * To start the dependency of the given application contexts + * + * @param applicationContexts the found applicationContexts to be started + */ + private boolean startDependency(List<ApplicationChildContext> applicationContexts, String instanceId) + throws ParentMonitorNotFoundException { + if (applicationContexts != null && applicationContexts.isEmpty()) { + //all the groups/clusters have been started and waiting for activation + log.info("There is no child found for the [group]: " + this.id); + return false; + + } + for (ApplicationChildContext context : applicationContexts) { + if (log.isDebugEnabled()) { + log.debug("Dependency check for the Group " + context.getId() + " started"); + } + //FIXME whether to start new monitor or throw exception + if (!this.aliasToActiveMonitorsMap.containsKey(context.getId())) { + String msg = "Required Monitor cannot be fount in the hierarchy"; + throw new ParentMonitorNotFoundException(msg); + } else { + //starting a new instance of the child + Monitor monitor = aliasToActiveMonitorsMap.get(context.getId()); + if (context instanceof ClusterChildContext) { + MonitorStatusEventBuilder.notifyChildCluster(monitor, ClusterStatus.Created, instanceId); + } else if (context instanceof GroupChildContext) { + MonitorStatusEventBuilder.notifyChildGroup(monitor, GroupStatus.Created, instanceId); + } + + } + } + + return true; + + } + + protected String generateInstanceId(ParentComponent component) { + String instanceId = component.getUniqueIdentifier() + "_" + + (component.getInstanceContextCount() + 1); + return instanceId; + } + + /** + * This will start the child monitors based on the active of siblings according to start up order + * + * @param eventId parent id of the event which received + */ + protected void onChildActivatedEvent(String eventId, String instanceId) { + try { + //if the activated monitor is in in_active map move it to active map + if (this.inactiveMonitorsList.contains(eventId)) { + this.inactiveMonitorsList.remove(eventId); + } + + if (this.terminatingMonitorsList.contains(eventId)) { + this.terminatingMonitorsList.remove(eventId); + } + + boolean startDep = startDependency(eventId, instanceId); + if (log.isDebugEnabled()) { + log.debug("started a child: " + startDep + " by the group/cluster: " + eventId); + + } + if (!startDep) { + StatusChecker.getInstance().onChildStatusChange(eventId, this.id, this.appId, instanceId); + } + } catch (TopologyInConsistentException e) { + //TODO revert the siblings and notify parent, change a flag for reverting/un-subscription + log.error(e); + } + + } + + /** + * @param eventId + */ + protected void onChildInactiveEvent(String eventId, String instanceId) { + List<ApplicationChildContext> terminationList; + Monitor monitor; + terminationList = this.startupDependencyTree.getTerminationDependencies(eventId); + //Need to notify the parent about the status change from Active-->InActive + if (this.parent != null) { + StatusChecker.getInstance().onChildStatusChange(eventId, this.id, this.appId, instanceId); + } + //TODO checking whether terminating them in reverse order, + // TODO if so can handle it in the parent event. + + //Since it is reached the most independent unit and has few independent monitors, + // has to put the children down to terminating + if (this.startupDependencyTree.getTerminationBehavior() == + DependencyTree.TerminationBehavior.TERMINATE_ALL && + terminationList.size() == this.aliasToActiveMonitorsMap.size()) { + //handling the killall scenario + if (this.parent != null) { + //send terminating to the parent. So that it will push terminating to its children + ApplicationBuilder.handleGroupTerminatingEvent(this.appId, eventId, instanceId); + } else { + //if it is an application, send terminating event individually for children + sendTerminatingEventOnNotification(terminationList, eventId, true, instanceId); + } + log.info("The group" + eventId + " has been marked as terminating " + + "due to all the children are to be terminated"); + } else { + sendTerminatingEventOnNotification(terminationList, eventId, false, instanceId); + } + } + + private void sendTerminatingEventOnNotification(List<ApplicationChildContext> terminationList, + String notifier, boolean terminateAll, String instanceId) { + Monitor monitor; + //Checking the termination dependents status + for (ApplicationChildContext terminationContext : terminationList) { + //Check whether dependent is in_active, then start to kill it + monitor = this.aliasToActiveMonitorsMap. + get(terminationContext.getId()); + //start to kill it + if (monitor != null) { + if (monitor instanceof GroupMonitor) { + //it is a group, so not sending terminating as it can be in inActive. If group needs terminating, + //it will be handled by the terminating case of its children + if (terminateAll || !notifier.equals(monitor.getId())) { + ApplicationBuilder.handleGroupTerminatingEvent(this.appId, + terminationContext.getId(), instanceId); + } + } else { + if (log.isInfoEnabled()) { + log.info("Publishing Cluster Terminating event for [application]: " + appId + + " [group] " + this.id + " [cluster]: " + terminationContext.getId()); + } + ClusterStatusEventPublisher.sendClusterTerminatingEvent(this.appId, + ((AbstractClusterMonitor) monitor).getServiceId(), + terminationContext.getId(), instanceId); + } + } else { + log.warn("The relevant [monitor] " + terminationContext.getId() + + "is not in the active map...."); + } + + } + } + + /** + * Act upon one of its children got terminated + * + * @param eventId id of the notifier + */ + + protected void onChildTerminatedEvent(String eventId, String instanceId) { + List<ApplicationChildContext> terminationList; + boolean allDependentTerminated = false; + + ApplicationChildContext context = this.startupDependencyTree. + findApplicationContextWithIdInPrimaryTree(eventId); + context.setTerminated(true); + terminationList = this.startupDependencyTree.getTerminationDependencies(eventId); + //Make sure that all the dependents have been terminated properly to start the recovery + if (terminationList != null) { + allDependentTerminated = allDependentTerminated(terminationList); + } + + List<ApplicationChildContext> parentContexts = this.startupDependencyTree. + findAllParentContextWithId(eventId); + boolean parentsTerminated = false; + boolean allParentsActive = false; + //make sure all the parent contexts got terminated or whether all of them are active + if (parentContexts != null) { + parentsTerminated = allParentTerminated(parentContexts); + allParentsActive = allParentActive(parentContexts); + } + + if ((terminationList.isEmpty() || allDependentTerminated) && + (parentContexts.isEmpty() || parentsTerminated || allParentsActive)) { + //Find the non existent monitor by traversing dependency tree + try { + this.startDependencyOnTermination(); + } catch (TopologyInConsistentException e) { + //TODO revert the siblings and notify parent, change a flag for reverting/un-subscription + log.error("Error while starting the monitor upon termination" + e); + } + } else { + StatusChecker.getInstance().onChildStatusChange(eventId, this.id, this.appId, instanceId); + log.info("Checking the status of group/application as no dependent found..."); + } + + + } + + private boolean allDependentTerminated(List<ApplicationChildContext> terminationList) { + boolean allDependentTerminated = false; + for (ApplicationChildContext context1 : terminationList) { + if (this.aliasToActiveMonitorsMap.containsKey(context1.getId())) { + log.warn("Dependent [monitor] " + context1.getId() + " not in the correct state"); + allDependentTerminated = false; + return allDependentTerminated; + } else if (this.inactiveMonitorsList.contains(context1.getId())) { + log.info("Waiting for the [dependent] " + context1.getId() + " to be terminated..."); + allDependentTerminated = false; + return allDependentTerminated; + } else { + allDependentTerminated = true; + } + } + return allDependentTerminated; + } + + + private boolean allParentTerminated(List<ApplicationChildContext> parentContexts) { + boolean parentsTerminated = false; + for (ApplicationChildContext context1 : parentContexts) { + if (this.inactiveMonitorsList.contains(context1.getId())) { + log.info("Waiting for the [Parent Monitor] " + context1.getId() + + " to be terminated"); + parentsTerminated = false; + return parentsTerminated; + } else if (this.aliasToActiveMonitorsMap.containsKey(context1.getId())) { + if (parentsTerminated) { + log.warn("Found the Dependent [monitor] " + context1.getId() + + " in the active list wrong state"); + } + } else { + log.info("[Parent Monitor] " + context1.getId() + + " has already been terminated"); + parentsTerminated = true; + } + } + return parentsTerminated; + } + + private boolean allParentActive(List<ApplicationChildContext> parentContexts) { + boolean parentsActive = false; + for (ApplicationChildContext context1 : parentContexts) { + if (this.inactiveMonitorsList.contains(context1.getId()) || + this.terminatingMonitorsList.contains(context1.getId())) { + parentsActive = false; + log.info("Dependent [Monitor] " + context1.getId() + + " is not yet active"); + return parentsActive; + } else if (this.aliasToActiveMonitorsMap.containsKey(context1.getId())) { + Monitor monitor = this.aliasToActiveMonitorsMap.get(context1.getId()); + + if (monitor instanceof GroupMonitor) { + GroupMonitor monitor1 = (GroupMonitor) monitor; + ApplicationHolder.acquireReadLock(); + try { + //TODO*********** + /*if (monitor1.getStatus() == GroupStatus.Active) { + parentsActive = true; + + }*/ + } finally { + ApplicationHolder.releaseReadLock(); + } + } else if (monitor instanceof AbstractClusterMonitor) { + AbstractClusterMonitor monitor1 = (AbstractClusterMonitor) monitor; + TopologyManager.acquireReadLockForCluster(monitor1.getServiceId(), + monitor1.getClusterId()); + try { + if (monitor1.getStatus() == ClusterStatus.Active) { + parentsActive = true; + } + } finally { + TopologyManager.releaseReadLockForCluster(monitor1.getServiceId(), + monitor1.getClusterId()); + } + } + + } + } + return parentsActive; + } + + // move to inactive monitors list to use in the Terminated event + protected synchronized void markMonitorAsInactive(String monitorKey) { + + if (!this.inactiveMonitorsList.contains(monitorKey)) { + this.inactiveMonitorsList.add(monitorKey); + } + } + + // move to inactive monitors list to use in the Terminated event + protected synchronized void markMonitorAsTerminating(String monitorKey) { + if (!this.terminatingMonitorsList.contains(monitorKey)) { + if (this.inactiveMonitorsList.contains(monitorKey)) { + this.inactiveMonitorsList.remove(monitorKey); + } + this.terminatingMonitorsList.add(monitorKey); + } + } + + protected synchronized void startMonitor(ParentComponentMonitor parent, + ApplicationChildContext context, List<String> instanceId) { + Thread th = null; + if (!this.aliasToActiveMonitorsMap.containsKey(context.getId())) { + th = new Thread( + new MonitorAdder(parent, context, this.appId, instanceId)); + if (log.isDebugEnabled()) { + log.debug(String + .format("Monitor Adder has been added: [cluster] %s ", + context.getId())); + } + } + if (th != null) { + th.start(); + log.info(String + .format("Monitor thread has been started successfully: [cluster] %s ", + context.getId())); + } + } + + public Map<String, Monitor> getAliasToActiveMonitorsMap() { + return aliasToActiveMonitorsMap; + } + + public void setAliasToActiveMonitorsMap(Map<String, Monitor> aliasToActiveMonitorsMap) { + this.aliasToActiveMonitorsMap = aliasToActiveMonitorsMap; + } + + public boolean hasActiveMonitors() { + boolean hasMonitor = false; + if ((this.aliasToActiveMonitorsMap != null && !this.aliasToActiveMonitorsMap.isEmpty())) { + hasMonitor = true; + } + return hasMonitor; + } + + public boolean hasMonitors() { + + return this.aliasToActiveMonitorsMap != null; + } + + public boolean hasIndependentChild() { + boolean hasInDepChild = false; + for (Monitor monitor : this.aliasToActiveMonitorsMap.values()) { + if (!monitor.hasStartupDependents()) { + hasInDepChild = true; + break; + } + } + return hasInDepChild; + } + + public List<String> getAliasToInActiveMonitorsMap() { + return this.inactiveMonitorsList; + } + + public void setAliasToInActiveMonitorsMap(List<String> inactiveMonitorsList) { + this.inactiveMonitorsList = inactiveMonitorsList; + } + + public List<String> getTerminatingMonitorsList() { + return terminatingMonitorsList; + } + + public void setTerminatingMonitorsList(List<String> terminatingMonitorsList) { + this.terminatingMonitorsList = terminatingMonitorsList; + } + + public AutoscaleAlgorithm getAutoscaleAlgorithm(String partitionAlgorithm) { + AutoscaleAlgorithm autoscaleAlgorithm = null; + if (log.isDebugEnabled()) { + log.debug(String.format("Partition algorithm is ", partitionAlgorithm)); + } + if (Constants.ROUND_ROBIN_ALGORITHM_ID.equals(partitionAlgorithm)) { + + autoscaleAlgorithm = new RoundRobin(); + } else if (Constants.ONE_AFTER_ANOTHER_ALGORITHM_ID.equals(partitionAlgorithm)) { + + autoscaleAlgorithm = new OneAfterAnother(); + } else { + if (log.isErrorEnabled()) { + log.error(String.format("Partition algorithm %s could not be identified !", partitionAlgorithm)); + } + } + return autoscaleAlgorithm; + } + + private class MonitorAdder implements Runnable { + private ApplicationChildContext context; + private ParentComponentMonitor parent; + private String appId; + private List<String> instanceId; + + public MonitorAdder(ParentComponentMonitor parent, ApplicationChildContext context, + String appId, List<String> instanceId) { + this.parent = parent; + this.context = context; + this.appId = appId; + this.instanceId = instanceId; + } + + public void run() { + Monitor monitor = null; + int retries = 5; + boolean success; + do { + try { + Thread.sleep(5000); + } catch (InterruptedException e1) { + } + + if (log.isDebugEnabled()) { + log.debug("Monitor is going to be started for [group/cluster] " + + context.getId()); + } + try { + monitor = MonitorFactory.getMonitor(parent, context, appId, instanceId); + } catch (DependencyBuilderException e) { + String msg = "Monitor creation failed for: " + context.getId(); + log.warn(msg, e); + retries--; + } catch (TopologyInConsistentException e) { + String msg = "Monitor creation failed for: " + context.getId(); + log.warn(msg, e); + retries--; + } catch (PolicyValidationException e) { + String msg = "Monitor creation failed for: " + context.getId(); + log.warn(msg, e); + retries--; + } catch (PartitionValidationException e) { + String msg = "Monitor creation failed for: " + context.getId(); + log.warn(msg, e); + retries--; + + } + success = true; + + } while (!success && retries != 0); + + + if (monitor == null) { + String msg = "Monitor creation failed, even after retrying for 5 times, " + + "for : " + context.getId(); + log.error(msg); + //TODO parent.notify(); + throw new RuntimeException(msg); + } + + aliasToActiveMonitorsMap.put(context.getId(), monitor); + // ApplicationBuilder. + if (log.isInfoEnabled()) { + log.info(String.format("Monitor has been added successfully for: %s", + context.getId())); + } + } + } + + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/events/builder/MonitorStatusEventBuilder.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/events/builder/MonitorStatusEventBuilder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/events/builder/MonitorStatusEventBuilder.java new file mode 100644 index 0000000..9ce891b --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/events/builder/MonitorStatusEventBuilder.java @@ -0,0 +1,91 @@ +/* + * 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.monitor.events.builder; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.autoscaler.monitor.Monitor; +import org.apache.stratos.autoscaler.monitor.component.ParentComponentMonitor; +import org.apache.stratos.autoscaler.monitor.events.*; +import org.apache.stratos.messaging.domain.applications.ApplicationStatus; +import org.apache.stratos.messaging.domain.topology.ClusterStatus; +import org.apache.stratos.messaging.domain.applications.GroupStatus; + +/** + * This will build the necessary monitor status events to be sent to the parent/child monitor + */ +public class MonitorStatusEventBuilder { + private static final Log log = LogFactory.getLog(MonitorStatusEventBuilder.class); + + public static void handleClusterStatusEvent(ParentComponentMonitor parent, ClusterStatus status, String clusterId) { + ClusterStatusEvent clusterStatusEvent = new ClusterStatusEvent(status, clusterId, null); + notifyParent(parent, clusterStatusEvent); + } + + public static void handleGroupStatusEvent(ParentComponentMonitor parent, GroupStatus status, + String groupId, String instanceId) { + GroupStatusEvent groupStatusEvent = new GroupStatusEvent(status, groupId, instanceId); + notifyParent(parent, groupStatusEvent); + } + + public static void handleApplicationStatusEvent(ParentComponentMonitor parent, ApplicationStatus status, + String appId, String instanceId) { + ApplicationStatusEvent applicationStatusEvent = new ApplicationStatusEvent(status, appId, instanceId); + notifyParent(parent, applicationStatusEvent); + } + + public static void handleClusterScalingEvent(ParentComponentMonitor parent, + String networkPartitionId, float factor, String appId) { + + //Send notifications to parent of the cluster monitor + MonitorScalingEvent monitorScalingEvent = new MonitorScalingEvent(appId, networkPartitionId, null,factor) ; + notifyParent(parent, monitorScalingEvent); + } + + private static void notifyParent(ParentComponentMonitor parent, MonitorStatusEvent statusEvent) { + parent.onChildStatusEvent(statusEvent); + } + + public static void notifyChildren (ParentComponentMonitor componentMonitor, MonitorStatusEvent statusEvent) { + for (Monitor activeChildMonitor : componentMonitor.getAliasToActiveMonitorsMap().values()) { + activeChildMonitor.onParentStatusEvent(statusEvent); + } + } + + public static void notifyChildGroup(Monitor child, GroupStatus state, String instanceId) { + MonitorStatusEvent statusEvent = new GroupStatusEvent(state, child.getId(), instanceId); + child.onParentStatusEvent(statusEvent); + } + + public static void notifyChildCluster(Monitor child, ClusterStatus state, String instanceId) { + MonitorStatusEvent statusEvent = new ClusterStatusEvent(state, child.getId(), instanceId); + child.onParentStatusEvent(statusEvent); + } + + private static void notifyParent(ParentComponentMonitor parent, MonitorScalingEvent scalingEvent) { + parent.onChildScalingEvent(scalingEvent); + } + + public static void notifyChildren (ParentComponentMonitor componentMonitor, MonitorScalingEvent scalingEvent) { + for (Monitor activeChildMonitor : componentMonitor.getAliasToActiveMonitorsMap().values()) { + activeChildMonitor.onParentScalingEvent(scalingEvent); + } + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/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 deleted file mode 100644 index a487df6..0000000 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/group/GroupMonitor.java +++ /dev/null @@ -1,338 +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.monitor.group; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.context.AutoscalerContext; -import org.apache.stratos.autoscaler.context.partition.network.GroupLevelNetworkPartitionContext; -import org.apache.stratos.autoscaler.algorithm.AutoscaleAlgorithm; -import org.apache.stratos.autoscaler.applications.ApplicationHolder; -import org.apache.stratos.autoscaler.applications.dependency.context.ApplicationChildContext; -import org.apache.stratos.autoscaler.applications.dependency.context.GroupChildContext; -import org.apache.stratos.autoscaler.applications.topic.ApplicationBuilder; -import org.apache.stratos.autoscaler.exception.DependencyBuilderException; -import org.apache.stratos.autoscaler.exception.TopologyInConsistentException; -import org.apache.stratos.autoscaler.monitor.EventHandler; -import org.apache.stratos.autoscaler.monitor.Monitor; -import org.apache.stratos.autoscaler.monitor.MonitorStatusEventBuilder; -import org.apache.stratos.autoscaler.monitor.ParentComponentMonitor; -import org.apache.stratos.autoscaler.monitor.application.ApplicationMonitor; -import org.apache.stratos.autoscaler.monitor.events.*; -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.messaging.domain.applications.*; -import org.apache.stratos.messaging.domain.instance.GroupInstance; -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.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * This is GroupMonitor to monitor the group which consists of - * groups and clusters - */ -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 - * - * @param group Takes the group from the Topology - * @throws DependencyBuilderException throws when couldn't build the Topology - * @throws TopologyInConsistentException throws when topology is inconsistent - */ - public GroupMonitor(Group group, String appId, List<String> parentInstanceId) throws DependencyBuilderException, - TopologyInConsistentException { - super(group); - this.appId = appId; - networkPartitionCtxts = new HashMap<String, GroupLevelNetworkPartitionContext>(); - - //starting the minimum start able dependencies - //startMinimumDependencies(group, parentInstanceId); - } - - /** - * Will set the status of the monitor based on Topology Group status/child status like scaling - * - * @param status status of the group - */ - public void setStatus(GroupStatus status, String instanceId) { - - if (status == GroupStatus.Inactive && !this.hasStartupDependents) { - log.info("[Group] " + this.id + "is not notifying the parent, " + - "since it is identified as the independent unit"); - } else { - // notify parent - log.info("[Group] " + this.id + "is notifying the [parent] " + this.parent.getId()); - if(this.isGroupScalingEnabled()) { - ApplicationHolder.acquireReadLock(); - try { - Application application = ApplicationHolder.getApplications(). - getApplication(this.appId); - if(application != null) { - //Notifying the parent using parent's instance Id, - // as it has group scaling enabled. - Group group = application.getGroupRecursively(this.id); - if(group != null) { - GroupInstance context = group.getInstanceContexts(instanceId); - MonitorStatusEventBuilder.handleGroupStatusEvent(this.parent, - status, this.id, context.getParentId()); - - } - } - } finally { - ApplicationHolder.releaseReadLock(); - } - } else { - MonitorStatusEventBuilder.handleGroupStatusEvent(this.parent, - status, this.id, instanceId); - } - } - //notify the children about the state change - MonitorStatusEventBuilder.notifyChildren(this, new GroupStatusEvent(status, getId(), null)); - } - - @Override - public void onChildStatusEvent(MonitorStatusEvent statusEvent) { - String id = statusEvent.getId(); - String instanceId = statusEvent.getInstanceId(); - LifeCycleState status1 = statusEvent.getStatus(); - //Events coming from parent are In_Active(in faulty detection), Scaling events, termination - if (status1 == ClusterStatus.Active || status1 == GroupStatus.Active) { - onChildActivatedEvent(id, instanceId); - - } else if (status1 == ClusterStatus.Inactive || status1 == GroupStatus.Inactive) { - this.markMonitorAsInactive(id); - onChildInactiveEvent(id, instanceId); - - } else if (status1 == ClusterStatus.Created || status1 == GroupStatus.Created) { - if (this.terminatingMonitorsList.contains(id)) { - this.terminatingMonitorsList.remove(id); - this.aliasToActiveMonitorsMap.remove(id); - if(AutoscalerContext.getInstance().getClusterMonitors().containsKey(id)) { - AutoscalerContext.getInstance().removeClusterMonitor(id); - } - } - //If cluster monitor, need to terminate the existing one - //TODO block - /*if (this.status == GroupStatus.Terminating) { - StatusChecker.getInstance().onChildStatusChange(id, this.id, this.appId); - } else { - onChildTerminatedEvent(id); - }*/ - - } else if (status1 == ClusterStatus.Terminating || status1 == GroupStatus.Terminating) { - //mark the child monitor as inActive in the map - this.markMonitorAsTerminating(id); - - } else if (status1 == ClusterStatus.Terminated || status1 == GroupStatus.Terminated) { - //Check whether all dependent goes Terminated and then start them in parallel. - if (this.terminatingMonitorsList.contains(id)) { - this.terminatingMonitorsList.remove(id); - this.aliasToActiveMonitorsMap.remove(id); - } else { - log.warn("[monitor] " + id + " cannot be found in the inActive monitors list"); - } - //TODO block - /*if (this.status == GroupStatus.Terminating || this.status == GroupStatus.Terminated) { - StatusChecker.getInstance().onChildStatusChange(id, this.id, this.appId); - log.info("Executing the un-subscription request for the [monitor] " + id); - }*/ - } - } - - @Override - public void onParentStatusEvent(MonitorStatusEvent statusEvent) { - String instanceId = statusEvent.getInstanceId(); - // send the ClusterTerminating event - if (statusEvent.getStatus() == GroupStatus.Terminating || - statusEvent.getStatus() == ApplicationStatus.Terminating) { - ApplicationBuilder.handleGroupTerminatingEvent(appId, id, instanceId); - } else if(statusEvent.getStatus() == ClusterStatus.Created || - statusEvent.getStatus() == GroupStatus.Created) { - Application application = ApplicationHolder.getApplications().getApplication(this.appId); - Group group = application.getGroupRecursively(statusEvent.getId()); - //starting a new instance of this monitor - createGroupInstance(group, statusEvent.getInstanceId()); - } - } - - @Override - public void onChildScalingEvent(MonitorScalingEvent scalingEvent) { - - if(hasGroupScalingDependent){ - - //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, from scaling dependency tree - GroupChildContext currentChildContextInScalingTree = - (GroupChildContext) scalingDependencyTree.findApplicationContextWithIdInScalingDependencyTree(id); - - //Notifying children, if this group has scaling dependencies - if (currentChildContextInScalingTree.isGroupScalingEnabled()){ - for (ApplicationChildContext applicationChildContext : currentChildContextInScalingTree.getApplicationChildContextList()){ - - //Get group monitor so that it can notify it's children - Monitor monitor = aliasToActiveMonitorsMap.get(applicationChildContext.getId()); - - if(monitor instanceof GroupMonitor || monitor instanceof ApplicationMonitor){ - - monitor.onParentScalingEvent(scalingEvent); - } - } - } - } - - @Override - public void onParentScalingEvent(MonitorScalingEvent scalingEvent) { - - //Notify all children about scaling - } - - @Override - public void onEvent(MonitorScalingEvent scalingEvent) { - - } - - public boolean isGroupScalingEnabled() { - return groupScalingEnabled; - } - - public void setGroupScalingEnabled(boolean groupScalingEnabled) { - this.groupScalingEnabled = groupScalingEnabled; - } - - public void startMinimumDependencies(Group group, List<String> parentInstanceIds) - throws TopologyInConsistentException { - int min = group.getGroupMinInstances(); - if(group.getInstanceContextCount() >= min) { - startDependency(group); - } else { - if(group.getInstanceContextCount() > 0) { - List<String> instanceIds = new ArrayList<String>(); - for(String parentInstanceId : parentInstanceIds) { - List<Instance> contexts1 = group.getInstanceContextsWithParentId(parentInstanceId); - //Finding the non startable instance ids - if(group.getInstanceContexts(parentInstanceId) == null || contexts1.isEmpty() || - contexts1.size() == 0) { - instanceIds.add(parentInstanceId); - - } - } - if(instanceIds.size() > 0) { - createInstanceAndStartDependency(group, parentInstanceIds); - } else { - startDependency(group); - } - } else { - //No available instances in the Applications. Need to start them all - createInstanceAndStartDependency(group, parentInstanceIds); - } - } - } - - private void createInstanceAndStartDependency(Group group, List<String> parentInstanceIds) - throws TopologyInConsistentException { - List<String> instanceIds = new ArrayList<String>(); - String deploymentPolicyName = group.getDeploymentPolicy(); - - String instanceId; - for(String parentInstanceId : parentInstanceIds) { - Application application = ApplicationHolder.getApplications().getApplication(this.appId); - Instance 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)) { - groupLevelNetworkPartitionContext = this.networkPartitionCtxts. - get(parentInstanceContext.getNetworkPartitionId()); - } else { - groupLevelNetworkPartitionContext = new GroupLevelNetworkPartitionContext( - parentInstanceContext.getNetworkPartitionId(), - null, null); - this.addNetworkPartitionContext(groupLevelNetworkPartitionContext); - } - - if(deploymentPolicyName != null) { - DeploymentPolicy deploymentPolicy = PolicyManager.getInstance() - .getDeploymentPolicy(deploymentPolicyName); - PartitionGroup partitionGroup = deploymentPolicy. - getPartitionGroup(parentInstanceContext.getNetworkPartitionId()); - - AutoscaleAlgorithm algorithm = this.getAutoscaleAlgorithm(partitionGroup.getPartitionAlgo()); - //Partition partition = algorithm.getNextScaleUpPartition(groupLevelNetworkPartitionContext, this.id); - } - instanceId = createGroupInstance(group, parentInstanceId); - instanceIds.add(instanceId); - } - startDependency(group, instanceIds); - } - - private String createGroupInstance(Group group, String parentInstanceId) { - String instanceId = parentInstanceId; - int minGroupInstances = group.getGroupMinInstances(); - int maxGroupInstances = group.getGroupMaxInstances(); - /* - * When min != 1 or max != 1, we need to generate - * instance ids as it is having more than one group instances - */ - if (minGroupInstances > 1 || maxGroupInstances > 1) { - instanceId = this.generateInstanceId(group); - } - ApplicationBuilder.handleGroupInstanceCreatedEvent(appId, group.getUniqueIdentifier(), - 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); - } -} http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/partition/PartitionManager.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/partition/PartitionManager.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/partition/PartitionManager.java index adc4290..6b40933 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/partition/PartitionManager.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/partition/PartitionManager.java @@ -26,8 +26,8 @@ import org.apache.stratos.autoscaler.NetworkPartitionLbHolder; import org.apache.stratos.autoscaler.client.CloudControllerClient; import org.apache.stratos.autoscaler.policy.model.DeploymentPolicy; import org.apache.stratos.autoscaler.exception.AutoScalerException; -import org.apache.stratos.autoscaler.exception.InvalidPartitionException; -import org.apache.stratos.autoscaler.exception.PartitionValidationException; +import org.apache.stratos.autoscaler.exception.partition.InvalidPartitionException; +import org.apache.stratos.autoscaler.exception.partition.PartitionValidationException; import org.apache.stratos.autoscaler.registry.RegistryManager; import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/policy/PolicyManager.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/policy/PolicyManager.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/policy/PolicyManager.java index 6ff2c2d..783c02e 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/policy/PolicyManager.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/policy/PolicyManager.java @@ -27,8 +27,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.stratos.autoscaler.policy.model.DeploymentPolicy; import org.apache.stratos.autoscaler.exception.AutoScalerException; -import org.apache.stratos.autoscaler.exception.InvalidPartitionException; -import org.apache.stratos.autoscaler.exception.InvalidPolicyException; +import org.apache.stratos.autoscaler.exception.partition.InvalidPartitionException; +import org.apache.stratos.autoscaler.exception.policy.InvalidPolicyException; import org.apache.stratos.autoscaler.partition.PartitionManager; import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; import org.apache.stratos.autoscaler.registry.RegistryManager; http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java index abc9878..d58bb40 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java @@ -32,7 +32,7 @@ import org.apache.stratos.autoscaler.context.cluster.KubernetesClusterContext; import org.apache.stratos.autoscaler.context.member.MemberStatsContext; import org.apache.stratos.autoscaler.context.partition.network.ClusterLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionContext; -import org.apache.stratos.autoscaler.exception.TerminationException; +import org.apache.stratos.autoscaler.exception.cartridge.TerminationException; import org.apache.stratos.autoscaler.monitor.cluster.AbstractClusterMonitor; import org.apache.stratos.autoscaler.monitor.cluster.VMClusterMonitor; import org.apache.stratos.autoscaler.monitor.cluster.VMServiceClusterMonitor; http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java index 7542d21..67b6e09 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java @@ -1991,6 +1991,11 @@ public class CloudControllerServiceImpl implements CloudControllerService { } @Override + public void updateClusterStatus(String clusterId, String instanceId, ClusterStatus status) { + //TODO + } + + @Override public MemberContext terminateContainer(String memberId) throws MemberTerminationFailedException { handleNullObject(memberId, "Failed to terminate member. Invalid Member id. [Member id] " + memberId); http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/CloudControllerService.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/CloudControllerService.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/CloudControllerService.java index 4526676..447ee3e 100644 --- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/CloudControllerService.java +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/interfaces/CloudControllerService.java @@ -21,6 +21,7 @@ package org.apache.stratos.cloud.controller.interfaces; import org.apache.stratos.cloud.controller.deployment.partition.Partition; import org.apache.stratos.cloud.controller.exception.*; import org.apache.stratos.cloud.controller.pojo.*; +import org.apache.stratos.messaging.domain.topology.ClusterStatus; /** * This API provides a way to communicate with underline @@ -155,6 +156,14 @@ public interface CloudControllerService { * @throws InvalidClusterException */ MemberContext[] updateContainers(String clusterId, int replicas) throws UnregisteredCartridgeException; + + /** + * Update the topology with current cluster status. + * @param clusterId id of the subjected cluster. + * @param instanceId id of the cluster instance + * @param status total number of replicas to be set to the controller. + */ + void updateClusterStatus(String clusterId, String instanceId, ClusterStatus status); /** * Unregister a docker service identified by the given cluster id.
