http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/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 deleted file mode 100644 index 7bcb234..0000000 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java +++ /dev/null @@ -1,287 +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.application; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.context.partition.network.ApplicationLevelNetworkPartitionContext; -import org.apache.stratos.autoscaler.applications.ApplicationHolder; -import org.apache.stratos.autoscaler.applications.topic.ApplicationBuilder; -import org.apache.stratos.autoscaler.exception.DependencyBuilderException; -import org.apache.stratos.autoscaler.exception.ParentMonitorNotFoundException; -import org.apache.stratos.autoscaler.exception.PolicyValidationException; -import org.apache.stratos.autoscaler.exception.TopologyInConsistentException; -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.events.ApplicationStatusEvent; -import org.apache.stratos.autoscaler.monitor.events.MonitorScalingEvent; -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.*; - -/** - * ApplicationMonitor is to control the child monitors - */ -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); - - } - - /** - * Find the group monitor by traversing recursively in the hierarchical monitors. - * - * @param groupId the unique alias of the Group - * @return the found GroupMonitor - */ - public Monitor findGroupMonitorWithId(String groupId) { - Monitor monitor; - //searching within active monitors - return findGroupMonitor(groupId, aliasToActiveMonitorsMap.values()); - } - - - /** - * Utility method to find the group monitor recursively within app monitor - * - * @param id the unique alias of the Group - * @param monitors the group monitors found in the app monitor - * @return the found GroupMonitor - */ - private Monitor findGroupMonitor(String id, Collection<Monitor> monitors) { - for (Monitor monitor : monitors) { - // check if alias is equal, if so, return - if (monitor.getId().equals(id)) { - return monitor; - } else { - // check if this Group has nested sub Groups. If so, traverse them as well - if (monitor instanceof ParentComponentMonitor) { - return findGroupMonitor(id, ((ParentComponentMonitor) monitor). - getAliasToActiveMonitorsMap().values()); - } - } - } - return null; - } - - /** - * To set the status of the application monitor - * - * @param status the status - */ - public void setStatus(ApplicationStatus status, String instanceId) { - //notify the children about the state change - MonitorStatusEventBuilder.notifyChildren(this, new ApplicationStatusEvent(status, appId, 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.Terminating || status1 == GroupStatus.Terminating) { - //mark the child monitor as inActive in the map - this.markMonitorAsTerminating(id); - - } else if (status1 == ClusterStatus.Created || status1 == GroupStatus.Created) { - if (this.terminatingMonitorsList.contains(id)) { - this.terminatingMonitorsList.remove(id); - this.aliasToActiveMonitorsMap.remove(id); - } - //TODO - /*if (this.status == ApplicationStatus.Terminating) { - StatusChecker.getInstance().onChildStatusChange(id, this.id, this.appId); - } else { - onChildTerminatedEvent(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 - /*if (this.status == ApplicationStatus.Terminating || this.status == ApplicationStatus.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) { - // nothing to do - } - - @Override - public void onChildScalingEvent(MonitorScalingEvent scalingEvent) { - - } - - @Override - public void onParentScalingEvent(MonitorScalingEvent scalingEvent) { - - } - - @Override - public void onEvent(MonitorScalingEvent scalingEvent) { - - } - - public void startMinimumDependencies(Application application) - throws TopologyInConsistentException, PolicyValidationException { - //There will be one application instance - //FIXME when having multiple network partitions - if (application.getInstanceContextCount() > 0) { - startDependency(application); - } else { - //No available instances in the Applications. Need to start them all - createInstanceAndStartDependency(application); - } - } - - private void createInstanceAndStartDependency(Application application) - throws TopologyInConsistentException, PolicyValidationException { - List<String> instanceIds = new ArrayList<String>(); - DeploymentPolicy deploymentPolicy = getDeploymentPolicy(application); - String instanceId; - for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { - if(partitionGroup.isActiveByDefault()) { - ApplicationLevelNetworkPartitionContext context = - new ApplicationLevelNetworkPartitionContext(partitionGroup.getId()); - instanceId = createApplicationInstance(application, partitionGroup.getId()); - context.addInstanceContext(application.getInstanceContexts(instanceId)); - - this.networkPartitionCtxts.put(context.getId(), context); - - instanceIds.add(instanceId); - } - - } - startDependency(application, instanceIds); - - - } - - public void createInstanceOnBurstingForApplication() throws TopologyInConsistentException, - PolicyValidationException, - ParentMonitorNotFoundException { - //TODO get lock - Application application = ApplicationHolder.getApplications().getApplication(appId); - if(application == null) { - String msg = "Application cannot be found in the Topology."; - throw new TopologyInConsistentException(msg); - } - DeploymentPolicy deploymentPolicy = getDeploymentPolicy(application); - String instanceId = null; - //Find out the inActive network partition - boolean burstNPFound = false; - for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { - if(!partitionGroup.isActiveByDefault()) { - ApplicationLevelNetworkPartitionContext context = - new ApplicationLevelNetworkPartitionContext(partitionGroup.getId()); - context.setCreatedOnBurst(true); - instanceId = createApplicationInstance(application, partitionGroup.getId()); - context.addInstanceContext(application.getInstanceContexts(instanceId)); - this.networkPartitionCtxts.put(context.getId(), context); - burstNPFound = true; - } - } - - if(!burstNPFound) { - log.warn("[Application] " + appId + " cannot be burst as no available resources found"); - } else { - startDependency(application, instanceId); - } - - } - - private DeploymentPolicy getDeploymentPolicy(Application application) throws PolicyValidationException { - String deploymentPolicyName = application.getDeploymentPolicy(); - if (deploymentPolicyName == null) { - String msg = "Deployment Policy is not specified to the [Application]:" + appId; - log.error(msg); - throw new PolicyValidationException(msg); - } - - DeploymentPolicy deploymentPolicy = - PolicyManager.getInstance() - .getDeploymentPolicy(deploymentPolicyName); - if (deploymentPolicy == null) { - if (deploymentPolicy == null) { - String msg = "Deployment policy is null: [policy-name] " + deploymentPolicyName; - log.error(msg); - throw new PolicyValidationException(msg); - } - } - - return deploymentPolicy; - } - - private String createApplicationInstance(Application application, String networkPartitionId) { - String instanceId = this.generateInstanceId(application); - ApplicationBuilder.handleApplicationInstanceCreatedEvent(appId, instanceId, networkPartitionId); - 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/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitorFactory.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitorFactory.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitorFactory.java deleted file mode 100644 index ec50cd2..0000000 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitorFactory.java +++ /dev/null @@ -1,256 +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.application; - -import org.apache.stratos.autoscaler.context.AutoscalerContext; -import org.apache.stratos.autoscaler.applications.ApplicationHolder; -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.client.CloudControllerClient; -import org.apache.stratos.autoscaler.exception.DependencyBuilderException; -import org.apache.stratos.autoscaler.exception.PartitionValidationException; -import org.apache.stratos.autoscaler.exception.PolicyValidationException; -import org.apache.stratos.autoscaler.exception.TopologyInConsistentException; -import org.apache.stratos.autoscaler.monitor.Monitor; -import org.apache.stratos.autoscaler.monitor.ParentComponentMonitor; -import org.apache.stratos.autoscaler.monitor.cluster.AbstractClusterMonitor; -import org.apache.stratos.autoscaler.monitor.cluster.ClusterMonitorFactory; -import org.apache.stratos.autoscaler.monitor.group.GroupMonitor; -import org.apache.stratos.messaging.domain.applications.Application; -import org.apache.stratos.messaging.domain.applications.Group; -import org.apache.stratos.messaging.domain.topology.Cluster; -import org.apache.stratos.messaging.domain.topology.Service; -import org.apache.stratos.messaging.domain.topology.Topology; -import org.apache.stratos.messaging.message.receiver.topology.TopologyManager; - -import java.util.List; - -/** - * Factory class to get the Monitors. - */ -public class ApplicationMonitorFactory { - - /** - * Factor method used to create relevant monitors based on the given context - * - * @param context Application/Group/Cluster context - * @param appId appId of the application which requires to create app monitor - * @param parentMonitor parent of the monitor - * @return Monitor which can be ApplicationMonitor/GroupMonitor/ClusterMonitor - * @throws TopologyInConsistentException throws while traversing thr topology - * @throws DependencyBuilderException throws while building dependency for app monitor - * @throws PolicyValidationException throws while validating the policy associated with cluster - * @throws PartitionValidationException throws while validating the partition used in a cluster - */ - public static Monitor getMonitor(ParentComponentMonitor parentMonitor, - ApplicationChildContext context, String appId, List<String> instanceId) - throws TopologyInConsistentException, - DependencyBuilderException, PolicyValidationException, PartitionValidationException { - - Monitor monitor; - if (context instanceof GroupChildContext) { - monitor = getGroupMonitor(parentMonitor, context, appId, instanceId); - } else if (context instanceof ClusterChildContext) { - monitor = getClusterMonitor(parentMonitor, (ClusterChildContext) context); - if (monitor != null) { - //((AbstractClusterMonitor)monitor).startScheduler(); - ClusterChildContext clusterChildCtxt = (ClusterChildContext) context; - AbstractClusterMonitor clusterMonitor = (AbstractClusterMonitor)monitor; - // FIXME: passing null as alias for cluster instance temporarily. should be removed. - createClusterInstance(clusterChildCtxt.getServiceName(), clusterMonitor.getClusterId(), null, instanceId.get(0)); - AutoscalerContext.getInstance().addClusterMonitor((AbstractClusterMonitor)monitor); - } - } else { - monitor = getApplicationMonitor(appId); - } - return monitor; - } - - private static void createClusterInstance (String serviceType, String clusterId, String alias, String instanceId) { - CloudControllerClient.getInstance().createClusterInstance(serviceType, clusterId, alias, instanceId); - } - - /** - * This will create the GroupMonitor based on given groupId by going thr Topology - * - * @param parentMonitor parent of the monitor - * @param context groupId of the group - * @param appId appId of the relevant application - * @return Group monitor - * @throws DependencyBuilderException throws while building dependency for app monitor - * @throws TopologyInConsistentException throws while traversing thr topology - */ - public static Monitor getGroupMonitor(ParentComponentMonitor parentMonitor, - ApplicationChildContext context, String appId, List<String> instanceIds) - throws DependencyBuilderException, - TopologyInConsistentException { - GroupMonitor groupMonitor; - ApplicationHolder.acquireReadLock(); - - try { - Group group = ApplicationHolder.getApplications(). - getApplication(appId).getGroupRecursively(context.getId()); - groupMonitor = new GroupMonitor(group, appId, instanceIds); - groupMonitor.setAppId(appId); - if (parentMonitor != null) { - groupMonitor.setParent(parentMonitor); - //Setting the dependent behaviour of the monitor - if (parentMonitor.hasStartupDependents() || (context.hasStartupDependents() && context.hasChild())) { - groupMonitor.setHasStartupDependents(true); - } else { - groupMonitor.setHasStartupDependents(false); - } - - if(group.isGroupScalingEnabled()) { - groupMonitor.setGroupScalingEnabled(true); - } else if(parentMonitor instanceof GroupMonitor) { - if(((GroupMonitor)parentMonitor).isGroupScalingEnabled() || - parentMonitor.hasGroupScalingDependent()) { - groupMonitor.setHasGroupScalingDependent(true); - } - } - - //Starting the minimum dependencies - groupMonitor.startMinimumDependencies(group, instanceIds); - //TODO*********** make it sync with the topology in the restart - - /*if (group.getStatus() != groupMonitor.getStatus()) { - //updating the status, if the group is not in created state when creating group Monitor - //so that groupMonitor will notify the parent (useful when restarting stratos) - groupMonitor.setStatus(group.getStatus()); - }*/ - } - - } finally { - ApplicationHolder.releaseReadLock(); - - } - return groupMonitor; - - } - - /** - * This will create a new app monitor based on the give appId by getting the - * application from Topology - * - * @param appId appId of the application which requires to create app monitor - * @return ApplicationMonitor - * @throws DependencyBuilderException throws while building dependency for app monitor - * @throws TopologyInConsistentException throws while traversing thr topology - */ - public static ApplicationMonitor getApplicationMonitor(String appId) - throws DependencyBuilderException, - TopologyInConsistentException, PolicyValidationException { - ApplicationMonitor applicationMonitor; - ApplicationHolder.acquireReadLock(); - try { - Application application = ApplicationHolder.getApplications().getApplication(appId); - if (application != null) { - applicationMonitor = new ApplicationMonitor(application); - applicationMonitor.setHasStartupDependents(false); - applicationMonitor.startMinimumDependencies(application); - - } else { - String msg = "[Application] " + appId + " cannot be found in the Topology"; - throw new TopologyInConsistentException(msg); - } - } finally { - ApplicationHolder.releaseReadLock(); - - } - - return applicationMonitor; - - } - - /** - * Updates ClusterContext for given cluster - * - * @param parentMonitor parent of the monitor - * @param context - * @return ClusterMonitor - Updated ClusterContext - * @throws org.apache.stratos.autoscaler.exception.PolicyValidationException - * @throws org.apache.stratos.autoscaler.exception.PartitionValidationException - */ - public static AbstractClusterMonitor getClusterMonitor(ParentComponentMonitor parentMonitor, - ClusterChildContext context) - throws PolicyValidationException, - PartitionValidationException, - TopologyInConsistentException { - - //Retrieving the Cluster from Topology - String clusterId = context.getId(); - String serviceName = context.getServiceName(); - Cluster cluster; - //acquire read lock for the service and cluster - TopologyManager.acquireReadLockForCluster(serviceName, clusterId); - try { - Topology topology = TopologyManager.getTopology(); - if (topology.serviceExists(serviceName)) { - Service service = topology.getService(serviceName); - if (service.clusterExists(clusterId)) { - cluster = service.getCluster(clusterId); - } else { - String msg = "[Cluster] " + clusterId + " cannot be found in the " + - "Topology for [service] " + serviceName; - throw new TopologyInConsistentException(msg); - } - } else { - String msg = "[Service] " + serviceName + " cannot be found in the Topology"; - throw new TopologyInConsistentException(msg); - } - AbstractClusterMonitor clusterMonitor = ClusterMonitorFactory.getMonitor(cluster); - //Setting the parent of the cluster monitor - clusterMonitor.setParent(parentMonitor); - clusterMonitor.setId(clusterId); - - //setting the startup dependent behaviour of the cluster monitor - if(parentMonitor.hasStartupDependents() || (context.hasStartupDependents() && context.hasChild())) { - clusterMonitor.setHasStartupDependents(true); - } else { - clusterMonitor.setHasStartupDependents(false); - } - - //setting the scaling dependent behaviour of the cluster monitor - if(parentMonitor.hasGroupScalingDependent() || (context.isGroupScalingEnabled())) { - clusterMonitor.setHasGroupScalingDependent(true); - } else { - clusterMonitor.setHasGroupScalingDependent(false); - } - //setting the status of the cluster, if it doesn't match with Topology cluster status. - //TODO after adding cluster instances************* - /*if (cluster.getStatus(null) != clusterMonitor.getStatus()) { - //updating the status, so that it will notify the parent - clusterMonitor.setStatus(cluster.getStatus(null)); - } else { - if(!cluster.hasMembers()) { - StatusChecker.getInstance().onMemberStatusChange(clusterId); - } - }*/ - if(cluster.getInstanceContextCount() > 0) { - //Starting the cluster monitor as existing instances are found - } - return clusterMonitor; - - } finally { - TopologyManager.releaseReadLockForCluster(serviceName, clusterId); - } - } -} http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/AbstractClusterMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/AbstractClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/AbstractClusterMonitor.java index 72bfe71..77b405e 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/AbstractClusterMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/AbstractClusterMonitor.java @@ -25,7 +25,7 @@ import org.apache.stratos.autoscaler.applications.ApplicationHolder; import org.apache.stratos.autoscaler.event.publisher.ClusterStatusEventPublisher; import org.apache.stratos.autoscaler.exception.InvalidArgumentException; import org.apache.stratos.autoscaler.monitor.Monitor; -import org.apache.stratos.autoscaler.monitor.MonitorStatusEventBuilder; +import org.apache.stratos.autoscaler.monitor.events.builder.MonitorStatusEventBuilder; import org.apache.stratos.autoscaler.monitor.events.MonitorScalingEvent; import org.apache.stratos.autoscaler.monitor.events.MonitorStatusEvent; import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator; http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitorFactory.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitorFactory.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitorFactory.java index b6cf44b..bfee5b3 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitorFactory.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitorFactory.java @@ -21,30 +21,15 @@ package org.apache.stratos.autoscaler.monitor.cluster; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.stratos.autoscaler.*; -import org.apache.stratos.autoscaler.client.CloudControllerClient; -import org.apache.stratos.autoscaler.exception.PartitionValidationException; -import org.apache.stratos.autoscaler.exception.PolicyValidationException; -import org.apache.stratos.autoscaler.partition.PartitionGroup; -import org.apache.stratos.autoscaler.partition.PartitionManager; -import org.apache.stratos.autoscaler.policy.PolicyManager; -import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy; -import org.apache.stratos.autoscaler.policy.model.DeploymentPolicy; -import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition; +import org.apache.stratos.autoscaler.exception.partition.PartitionValidationException; +import org.apache.stratos.autoscaler.exception.policy.PolicyValidationException; import org.apache.stratos.cloud.controller.stub.pojo.MemberContext; -import org.apache.stratos.cloud.controller.stub.pojo.Properties; -import org.apache.stratos.cloud.controller.stub.pojo.Property; -import org.apache.stratos.common.constants.StratosConstants; import org.apache.stratos.messaging.domain.topology.Cluster; import org.apache.stratos.messaging.domain.topology.ClusterStatus; import org.apache.stratos.messaging.domain.topology.Member; import org.apache.stratos.messaging.domain.topology.MemberStatus; import org.apache.stratos.messaging.util.Constants; -import java.util.HashMap; -import java.util.Map; -import java.util.Random; - /* * Factory class for creating cluster monitors. */ http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/KubernetesClusterMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/KubernetesClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/KubernetesClusterMonitor.java index d0688fd..a8bd3f2 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/KubernetesClusterMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/KubernetesClusterMonitor.java @@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory; import org.apache.stratos.autoscaler.context.cluster.KubernetesClusterContext; import org.apache.stratos.autoscaler.context.member.MemberStatsContext; import org.apache.stratos.autoscaler.client.CloudControllerClient; -import org.apache.stratos.autoscaler.exception.TerminationException; +import org.apache.stratos.autoscaler.exception.cartridge.TerminationException; import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator; import org.apache.stratos.messaging.domain.topology.Cluster; import org.apache.stratos.messaging.domain.topology.Member; http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java index 3bc84f4..394c546 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMClusterMonitor.java @@ -30,7 +30,7 @@ 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.InvalidArgumentException; -import org.apache.stratos.autoscaler.exception.TerminationException; +import org.apache.stratos.autoscaler.exception.cartridge.TerminationException; import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator; import org.apache.stratos.autoscaler.status.processor.StatusChecker; import org.apache.stratos.cloud.controller.stub.pojo.MemberContext; http://git-wip-us.apache.org/repos/asf/stratos/blob/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMServiceClusterMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMServiceClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMServiceClusterMonitor.java index 7cc22f4..9d1a0ca 100644 --- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMServiceClusterMonitor.java +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/VMServiceClusterMonitor.java @@ -26,7 +26,7 @@ import org.apache.stratos.autoscaler.context.cluster.VMClusterContext; import org.apache.stratos.autoscaler.context.partition.network.ClusterLevelNetworkPartitionContext; import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionContext; import org.apache.stratos.autoscaler.event.publisher.ClusterStatusEventPublisher; -import org.apache.stratos.autoscaler.monitor.MonitorStatusEventBuilder; +import org.apache.stratos.autoscaler.monitor.events.builder.MonitorStatusEventBuilder; import org.apache.stratos.autoscaler.monitor.events.MonitorScalingEvent; import org.apache.stratos.autoscaler.monitor.events.MonitorStatusEvent; import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator; 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/ApplicationMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java new file mode 100644 index 0000000..64dd43b --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ApplicationMonitor.java @@ -0,0 +1,285 @@ +/* + * 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.context.partition.network.ApplicationLevelNetworkPartitionContext; +import org.apache.stratos.autoscaler.applications.ApplicationHolder; +import org.apache.stratos.autoscaler.applications.topic.ApplicationBuilder; +import org.apache.stratos.autoscaler.exception.application.DependencyBuilderException; +import org.apache.stratos.autoscaler.exception.application.ParentMonitorNotFoundException; +import org.apache.stratos.autoscaler.exception.policy.PolicyValidationException; +import org.apache.stratos.autoscaler.exception.application.TopologyInConsistentException; +import org.apache.stratos.autoscaler.monitor.Monitor; +import org.apache.stratos.autoscaler.monitor.events.builder.MonitorStatusEventBuilder; +import org.apache.stratos.autoscaler.monitor.events.ApplicationStatusEvent; +import org.apache.stratos.autoscaler.monitor.events.MonitorScalingEvent; +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.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.*; + +/** + * ApplicationMonitor is to control the child monitors + */ +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); + + } + + /** + * Find the group monitor by traversing recursively in the hierarchical monitors. + * + * @param groupId the unique alias of the Group + * @return the found GroupMonitor + */ + public Monitor findGroupMonitorWithId(String groupId) { + Monitor monitor; + //searching within active monitors + return findGroupMonitor(groupId, aliasToActiveMonitorsMap.values()); + } + + + /** + * Utility method to find the group monitor recursively within app monitor + * + * @param id the unique alias of the Group + * @param monitors the group monitors found in the app monitor + * @return the found GroupMonitor + */ + private Monitor findGroupMonitor(String id, Collection<Monitor> monitors) { + for (Monitor monitor : monitors) { + // check if alias is equal, if so, return + if (monitor.getId().equals(id)) { + return monitor; + } else { + // check if this Group has nested sub Groups. If so, traverse them as well + if (monitor instanceof ParentComponentMonitor) { + return findGroupMonitor(id, ((ParentComponentMonitor) monitor). + getAliasToActiveMonitorsMap().values()); + } + } + } + return null; + } + + /** + * To set the status of the application monitor + * + * @param status the status + */ + public void setStatus(ApplicationStatus status, String instanceId) { + //notify the children about the state change + MonitorStatusEventBuilder.notifyChildren(this, new ApplicationStatusEvent(status, appId, 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.Terminating || status1 == GroupStatus.Terminating) { + //mark the child monitor as inActive in the map + this.markMonitorAsTerminating(id); + + } else if (status1 == ClusterStatus.Created || status1 == GroupStatus.Created) { + if (this.terminatingMonitorsList.contains(id)) { + this.terminatingMonitorsList.remove(id); + this.aliasToActiveMonitorsMap.remove(id); + } + //TODO + /*if (this.status == ApplicationStatus.Terminating) { + StatusChecker.getInstance().onChildStatusChange(id, this.id, this.appId); + } else { + onChildTerminatedEvent(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 + /*if (this.status == ApplicationStatus.Terminating || this.status == ApplicationStatus.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) { + // nothing to do + } + + @Override + public void onChildScalingEvent(MonitorScalingEvent scalingEvent) { + + } + + @Override + public void onParentScalingEvent(MonitorScalingEvent scalingEvent) { + + } + + @Override + public void onEvent(MonitorScalingEvent scalingEvent) { + + } + + public void startMinimumDependencies(Application application) + throws TopologyInConsistentException, PolicyValidationException { + //There will be one application instance + //FIXME when having multiple network partitions + if (application.getInstanceContextCount() > 0) { + startDependency(application); + } else { + //No available instances in the Applications. Need to start them all + createInstanceAndStartDependency(application); + } + } + + private void createInstanceAndStartDependency(Application application) + throws TopologyInConsistentException, PolicyValidationException { + List<String> instanceIds = new ArrayList<String>(); + DeploymentPolicy deploymentPolicy = getDeploymentPolicy(application); + String instanceId; + for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { + if(partitionGroup.isActiveByDefault()) { + ApplicationLevelNetworkPartitionContext context = + new ApplicationLevelNetworkPartitionContext(partitionGroup.getId()); + instanceId = createApplicationInstance(application, partitionGroup.getId()); + context.addInstanceContext(application.getInstanceContexts(instanceId)); + + this.networkPartitionCtxts.put(context.getId(), context); + + instanceIds.add(instanceId); + } + + } + startDependency(application, instanceIds); + + + } + + public void createInstanceOnBurstingForApplication() throws TopologyInConsistentException, + PolicyValidationException, + ParentMonitorNotFoundException { + //TODO get lock + Application application = ApplicationHolder.getApplications().getApplication(appId); + if(application == null) { + String msg = "Application cannot be found in the Topology."; + throw new TopologyInConsistentException(msg); + } + DeploymentPolicy deploymentPolicy = getDeploymentPolicy(application); + String instanceId = null; + //Find out the inActive network partition + boolean burstNPFound = false; + for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) { + if(!partitionGroup.isActiveByDefault()) { + ApplicationLevelNetworkPartitionContext context = + new ApplicationLevelNetworkPartitionContext(partitionGroup.getId()); + context.setCreatedOnBurst(true); + instanceId = createApplicationInstance(application, partitionGroup.getId()); + context.addInstanceContext(application.getInstanceContexts(instanceId)); + this.networkPartitionCtxts.put(context.getId(), context); + burstNPFound = true; + } + } + + if(!burstNPFound) { + log.warn("[Application] " + appId + " cannot be burst as no available resources found"); + } else { + startDependency(application, instanceId); + } + + } + + private DeploymentPolicy getDeploymentPolicy(Application application) throws PolicyValidationException { + String deploymentPolicyName = application.getDeploymentPolicy(); + if (deploymentPolicyName == null) { + String msg = "Deployment Policy is not specified to the [Application]:" + appId; + log.error(msg); + throw new PolicyValidationException(msg); + } + + DeploymentPolicy deploymentPolicy = + PolicyManager.getInstance() + .getDeploymentPolicy(deploymentPolicyName); + if (deploymentPolicy == null) { + if (deploymentPolicy == null) { + String msg = "Deployment policy is null: [policy-name] " + deploymentPolicyName; + log.error(msg); + throw new PolicyValidationException(msg); + } + } + + return deploymentPolicy; + } + + private String createApplicationInstance(Application application, String networkPartitionId) { + String instanceId = this.generateInstanceId(application); + ApplicationBuilder.handleApplicationInstanceCreatedEvent(appId, instanceId, networkPartitionId); + 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/e9902546/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java new file mode 100644 index 0000000..eb15900 --- /dev/null +++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java @@ -0,0 +1,336 @@ +/* + * 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.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.application.DependencyBuilderException; +import org.apache.stratos.autoscaler.exception.application.TopologyInConsistentException; +import org.apache.stratos.autoscaler.monitor.EventHandler; +import org.apache.stratos.autoscaler.monitor.Monitor; +import org.apache.stratos.autoscaler.monitor.events.builder.MonitorStatusEventBuilder; +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); + } +}
