You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by re...@apache.org on 2015/05/06 14:25:13 UTC

[1/2] stratos git commit: fixing STRATOS-1353 and refactoring the ParentComponentMonitor

Repository: stratos
Updated Branches:
  refs/heads/master 4750f1a6a -> 1ef37dbb2


fixing STRATOS-1353 and refactoring the ParentComponentMonitor


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/1ef37dbb
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/1ef37dbb
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/1ef37dbb

Branch: refs/heads/master
Commit: 1ef37dbb2a23583ec406e5fa928af7fabb979b8d
Parents: 60493dc
Author: reka <rt...@gmail.com>
Authored: Wed May 6 16:11:03 2015 +0530
Committer: reka <rt...@gmail.com>
Committed: Wed May 6 17:48:56 2015 +0530

----------------------------------------------------------------------
 .../monitor/component/ApplicationMonitor.java   |   2 +
 .../monitor/component/GroupMonitor.java         |  40 ++--
 .../component/ParentComponentMonitor.java       | 214 ++++++++++++-------
 3 files changed, 153 insertions(+), 103 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/1ef37dbb/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
index 8568b0d..314be1e 100644
--- 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
@@ -291,6 +291,8 @@ public class ApplicationMonitor extends ParentComponentMonitor {
                     Monitor monitor = this.getMonitor(childId);
                     boolean active = false;
                     if (monitor instanceof GroupMonitor) {
+                        //Checking whether the Group is still active in case the faulty member
+                        // identified after scaling up
                         active = verifyGroupStatus(childId, instanceId, GroupStatus.Active);
                     }
                     if (!active) {

http://git-wip-us.apache.org/repos/asf/stratos/blob/1ef37dbb/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java
index 5892bb6..4c62889 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/GroupMonitor.java
@@ -149,8 +149,7 @@ public class GroupMonitor extends ParentComponentMonitor {
                             getMinInstanceCount();
                     int maxInstances = ((GroupLevelNetworkPartitionContext) networkPartitionContext).
                             getMaxInstanceCount();
-                    int activeInstances = ((GroupLevelNetworkPartitionContext) networkPartitionContext).
-                            getActiveInstancesCount();
+                    int activeInstances = networkPartitionContext.getActiveInstancesCount();
                     if (nonTerminatedInstancesCount < minInstances) {
                         int instancesToBeCreated = minInstances - nonTerminatedInstancesCount;
                         for (int i = 0; i < instancesToBeCreated; i++) {
@@ -177,7 +176,7 @@ public class GroupMonitor extends ParentComponentMonitor {
                         int instancesToBeTerminated = activeInstances - maxInstances;
                         Collection<InstanceContext> contexts = networkPartitionContext.
                                 getInstanceIdToInstanceContextMap().values();
-                        List<InstanceContext> contextList = new ArrayList<InstanceContext>();
+                        List<InstanceContext> contextList = new ArrayList<InstanceContext>(contexts);
                         for (int i = 0; i < instancesToBeTerminated; i++) {
                             InstanceContext instanceContext = contextList.get(i);
                             //scale down only when extra instances found
@@ -372,14 +371,12 @@ public class GroupMonitor extends ParentComponentMonitor {
                             getApplication(this.appId);
                     if (application != null) {
                         //Notifying the parent using parent's instance Id,
-                        // as it has group scaling enabled.
-                        if (group != null) {
-                            // notify parent
-                            log.info("[Group] " + this.id + " is notifying the [parent] " + this.parent.getId() +
-                                    " [instance] " + parentInstanceId);
-                            MonitorStatusEventBuilder.handleGroupStatusEvent(this.parent,
-                                    status, this.id, parentInstanceId);
-                        }
+                        // as it has group scaling enabled. Notify parent
+                        log.info("[Group] " + this.id + " is notifying the [parent] " + this.parent.getId() +
+                                " [instance] " + parentInstanceId);
+                        MonitorStatusEventBuilder.handleGroupStatusEvent(this.parent,
+                                status, this.id, parentInstanceId);
+
                     }
                 } finally {
                     ApplicationHolder.releaseReadLock();
@@ -600,9 +597,9 @@ public class GroupMonitor extends ParentComponentMonitor {
             if (deploymentPolicy != null) {
                 NetworkPartition[] networkPartitions = deploymentPolicy.getNetworkPartitions();
                 NetworkPartition networkPartition = null;
-                for (int i = 0; i < networkPartitions.length; i++) {
-                    if (networkPartitions[i].getId().equals(networkPartitionId)) {
-                        networkPartition = networkPartitions[i];
+                for (NetworkPartition networkPartition1 : networkPartitions) {
+                    if (networkPartition1.getId().equals(networkPartitionId)) {
+                        networkPartition = networkPartition1;
                     }
                 }
 
@@ -634,14 +631,12 @@ public class GroupMonitor extends ParentComponentMonitor {
      *
      * @param parentInstanceContext   the parent instance context
      * @param networkPartitionContext the GroupLevelNetworkPartitionContext
-     * @param groupAlias              TODO
-     * @return the partition context
+     * @param groupAlias alias of the group
      */
     private void addPartitionContext(Instance parentInstanceContext,
                                      GroupLevelNetworkPartitionContext networkPartitionContext, String groupAlias) {
 
         String networkPartitionId = parentInstanceContext.getNetworkPartitionId();
-        List<GroupLevelPartitionContext> childPartitionContexts = new ArrayList<GroupLevelPartitionContext>();
 
         String deploymentPolicyId = AutoscalerUtil.getDeploymentPolicyIdByAlias(appId, groupAlias);
         DeploymentPolicy deploymentPolicy = PolicyManager.getInstance().getDeploymentPolicy(deploymentPolicyId);
@@ -651,7 +646,7 @@ public class GroupMonitor extends ParentComponentMonitor {
             String parentPartitionId = parentInstanceContext.getPartitionId();
             if (parentPartitionId != null && networkPartitionContext.getPartitionCtxt(parentPartitionId) == null) {
                 GroupLevelPartitionContext partitionContext = new GroupLevelPartitionContext(parentPartitionId, networkPartitionId);
-                networkPartitionContext.addPartitionContext((GroupLevelPartitionContext) partitionContext);
+                networkPartitionContext.addPartitionContext(partitionContext);
                 if (log.isInfoEnabled()) {
                     log.info("[Partition] " + parentPartitionId + "has been added for the " + "[Group] " + this.id);
                 }
@@ -679,8 +674,6 @@ public class GroupMonitor extends ParentComponentMonitor {
 
                                 GroupLevelPartitionContext groupLevelPartitionContext = new GroupLevelPartitionContext(
                                         partition.getId(), networkPartitionId, deploymentPolicyId);
-
-                                childPartitionContexts.add(groupLevelPartitionContext);
                                 networkPartitionContext.addPartitionContext(groupLevelPartitionContext);
                                 if (log.isInfoEnabled()) {
                                     log.info(String.format("[Partition] %s has been added for the [Group] %s",
@@ -906,12 +899,7 @@ public class GroupMonitor extends ParentComponentMonitor {
         }
         //TODO Starting all the instances, can do in parallel
         for (String instanceId : instanceIdsToStart) {
-            try {
-                startDependency(group, instanceId);
-            } catch (MonitorNotFoundException e) {
-                //TODO exception handling
-                log.error("Error while creating the group/cluster instance", e);
-            }
+            startDependency(group, instanceId);
         }
         return startedOnDemand;
     }

http://git-wip-us.apache.org/repos/asf/stratos/blob/1ef37dbb/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java
index fe3812b..4ffda9f 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/component/ParentComponentMonitor.java
@@ -136,11 +136,17 @@ public abstract class ParentComponentMonitor extends Monitor {
     }
 
     /**
+     *
+     */
+
+    /**
      * This will start the parallel dependencies at once from the top level.
      * it will get invoked when the monitor starts up only.
+     *
+     * @param component        The component which needs to be used to create the monitor
+     * @param parentInstanceId parent-instance-id of the instance which added to the monitor
      */
-    public void startDependency(ParentComponent component, String parentInstanceId) throws
-            MonitorNotFoundException {
+    public void startDependency(ParentComponent component, String parentInstanceId) {
         //start the first dependency
         List<ApplicationChildContext> applicationContexts = this.startupDependencyTree.
                 getStartAbleDependencies();
@@ -153,14 +159,20 @@ public abstract class ParentComponentMonitor extends Monitor {
      * This will get invoked based on the activation event of its one of the child
      *
      * @param componentId alias/clusterId of which receive the activated event
+     * @param instanceId  instance id of the instance
+     * @return whether the instance has created or not
+     * @throws MonitorNotFoundException if the monitor is not there
      */
-    public boolean startDependency(String componentId, String instanceId) throws MonitorNotFoundException {
-        List<ApplicationChildContext> applicationContexts = this.startupDependencyTree.getStarAbleDependencies(componentId);
+    public boolean startDependency(String componentId, String instanceId)
+            throws MonitorNotFoundException {
+        List<ApplicationChildContext> applicationContexts = this.startupDependencyTree.
+                getStarAbleDependencies(componentId);
         List<String> instanceIds = new ArrayList<String>();
         instanceIds.add(instanceId);
         return startDependency(applicationContexts, instanceIds);
     }
 
+
     /**
      * This will start the parallel dependencies at once from the top level
      * by traversing to find the terminated dependencies.
@@ -168,8 +180,7 @@ public abstract class ParentComponentMonitor extends Monitor {
      *
      * @param instanceId instance id of the instance
      */
-    public void startDependencyOnTermination(String instanceId) throws TopologyInConsistentException,
-            MonitorNotFoundException, PolicyValidationException, PartitionValidationException {
+    public void startDependencyOnTermination(String instanceId) {
 
         //start the first dependency which went to terminated
         List<ApplicationChildContext> applicationContexts = this.startupDependencyTree.
@@ -197,32 +208,37 @@ public abstract class ParentComponentMonitor extends Monitor {
      * To start the dependency of the given application contexts
      *
      * @param applicationContexts the found applicationContexts to be started
+     * @param parentInstanceIds   the instance-ids of the parent instance
      */
-    private boolean startDependency(List<ApplicationChildContext> applicationContexts, List<String> parentInstanceIds) {
-        if (applicationContexts != null && applicationContexts.isEmpty()) {
+    private boolean startDependency(List<ApplicationChildContext> applicationContexts,
+                                    List<String> parentInstanceIds) {
+        if (applicationContexts == null || applicationContexts.isEmpty()) {
             //all the groups/clusters have been started and waiting for activation
-            log.info("No more dependent monitors to be started for component: [type] " + getMonitorType().toString().toLowerCase()
+            log.info("No more dependent monitors to be started for component: [type] " +
+                    getMonitorType().toString().toLowerCase()
                     + "[component] " + this.id);
             return false;
 
-        }
-        for (ApplicationChildContext context : applicationContexts) {
-            if (!this.aliasToActiveChildMonitorsMap.containsKey(context.getId())) {
-                log.info(String.format("Starting dependent monitor: [application] %s [component] %s",
-                        getAppId(), context.getId()));
-                startMonitor(this, context, parentInstanceIds);
-            } else {
-                log.info(String.format("Dependent monitor already created, creating instance: " +
-                        "[application] %s [component] %s", getAppId(), context.getId()));
+        } else {
+            for (ApplicationChildContext context : applicationContexts) {
+                if (!this.aliasToActiveChildMonitorsMap.containsKey(context.getId())) {
+                    log.info(String.format("Starting dependent monitor: [application] %s [component] %s",
+                            getAppId(), context.getId()));
+                    startMonitor(this, context, parentInstanceIds);
+                } else {
+                    log.info(String.format("Dependent monitor already created, creating instance: " +
+                            "[application] %s [component] %s", getAppId(), context.getId()));
 
-                Monitor monitor = aliasToActiveChildMonitorsMap.get(context.getId());
-                // Creating new instance
-                for (String instanceId : parentInstanceIds) {
-                    monitor.createInstanceOnDemand(instanceId);
+                    Monitor monitor = aliasToActiveChildMonitorsMap.get(context.getId());
+                    // Creating new instance
+                    for (String instanceId : parentInstanceIds) {
+                        monitor.createInstanceOnDemand(instanceId);
+                    }
                 }
             }
+            return true;
         }
-        return true;
+
     }
 
     @Override
@@ -253,6 +269,13 @@ public abstract class ParentComponentMonitor extends Monitor {
 
     }
 
+    /**
+     * This will get triggered by the child when scale down beyond min happened in the child
+     *
+     * @param scalingDownBeyondMinEvent scalingDownBeyondMinEvent used to keep the instance-id,
+     *                                  network-partition-id of the instance
+     *                                  which is trying to get scale down.
+     */
     public void onChildScalingDownBeyondMinEvent(ScalingDownBeyondMinEvent scalingDownBeyondMinEvent) {
 
         String networkPartitionId = scalingDownBeyondMinEvent.getNetworkPartitionId();
@@ -308,7 +331,8 @@ public abstract class ParentComponentMonitor extends Monitor {
             removeInstanceFromFromTerminatingMap(childId, instanceId);
 
             boolean startDep = false;
-            if (!aliasToActiveChildMonitorsMap.containsKey(childId) || !pendingChildMonitorsList.contains(childId)) {
+            if (!aliasToActiveChildMonitorsMap.containsKey(childId) ||
+                    !pendingChildMonitorsList.contains(childId)) {
                 startDep = startDependency(childId, instanceId);
             }
 
@@ -326,39 +350,58 @@ public abstract class ParentComponentMonitor extends Monitor {
     }
 
     /**
-     * @param childId
+     * This will act upon the any child in-activated event and terminate other dependents or
+     * terminate all according to the termination behavior
+     *
+     * @param childId    id of the child
+     * @param instanceId id of the instance which got the status changed
      */
     protected void onChildInactiveEvent(String childId, final String instanceId) {
         List<ApplicationChildContext> terminationList;
         terminationList = this.startupDependencyTree.getTerminationDependencies(childId);
+
         //Need to notify the parent about the status  change from Active-->Inactive
-        // TODO to make app also inaction if (this.parent != null) {
         ServiceReferenceHolder.getInstance().getGroupStatusProcessorChain().
                 process(id, appId, instanceId);
 
-        //TODO checking whether terminating them in reverse order,
-        // TODO if so can handle it in the parent event.
-
-        //Since it is reached the most independent unit and has few independent monitors,
-        // has to put the children down to terminating
+        /**
+         * Since it is reached the most independent unit and has few independent monitors,
+         * has to put the children down to terminating
+         */
         if (this.startupDependencyTree.getTerminationBehavior() ==
                 DependencyTree.TerminationBehavior.TERMINATE_ALL &&
                 terminationList.size() == this.aliasToActiveChildMonitorsMap.size()) {
-            //handling the killall scenario
-            if (this.parent != null) {
+            //handling the kill-all scenario
+            if (parent != null) {
                 //send terminating to the parent. So that it will push terminating to its children
-                ApplicationBuilder.handleGroupTerminatingEvent(this.appId, this.id, instanceId);
+                log.info("[group-instance] " + instanceId + "  in [group] " + id +
+                        " in [application] " + appId + " has been marked as " +
+                        "terminating due to [terminate-all] behavior");
+                ApplicationBuilder.handleGroupTerminatingEvent(appId, id, instanceId);
+
             } else {
                 //if it is an application, send terminating event individually for children
+                log.info("Since this is application, all children will get terminated one-by-one " +
+                        "for [application] " + appId + " [application-instance] " + instanceId +
+                        " due to [terminate-all] behavior");
                 sendTerminatingEventOnNotification(terminationList, childId, true, instanceId);
             }
-            log.info("The group" + childId + " has been marked as terminating " +
-                    "due to all the children are to be terminated");
         } else {
+            log.info("Dependent children of [instance] " + instanceId + "  in [group] " + id +
+                    " in [application] " + appId + " will be marked as terminating due to " +
+                    "[terminate-dependents] behavior");
             sendTerminatingEventOnNotification(terminationList, childId, false, instanceId);
         }
     }
 
+    /**
+     * Utility method to send the termination notification to group/cluster based on termination list
+     *
+     * @param terminationList termination list of siblings
+     * @param notifier        who notified
+     * @param terminateAll    whether terminate-all or not
+     * @param instanceId      instance id of the instance
+     */
     private void sendTerminatingEventOnNotification(List<ApplicationChildContext> terminationList,
                                                     String notifier, boolean terminateAll, String instanceId) {
         Monitor monitor;
@@ -398,21 +441,20 @@ public abstract class ParentComponentMonitor extends Monitor {
      *
      * @param eventId id of the notifier
      */
-
     protected void onChildTerminatedEvent(String eventId, String instanceId) {
         List<ApplicationChildContext> terminationList;
         boolean allDependentTerminated = false;
 
-        ApplicationChildContext context = this.startupDependencyTree.
-                getApplicationChildContextByIdInPrimaryTree(eventId);
-        context.setTerminated(true);
+        //Retrieving the termination list
         terminationList = this.startupDependencyTree.getTerminationDependencies(eventId);
+
         //Make sure that all the dependents have been terminated properly to start the recovery
         if (terminationList != null) {
             allDependentTerminated = allDependentTerminated(terminationList, instanceId);
         }
         log.info("Calculating the dependencies to be started upon the termination of the " +
-                "group/cluster " + eventId + " for [instance] " + instanceId);
+                "[group/cluster] " + eventId + " for [instance] " + instanceId +
+                " of [application] " + appId);
 
         List<ApplicationChildContext> parentContexts = this.startupDependencyTree.
                 findAllParentContextWithId(eventId);
@@ -424,35 +466,28 @@ public abstract class ParentComponentMonitor extends Monitor {
             allParentsActive = allParentActive(parentContexts, instanceId);
         }
 
-        if ((terminationList.isEmpty() || allDependentTerminated) &&
-                (parentContexts.isEmpty() || parentsTerminated || allParentsActive)) {
-            //Find the non existent monitor by traversing dependency tree
-
-            String errorMessage = String.format("Could not start dependency on termination: [instance-id] %s", instanceId);
-
-            try {
-                try {
-                    this.startDependencyOnTermination(instanceId);
-                } catch (MonitorNotFoundException e) {
-                    log.error(errorMessage, e);
-                } catch (PolicyValidationException e) {
-                    log.error(errorMessage, e);
-                } catch (PartitionValidationException e) {
-                    log.error(errorMessage, e);
-                }
-            } catch (TopologyInConsistentException e) {
-                //TODO revert the siblings and notify parent, change a flag for reverting/un-subscription
-                log.error("Error while starting the monitor upon termination" + e);
-            }
+        if ((terminationList == null || terminationList.isEmpty() || allDependentTerminated) &&
+                (parentContexts == null || parentContexts.isEmpty() ||
+                        parentsTerminated || allParentsActive)) {
+            //Starting the dependency sibling upon termination of most in-dependent sibling
+            this.startDependencyOnTermination(instanceId);
         } else {
             ServiceReferenceHolder.getInstance().getGroupStatusProcessorChain().
-                    process(this.id, this.appId, instanceId);
-            log.info("Checking the status of group/application as no dependent found...");
+                    process(id, appId, instanceId);
+            log.info("Checking the status of [group/application] as no dependent found for " +
+                    "[application] " + appId + " [group] " + id + " [instance] " + instanceId);
         }
 
 
     }
 
+    /**
+     * Calculating whether all the dependent has terminated or not
+     *
+     * @param terminationList termination list of siblings
+     * @param instanceId      instance id of the instance
+     * @return whether all dependents terminated or not
+     */
     private boolean allDependentTerminated(List<ApplicationChildContext> terminationList, String instanceId) {
         boolean allDependentTerminated = false;
         for (ApplicationChildContext context1 : terminationList) {
@@ -462,8 +497,7 @@ public abstract class ParentComponentMonitor extends Monitor {
                     this.terminatingInstancesMap.get(context1.getId()).contains(instanceId)) {
                 log.info("Waiting for the [dependent] " + context1.getId() + " [instance] " +
                         instanceId + "to be terminated...");
-                allDependentTerminated = false;
-                return allDependentTerminated;
+                return false;
             } else if (this.aliasToActiveChildMonitorsMap.get(context1.getId()).getInstance(instanceId) != null) {
                 log.info("[Dependent] " + context1.getId() + "[Instance] " + instanceId +
                         "has not been started to terminate yet. Hence waiting....");
@@ -475,6 +509,13 @@ public abstract class ParentComponentMonitor extends Monitor {
     }
 
 
+    /**
+     * Calculating whether all the required siblings are terminated or not
+     *
+     * @param parentContexts all the siblings who required to be active
+     * @param instanceId     instance id of the instance which has state change
+     * @return whether all the required siblings are terminated or not
+     */
     private boolean allParentTerminated(List<ApplicationChildContext> parentContexts,
                                         String instanceId) {
         boolean parentsTerminated = false;
@@ -485,8 +526,7 @@ public abstract class ParentComponentMonitor extends Monitor {
                     this.terminatingInstancesMap.get(context1.getId()).contains(instanceId)) {
                 log.info("Waiting for the [Parent Monitor] " + context1.getId()
                         + " to be terminated");
-                parentsTerminated = false;
-                return parentsTerminated;
+                return false;
             } else if (this.aliasToActiveChildMonitorsMap.get(context1.getId()).getInstance(instanceId) != null) {
                 log.info("[Dependent Parent] " + context1.getId() + "[Instance] " + instanceId +
                         "has not been started to terminate yet. Hence waiting....");
@@ -499,6 +539,13 @@ public abstract class ParentComponentMonitor extends Monitor {
         return parentsTerminated;
     }
 
+    /**
+     * Calculating whether all the required siblings are active or not
+     *
+     * @param parentContexts all the siblings who required to be active
+     * @param instanceId     instance id of the instance which has state change
+     * @return whether all the required siblings are active or not
+     */
     private boolean allParentActive(List<ApplicationChildContext> parentContexts, String instanceId) {
         boolean parentsActive = false;
         for (ApplicationChildContext context1 : parentContexts) {
@@ -506,31 +553,36 @@ public abstract class ParentComponentMonitor extends Monitor {
                     this.inactiveInstancesMap.get(context1.getId()).contains(instanceId) ||
                     this.terminatingInstancesMap.containsKey(context1.getId()) &&
                             this.terminatingInstancesMap.get(context1.getId()).contains(instanceId)) {
-                parentsActive = false;
                 log.info("Dependent [Monitor] " + context1.getId()
                         + " is not yet active");
-                return parentsActive;
+                return false;
             } else if (this.aliasToActiveChildMonitorsMap.containsKey(context1.getId())) {
                 Monitor monitor = this.aliasToActiveChildMonitorsMap.get(context1.getId());
 
                 if (monitor instanceof GroupMonitor) {
                     try {
                         ApplicationHolder.acquireReadLock();
+                        //verify whether the GroupInstance is active or not
                         if (verifyGroupStatus(context1.getId(), instanceId, GroupStatus.Active)) {
                             parentsActive = true;
-
+                        } else {
+                            parentsActive = false;
                         }
                     } finally {
                         ApplicationHolder.releaseReadLock();
                     }
                 } else if (monitor instanceof ClusterMonitor) {
                     ClusterMonitor monitor1 = (ClusterMonitor) monitor;
-                    TopologyManager.acquireReadLockForCluster(monitor1.getServiceId(),
-                            monitor1.getClusterId());
                     try {
-                        if (((ClusterInstance) monitor1.getInstance(instanceId)).getStatus()
+                        TopologyManager.acquireReadLockForCluster(monitor1.getServiceId(),
+                                monitor1.getClusterId());
+                        ClusterInstance clusterInstance = (ClusterInstance) monitor1.
+                                getInstance(instanceId);
+                        if (clusterInstance != null && clusterInstance.getStatus()
                                 == ClusterStatus.Active) {
                             parentsActive = true;
+                        } else {
+                            parentsActive = false;
                         }
                     } finally {
                         TopologyManager.releaseReadLockForCluster(monitor1.getServiceId(),
@@ -543,6 +595,14 @@ public abstract class ParentComponentMonitor extends Monitor {
         return parentsActive;
     }
 
+    /**
+     * Calculating whether the instance of the group in a required status
+     *
+     * @param childId        id of the child where the instance resides
+     * @param instanceId     instance id of the instance which has state change
+     * @param requiredStatus the status to be checked
+     * @return whether the group instance in required status or not
+     */
     public boolean verifyGroupStatus(String childId, String instanceId, GroupStatus requiredStatus) {
         Monitor monitor = this.getMonitor(childId);
         if (!(monitor instanceof GroupMonitor)) {
@@ -775,7 +835,7 @@ public abstract class ParentComponentMonitor extends Monitor {
     public PartitionAlgorithm getAutoscaleAlgorithm(String partitionAlgorithm) {
         PartitionAlgorithm autoscaleAlgorithm = null;
         if (log.isDebugEnabled()) {
-            log.debug(String.format("Partition algorithm is ", partitionAlgorithm));
+            log.debug(String.format("Partition algorithm is %s ", partitionAlgorithm));
         }
         if (StratosConstants.PARTITION_ROUND_ROBIN_ALGORITHM_ID.equals(partitionAlgorithm)) {
 
@@ -827,7 +887,7 @@ public abstract class ParentComponentMonitor extends Monitor {
                 int retries = 5;
                 Monitor monitor = null;
                 boolean success = false;
-                while (!success && retries != 0) {
+                while (!success && retries >= 0) {
 
                     startTime = System.currentTimeMillis();
                     if (log.isInfoEnabled()) {
@@ -863,8 +923,8 @@ public abstract class ParentComponentMonitor extends Monitor {
                 }
 
                 if (monitor == null) {
-                    String msg = String.format("Monitor creation failed even after retrying for 5 times: "
-                            + "[type] %s [component] ", monitorTypeStr, context.getId());
+                    String msg = String.format("Monitor creation failed even after retrying for " +
+                            "5 times: [type] %s [component] %s ", monitorTypeStr, context.getId());
                     log.error(msg);
                     //TODO parent.notify();
                     throw new RuntimeException(msg);


[2/2] stratos git commit: fixing AutoscalerRuleEvaluator to parse drools once and added ksession per ClsuterInstanceContext as it shouldn't be shared by threads

Posted by re...@apache.org.
fixing AutoscalerRuleEvaluator to parse drools once and added ksession per ClsuterInstanceContext as it shouldn't be shared by threads


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/60493dc0
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/60493dc0
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/60493dc0

Branch: refs/heads/master
Commit: 60493dc05657ea13c917074c96ae55940ef4b690
Parents: 4750f1a
Author: reka <rt...@gmail.com>
Authored: Tue May 5 18:36:41 2015 +0530
Committer: reka <rt...@gmail.com>
Committed: Wed May 6 17:48:56 2015 +0530

----------------------------------------------------------------------
 .../context/cluster/ClusterInstanceContext.java | 107 ++++++++++
 .../monitor/cluster/ClusterMonitor.java         | 207 ++++++-------------
 .../rule/AutoscalerRuleEvaluator.java           |  42 ++--
 3 files changed, 197 insertions(+), 159 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/60493dc0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java
index 67787f5..9a8f31d 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/context/cluster/ClusterInstanceContext.java
@@ -25,7 +25,11 @@ import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionCont
 import org.apache.stratos.autoscaler.pojo.policy.autoscale.LoadAverage;
 import org.apache.stratos.autoscaler.pojo.policy.autoscale.MemoryConsumption;
 import org.apache.stratos.autoscaler.pojo.policy.autoscale.RequestsInFlight;
+import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
+import org.apache.stratos.common.constants.StratosConstants;
 import org.apache.stratos.messaging.domain.topology.Member;
+import org.drools.runtime.StatefulKnowledgeSession;
+import org.drools.runtime.rule.FactHandle;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -68,6 +72,17 @@ public class ClusterInstanceContext extends InstanceContext {
 
     private boolean hasScalingDependants;
     private boolean groupScalingEnabledSubtree;
+    private StatefulKnowledgeSession minCheckKnowledgeSession;
+    private StatefulKnowledgeSession maxCheckKnowledgeSession;
+    private StatefulKnowledgeSession obsoleteCheckKnowledgeSession;
+    private StatefulKnowledgeSession scaleCheckKnowledgeSession;
+    private StatefulKnowledgeSession dependentScaleCheckKnowledgeSession;
+    private AutoscalerRuleEvaluator autoscalerRuleEvaluator;
+    private FactHandle minCheckFactHandle;
+    private FactHandle maxCheckFactHandle;
+    private FactHandle obsoleteCheckFactHandle;
+    private FactHandle scaleCheckFactHandle;
+    private FactHandle dependentScaleCheckFactHandle;
 
     public ClusterInstanceContext(String clusterInstanceId, String partitionAlgo,
                                   int min, int max, String networkPartitionId, String clusterId,
@@ -88,6 +103,19 @@ public class ClusterInstanceContext extends InstanceContext {
         requiredInstanceCountBasedOnDependencies = minInstanceCount;
         this.hasScalingDependants = hasScalingDependants;
         this.groupScalingEnabledSubtree = groupScalingEnabledSubtree;
+
+        autoscalerRuleEvaluator = AutoscalerRuleEvaluator.getInstance();
+
+        this.obsoleteCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
+                StratosConstants.OBSOLETE_CHECK_DROOL_FILE);
+        this.scaleCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
+                StratosConstants.SCALE_CHECK_DROOL_FILE);
+        this.minCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
+                StratosConstants.MIN_CHECK_DROOL_FILE);
+        this.maxCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
+                StratosConstants.MAX_CHECK_DROOL_FILE);
+        this.dependentScaleCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
+                StratosConstants.DEPENDENT_SCALE_CHECK_DROOL_FILE);
     }
 
     public List<ClusterLevelPartitionContext> getPartitionCtxts() {
@@ -481,4 +509,83 @@ public class ClusterInstanceContext extends InstanceContext {
     public boolean isInGroupScalingEnabledSubtree() {
         return groupScalingEnabledSubtree;
     }
+
+    public StatefulKnowledgeSession getMinCheckKnowledgeSession() {
+        return minCheckKnowledgeSession;
+    }
+
+    public StatefulKnowledgeSession getMaxCheckKnowledgeSession() {
+        return maxCheckKnowledgeSession;
+    }
+
+    public void setMinCheckKnowledgeSession(
+            StatefulKnowledgeSession minCheckKnowledgeSession) {
+        this.minCheckKnowledgeSession = minCheckKnowledgeSession;
+    }
+
+    public StatefulKnowledgeSession getObsoleteCheckKnowledgeSession() {
+        return obsoleteCheckKnowledgeSession;
+    }
+
+    public void setObsoleteCheckKnowledgeSession(
+            StatefulKnowledgeSession obsoleteCheckKnowledgeSession) {
+        this.obsoleteCheckKnowledgeSession = obsoleteCheckKnowledgeSession;
+    }
+
+    public StatefulKnowledgeSession getScaleCheckKnowledgeSession() {
+        return scaleCheckKnowledgeSession;
+    }
+
+    public void setScaleCheckKnowledgeSession(
+            StatefulKnowledgeSession scaleCheckKnowledgeSession) {
+        this.scaleCheckKnowledgeSession = scaleCheckKnowledgeSession;
+    }
+
+    public StatefulKnowledgeSession getDependentScaleCheckKnowledgeSession() {
+        return dependentScaleCheckKnowledgeSession;
+    }
+
+    public void setDependentScaleCheckKnowledgeSession(StatefulKnowledgeSession dependentScaleCheckKnowledgeSession) {
+        this.dependentScaleCheckKnowledgeSession = dependentScaleCheckKnowledgeSession;
+    }
+
+    public FactHandle getMinCheckFactHandle() {
+        return minCheckFactHandle;
+    }
+
+    public void setMinCheckFactHandle(FactHandle minCheckFactHandle) {
+        this.minCheckFactHandle = minCheckFactHandle;
+    }
+
+    public FactHandle getObsoleteCheckFactHandle() {
+        return obsoleteCheckFactHandle;
+    }
+
+    public void setObsoleteCheckFactHandle(FactHandle obsoleteCheckFactHandle) {
+        this.obsoleteCheckFactHandle = obsoleteCheckFactHandle;
+    }
+
+    public FactHandle getScaleCheckFactHandle() {
+        return scaleCheckFactHandle;
+    }
+
+    public void setScaleCheckFactHandle(FactHandle scaleCheckFactHandle) {
+        this.scaleCheckFactHandle = scaleCheckFactHandle;
+    }
+
+    public FactHandle getMaxCheckFactHandle() {
+        return maxCheckFactHandle;
+    }
+
+    public void setMaxCheckFactHandle(FactHandle maxCheckFactHandle) {
+        this.maxCheckFactHandle = maxCheckFactHandle;
+    }
+
+    public FactHandle getDependentScaleCheckFactHandle() {
+        return dependentScaleCheckFactHandle;
+    }
+
+    public void setDependentScaleCheckFactHandle(FactHandle dependentScaleCheckFactHandle) {
+        this.dependentScaleCheckFactHandle = dependentScaleCheckFactHandle;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/60493dc0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitor.java
index d000f07..fec8f1e 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/cluster/ClusterMonitor.java
@@ -41,6 +41,7 @@ import org.apache.stratos.autoscaler.monitor.events.ScalingEvent;
 import org.apache.stratos.autoscaler.monitor.events.ScalingUpBeyondMaxEvent;
 import org.apache.stratos.autoscaler.monitor.events.builder.MonitorStatusEventBuilder;
 import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
+import org.apache.stratos.autoscaler.rule.RuleTasksDelegator;
 import org.apache.stratos.autoscaler.status.processor.cluster.ClusterStatusActiveProcessor;
 import org.apache.stratos.autoscaler.status.processor.cluster.ClusterStatusInactiveProcessor;
 import org.apache.stratos.autoscaler.status.processor.cluster.ClusterStatusTerminatedProcessor;
@@ -87,20 +88,10 @@ public class ClusterMonitor extends Monitor {
     private final ScheduledExecutorService scheduler;
     private final ExecutorService executorService;
 
-    protected FactHandle minCheckFactHandle;
-    protected FactHandle maxCheckFactHandle;
-    protected FactHandle obsoleteCheckFactHandle;
-    protected FactHandle scaleCheckFactHandle;
-    protected FactHandle dependentScaleCheckFactHandle;
+
     protected boolean hasFaultyMember = false;
     protected boolean stop = false;
     protected ClusterContext clusterContext;
-    protected StatefulKnowledgeSession minCheckKnowledgeSession;
-    protected StatefulKnowledgeSession maxCheckKnowledgeSession;
-    protected StatefulKnowledgeSession obsoleteCheckKnowledgeSession;
-    protected StatefulKnowledgeSession scaleCheckKnowledgeSession;
-    protected StatefulKnowledgeSession dependentScaleCheckKnowledgeSession;
-    protected AutoscalerRuleEvaluator autoscalerRuleEvaluator;
     protected String serviceType;
     private AtomicBoolean monitoringStarted;
     protected String clusterId;
@@ -124,26 +115,7 @@ public class ClusterMonitor extends Monitor {
         executorService = StratosThreadPool.getExecutorService(
                 AutoscalerConstants.CLUSTER_MONITOR_THREAD_POOL_ID, threadPoolSize);
         this.clusterId = cluster.getClusterId();
-
         readConfigurations();
-        autoscalerRuleEvaluator = new AutoscalerRuleEvaluator(cluster.getClusterId());
-        autoscalerRuleEvaluator.parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.OBSOLETE_CHECK_DROOL_FILE);
-        autoscalerRuleEvaluator.parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.SCALE_CHECK_DROOL_FILE);
-        autoscalerRuleEvaluator.parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.MIN_CHECK_DROOL_FILE);
-        autoscalerRuleEvaluator.parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.MAX_CHECK_DROOL_FILE);
-        autoscalerRuleEvaluator.parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.DEPENDENT_SCALE_CHECK_DROOL_FILE);
-
-        this.obsoleteCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
-                StratosConstants.OBSOLETE_CHECK_DROOL_FILE);
-        this.scaleCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
-                StratosConstants.SCALE_CHECK_DROOL_FILE);
-        this.minCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
-                StratosConstants.MIN_CHECK_DROOL_FILE);
-        this.maxCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
-                StratosConstants.MAX_CHECK_DROOL_FILE);
-        this.dependentScaleCheckKnowledgeSession = autoscalerRuleEvaluator.getStatefulSession(
-                StratosConstants.DEPENDENT_SCALE_CHECK_DROOL_FILE);
-
         this.groupScalingEnabledSubtree = groupScalingEnabledSubtree;
         this.setCluster(new Cluster(cluster));
         this.serviceType = cluster.getServiceName();
@@ -231,61 +203,6 @@ public class ClusterMonitor extends Monitor {
         this.monitoringIntervalMilliseconds = monitorIntervalMilliseconds;
     }
 
-    public FactHandle getMinCheckFactHandle() {
-        return minCheckFactHandle;
-    }
-
-    public void setMinCheckFactHandle(FactHandle minCheckFactHandle) {
-        this.minCheckFactHandle = minCheckFactHandle;
-    }
-
-    public FactHandle getObsoleteCheckFactHandle() {
-        return obsoleteCheckFactHandle;
-    }
-
-    public void setObsoleteCheckFactHandle(FactHandle obsoleteCheckFactHandle) {
-        this.obsoleteCheckFactHandle = obsoleteCheckFactHandle;
-    }
-
-    public FactHandle getScaleCheckFactHandle() {
-        return scaleCheckFactHandle;
-    }
-
-    public void setScaleCheckFactHandle(FactHandle scaleCheckFactHandle) {
-        this.scaleCheckFactHandle = scaleCheckFactHandle;
-    }
-
-    public StatefulKnowledgeSession getMinCheckKnowledgeSession() {
-        return minCheckKnowledgeSession;
-    }
-
-    public StatefulKnowledgeSession getMaxCheckKnowledgeSession() {
-        return maxCheckKnowledgeSession;
-    }
-
-    public void setMinCheckKnowledgeSession(
-            StatefulKnowledgeSession minCheckKnowledgeSession) {
-        this.minCheckKnowledgeSession = minCheckKnowledgeSession;
-    }
-
-    public StatefulKnowledgeSession getObsoleteCheckKnowledgeSession() {
-        return obsoleteCheckKnowledgeSession;
-    }
-
-    public void setObsoleteCheckKnowledgeSession(
-            StatefulKnowledgeSession obsoleteCheckKnowledgeSession) {
-        this.obsoleteCheckKnowledgeSession = obsoleteCheckKnowledgeSession;
-    }
-
-    public StatefulKnowledgeSession getScaleCheckKnowledgeSession() {
-        return scaleCheckKnowledgeSession;
-    }
-
-    public void setScaleCheckKnowledgeSession(
-            StatefulKnowledgeSession scaleCheckKnowledgeSession) {
-        this.scaleCheckKnowledgeSession = scaleCheckKnowledgeSession;
-    }
-
     public boolean isDestroyed() {
         return isDestroyed;
     }
@@ -294,15 +211,6 @@ public class ClusterMonitor extends Monitor {
         this.isDestroyed = isDestroyed;
     }
 
-    public AutoscalerRuleEvaluator getAutoscalerRuleEvaluator() {
-        return autoscalerRuleEvaluator;
-    }
-
-    public void setAutoscalerRuleEvaluator(
-            AutoscalerRuleEvaluator autoscalerRuleEvaluator) {
-        this.autoscalerRuleEvaluator = autoscalerRuleEvaluator;
-    }
-
     public boolean isHasFaultyMember() {
         return hasFaultyMember;
     }
@@ -337,14 +245,6 @@ public class ClusterMonitor extends Monitor {
         this.monitoringStarted.set(monitoringStarted);
     }
 
-    public StatefulKnowledgeSession getDependentScaleCheckKnowledgeSession() {
-        return dependentScaleCheckKnowledgeSession;
-    }
-
-    public void setDependentScaleCheckKnowledgeSession(StatefulKnowledgeSession dependentScaleCheckKnowledgeSession) {
-        this.dependentScaleCheckKnowledgeSession = dependentScaleCheckKnowledgeSession;
-    }
-
     public ClusterContext getClusterContext() {
         return clusterContext;
     }
@@ -465,7 +365,7 @@ public class ClusterMonitor extends Monitor {
 
                 for (final InstanceContext pInstanceContext : clusterInstanceContexts) {
                     final ClusterInstanceContext instanceContext = (ClusterInstanceContext) pInstanceContext;
-                    ClusterInstance instance = (ClusterInstance) this.instanceIdToInstanceMap.
+                    final ClusterInstance instance = (ClusterInstance) this.instanceIdToInstanceMap.
                             get(instanceContext.getId());
 
                     if ((instance.getStatus().getCode() <= ClusterStatus.Active.getCode()) ||
@@ -501,14 +401,14 @@ public class ClusterMonitor extends Monitor {
                                     }
                                 }
 
-                                getMinCheckKnowledgeSession().setGlobal("primaryMemberCount",
+                                instanceContext.getMinCheckKnowledgeSession().setGlobal("primaryMemberCount",
                                         primaryMemberListInClusterInstance.size());
-                                getMinCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
-                                getMinCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
+                                instanceContext.getMinCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
+                                instanceContext.getMinCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
                                 //FIXME when parent chosen the partition
                                 String paritionAlgo = instanceContext.getPartitionAlgorithm();
 
-                                getMinCheckKnowledgeSession().setGlobal("algorithmName",
+                                instanceContext.getMinCheckKnowledgeSession().setGlobal("algorithmName",
                                         paritionAlgo);
 
                                 if (log.isDebugEnabled()) {
@@ -516,23 +416,25 @@ public class ClusterMonitor extends Monitor {
                                             instanceContext.getId() + " for the cluster: " + clusterId));
                                 }
 
-                                minCheckFactHandle = AutoscalerRuleEvaluator.evaluate(getMinCheckKnowledgeSession(),
-                                        minCheckFactHandle, instanceContext);
+                                instanceContext.setMinCheckFactHandle(evaluate(instanceContext.
+                                                getMinCheckKnowledgeSession(),
+                                        instanceContext.getMinCheckFactHandle(), instanceContext));
 
 
-                                getMaxCheckKnowledgeSession().setGlobal("primaryMemberCount",
+                                instanceContext.getMaxCheckKnowledgeSession().setGlobal("primaryMemberCount",
                                         primaryMemberListInClusterInstance.size());
-                                getMaxCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
-                                getMaxCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
-                                getMaxCheckKnowledgeSession().setGlobal("primaryMembers",
+                                instanceContext.getMaxCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
+                                instanceContext.getMaxCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
+                                instanceContext.getMaxCheckKnowledgeSession().setGlobal("primaryMembers",
                                         primaryMemberListInClusterInstance);
                                 if (log.isDebugEnabled()) {
                                     log.debug(String.format("Running max check for cluster instance %s ",
                                             instanceContext.getId() + " for the cluster: " + clusterId));
                                 }
 
-                                maxCheckFactHandle = AutoscalerRuleEvaluator.evaluate(getMaxCheckKnowledgeSession(),
-                                        maxCheckFactHandle, instanceContext);
+                                instanceContext.setMaxCheckFactHandle(evaluate(instanceContext.
+                                                getMaxCheckKnowledgeSession(),
+                                        instanceContext.getMaxCheckFactHandle(), instanceContext));
 
 
                                 //checking the status of the cluster
@@ -553,17 +455,17 @@ public class ClusterMonitor extends Monitor {
                                     log.info("Executing scaling rule as statistics have been reset");
                                     ClusterContext clusterContext = (ClusterContext) ClusterMonitor.this.clusterContext;
 
-                                    getScaleCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
-                                    getScaleCheckKnowledgeSession().setGlobal("rifReset", rifReset);
-                                    getScaleCheckKnowledgeSession().setGlobal("mcReset", memoryConsumptionReset);
-                                    getScaleCheckKnowledgeSession().setGlobal("laReset", loadAverageReset);
-                                    getScaleCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
-                                    getScaleCheckKnowledgeSession().setGlobal("algorithmName", paritionAlgo);
-                                    getScaleCheckKnowledgeSession().setGlobal("autoscalePolicy",
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("rifReset", rifReset);
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("mcReset", memoryConsumptionReset);
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("laReset", loadAverageReset);
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("algorithmName", paritionAlgo);
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("autoscalePolicy",
                                             clusterContext.getAutoscalePolicy());
-                                    getScaleCheckKnowledgeSession().setGlobal("arspiReset",
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("arspiReset",
                                             averageRequestServedPerInstanceReset);
-                                    getScaleCheckKnowledgeSession().setGlobal("primaryMembers",
+                                    instanceContext.getScaleCheckKnowledgeSession().setGlobal("primaryMembers",
                                             primaryMemberListInClusterInstance);
 
                                     if (log.isDebugEnabled()) {
@@ -572,8 +474,9 @@ public class ClusterMonitor extends Monitor {
                                         log.debug(" Primary members : " + primaryMemberListInClusterInstance);
                                     }
 
-                                    scaleCheckFactHandle = AutoscalerRuleEvaluator.evaluate(getScaleCheckKnowledgeSession()
-                                            , scaleCheckFactHandle, instanceContext);
+                                    instanceContext.setScaleCheckFactHandle(evaluate(
+                                            instanceContext.getScaleCheckKnowledgeSession()
+                                            , instanceContext.getScaleCheckFactHandle(), instanceContext));
 
                                     instanceContext.setRifReset(false);
                                     instanceContext.setMemoryConsumptionReset(false);
@@ -593,9 +496,10 @@ public class ClusterMonitor extends Monitor {
                         Runnable monitoringRunnable = new Runnable() {
                             @Override
                             public void run() {
-                                getObsoleteCheckKnowledgeSession().setGlobal("clusterId", clusterId);
-                                obsoleteCheckFactHandle = AutoscalerRuleEvaluator.evaluate(
-                                        getObsoleteCheckKnowledgeSession(), obsoleteCheckFactHandle, partitionContext);
+                                instanceContext.getObsoleteCheckKnowledgeSession().setGlobal("clusterId", clusterId);
+                                instanceContext.setObsoleteCheckFactHandle(evaluate(
+                                        instanceContext.getObsoleteCheckKnowledgeSession(),
+                                        instanceContext.getObsoleteCheckFactHandle(), partitionContext));
 
                                 if (partitionContext.isObsoletePartition()
                                         && partitionContext.getTerminationPendingMembers().size() == 0
@@ -614,6 +518,20 @@ public class ClusterMonitor extends Monitor {
         }
     }
 
+    private FactHandle evaluate(StatefulKnowledgeSession ksession, FactHandle handle, Object obj) {
+        if (handle == null) {
+            ksession.setGlobal("delegator", new RuleTasksDelegator());
+            handle = ksession.insert(obj);
+        } else {
+            ksession.update(handle, obj);
+        }
+        ksession.fireAllRules();
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Rule executed for: %s ", obj));
+        }
+        return handle;
+    }
+
     private void readConfigurations() {
         XMLConfiguration conf = ConfUtil.getInstance(null).getConfiguration();
         int monitorInterval = conf.getInt(AutoscalerConstants.Cluster_MONITOR_INTERVAL, 90000);
@@ -627,9 +545,19 @@ public class ClusterMonitor extends Monitor {
 
     @Override
     public void destroy() {
-        getMinCheckKnowledgeSession().dispose();
-        getObsoleteCheckKnowledgeSession().dispose();
-        getScaleCheckKnowledgeSession().dispose();
+        for (ClusterLevelNetworkPartitionContext networkPartitionContext : getNetworkPartitionCtxts()) {
+
+            Collection<InstanceContext> clusterInstanceContexts = networkPartitionContext.
+                    getInstanceIdToInstanceContextMap().values();
+
+            for (final InstanceContext pInstanceContext : clusterInstanceContexts) {
+                ClusterInstanceContext instanceContext = (ClusterInstanceContext) pInstanceContext;
+                instanceContext.getMinCheckKnowledgeSession().dispose();
+                instanceContext.getObsoleteCheckKnowledgeSession().dispose();
+                instanceContext.getScaleCheckKnowledgeSession().dispose();
+            }
+        }
+
         setDestroyed(true);
         if (log.isDebugEnabled()) {
             log.debug("ClusterMonitor Drools session has been disposed. " + this.toString());
@@ -723,13 +651,14 @@ public class ClusterMonitor extends Monitor {
                 vmClusterContext.getAutoscalePolicy().getInstanceRoundingFactor());
         clusterInstanceContext.setRequiredInstanceCountBasedOnDependencies(roundedRequiredInstanceCount);
 
-        getDependentScaleCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
-        getDependentScaleCheckKnowledgeSession().setGlobal("roundedRequiredInstanceCount", roundedRequiredInstanceCount);
-        getDependentScaleCheckKnowledgeSession().setGlobal("algorithmName", clusterInstanceContext.getPartitionAlgorithm());
-        getDependentScaleCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
-        getDependentScaleCheckKnowledgeSession().setGlobal("primaryMembers", primaryMemberListInClusterInstance);
-        dependentScaleCheckFactHandle = AutoscalerRuleEvaluator.evaluate(getDependentScaleCheckKnowledgeSession()
-                , dependentScaleCheckFactHandle, clusterInstanceContext);
+        clusterInstanceContext.getDependentScaleCheckKnowledgeSession().setGlobal("clusterId", getClusterId());
+        clusterInstanceContext.getDependentScaleCheckKnowledgeSession().setGlobal("roundedRequiredInstanceCount", roundedRequiredInstanceCount);
+        clusterInstanceContext.getDependentScaleCheckKnowledgeSession().setGlobal("algorithmName", clusterInstanceContext.getPartitionAlgorithm());
+        clusterInstanceContext.getDependentScaleCheckKnowledgeSession().setGlobal("isPrimary", hasPrimary);
+        clusterInstanceContext.getDependentScaleCheckKnowledgeSession().setGlobal("primaryMembers", primaryMemberListInClusterInstance);
+        clusterInstanceContext.setDependentScaleCheckFactHandle(evaluate(
+                clusterInstanceContext.getDependentScaleCheckKnowledgeSession()
+                , clusterInstanceContext.getDependentScaleCheckFactHandle(), clusterInstanceContext));
 
     }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/60493dc0/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/AutoscalerRuleEvaluator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/AutoscalerRuleEvaluator.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/AutoscalerRuleEvaluator.java
index c51e2ea..4166ce4 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/AutoscalerRuleEvaluator.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/AutoscalerRuleEvaluator.java
@@ -43,42 +43,44 @@ public class AutoscalerRuleEvaluator {
 
     private static final Log log = LogFactory.getLog(AutoscalerRuleEvaluator.class);
 
-    private static Map<String, KnowledgeBase> knowledgeBases;
-    private String clusterId;
+    private Map<String, KnowledgeBase> knowledgeBases;
+    private static volatile AutoscalerRuleEvaluator instance;
 
-    public AutoscalerRuleEvaluator(String clusterId) {
+    private AutoscalerRuleEvaluator() {
         knowledgeBases = new HashMap<String, KnowledgeBase>();
-        this.clusterId = clusterId;
+        parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.OBSOLETE_CHECK_DROOL_FILE);
+        parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.SCALE_CHECK_DROOL_FILE);
+        parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.MIN_CHECK_DROOL_FILE);
+        parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.MAX_CHECK_DROOL_FILE);
+        parseAndBuildKnowledgeBaseForDroolsFile(StratosConstants.DEPENDENT_SCALE_CHECK_DROOL_FILE);
+
+
+    }
+    public static AutoscalerRuleEvaluator getInstance() {
+        if (instance == null) {
+            synchronized (AutoscalerRuleEvaluator.class) {
+                if (instance == null) {
+                    instance = new AutoscalerRuleEvaluator();
+                }
+            }
+        }
+        return instance;
     }
 
     public void parseAndBuildKnowledgeBaseForDroolsFile(String drlFileName) {
         KnowledgeBase knowledgeBase = readKnowledgeBase(drlFileName);
         if(knowledgeBase == null) {
-            log.error("Knowledge base couldn't be read for [cluster] " + clusterId +
+            log.error("Knowledge base couldn't be read for" +
                     " [drool-file] " + drlFileName);
         } else {
             knowledgeBases.put(drlFileName, knowledgeBase);
             if (log.isDebugEnabled()) {
-                log.debug("Drools file is parsed successfully: [cluster] " + clusterId +
+                log.debug("Drools file is parsed successfully:" +
                         " [ file-name] " + drlFileName);
             }
         }
     }
 
-    public static FactHandle evaluate(StatefulKnowledgeSession ksession, FactHandle handle, Object obj) {
-        if (handle == null) {
-            ksession.setGlobal("delegator", new RuleTasksDelegator());
-            handle = ksession.insert(obj);
-        } else {
-            ksession.update(handle, obj);
-        }
-        ksession.fireAllRules();
-        if (log.isDebugEnabled()) {
-            log.debug(String.format("Rule executed for: %s ", obj));
-        }
-        return handle;
-    }
-
     public StatefulKnowledgeSession getStatefulSession(String drlFileName) {
         StatefulKnowledgeSession ksession;
         ksession = knowledgeBases.get(drlFileName).newStatefulKnowledgeSession();