You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by ma...@apache.org on 2014/07/08 09:42:00 UTC

[10/14] git commit: Clustering changes for stratos

Clustering changes for stratos


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

Branch: refs/heads/4.0.0
Commit: 7b35e29e5eebc9a7f3efb8bb42042dcc48150f1e
Parents: fcc90fc
Author: Manula Thantriwatte <ma...@apache.org>
Authored: Tue Jul 1 06:37:12 2014 +0000
Committer: Manula Thantriwatte <ma...@apache.org>
Committed: Tue Jul 1 06:37:12 2014 +0000

----------------------------------------------------------------------
 .../stratos/autoscaler/PartitionContext.java    |   6 +-
 .../cloud/controller/CloudControllerClient.java |  25 +-
 .../AutoscalerTopologyEventReceiver.java        |  82 +-
 .../autoscaler/monitor/AbstractMonitor.java     |  25 +-
 .../autoscaler/monitor/ClusterMonitor.java      | 115 ++-
 .../autoscaler/monitor/LbClusterMonitor.java    |  26 +-
 .../autoscaler/rule/RuleTasksDelegator.java     |  43 +-
 .../autoscaler/util/AutoScalerConstants.java    |   6 +
 .../stratos/autoscaler/util/AutoscalerUtil.java |  26 +-
 .../cartridge/agent/ArtifactCopyTask.java       |  39 +
 .../stratos/cartridge/agent/CartridgeAgent.java | 478 ++++++---
 .../apache/stratos/cartridge/agent/Main.java    |  40 +-
 .../cartridge/agent/RepositoryFileListener.java |   8 +-
 .../synchronizer/RepositoryInformation.java     |  10 +-
 .../git/impl/GitBasedArtifactRepository.java    | 740 +++++++++-----
 .../GitDeploymentSynchronizerConstants.java     |  12 +
 .../synchronizer/git/util/Utilities.java        |   3 +
 .../config/CartridgeAgentConfiguration.java     | 348 +++++--
 .../config/configurator/JndiConfigurator.java   |  21 +-
 .../agent/data/publisher/log/Constants.java     |  13 +
 .../publisher/log/FileBasedLogPublisher.java    |   6 +-
 .../agent/data/publisher/log/LogPublisher.java  |   9 +-
 .../data/publisher/log/LogPublisherManager.java |  65 +-
 .../publisher/CartridgeAgentEventPublisher.java |  11 +-
 .../extensions/DefaultExtensionHandler.java     | 992 +++++++++++++++++++
 .../agent/extensions/ExtensionHandler.java      |  64 ++
 .../agent/util/CartridgeAgentConstants.java     |  56 +-
 .../agent/util/CartridgeAgentUtils.java         |   5 +-
 .../cartridge/agent/util/ExtensionUtils.java    | 500 +++++++++-
 .../stratos/cli/RestCommandLineService.java     | 310 +++++-
 .../stratos/cli/beans/cartridge/Cartridge.java  |   9 +
 .../stratos/cli/commands/SubscribeCommand.java  | 347 ++++---
 .../concurrent/PartitionValidatorCallable.java  |   4 +
 .../impl/CloudControllerServiceImpl.java        |  80 +-
 .../cloud/controller/pojo/Cartridge.java        |  52 +-
 .../cloud/controller/pojo/CartridgeInfo.java    |  10 +
 .../cloud/controller/pojo/MemberContext.java    |  10 +
 .../CartridgeInstanceDataPublisher.java         | 123 ++-
 .../controller/topology/TopologyBuilder.java    |  98 +-
 .../topology/TopologyEventPublisher.java        |  27 +-
 .../controller/util/CloudControllerUtil.java    |   1 +
 .../validate/AWSEC2PartitionValidator.java      |  30 +-
 .../stratos/common/util/CommandUtils.java       |  30 +
 .../LoadBalancerTenantEventReceiver.java        | 199 ++--
 .../LoadBalancerTopologyEventReceiver.java      |  37 +-
 .../conf/LoadBalancerConfiguration.java         |  29 +-
 .../balancer/context/LoadBalancerContext.java   |  11 +-
 .../context/LoadBalancerContextUtil.java        | 417 +++++++-
 .../context/map/HostNameAppContextMap.java      |  51 +
 .../context/map/HostNameClusterMap.java         |   2 +-
 .../context/map/MultiTenantClusterMap.java      |  13 +-
 .../TenantAwareLoadBalanceEndpoint.java         | 398 ++++++--
 .../stratos/load/balancer/util/Constants.java   |   9 +-
 .../test/LoadBalancerConfigurationTest.java     |  20 +-
 .../behaviour/CartridgeMgtBehaviour.java        |  13 +-
 .../org/apache/stratos/manager/dao/Cluster.java |   6 +-
 .../stratos/manager/deploy/service/Service.java |   9 +-
 .../service/ServiceDeploymentManager.java       |  49 +-
 .../multitenant/lb/DefaultLBService.java        | 110 ++
 .../multitenant/lb/ExistingLBService.java       |  52 +
 .../service/multitenant/lb/LBService.java       |  69 ++
 .../multitenant/lb/ServiceAwareLBService.java   | 137 +++
 .../category/DefaultLoadBalancerCategory.java   |  13 +-
 .../ServiceLevelLoadBalancerCategory.java       |   6 +-
 .../manager/CartridgeSubscriptionManager.java   | 224 ++++-
 .../manager/payload/BasicPayloadData.java       |  15 +-
 .../InstanceNotificationPublisher.java          |   5 +-
 .../publisher/TenantSynzhronizerTask.java       |  19 +-
 .../stratos/manager/repository/Repository.java  |   9 +
 .../repository/RepositoryNotification.java      |   2 +-
 .../DataInsertionAndRetrievalManager.java       |  25 +
 .../subscription/CartridgeSubscription.java     |  34 +-
 .../InternalRepoBasedCartridgeSubscription.java |  14 +-
 .../subscription/LBCartridgeSubscription.java   |  26 +-
 .../manager/subscription/SubscriptionData.java  |  34 +
 .../subscription/SubscriptionDomain.java        |  48 +
 .../factory/CartridgeSubscriptionFactory.java   |   9 +-
 .../utils/CartridgeSubscriptionUtils.java       |  29 +-
 .../model/TopologyClusterInformationModel.java  |  19 +
 .../manager/utils/RepositoryCreator.java        |   7 +-
 components/org.apache.stratos.messaging/pom.xml |   5 +
 .../messaging/domain/tenant/Subscription.java   |  77 ++
 .../domain/tenant/SubscriptionDomain.java       |  41 +
 .../stratos/messaging/domain/tenant/Tenant.java |  29 +-
 .../messaging/domain/topology/Cluster.java      |  10 +
 .../domain/topology/ClusterStatus.java          |  36 +
 .../messaging/domain/topology/Member.java       |  68 +-
 .../messaging/domain/topology/Service.java      |  30 +-
 .../instance/notifier/ArtifactUpdatedEvent.java |   9 +
 .../tenant/SubscriptionDomainAddedEvent.java    |  67 ++
 .../tenant/SubscriptionDomainRemovedEvent.java  |  60 ++
 .../tenant/SubscriptionDomainsAddedEvent.java   |  60 ++
 .../tenant/SubscriptionDomainsRemovedEvent.java |  60 ++
 .../event/tenant/TenantSubscribedEvent.java     |   9 +-
 .../event/tenant/TenantUnSubscribedEvent.java   |  10 +-
 .../topology/ClusterMaintenanceModeEvent.java   |  58 ++
 .../event/topology/InstanceSpawnedEvent.java    |  12 +-
 .../event/topology/MemberActivatedEvent.java    |  40 +-
 .../event/topology/MemberTerminatedEvent.java   |  11 +
 .../event/topology/ServiceCreatedEvent.java     |  37 +-
 .../SubscriptionDomainsAddedEventListener.java  |  28 +
 ...SubscriptionDomainsRemovedEventListener.java |  28 +
 .../ClusterMaintenanceModeEventListener.java    |  25 +
 ...SubscriptionDomainAddedMessageProcessor.java |  95 ++
 ...bscriptionDomainRemovedMessageProcessor.java |  94 ++
 .../tenant/TenantMessageProcessorChain.java     |  12 +
 .../TenantSubscribedMessageProcessor.java       |   5 +-
 .../TenantUnSubscribedMessageProcessor.java     |   2 +-
 .../ClusterMaintenanceModeMessageProcessor.java | 115 +++
 .../InstanceSpawnedMessageProcessor.java        |   1 +
 .../topology/TopologyMessageProcessorChain.java |   6 +
 .../message/receiver/tenant/TenantManager.java  |   5 +
 .../stratos/messaging/util/Constants.java       |   2 +
 .../messaging/test/TenantDomainTest.java        |  45 +
 .../rest/endpoint/bean/CartridgeInfoBean.java   |  11 +
 .../bean/SubscriptionDomainRequest.java         |  35 +
 .../domain/SubscriptionDomainBean.java          |  29 +
 .../bean/util/converter/PojoConverter.java      |  30 +
 .../CustomThrowableExceptionMapper.java         |  39 +
 .../handlers/GenericExceptionMapper.java        |  46 +
 .../handlers/StratosAuthenticationHandler.java  |  43 +-
 .../stratos/rest/endpoint/mock/MockContext.java |  88 ++
 .../rest/endpoint/mock/StratosTestAdmin.java    |  46 +-
 .../rest/endpoint/services/ServiceUtils.java    | 130 ++-
 .../rest/endpoint/services/StratosAdmin.java    | 106 +-
 .../webapp/stratos-test/WEB-INF/cxf-servlet.xml |   2 +
 .../main/webapp/stratos/WEB-INF/cxf-servlet.xml |   4 +
 .../distribution/src/main/assembly/bin.xml      |  11 +-
 .../distribution/src/main/bin/stratos.sh        |  31 +-
 .../distribution/src/main/conf/log4j.properties |   4 +-
 .../conf/templates/jndi.properties.template     |   6 +-
 .../src/main/extensions/artifacts-copy.sh       |  29 +
 .../src/main/extensions/artifacts-updated.sh    |   2 +-
 .../distribution/src/main/extensions/clean.sh   |   2 +-
 .../src/main/extensions/complete-tenant.sh      |  30 +
 .../src/main/extensions/complete-topology.sh    |  34 +
 .../src/main/extensions/instance-activated.sh   |   2 +-
 .../src/main/extensions/instance-started.sh     |   2 +-
 .../src/main/extensions/member-activated.sh     |  43 +
 .../src/main/extensions/member-started.sh       |  43 +
 .../src/main/extensions/member-suspended.sh     |  43 +
 .../src/main/extensions/member-terminated.sh    |  43 +
 .../src/main/extensions/mount-volumes.sh        |  87 ++
 .../src/main/extensions/start-servers.sh        |  14 +-
 .../extensions/subscription-domain-added.sh     |  37 +
 .../extensions/subscription-domain-removed.sh   |  36 +
 products/stratos/conf/tenant-mgt.xml            |  42 +
 .../modules/distribution/src/assembly/bin.xml   |  17 +-
 .../distribution/src/main/conf/autoscaler.xml   |   2 +
 .../distribution/src/main/conf/mincheck.drl     |  13 +-
 .../distribution/src/main/conf/scaling.drl      |  17 +-
 .../src/main/conf/siddhi/siddhi.extension       |   1 +
 .../main/resources/CloudControllerService.wsdl  | 769 +++++++-------
 153 files changed, 8445 insertions(+), 1790 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/PartitionContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/PartitionContext.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/PartitionContext.java
index 86c2e49..1def03c 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/PartitionContext.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/PartitionContext.java
@@ -358,8 +358,12 @@ public class PartitionContext implements Serializable{
     public int getNonTerminatedMemberCount() {
         return activeMembers.size() + pendingMembers.size() + terminationPendingMembers.size();
     }
+    
+    public List<MemberContext> getActiveMembers() {
+		return activeMembers;
+	}
 
-    public boolean removeActiveMemberById(String memberId) {
+	public boolean removeActiveMemberById(String memberId) {
         boolean removeActiveMember = false;
         synchronized (activeMembers) {
             Iterator<MemberContext> iterator = activeMembers.listIterator();

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/client/cloud/controller/CloudControllerClient.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/client/cloud/controller/CloudControllerClient.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/client/cloud/controller/CloudControllerClient.java
index ee86c0f..b6cdac9 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/client/cloud/controller/CloudControllerClient.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/client/cloud/controller/CloudControllerClient.java
@@ -32,6 +32,10 @@ import org.apache.stratos.autoscaler.util.ConfUtil;
 import org.apache.stratos.cloud.controller.stub.*;
 import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition;
 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.messaging.domain.topology.Topology;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
 
 import java.rmi.RemoteException;
 
@@ -75,7 +79,7 @@ public class CloudControllerClient {
      * This will validate the given partitions against the given cartridge type.
      */
     
-    public boolean validateDeploymentPolicy(String cartridgeType, DeploymentPolicy deploymentPolicy) throws PartitionValidationException{
+    public synchronized boolean validateDeploymentPolicy(String cartridgeType, DeploymentPolicy deploymentPolicy) throws PartitionValidationException{
         try {
             if(log.isInfoEnabled()) {
                 log.info(String.format("Validating partitions of policy via cloud controller: [id] %s", deploymentPolicy.getId()));
@@ -103,7 +107,7 @@ public class CloudControllerClient {
     /*
      * Calls the CC to validate the partition.
      */
-    public boolean validatePartition(Partition partition) throws PartitionValidationException{
+    public synchronized boolean validatePartition(Partition partition) throws PartitionValidationException{
         
         try {
             if(log.isInfoEnabled()) {
@@ -127,7 +131,7 @@ public class CloudControllerClient {
     }
 
     public synchronized MemberContext spawnAnInstance(Partition partition,
-    		String clusterId, String lbClusterId, String networkPartitionId) throws SpawningException {
+    		String clusterId, String lbClusterId, String networkPartitionId, boolean isPrimary, int minMemberCount) throws SpawningException {
         try {
             if(log.isInfoEnabled()) {
                 log.info(String.format("Trying to spawn an instance via cloud controller: [cluster] %s [partition] %s [lb-cluster] %s [network-partition-id] %s",
@@ -140,7 +144,20 @@ public class CloudControllerClient {
             member.setLbClusterId(lbClusterId);
             member.setInitTime(System.currentTimeMillis());
             member.setNetworkPartitionId(networkPartitionId);
-
+            Properties memberContextProps = new Properties();
+            Property isPrimaryProp = new Property();
+            isPrimaryProp.setName("PRIMARY");
+            isPrimaryProp.setValue(String.valueOf(isPrimary));
+            
+            Property minCountProp = new Property();
+            minCountProp.setName("MIN_COUNT");
+            minCountProp.setValue(String.valueOf(minMemberCount));
+            
+            memberContextProps.addProperties(isPrimaryProp);
+            memberContextProps.addProperties(minCountProp);
+            member.setProperties(memberContextProps);
+            
+            
             long startTime = System.currentTimeMillis();
             MemberContext memberContext = stub.startInstance(member);
             if(log.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/message/receiver/topology/AutoscalerTopologyEventReceiver.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/message/receiver/topology/AutoscalerTopologyEventReceiver.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/message/receiver/topology/AutoscalerTopologyEventReceiver.java
index cf6223c..601502f 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/message/receiver/topology/AutoscalerTopologyEventReceiver.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/message/receiver/topology/AutoscalerTopologyEventReceiver.java
@@ -22,9 +22,12 @@ package org.apache.stratos.autoscaler.message.receiver.topology;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.autoscaler.*;
+import org.apache.stratos.autoscaler.client.cloud.controller.CloudControllerClient;
+import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition;
 import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy;
 import org.apache.stratos.autoscaler.exception.PartitionValidationException;
 import org.apache.stratos.autoscaler.exception.PolicyValidationException;
+import org.apache.stratos.autoscaler.exception.TerminationException;
 import org.apache.stratos.autoscaler.monitor.AbstractMonitor;
 import org.apache.stratos.autoscaler.monitor.ClusterMonitor;
 import org.apache.stratos.autoscaler.monitor.LbClusterMonitor;
@@ -107,16 +110,89 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
 
         });
 
+        topologyEventReceiver.addEventListener(new MemberReadyToShutdownEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    MemberReadyToShutdownEvent memberReadyToShutdownEvent = (MemberReadyToShutdownEvent)event;
+                    AutoscalerContext asCtx = AutoscalerContext.getInstance();
+                    AbstractMonitor monitor;
+                    String clusterId = memberReadyToShutdownEvent.getClusterId();
+                    String memberId = memberReadyToShutdownEvent.getMemberId();
+
+                    if(asCtx.monitorExist(clusterId)){
+                        monitor = asCtx.getMonitor(clusterId);
+                    }else if(asCtx.lbMonitorExist(clusterId)){
+                        monitor = asCtx.getLBMonitor(clusterId);
+                    }else{
+                        if(log.isDebugEnabled()){
+                            log.debug(String.format("A cluster monitor is not found in autoscaler context [cluster] %s", clusterId));
+                        }
+                        return;
+                    }
+
+                    NetworkPartitionContext nwPartitionCtxt;
+                    nwPartitionCtxt = monitor.getNetworkPartitionCtxt(memberReadyToShutdownEvent.getNetworkPartitionId());
+
+                    // start a new member in the same Partition
+                    String partitionId = monitor.getPartitionOfMember(memberId);
+                    Partition partition = monitor.getDeploymentPolicy().getPartitionById(partitionId);
+                    PartitionContext partitionCtxt = nwPartitionCtxt.getPartitionCtxt(partitionId);
+
+
+                    // terminate the shutdown ready member
+                    CloudControllerClient ccClient = CloudControllerClient.getInstance();
+                    ccClient.terminate(memberId);
+
+                    // remove from active member list
+                    partitionCtxt.removeActiveMemberById(memberId);
+
+                    if (log.isInfoEnabled()) {
+                        log.info(String.format("Member is terminated and removed from the active members list: [member] %s [partition] %s [cluster] %s ",
+                                               memberId, partitionId, clusterId));
+                    }
+                } catch (TerminationException e) {
+                    log.error(e);
+                }
+            }
+
+        });
+
         topologyEventReceiver.addEventListener(new ClusterCreatedEventListener() {
+                    @Override
+                    protected void onEvent(Event event) {
+                        try {
+                            log.info("Event received: " + event);
+                            ClusterCreatedEvent e = (ClusterCreatedEvent) event;
+                            TopologyManager.acquireReadLock();
+                            Service service = TopologyManager.getTopology().getService(e.getServiceName());
+                            Cluster cluster = service.getCluster(e.getClusterId());
+                            startClusterMonitor(cluster);
+                        } catch (Exception e) {
+                            log.error("Error processing event", e);
+                        } finally {
+                            TopologyManager.releaseReadLock();
+                        }
+                    }
+
+                });
+
+        topologyEventReceiver.addEventListener(new ClusterMaintenanceModeEventListener() {
             @Override
             protected void onEvent(Event event) {
                 try {
                     log.info("Event received: " + event);
-                    ClusterCreatedEvent e = (ClusterCreatedEvent) event;
+                    ClusterMaintenanceModeEvent e = (ClusterMaintenanceModeEvent) event;
                     TopologyManager.acquireReadLock();
                     Service service = TopologyManager.getTopology().getService(e.getServiceName());
                     Cluster cluster = service.getCluster(e.getClusterId());
-                    startClusterMonitor(cluster);
+                    if(AutoscalerContext.getInstance().monitorExist((cluster.getClusterId()))) {
+                        AutoscalerContext.getInstance().getMonitor(e.getClusterId()).setStatus(e.getStatus());
+                    } else if (AutoscalerContext.getInstance().lbMonitorExist((cluster.getClusterId()))) {
+                        AutoscalerContext.getInstance().getLBMonitor(e.getClusterId()).setStatus(e.getStatus());
+                    } else {
+                        log.error("cluster monitor not exists for the cluster: " + cluster.toString());
+                    }
                 } catch (Exception e) {
                     log.error("Error processing event", e);
                 } finally {
@@ -124,7 +200,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
                 }
             }
 
-        });
+                });
 
         topologyEventReceiver.addEventListener(new ClusterRemovedEventListener() {
             @Override

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/AbstractMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/AbstractMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/AbstractMonitor.java
index 30ed61a..c1441bb 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/AbstractMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/AbstractMonitor.java
@@ -20,12 +20,15 @@ package org.apache.stratos.autoscaler.monitor;
 
 import java.util.Map;
 
+import org.apache.commons.configuration.XMLConfiguration;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.autoscaler.NetworkPartitionContext;
 import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy;
 import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy;
 import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
+import org.apache.stratos.autoscaler.util.AutoScalerConstants;
+import org.apache.stratos.autoscaler.util.ConfUtil;
 import org.apache.stratos.messaging.domain.topology.Cluster;
 import org.apache.stratos.messaging.domain.topology.Member;
 import org.apache.stratos.messaging.domain.topology.Service;
@@ -59,7 +62,23 @@ import org.drools.runtime.rule.FactHandle;
 	protected String serviceId;
 	
 	protected AutoscalerRuleEvaluator autoscalerRuleEvaluator;
-	
+
+    // time intereval between two runs of the Monitor. Default is 90000ms.
+    protected int monitorInterval;
+
+    public AbstractMonitor() {
+        readConfigurations();
+    }
+
+    private void readConfigurations () {
+
+        XMLConfiguration conf = ConfUtil.getInstance(null).getConfiguration();
+        monitorInterval = conf.getInt(AutoScalerConstants.AUTOSCALER_MONITOR_INTERVAL, 90000);
+        if (log.isDebugEnabled()) {
+            log.debug("Cluster Monitor task interval: " + getMonitorInterval());
+        }
+    }
+
 	@Override
 	public void run() {
 		// TODO Auto-generated method stub
@@ -177,4 +196,8 @@ import org.drools.runtime.rule.FactHandle;
     public void setMinCheckFactHandle(FactHandle minCheckFactHandle) {
         this.minCheckFactHandle = minCheckFactHandle;
     }
+
+    public int getMonitorInterval() {
+        return monitorInterval;
+    }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ClusterMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ClusterMonitor.java
index 6c44e4e..5bb478e 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ClusterMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/ClusterMonitor.java
@@ -25,7 +25,13 @@ import org.apache.stratos.autoscaler.PartitionContext;
 import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy;
 import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy;
 import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
+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.messaging.domain.topology.ClusterStatus;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
@@ -34,10 +40,12 @@ import java.util.concurrent.ConcurrentHashMap;
  * rules engine.
  *
  */
-public class ClusterMonitor extends AbstractMonitor{
+public class ClusterMonitor extends AbstractMonitor {
 
-    private static final Log log = LogFactory.getLog(ClusterMonitor.class);    
+    private static final Log log = LogFactory.getLog(ClusterMonitor.class);
     private String lbReferenceType;
+    private boolean hasPrimary;
+    private ClusterStatus status;
 
     public ClusterMonitor(String clusterId, String serviceId, DeploymentPolicy deploymentPolicy,
                           AutoscalePolicy autoscalePolicy) {
@@ -64,34 +72,78 @@ public class ClusterMonitor extends AbstractMonitor{
             Thread.sleep(60000);
         } catch (InterruptedException ignore) {
         }
+
         while (!isDestroyed()) {
             if (log.isDebugEnabled()) {
-                log.debug("Cluster monitor is running.. "+this.toString());
+                log.debug("Cluster monitor is running.. " + this.toString());
             }
             try {
-                monitor();
+                if(!ClusterStatus.In_Maintenance.equals(status)) {
+                    monitor();
+                } else {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Cluster monitor is suspended as the cluster is in " +
+                                    ClusterStatus.In_Maintenance + " mode......");
+                    }
+                }
             } catch (Exception e) {
-                log.error("Cluster monitor: Monitor failed."+this.toString(), e);
+                log.error("Cluster monitor: Monitor failed." + this.toString(), e);
             }
             try {
-                // TODO make this configurable
-                Thread.sleep(30000);
+                Thread.sleep(monitorInterval);
             } catch (InterruptedException ignore) {
             }
         }
     }
-    
+
+    private boolean isPrimaryMember(MemberContext memberContext){
+        Properties props = memberContext.getProperties();
+        if (log.isDebugEnabled()) {
+            log.debug(" Properties [" + props + "] ");
+        }
+        if (props != null && props.getProperties() != null) {
+            for (Property prop : props.getProperties()) {
+                if (prop.getName().equals("PRIMARY")) {
+                    if (Boolean.parseBoolean(prop.getValue())) {
+                        log.debug("Adding member id [" + memberContext.getMemberId() + "] " +
+                                "member instance id [" + memberContext.getInstanceId() + "] as a primary member");
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
     private void monitor() {
-//        if(clusterCtxt != null ) {
-            //TODO make this concurrent
+
+        //TODO make this concurrent
         for (NetworkPartitionContext networkPartitionContext : networkPartitionCtxts.values()) {
+            // store primary members in the network partition context
+            List<String> primaryMemberListInNetworkPartition = new ArrayList<String>();
 
             //minimum check per partition
-            for(PartitionContext partitionContext: networkPartitionContext.getPartitionCtxts().values()){
-
+            for (PartitionContext partitionContext : networkPartitionContext.getPartitionCtxts().values()) {
+                // store primary members in the partition context
+                List<String> primaryMemberListInPartition = new ArrayList<String>();
+                // get active primary members in this partition context
+                for (MemberContext memberContext : partitionContext.getActiveMembers()) {
+                    if (isPrimaryMember(memberContext)){
+                        primaryMemberListInPartition.add(memberContext.getMemberId());
+                    }
+                }
+                // get pending primary members in this partition context
+                for (MemberContext memberContext : partitionContext.getPendingMembers()) {
+                    if (isPrimaryMember(memberContext)){
+                        primaryMemberListInPartition.add(memberContext.getMemberId());
+                    }
+                }
+                primaryMemberListInNetworkPartition.addAll(primaryMemberListInPartition);
                 minCheckKnowledgeSession.setGlobal("clusterId", clusterId);
                 minCheckKnowledgeSession.setGlobal("lbRef", lbReferenceType);
-                
+                minCheckKnowledgeSession.setGlobal("isPrimary", hasPrimary);
+                minCheckKnowledgeSession.setGlobal("primaryMemberCount", primaryMemberListInPartition.size());
+
                 if (log.isDebugEnabled()) {
                     log.debug(String.format("Running minimum check for partition %s ", partitionContext.getPartitionId()));
                 }
@@ -104,8 +156,11 @@ public class ClusterMonitor extends AbstractMonitor{
             boolean rifReset = networkPartitionContext.isRifReset();
             boolean memoryConsumptionReset = networkPartitionContext.isMemoryConsumptionReset();
             boolean loadAverageReset = networkPartitionContext.isLoadAverageReset();
-            if(rifReset || memoryConsumptionReset || loadAverageReset){
-
+            if (log.isDebugEnabled()) {
+                log.debug("flag of rifReset: "  + rifReset + " flag of memoryConsumptionReset" + memoryConsumptionReset
+                        + " flag of loadAverageReset" + loadAverageReset);
+            }
+            if (rifReset || memoryConsumptionReset || loadAverageReset) {
                 scaleCheckKnowledgeSession.setGlobal("clusterId", clusterId);
                 //scaleCheckKnowledgeSession.setGlobal("deploymentPolicy", deploymentPolicy);
                 scaleCheckKnowledgeSession.setGlobal("autoscalePolicy", autoscalePolicy);
@@ -113,9 +168,12 @@ public class ClusterMonitor extends AbstractMonitor{
                 scaleCheckKnowledgeSession.setGlobal("mcReset", memoryConsumptionReset);
                 scaleCheckKnowledgeSession.setGlobal("laReset", loadAverageReset);
                 scaleCheckKnowledgeSession.setGlobal("lbRef", lbReferenceType);
+                scaleCheckKnowledgeSession.setGlobal("isPrimary", false);
+                scaleCheckKnowledgeSession.setGlobal("primaryMembers", primaryMemberListInNetworkPartition);
 
                 if (log.isDebugEnabled()) {
                     log.debug(String.format("Running scale check for network partition %s ", networkPartitionContext.getId()));
+                    log.debug(" Primary members : " + primaryMemberListInNetworkPartition);
                 }
 
                 scaleCheckFactHandle = AutoscalerRuleEvaluator.evaluateScaleCheck(scaleCheckKnowledgeSession
@@ -124,9 +182,9 @@ public class ClusterMonitor extends AbstractMonitor{
                 networkPartitionContext.setRifReset(false);
                 networkPartitionContext.setMemoryConsumptionReset(false);
                 networkPartitionContext.setLoadAverageReset(false);
-            } else if(log.isDebugEnabled()){
-                    log.debug(String.format("Scale rule will not run since the LB statistics have not received before this " +
-                            "cycle for network partition %s", networkPartitionContext.getId()) );
+            } else if (log.isDebugEnabled()) {
+                log.debug(String.format("Scale rule will not run since the LB statistics have not received before this " +
+                        "cycle for network partition %s", networkPartitionContext.getId()));
             }
         }
     }
@@ -134,8 +192,9 @@ public class ClusterMonitor extends AbstractMonitor{
     @Override
     public String toString() {
         return "ClusterMonitor [clusterId=" + clusterId + ", serviceId=" + serviceId +
-               ", deploymentPolicy=" + deploymentPolicy + ", autoscalePolicy=" + autoscalePolicy +
-               ", lbReferenceType=" + lbReferenceType + "]";
+                ", deploymentPolicy=" + deploymentPolicy + ", autoscalePolicy=" + autoscalePolicy +
+                ", lbReferenceType=" + lbReferenceType +
+                ", hasPrimary=" + hasPrimary + " ]";
     }
 
     public String getLbReferenceType() {
@@ -145,4 +204,20 @@ public class ClusterMonitor extends AbstractMonitor{
     public void setLbReferenceType(String lbReferenceType) {
         this.lbReferenceType = lbReferenceType;
     }
+
+    public boolean isHasPrimary() {
+        return hasPrimary;
+    }
+
+    public void setHasPrimary(boolean hasPrimary) {
+        this.hasPrimary = hasPrimary;
+    }
+
+    public ClusterStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(ClusterStatus status) {
+        this.status = status;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/LbClusterMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/LbClusterMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/LbClusterMonitor.java
index d5c1c92..5774461 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/LbClusterMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/LbClusterMonitor.java
@@ -27,6 +27,9 @@ import org.apache.stratos.autoscaler.PartitionContext;
 import org.apache.stratos.autoscaler.deployment.policy.DeploymentPolicy;
 import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy;
 import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
+import org.apache.stratos.messaging.domain.topology.ClusterStatus;
+
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Is responsible for monitoring a service cluster. This runs periodically
@@ -37,6 +40,7 @@ import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
 public class LbClusterMonitor extends AbstractMonitor{
 
     private static final Log log = LogFactory.getLog(LbClusterMonitor.class);
+    private ClusterStatus status;
 
     public LbClusterMonitor(String clusterId, String serviceId, DeploymentPolicy deploymentPolicy,
                             AutoscalePolicy autoscalePolicy) {
@@ -60,13 +64,19 @@ public class LbClusterMonitor extends AbstractMonitor{
                 log.debug("Cluster monitor is running.. "+this.toString());
             }
             try {
-                monitor();
+                if( !ClusterStatus.In_Maintenance.equals(status)) {
+                    monitor();
+                } else {
+                    if (log.isDebugEnabled()) {
+                        log.debug("LB Cluster monitor is suspended as the cluster is in " +
+                                    ClusterStatus.In_Maintenance + " mode......");
+                    }
+                }
             } catch (Exception e) {
                 log.error("Cluster monitor: Monitor failed. "+this.toString(), e);
             }
             try {
-                // TODO make this configurable
-                Thread.sleep(30000);
+                Thread.sleep(monitorInterval);
             } catch (InterruptedException ignore) {
             }
         }
@@ -82,7 +92,8 @@ public class LbClusterMonitor extends AbstractMonitor{
 
                 if (partitionContext != null) {
                     minCheckKnowledgeSession.setGlobal("clusterId", clusterId);
-
+                    minCheckKnowledgeSession.setGlobal("isPrimary", false);
+                    
                     if (log.isDebugEnabled()) {
                         log.debug(String.format("Running minimum check for partition %s ",
                                                 partitionContext.getPartitionId()));
@@ -107,4 +118,11 @@ public class LbClusterMonitor extends AbstractMonitor{
     }
 
 
+    public ClusterStatus getStatus() {
+        return status;
+    }
+
+    public void setStatus(ClusterStatus status) {
+        this.status = status;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java
index 7d8304b..94def43 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/rule/RuleTasksDelegator.java
@@ -74,14 +74,47 @@ public class RuleTasksDelegator {
         }
         return autoscaleAlgorithm;
     }
+    
+    public void delegateSpawn(PartitionContext partitionContext, String clusterId, String lbRefType, boolean isPrimary) {
+    	
+        try {
+
+            String nwPartitionId = partitionContext.getNetworkPartitionId();
+            NetworkPartitionLbHolder lbHolder =
+                                          PartitionManager.getInstance()
+                                                          .getNetworkPartitionLbHolder(nwPartitionId);
+            String lbClusterId = getLbClusterId(lbRefType, partitionContext, lbHolder);
+            MemberContext memberContext =
+                                         CloudControllerClient.getInstance()
+                                                              .spawnAnInstance(partitionContext.getPartition(),
+                                                                      clusterId,
+                                                                      lbClusterId, partitionContext.getNetworkPartitionId(),
+                                                                      isPrimary,
+                                                                      partitionContext.getMinimumMemberCount());
+            if (memberContext != null) {
+                partitionContext.addPendingMember(memberContext);
+                if(log.isDebugEnabled()){
+                    log.debug(String.format("Pending member added, [member] %s [partition] %s", memberContext.getMemberId(),
+                            memberContext.getPartition().getId()));
+                }
+            } else if(log.isDebugEnabled()){
+                log.debug("Returned member context is null, did not add to pending members");
+            }
+
+        } catch (Throwable e) {
+            String message = "Cannot spawn an instance";
+            log.error(message, e);
+            throw new RuntimeException(message, e);
+        }
+    }
 
-    public void delegateSpawn(PartitionContext partitionContext, String clusterId, String lbRefType) {
+    // Original method. Assume this is invoked from mincheck.drl
+    
+   /* public void delegateSpawn(PartitionContext partitionContext, String clusterId, String lbRefType) {
         try {
 
             String nwPartitionId = partitionContext.getNetworkPartitionId();
-//            NetworkPartitionContext ctxt =
-//                                          PartitionManager.getInstance()
-//                                                          .getNetworkPartitionLbHolder(nwPartitionId);
+                                                         .getNetworkPartitionLbHolder(nwPartitionId);
             NetworkPartitionLbHolder lbHolder =
                                           PartitionManager.getInstance()
                                                           .getNetworkPartitionLbHolder(nwPartitionId);
@@ -109,7 +142,7 @@ public class RuleTasksDelegator {
             log.error(message, e);
             throw new RuntimeException(message, e);
         }
-   	}
+   	}*/
 
 
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java
index 5395d96..03cf861 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoScalerConstants.java
@@ -38,5 +38,11 @@ public final class AutoScalerConstants {
 	public static final String NETWORK_PARTITION_LB_HOLDER_RESOURCE = "/network-partitions";
 	public static final String AS_POLICY_RESOURCE = "/policies/autoscalingPolicies";
 	public static final String DEPLOYMENT_POLICY_RESOURCE = "/policies/deploymentPolicies";
+
+
+    /**
+     * Configs
+     */
+    public static final String AUTOSCALER_MONITOR_INTERVAL = "autoscaler.monitorInterval";
        
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java
index 9ab1460..69b5acf 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/util/AutoscalerUtil.java
@@ -38,9 +38,11 @@ import org.apache.stratos.autoscaler.policy.PolicyManager;
 import org.apache.stratos.autoscaler.policy.model.AutoscalePolicy;
 import org.apache.stratos.cloud.controller.stub.deployment.partition.Partition;
 import org.apache.stratos.cloud.controller.stub.pojo.MemberContext;
+import org.apache.stratos.cloud.controller.stub.pojo.Property;
 import org.apache.stratos.cloud.controller.stub.pojo.Properties;
 import org.apache.stratos.cloud.controller.stub.pojo.Property;
 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;
@@ -111,6 +113,7 @@ public class AutoscalerUtil {
                                         new ClusterMonitor(cluster.getClusterId(),
                                                            cluster.getServiceName(),
                                                            deploymentPolicy, policy);
+        clusterMonitor.setStatus(ClusterStatus.Created);
         
         for (PartitionGroup partitionGroup: deploymentPolicy.getPartitionGroups()){
 
@@ -130,7 +133,8 @@ public class AutoscalerUtil {
                         memberContext.setClusterId(member.getClusterId());
                         memberContext.setMemberId(memberId);
                         memberContext.setPartition(partition);
-
+                        memberContext.setProperties(convertMemberPropsToMemberContextProps(member.getProperties()));
+                        
                         if(MemberStatus.Activated.equals(member.getStatus())){
                             partitionContext.addActiveMember(memberContext);
 //                            networkPartitionContext.increaseMemberCountOfPartition(partition.getNetworkPartitionId(), 1);
@@ -175,12 +179,29 @@ public class AutoscalerUtil {
                 log.debug("Set the lb reference type: "+value);
             }
         }
+        
+        // set hasPrimary property
+        // hasPrimary is true if there are primary members available in that cluster
+        clusterMonitor.setHasPrimary(Boolean.parseBoolean(cluster.getProperties().getProperty(Constants.IS_PRIMARY)));
 
         log.info("Cluster monitor created: "+clusterMonitor.toString());
         return clusterMonitor;
     }
     
-    public static LbClusterMonitor getLBClusterMonitor(Cluster cluster) throws PolicyValidationException, PartitionValidationException {
+    private static Properties convertMemberPropsToMemberContextProps(
+			java.util.Properties properties) {
+    	Properties props = new Properties();
+    	for (Map.Entry<Object, Object> e : properties.entrySet()	) {
+			Property prop = new Property();
+			prop.setName((String)e.getKey());
+			prop.setValue((String)e.getValue());
+			props.addProperties(prop);
+		}    	
+		return props;
+	}
+
+
+	public static LbClusterMonitor getLBClusterMonitor(Cluster cluster) throws PolicyValidationException, PartitionValidationException {
         // FIXME fix the following code to correctly update
         // AutoscalerContext context = AutoscalerContext.getInstance();
         if (null == cluster) {
@@ -213,6 +234,7 @@ public class AutoscalerUtil {
                                         new LbClusterMonitor(clusterId,
                                                            cluster.getServiceName(),
                                                            deploymentPolicy, policy);
+        clusterMonitor.setStatus(ClusterStatus.Created);
         // partition group = network partition context
         for (PartitionGroup partitionGroup : deploymentPolicy.getPartitionGroups()) {
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/ArtifactCopyTask.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/ArtifactCopyTask.java b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/ArtifactCopyTask.java
new file mode 100644
index 0000000..75a5d1e
--- /dev/null
+++ b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/ArtifactCopyTask.java
@@ -0,0 +1,39 @@
+/**
+ *
+ */
+package org.apache.stratos.cartridge.agent;
+
+import java.io.File;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.cartridge.agent.extensions.ExtensionHandler;
+
+/**
+ *
+ */
+public class ArtifactCopyTask implements Runnable {
+
+    private static final Log log = LogFactory.getLog(ArtifactCopyTask.class);
+    private final ExtensionHandler extensionHandler;
+    private String source;
+    private String destination;
+
+    public ArtifactCopyTask(String src, String des) {
+    	this.source = src;
+    	this.destination = des;
+        extensionHandler = CartridgeAgent.getExtensionHandler();
+    }
+
+    @Override
+    public void run() {
+        if (log.isDebugEnabled()) {
+            log.debug("Executing Artifact Copy Task source[" + source +"] destination[" + destination +"] ");
+        }        
+
+        if (new File(destination).exists()) {
+            extensionHandler.onCopyArtifactsExtension(source, destination);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/CartridgeAgent.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/CartridgeAgent.java b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/CartridgeAgent.java
index e4ddaed..dac128a 100644
--- a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/CartridgeAgent.java
+++ b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/CartridgeAgent.java
@@ -20,28 +20,38 @@ package org.apache.stratos.cartridge.agent;
  *
 */
 
-
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.stratos.cartridge.agent.artifact.deployment.synchronizer.RepositoryInformation;
-import org.apache.stratos.cartridge.agent.artifact.deployment.synchronizer.git.impl.GitBasedArtifactRepository;
 import org.apache.stratos.cartridge.agent.config.CartridgeAgentConfiguration;
 import org.apache.stratos.cartridge.agent.data.publisher.DataPublisherConfiguration;
 import org.apache.stratos.cartridge.agent.data.publisher.exception.DataPublisherException;
 import org.apache.stratos.cartridge.agent.data.publisher.log.LogPublisherManager;
 import org.apache.stratos.cartridge.agent.event.publisher.CartridgeAgentEventPublisher;
+import org.apache.stratos.cartridge.agent.extensions.DefaultExtensionHandler;
+import org.apache.stratos.cartridge.agent.extensions.ExtensionHandler;
 import org.apache.stratos.cartridge.agent.util.CartridgeAgentConstants;
 import org.apache.stratos.cartridge.agent.util.CartridgeAgentUtils;
-import org.apache.stratos.cartridge.agent.util.ExtensionUtils;
 import org.apache.stratos.messaging.event.Event;
 import org.apache.stratos.messaging.event.instance.notifier.ArtifactUpdatedEvent;
 import org.apache.stratos.messaging.event.instance.notifier.InstanceCleanupClusterEvent;
 import org.apache.stratos.messaging.event.instance.notifier.InstanceCleanupMemberEvent;
+import org.apache.stratos.messaging.event.tenant.CompleteTenantEvent;
+import org.apache.stratos.messaging.event.tenant.SubscriptionDomainAddedEvent;
+import org.apache.stratos.messaging.event.tenant.SubscriptionDomainRemovedEvent;
+import org.apache.stratos.messaging.event.topology.*;
 import org.apache.stratos.messaging.listener.instance.notifier.ArtifactUpdateEventListener;
 import org.apache.stratos.messaging.listener.instance.notifier.InstanceCleanupClusterEventListener;
 import org.apache.stratos.messaging.listener.instance.notifier.InstanceCleanupMemberEventListener;
+import org.apache.stratos.messaging.listener.tenant.CompleteTenantEventListener;
+import org.apache.stratos.messaging.listener.tenant.SubscriptionDomainsAddedEventListener;
+import org.apache.stratos.messaging.listener.tenant.SubscriptionDomainsRemovedEventListener;
+import org.apache.stratos.messaging.listener.topology.*;
 import org.apache.stratos.messaging.message.receiver.instance.notifier.InstanceNotifierEventReceiver;
+import org.apache.stratos.messaging.message.receiver.tenant.TenantEventReceiver;
+import org.apache.stratos.messaging.message.receiver.tenant.TenantManager;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyEventReceiver;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
 
 import java.util.List;
 import java.util.concurrent.Executors;
@@ -53,13 +63,13 @@ import java.util.concurrent.TimeUnit;
  */
 public class CartridgeAgent implements Runnable {
 
-    private static final Log log = LogFactory.getLog(CartridgeAgent.class);
-
+   	private static final Log log = LogFactory.getLog(CartridgeAgent.class);
+    private static final ExtensionHandler extensionHandler = new DefaultExtensionHandler();
     private boolean terminated;
 
     @Override
     public void run() {
-        if(log.isInfoEnabled()) {
+        if (log.isInfoEnabled()) {
             log.info("Cartridge agent started");
         }
 
@@ -68,11 +78,26 @@ public class CartridgeAgent implements Runnable {
         // Start instance notifier listener thread
         subscribeToTopicsAndRegisterListeners();
 
+        // Start topology event receiver thread
+        registerTopologyEventListeners();
+
+        // Start tenant event receiver thread
+        registerTenantEventListeners();
+
+        // Execute instance started shell script
+        extensionHandler.onInstanceStartedEvent();
+
         // Publish instance started event
         CartridgeAgentEventPublisher.publishInstanceStartedEvent();
 
         // Execute start servers extension
-        ExtensionUtils.executeStartServersExtension();
+        try {
+            extensionHandler.startServerExtension();
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Error processing start servers event", e);
+            }
+        }
 
         // Wait for all ports to be active
         CartridgeAgentUtils.waitUntilPortsActive(CartridgeAgentConfiguration.getInstance().getListenAddress(),
@@ -80,128 +105,379 @@ public class CartridgeAgent implements Runnable {
 
         // Check repo url
         String repoUrl = CartridgeAgentConfiguration.getInstance().getRepoUrl();
+        /*if(CartridgeAgentConfiguration.getInstance().isMultitenant()) {
+            if (CartridgeAgentConfiguration.getInstance().isCommitsEnabled()) {
+                log.info(" Commits enabled. Starting File listener ");
+                ScheduledExecutorService scheduler = Executors
+                        .newScheduledThreadPool(1);
+                scheduler.scheduleWithFixedDelay(new RepositoryFileListener(), 0,
+                        10, TimeUnit.SECONDS);
+            }
+            
+            // Start super tenant artifact copy task
+            // from temp location to super tenant app path
+			//ScheduledExecutorService scheduler = Executors
+			//		.newScheduledThreadPool(1);
+			//scheduler.scheduleWithFixedDelay(new ArtifactCopyTask(
+			//		CartridgeAgentConstants.SUPERTENANT_TEMP_PATH,
+			//		CartridgeAgentConfiguration.getInstance().getAppPath()+ "/repository/deployment/server/"
+			//		),
+			//		0, 10, TimeUnit.SECONDS);
+        } */
+
         if ("null".equals(repoUrl) || StringUtils.isBlank(repoUrl)) {
-            if(log.isInfoEnabled()) {
+            if (log.isInfoEnabled()) {
                 log.info("No artifact repository found");
             }
+            // Execute instance activated shell script
+            extensionHandler.onInstanceActivatedEvent();
 
             // Publish instance activated event
             CartridgeAgentEventPublisher.publishInstanceActivatedEvent();
         } else {
             //Start periodical file checker task
-    		if (CartridgeAgentConfiguration.getInstance().isCommitsEnabled()) {
-    			log.info(" Commits enabled. Starting File listener ");
-    			ScheduledExecutorService scheduler = Executors
-    					.newScheduledThreadPool(1);
-    			scheduler.scheduleWithFixedDelay(new RepositoryFileListener(), 0,
-    					10, TimeUnit.SECONDS);
-    		}
+            /*if (CartridgeAgentConfiguration.getInstance().isCommitsEnabled()) {
+                log.info(" Commits enabled. Starting File listener ");
+                ScheduledExecutorService scheduler = Executors
+                        .newScheduledThreadPool(1);
+                scheduler.scheduleWithFixedDelay(new RepositoryFileListener(), 0,
+                        10, TimeUnit.SECONDS);
+            } */
         }
 
-        String persistanceMappingsPayload = CartridgeAgentConfiguration.getInstance().getPersistenceMappings();
-        if(persistanceMappingsPayload != null) {
-            ExtensionUtils.executeVolumeMountExtension(persistanceMappingsPayload);
+//        if (CartridgeAgentConfiguration.getInstance().isInternalRepo()) {
+//            // Start periodic file copy for super tenant
+//            // From repo/deployment/server to /tmp/-1234
+//
+//            ScheduledExecutorService scheduler = Executors
+//                    .newScheduledThreadPool(1);
+//            scheduler.scheduleWithFixedDelay(
+//            		new ArtifactCopyTask(CartridgeAgentConfiguration.getInstance().getAppPath()
+//            		+ "/repository/deployment/server/",
+//            		CartridgeAgentConstants.SUPERTENANT_TEMP_PATH), 0,
+//                    10, TimeUnit.SECONDS);
+//        }
+
+        String persistenceMappingsPayload = CartridgeAgentConfiguration.getInstance().getPersistenceMappings();
+        if (persistenceMappingsPayload != null) {
+            extensionHandler.volumeMountExtension(persistenceMappingsPayload);
         }
-       
-
-        // Keep the thread live until terminated
 
         // start log publishing
         LogPublisherManager logPublisherManager = new LogPublisherManager();
         publishLogs(logPublisherManager);
 
+        // Keep the thread live until terminated
         while (!terminated) {
-        	try {
-				Thread.sleep(1000);
-			} catch (InterruptedException ignore) {
-			}
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ignore) {
+            }
         }
 
         logPublisherManager.stop();
     }
 
-	protected void subscribeToTopicsAndRegisterListeners() {
-		if(log.isDebugEnabled()) {
+    protected void subscribeToTopicsAndRegisterListeners() {
+        if (log.isDebugEnabled()) {
             log.debug("Starting instance notifier event message receiver thread");
         }
 
-        InstanceNotifierEventReceiver eventReceiver = new InstanceNotifierEventReceiver();
-        eventReceiver.addEventListener(new ArtifactUpdateEventListener() {
+        InstanceNotifierEventReceiver instanceNotifierEventReceiver = new InstanceNotifierEventReceiver();
+        instanceNotifierEventReceiver.addEventListener(new ArtifactUpdateEventListener() {
             @Override
             protected void onEvent(Event event) {
-                onArtifactUpdateEvent((ArtifactUpdatedEvent) event);
+                try {
+                    extensionHandler.onArtifactUpdatedEvent((ArtifactUpdatedEvent) event);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing artifact update event", e);
+                    }
+                }
             }
         });
 
-        eventReceiver.addEventListener(new InstanceCleanupMemberEventListener() {
+        instanceNotifierEventReceiver.addEventListener(new InstanceCleanupMemberEventListener() {
             @Override
             protected void onEvent(Event event) {
-                String memberIdInPayload = CartridgeAgentConfiguration.getInstance().getMemberId();
-                InstanceCleanupMemberEvent instanceCleanupMemberEvent = (InstanceCleanupMemberEvent) event;
-                if (memberIdInPayload.equals(instanceCleanupMemberEvent.getMemberId())) {
-                    onInstanceCleanupEvent();
+                try {
+                    String memberIdInPayload = CartridgeAgentConfiguration.getInstance().getMemberId();
+                    InstanceCleanupMemberEvent instanceCleanupMemberEvent = (InstanceCleanupMemberEvent) event;
+                    if (memberIdInPayload.equals(instanceCleanupMemberEvent.getMemberId())) {
+                        extensionHandler.onInstanceCleanupMemberEvent(instanceCleanupMemberEvent);
+                    }
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing instance cleanup member event", e);
+                    }
                 }
+
             }
         });
 
-        eventReceiver.addEventListener(new InstanceCleanupClusterEventListener() {
+        instanceNotifierEventReceiver.addEventListener(new InstanceCleanupClusterEventListener() {
             @Override
             protected void onEvent(Event event) {
                 String clusterIdInPayload = CartridgeAgentConfiguration.getInstance().getClusterId();
                 InstanceCleanupClusterEvent instanceCleanupClusterEvent = (InstanceCleanupClusterEvent) event;
                 if (clusterIdInPayload.equals(instanceCleanupClusterEvent.getClusterId())) {
-                    onInstanceCleanupEvent();
+                    extensionHandler.onInstanceCleanupClusterEvent(instanceCleanupClusterEvent);
                 }
             }
         });
-        Thread eventReceiverThread = new Thread(eventReceiver);
-        eventReceiverThread.start();
 
-        // Wait until message receiver is subscribed to the topic to
-        // send the instance started event
-        while (!eventReceiver.isSubscribed())  {
+        Thread instanceNotifierEventReceiverThread = new Thread(instanceNotifierEventReceiver);
+        instanceNotifierEventReceiverThread.start();
+        if (log.isInfoEnabled()) {
+            log.info("Instance notifier event message receiver thread started");
+        }
+
+        if (log.isDebugEnabled()) {
+            log.debug("Starting tenant event message receiver thread");
+        }
+
+        // Wait until message receiver is subscribed to the topic to send the instance started event
+        while (!instanceNotifierEventReceiver.isSubscribed()) {
             try {
                 Thread.sleep(2000);
             } catch (InterruptedException e) {
             }
         }
-	}
+    }
+
+    protected void registerTopologyEventListeners() {
+        if (log.isDebugEnabled()) {
+            log.debug("Starting topology event message receiver thread");
+        }
+        TopologyEventReceiver topologyEventReceiver = new TopologyEventReceiver();
+        topologyEventReceiver.addEventListener(new MemberActivatedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    TopologyManager.acquireReadLock();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Member activated event received");
+                    }
+                    MemberActivatedEvent memberActivatedEvent = (MemberActivatedEvent) event;
+                    extensionHandler.onMemberActivatedEvent(memberActivatedEvent);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing member activated event", e);
+                    }
+                } finally {
+                    TopologyManager.releaseReadLock();
+                }
+            }
+        });
+
+        topologyEventReceiver.addEventListener(new MemberTerminatedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    TopologyManager.acquireReadLock();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Member terminated event received");
+                    }
+                    MemberTerminatedEvent memberTerminatedEvent = (MemberTerminatedEvent) event;
+                    extensionHandler.onMemberTerminatedEvent(memberTerminatedEvent);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing member terminated event", e);
+                    }
+                } finally {
+                    TopologyManager.releaseReadLock();
+                }
+            }
+        });
+
+        topologyEventReceiver.addEventListener(new MemberSuspendedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    TopologyManager.acquireReadLock();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Member suspended event received");
+                    }
+                    MemberSuspendedEvent memberSuspendedEvent = (MemberSuspendedEvent) event;
+                    extensionHandler.onMemberSuspendedEvent(memberSuspendedEvent);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing member suspended event", e);
+                    }
+                } finally {
+                    TopologyManager.releaseReadLock();
+                }
+            }
+        });
+
+        topologyEventReceiver.addEventListener(new CompleteTopologyEventListener() {
+            private boolean initialized;
+
+            @Override
+            protected void onEvent(Event event) {
+                if (!initialized) {
+                    try {
+                        TopologyManager.acquireReadLock();
+                        if (log.isDebugEnabled()) {
+                            log.debug("Complete topology event received");
+                        }
+                        CompleteTopologyEvent completeTopologyEvent = (CompleteTopologyEvent) event;
+                        extensionHandler.onCompleteTopologyEvent(completeTopologyEvent);
+                        initialized = true;
+                    } catch (Exception e) {
+                        if (log.isErrorEnabled()) {
+                            log.error("Error processing complete topology event", e);
+                        }
+                    } finally {
+                        TopologyManager.releaseReadLock();
+                    }
+                }
+            }
+        });
+
+        topologyEventReceiver.addEventListener(new MemberStartedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    TopologyManager.acquireReadLock();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Member started event received");
+                    }
+                    MemberStartedEvent memberStartedEvent = (MemberStartedEvent) event;
+                    extensionHandler.onMemberStartedEvent(memberStartedEvent);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing member started event", e);
+                    }
+                } finally {
+                    TopologyManager.releaseReadLock();
+                }
+            }
+        });
+
+        Thread thread = new Thread(topologyEventReceiver);
+        thread.start();
+        if (log.isDebugEnabled()) {
+            log.info("Cartridge Agent topology receiver thread started");
+        }
+    }
+
+    protected void registerTenantEventListeners() {
+
+        if (log.isDebugEnabled()) {
+            log.debug("Starting tenant event message receiver thread");
+        }
 
-	protected void validateRequiredSystemProperties() {
-		String jndiPropertiesDir = System.getProperty(CartridgeAgentConstants.JNDI_PROPERTIES_DIR);
-        if(StringUtils.isBlank(jndiPropertiesDir)) {
-            if(log.isErrorEnabled()){
+        TenantEventReceiver tenantEventReceiver = new TenantEventReceiver();
+        tenantEventReceiver.addEventListener(new SubscriptionDomainsAddedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    TenantManager.acquireReadLock();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Subscription domain added event received");
+                    }
+                    SubscriptionDomainAddedEvent subscriptionDomainAddedEvent = (SubscriptionDomainAddedEvent) event;
+                    extensionHandler.onSubscriptionDomainAddedEvent(subscriptionDomainAddedEvent);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing subscription domains added event", e);
+                    }
+                } finally {
+                    TenantManager.releaseReadLock();
+                }
+
+            }
+        });
+
+        tenantEventReceiver.addEventListener(new SubscriptionDomainsRemovedEventListener() {
+            @Override
+            protected void onEvent(Event event) {
+                try {
+                    TenantManager.acquireReadLock();
+                    if (log.isDebugEnabled()) {
+                        log.debug("Subscription domain removed event received");
+                    }
+                    SubscriptionDomainRemovedEvent subscriptionDomainRemovedEvent = (SubscriptionDomainRemovedEvent) event;
+                    extensionHandler.onSubscriptionDomainRemovedEvent(subscriptionDomainRemovedEvent);
+                } catch (Exception e) {
+                    if (log.isErrorEnabled()) {
+                        log.error("Error processing subscription domains removed event", e);
+                    }
+                } finally {
+                    TenantManager.releaseReadLock();
+                }
+            }
+        });
+
+        tenantEventReceiver.addEventListener(new CompleteTenantEventListener() {
+            private boolean initialized;
+            @Override
+            protected void onEvent(Event event) {
+                if (!initialized) {
+                    try {
+                        TenantManager.acquireReadLock();
+                        if (log.isDebugEnabled()) {
+                            log.debug("Complete tenant event received");
+                        }
+                        CompleteTenantEvent completeTenantEvent = (CompleteTenantEvent) event;
+                        extensionHandler.onCompleteTenantEvent(completeTenantEvent);
+                        initialized = true;
+                    } catch (Exception e) {
+                        if (log.isErrorEnabled()) {
+                            log.error("Error processing complete tenant event", e);
+                        }
+                    } finally {
+                        TenantManager.releaseReadLock();
+                    }
+
+                } else {
+                    if (log.isInfoEnabled()) {
+                        log.info("Complete tenant event updating task disabled");
+                    }
+                }
+            }
+        });
+
+        Thread tenantEventReceiverThread = new Thread(tenantEventReceiver);
+        tenantEventReceiverThread.start();
+        if (log.isInfoEnabled()) {
+            log.info("Tenant event message receiver thread started");
+        }
+    }
+
+    protected void validateRequiredSystemProperties() {
+        String jndiPropertiesDir = System.getProperty(CartridgeAgentConstants.JNDI_PROPERTIES_DIR);
+        if (StringUtils.isBlank(jndiPropertiesDir)) {
+            if (log.isErrorEnabled()) {
                 log.error(String.format("System property not found: %s", CartridgeAgentConstants.JNDI_PROPERTIES_DIR));
             }
             return;
         }
 
         String payloadPath = System.getProperty(CartridgeAgentConstants.PARAM_FILE_PATH);
-        if(StringUtils.isBlank(payloadPath)) {
-            if(log.isErrorEnabled()){
+        if (StringUtils.isBlank(payloadPath)) {
+            if (log.isErrorEnabled()) {
                 log.error(String.format("System property not found: %s", CartridgeAgentConstants.PARAM_FILE_PATH));
             }
             return;
         }
 
         String extensionsDir = System.getProperty(CartridgeAgentConstants.EXTENSIONS_DIR);
-        if(StringUtils.isBlank(extensionsDir)) {
-            if(log.isWarnEnabled()){
+        if (StringUtils.isBlank(extensionsDir)) {
+            if (log.isWarnEnabled()) {
                 log.warn(String.format("System property not found: %s", CartridgeAgentConstants.EXTENSIONS_DIR));
             }
         }
-	}
-
-    private static void publishLogs (LogPublisherManager logPublisherManager) {
+    }
 
+    private static void publishLogs(LogPublisherManager logPublisherManager) {
         // check if enabled
         if (DataPublisherConfiguration.getInstance().isEnabled()) {
-
             List<String> logFilePaths = CartridgeAgentConfiguration.getInstance().getLogFilePaths();
             if (logFilePaths == null) {
                 log.error("No valid log file paths found, no logs will be published");
                 return;
-
             } else {
                 // initialize the log publishing
                 try {
@@ -216,7 +492,6 @@ public class CartridgeAgent implements Runnable {
                 for (String logFilePath : logFilePaths) {
                     try {
                         logPublisherManager.start(logFilePath);
-
                     } catch (DataPublisherException e) {
                         log.error("Error occurred in publishing logs ", e);
                     }
@@ -225,91 +500,8 @@ public class CartridgeAgent implements Runnable {
         }
     }
 
-    private void onArtifactUpdateEvent(ArtifactUpdatedEvent event) {
-        ArtifactUpdatedEvent artifactUpdatedEvent = event;
-        if(log.isInfoEnabled()) {
-            log.info(String.format("Artifact update event received: %s", artifactUpdatedEvent.toString()));
-        }
-
-        String clusterIdInPayload = CartridgeAgentConfiguration.getInstance().getClusterId();
-        String localRepoPath = CartridgeAgentConfiguration.getInstance().getAppPath();
-        String clusterIdInMessage = artifactUpdatedEvent.getClusterId();
-        String repoURL = artifactUpdatedEvent.getRepoURL();
-        String repoPassword = CartridgeAgentUtils.decryptPassword(artifactUpdatedEvent.getRepoPassword());
-        String repoUsername = artifactUpdatedEvent.getRepoUserName();
-        String tenantId = artifactUpdatedEvent.getTenantId();
-        boolean isMultitenant = CartridgeAgentConfiguration.getInstance().isMultitenant();
-
-        if(StringUtils.isNotEmpty(repoURL) && (clusterIdInPayload != null) && clusterIdInPayload.equals(clusterIdInMessage)) {
-            if(log.isInfoEnabled()) {
-                log.info("Executing git checkout");
-            }
-            RepositoryInformation repoInformation = new RepositoryInformation();
-            repoInformation.setRepoUsername(repoUsername);
-            if(repoPassword == null) {
-            	repoInformation.setRepoPassword("");
-            }else {
-            	repoInformation.setRepoPassword(repoPassword);
-            }            
-            repoInformation.setRepoUrl(repoURL);
-            repoInformation.setRepoPath(localRepoPath);
-            repoInformation.setTenantId(tenantId);
-            repoInformation.setMultitenant(isMultitenant);
-            boolean cloneExists = GitBasedArtifactRepository.getInstance().cloneExists(repoInformation);
-            GitBasedArtifactRepository.getInstance().checkout(repoInformation);
-
-            ExtensionUtils.executeArtifactsUpdatedExtension();
-
-            if(!cloneExists){
-                // Executed git clone, publish instance activated event
-                CartridgeAgentEventPublisher.publishInstanceActivatedEvent();
-            }
-
-            // Start the artifact update task
-            boolean artifactUpdateEnabled = Boolean.parseBoolean(System.getProperty(CartridgeAgentConstants.ENABLE_ARTIFACT_UPDATE));
-            if (artifactUpdateEnabled) {
-
-                long artifactUpdateInterval = 10;
-                // get update interval
-                String artifactUpdateIntervalStr = System.getProperty(CartridgeAgentConstants.ARTIFACT_UPDATE_INTERVAL);
-
-                if (artifactUpdateIntervalStr != null && !artifactUpdateIntervalStr.isEmpty()) {
-                    try {
-                        artifactUpdateInterval = Long.parseLong(artifactUpdateIntervalStr);
-
-                    } catch (NumberFormatException e) {
-                        log.error("Invalid artifact sync interval specified ", e);
-                        artifactUpdateInterval = 10;
-                    }
-                }
-
-                log.info("Artifact updating task enabled, update interval: " + artifactUpdateInterval + "s");
-                GitBasedArtifactRepository.getInstance().scheduleSyncTask(repoInformation, artifactUpdateInterval);
-
-            } else {
-                log.info("Artifact updating task disabled");
-            }
-
-        }
-    }
-
-    private void onInstanceCleanupEvent() {
-        if(log.isInfoEnabled()) {
-            log.info("Executing cleaning up the data in the cartridge instance...");
-        }
-        //sending event on the maintenance mode
-        CartridgeAgentEventPublisher.publishMaintenanceModeEvent();
-
-        //cleaning up the cartridge instance's data
-        ExtensionUtils.executeCleanupExtension();
-        if(log.isInfoEnabled()) {
-            log.info("cleaning up finished in the cartridge instance...");
-        }
-        if(log.isInfoEnabled()) {
-            log.info("publishing ready to shutdown event...");
-        }
-        //publishing the Ready to shutdown event after performing the cleanup
-        CartridgeAgentEventPublisher.publishInstanceReadyToShutdownEvent();
+    public static ExtensionHandler getExtensionHandler() {
+        return extensionHandler;
     }
 
     public void terminate() {

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/Main.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/Main.java b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/Main.java
index a1be237..c2fbed1 100644
--- a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/Main.java
+++ b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/Main.java
@@ -53,12 +53,6 @@ public class Main {
                 }
             });
 
-            // Configure log4j properties
-            if(log.isDebugEnabled()) {
-                log.debug("Configuring log4j.properties file path");
-            }
-            PropertyConfigurator.configure(System.getProperty("log4j.properties.file.path"));
-
             // Generate jndi.properties file
             JndiConfigurator.configure();
 
@@ -66,25 +60,25 @@ public class Main {
             CartridgeAgentConfiguration.getInstance();
 
             if (args.length >= 1) {
-            	String className = args[0];
-				try {
-					Constructor<?> c = Class.forName(className)
-							.getConstructor();
-					cartridgeAgent = (CartridgeAgent) c.newInstance();
-					log.info("Loaded Cartridge Agent using [class] "+className);
-				} catch (Exception e) {
-					String msg = String.format("Cannot load Cartridge Agent from [class name] %s, "
-							+ "hence using the default agent.", className);
-					log.warn(msg, e);
-				}
+                String className = args[0];
+                try {
+                    Constructor<?> c = Class.forName(className)
+                            .getConstructor();
+                    cartridgeAgent = (CartridgeAgent) c.newInstance();
+                    log.info("Loaded Cartridge Agent using [class] " + className);
+                } catch (Exception e) {
+                    String msg = String.format("Cannot load Cartridge Agent from [class name] %s, "
+                            + "hence using the default agent.", className);
+                    log.warn(msg, e);
+                }
             }
-            
+
             if (cartridgeAgent == null) {
-            	// load default agent
-            	cartridgeAgent = new CartridgeAgent();
-            	if (log.isDebugEnabled()) {
-            		log.debug("Loading default Cartridge Agent.");
-            	}
+                // load default agent
+                cartridgeAgent = new CartridgeAgent();
+                if (log.isDebugEnabled()) {
+                    log.debug("Loading default Cartridge Agent.");
+                }
             }
             // start agent
             Thread thread = new Thread(cartridgeAgent);

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/RepositoryFileListener.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/RepositoryFileListener.java b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/RepositoryFileListener.java
index 8e79c66..59163d5 100644
--- a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/RepositoryFileListener.java
+++ b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/RepositoryFileListener.java
@@ -32,10 +32,10 @@ public class RepositoryFileListener implements Runnable {
         if(log.isDebugEnabled()) {
 		    log.debug("Executing repository file listener");
         }
-		boolean commitStatus = GitBasedArtifactRepository.getInstance().commit();
-        if(log.isDebugEnabled()) {
-		    log.debug("Commit status: " + commitStatus);
-        }
+		//boolean commitStatus = GitBasedArtifactRepository.getInstance().commit();
+        //if(log.isDebugEnabled()) {
+		//    log.debug("Commit status: " + commitStatus);
+       // }
 	}
 
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/artifact/deployment/synchronizer/RepositoryInformation.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/artifact/deployment/synchronizer/RepositoryInformation.java b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/artifact/deployment/synchronizer/RepositoryInformation.java
index 1be78a4..c35b70d 100644
--- a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/artifact/deployment/synchronizer/RepositoryInformation.java
+++ b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/artifact/deployment/synchronizer/RepositoryInformation.java
@@ -31,6 +31,7 @@ public class RepositoryInformation {
 	private String repoPath;
 	private String tenantId;
 	private boolean isMultitenant;
+    private boolean commitEnabled;
 	
 	public String getRepoUrl() {
 		return repoUrl;
@@ -68,5 +69,12 @@ public class RepositoryInformation {
 	public void setMultitenant(boolean isMultitenant) {
 		this.isMultitenant = isMultitenant;
 	}
-	
+
+    public boolean isCommitEnabled() {
+        return commitEnabled;
+    }
+
+    public void setCommitEnabled(boolean commitEnabled) {
+        this.commitEnabled = commitEnabled;
+    }
 }