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);
+    }
+}

Reply via email to