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:41:57 UTC

[07/14] Clustering changes for stratos

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/util/ExtensionUtils.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/util/ExtensionUtils.java b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/util/ExtensionUtils.java
index 2a11103..ed7d3bb 100644
--- a/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/util/ExtensionUtils.java
+++ b/components/org.apache.stratos.cartridge.agent/src/main/java/org/apache/stratos/cartridge/agent/util/ExtensionUtils.java
@@ -24,8 +24,18 @@ import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.cartridge.agent.config.CartridgeAgentConfiguration;
 import org.apache.stratos.common.util.CommandUtils;
+import org.apache.stratos.messaging.domain.topology.Cluster;
+import org.apache.stratos.messaging.domain.topology.Member;
+import org.apache.stratos.messaging.domain.topology.Service;
+import org.apache.stratos.messaging.domain.topology.Topology;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
 
 import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
 
 /**
  * Cartridge agent extension utility methods.
@@ -35,81 +45,272 @@ public class ExtensionUtils {
 
     private static String getExtensionsDir() {
         String extensionsDir = System.getProperty(CartridgeAgentConstants.EXTENSIONS_DIR);
-        if(StringUtils.isBlank(extensionsDir)) {
+        if (StringUtils.isBlank(extensionsDir)) {
             throw new RuntimeException(String.format("System property not found: %s", CartridgeAgentConstants.EXTENSIONS_DIR));
         }
         return extensionsDir;
     }
 
-    private static String prepareCommand(String scriptFile) {
+    private static String prepareCommand(String scriptFile) throws FileNotFoundException {
         String extensionsDir = getExtensionsDir();
-        return (extensionsDir.endsWith(File.separator)) ?
-                extensionsDir + scriptFile:
+        String filePath = (extensionsDir.endsWith(File.separator)) ?
+                extensionsDir + scriptFile :
                 extensionsDir + File.separator + scriptFile;
+
+        File file = new File(filePath);
+        if (file.exists() && !file.isDirectory()) {
+            return filePath;
+        }
+
+        throw new FileNotFoundException("Script file not found:" + filePath);
     }
 
-    public static void executeStartServersExtension() {
-        try {
-            if(log.isDebugEnabled()) {
-                log.debug("Executing start servers extension");
+    public static void addPayloadParameters(Map<String, String> envParameters){
+        envParameters.put("STRATOS_APP_PATH", CartridgeAgentConfiguration.getInstance().getAppPath());
+        envParameters.put("STRATOS_PARAM_FILE_PATH", System.getProperty(CartridgeAgentConstants.PARAM_FILE_PATH));
+        envParameters.put("STRATOS_SERVICE_NAME", CartridgeAgentConfiguration.getInstance().getServiceName());
+        envParameters.put("STRATOS_TENANT_ID", CartridgeAgentConfiguration.getInstance().getTenantId());
+        envParameters.put("STRATOS_CARTRIDGE_KEY", CartridgeAgentConfiguration.getInstance().getCartridgeKey());
+        envParameters.put("STRATOS_LB_CLUSTER_ID", CartridgeAgentConfiguration.getInstance().getLbClusterId());
+        envParameters.put("STRATOS_CLUSTER_ID", CartridgeAgentConfiguration.getInstance().getClusterId());
+        envParameters.put("STRATOS_NETWORK_PARTITION_ID", CartridgeAgentConfiguration.getInstance().getNetworkPartitionId());
+        envParameters.put("STRATOS_PARTITION_ID", CartridgeAgentConfiguration.getInstance().getPartitionId());
+        envParameters.put("STRATOS_PERSISTENCE_MAPPINGS", CartridgeAgentConfiguration.getInstance().getPersistenceMappings());
+        envParameters.put("STRATOS_REPO_URL", CartridgeAgentConfiguration.getInstance().getRepoUrl());
+
+        // Add LB instance public/private IPs to environment parameters
+        String lbClusterIdInPayload = CartridgeAgentConfiguration.getInstance().getLbClusterId();
+        String[] memberIps = getLbMemberIp(lbClusterIdInPayload);
+        String lbIp, lbPublicIp;
+        if (memberIps != null && memberIps.length > 1) {
+        	lbIp = memberIps[0];
+        	lbPublicIp = memberIps[1];
+        } else {
+        	lbIp = CartridgeAgentConfiguration.getInstance().getLbPrivateIp();
+        	lbPublicIp = CartridgeAgentConfiguration.getInstance().getLbPublicIp();
+        }
+        
+        envParameters.put("STRATOS_LB_IP", lbIp);
+        envParameters.put("STRATOS_LB_PUBLIC_IP", lbPublicIp);
+
+        Topology topology = TopologyManager.getTopology();
+        if (topology.isInitialized()){
+            Service service = topology.getService(CartridgeAgentConfiguration.getInstance().getServiceName());
+            Cluster cluster = service.getCluster(CartridgeAgentConfiguration.getInstance().getClusterId());
+            String memberIdInPayload = CartridgeAgentConfiguration.getInstance().getMemberId();
+            addProperties(service.getProperties(), envParameters, "SERVICE_PROPERTY");
+            addProperties(cluster.getProperties(), envParameters, "CLUSTER_PROPERTY");
+            addProperties(cluster.getMember(memberIdInPayload).getProperties(), envParameters, "MEMBER_PROPERTY");
+        }
+    }
+
+    public static void addProperties(Properties properties, Map<String, String> envParameters, String prefix){
+        if (properties == null || properties.entrySet() == null){
+            return;
+        }
+        for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+            envParameters.put("STRATOS_ " + prefix + "_" + entry.getKey().toString(), entry.getValue().toString());
+            if (log.isDebugEnabled()) {
+                log.debug(String.format("Property added: [key] %s [value] %s",
+                        "STRATOS_ " + prefix + "_" + entry.getKey().toString(), entry.getValue().toString()));
             }
-            String command = prepareCommand(CartridgeAgentConstants.START_SERVERS_SH);
-            CommandUtils.executeCommand(command);
         }
-        catch (Exception e) {
-            log.error("Could not execute start servers extension", e);
+    }
+
+    public static String[] getLbMemberIp(String lbClusterId) {
+        Topology topology = TopologyManager.getTopology();
+        Collection<Service> serviceCollection = topology.getServices();
+
+        for (Service service : serviceCollection) {
+            Collection<Cluster> clusterCollection = service.getClusters();
+            for (Cluster cluster : clusterCollection) {
+                Collection<Member> memberCollection = cluster.getMembers();
+                for (Member member : memberCollection) {
+                    if (member.getClusterId().equals(lbClusterId)) {
+                        return new String[]{member.getMemberIp(), member.getMemberPublicIp()};
+                    }
+                }
+            }
         }
+        return null;
     }
 
-    public static void executeCleanupExtension() {
+    public static boolean isRelevantMemberEvent(String serviceName, String clusterId, String lbClusterId) {
+        String clusterIdInPayload = CartridgeAgentConfiguration.getInstance().getClusterId();
+        if (clusterIdInPayload == null) {
+            return false;
+        }
+        Topology topology = TopologyManager.getTopology();
+        if (topology == null || !topology.isInitialized()) {
+            return false;
+        }
+
+        if (clusterIdInPayload.equals(clusterId)) {
+            return true;
+        }
+
+        if (clusterIdInPayload.equals(lbClusterId)) {
+            return true;
+        }
+
+        String serviceGroupInPayload = CartridgeAgentConfiguration.getInstance().getServiceGroup();
+        if (serviceGroupInPayload != null) {
+            Properties serviceProperties = topology.getService(serviceName).getProperties();
+            if (serviceProperties == null) {
+                return false;
+            }
+            String memberServiceGroup = serviceProperties.getProperty(CartridgeAgentConstants.SERVICE_GROUP_TOPOLOGY_KEY);
+            if (memberServiceGroup != null && memberServiceGroup.equals(serviceGroupInPayload)) {            	
+            	if(serviceName.equals(CartridgeAgentConfiguration.getInstance().getServiceName())) {
+            		if (log.isDebugEnabled()) {
+            			log.debug("Service names are same");
+            		}
+            		return true;
+            	}else if(CartridgeAgentConfiguration.getInstance().getServiceName().equals("apistore") && "publisher".equals(serviceName)) {
+            		if (log.isDebugEnabled()) {
+            			log.debug("Service name in payload is [store]. Serivce name in event is ["+serviceName+"] ");
+            		}
+            		return true;
+            	}else if(CartridgeAgentConfiguration.getInstance().getServiceName().equals("publisher") && "apistore".equals(serviceName)) {
+            		if (log.isDebugEnabled()) {
+            			log.debug("Service name in payload is [publisher]. Serivce name in event is ["+serviceName+"] ");
+            		}
+            		return true;
+            	}else if(CartridgeAgentConstants.DEPLOYMENT_WORKER.equals(CartridgeAgentConfiguration.getInstance().getDeployment()) &&
+            			serviceName.equals(CartridgeAgentConfiguration.getInstance().getManagerServiceName())) {
+            		if (log.isDebugEnabled()) {
+            			log.debug("Deployment is worker. Worker's manager service name & service name in event are same");
+            		}
+            		return true;
+            	}else if (CartridgeAgentConstants.DEPLOYMENT_MANAGER.equals(CartridgeAgentConfiguration.getInstance().getDeployment()) &&
+            			serviceName.equals(CartridgeAgentConfiguration.getInstance().getWorkerServiceName())) {
+            		if (log.isDebugEnabled()) {
+            			log.debug("Deployment is manager. Manager's worker service name & service name in event are same");
+            		}
+            		return true;
+            	}
+            }
+        }
+                
+        return false;
+    }
+
+    private static Map<String, String> cleanProcessParameters(Map<String, String> envParameters) {
+        Iterator<Map.Entry<String, String>> iter = envParameters.entrySet().iterator();
+        while (iter.hasNext()) {
+            Map.Entry<String, String> entry = iter.next();
+            if (entry.getValue() == null) {
+                iter.remove();
+            }
+        }
+        return envParameters;
+    }
+
+    public static void executeStartServersExtension(Map<String, String> envParameters) {
         try {
-            if(log.isDebugEnabled()) {
+            if (log.isDebugEnabled()) {
                 log.debug("Executing start servers extension");
             }
-            String command = prepareCommand(CartridgeAgentConstants.CLEAN_UP_SH);
-            CommandUtils.executeCommand(command);
+            String script = System.getProperty(CartridgeAgentConstants.START_SERVERS_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Start server script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute start servers extension", e);
+            }
         }
-        catch (Exception e) {
-            log.error("Could not execute start servers extension", e);
+    }
+
+    public static void executeCleanupExtension() {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing cleanup extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.CLEAN_UP_SCRIPT);
+            String command = prepareCommand(script);
+            String output = CommandUtils.executeCommand(command);
+            if (log.isDebugEnabled()) {
+                log.debug("Cleanup script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute cleanup extension", e);
+            }
         }
     }
 
-    public static void executeInstanceStartedExtension() {
+    public static void executeInstanceStartedExtension(Map<String, String> envParameters) {
         try {
-            if(log.isDebugEnabled()) {
+            if (log.isDebugEnabled()) {
                 log.debug("Executing instance started extension");
             }
-            String command = prepareCommand(CartridgeAgentConstants.INSTANCE_STARTED_SH);
-            CommandUtils.executeCommand(command);
-        }
-        catch (Exception e) {
-            log.error("Could not execute instance started extension", e);
+            String script = System.getProperty(CartridgeAgentConstants.INSTANCE_STARTED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Instance started script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute instance started extension", e);
+            }
         }
     }
 
     public static void executeInstanceActivatedExtension() {
         try {
-            if(log.isDebugEnabled()) {
+            if (log.isDebugEnabled()) {
                 log.debug("Executing instance activated extension");
             }
-            String command = prepareCommand(CartridgeAgentConstants.INSTANCE_ACTIVATED_SH);
-            CommandUtils.executeCommand(command);
-        }
-        catch (Exception e) {
-            log.error("Could not execute instance activated extension", e);
+            String script = System.getProperty(CartridgeAgentConstants.INSTANCE_ACTIVATED_SCRIPT);
+            String command = prepareCommand(script);
+            String output = CommandUtils.executeCommand(command);
+            if (log.isDebugEnabled()) {
+                log.debug("Instance activated script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute instance activated extension", e);
+            }
         }
     }
 
-    public static void executeArtifactsUpdatedExtension() {
+    public static void executeArtifactsUpdatedExtension(Map<String, String> envParameters) {
         try {
-            if(log.isDebugEnabled()) {
+            if (log.isDebugEnabled()) {
                 log.debug("Executing artifacts updated extension");
             }
-            String command = prepareCommand(CartridgeAgentConstants.ARTIFACTS_UPDATED_SH);
-            CommandUtils.executeCommand(command);
+            String script = System.getProperty(CartridgeAgentConstants.ARTIFACTS_UPDATED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Artifacts updated script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute artifacts updated extension", e);
+            }
         }
-        catch (Exception e) {
-            log.error("Could not execute artifacts updated extension", e);
+    }
+
+    public static void executeCopyArtifactsExtension(String source, String destination) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing artifacts copy extension");
+            }
+            String command = prepareCommand(System.getProperty(CartridgeAgentConstants.ARTIFACTS_COPY_SCRIPT));
+            CommandUtils.executeCommand(command + " " + source + " " + destination);
+        } catch (Exception e) {
+            log.error("Could not execute artifacts copy extension", e);
         }
     }
 
@@ -117,19 +318,230 @@ public class ExtensionUtils {
     This will execute the volume mounting script which format and mount the
     persistance volumes.
      */
-    public static void executeVolumeMountExtension(String persistanceMappingsPayload) {
+    public static void executeVolumeMountExtension(String persistenceMappingsPayload) {
         try {
-            if(log.isDebugEnabled()) {
-                    log.debug("Executing volume mounting extension");
+            if (log.isDebugEnabled()) {
+                log.debug(String.format("Executing volume mounting extension: [payload] %s", persistenceMappingsPayload));
             }
-            String command = prepareCommand(CartridgeAgentConstants.MOUNT_VOLUMES_SH);
+            String script = System.getProperty(CartridgeAgentConstants.MOUNT_VOLUMES_SCRIPT);
+            String command = prepareCommand(script);
             //String payloadPath = System.getProperty(CartridgeAgentConstants.PARAM_FILE_PATH);
             // add payload file path as argument so inside the script we can source
             // it  to get the env variables set by the startup script
-            CommandUtils.executeCommand(command + " " + persistanceMappingsPayload);
-        }
-        catch (Exception e) {
+            String output = CommandUtils.executeCommand(command + " " + persistenceMappingsPayload);
+            if (log.isDebugEnabled()) {
+                log.debug("Volume mount script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
                 log.error("Could not execute volume mounting extension", e);
+            }
+        }
+    }
+
+    public static void executeMemberActivatedExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing member activated extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.MEMBER_ACTIVATED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Member activated script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute member activated extension", e);
+            }
+        }
+    }
+
+    public static void executeMemberTerminatedExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing member terminated extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.MEMBER_TERMINATED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Member terminated script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute member terminated extension", e);
+            }
+        }
+    }
+
+    public static void executeMemberStartedExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing member started extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.MEMBER_STARTED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Member started script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute member started extension", e);
+            }
+        }
+    }
+
+    public static void executeMemberSuspendedExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing member suspended extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.MEMBER_SUSPENDED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Member suspended script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute member suspended extension", e);
+            }
+        }
+    }
+
+    public static void executeCompleteTopologyExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing complete topology extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.COMPLETE_TOPOLOGY_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Complete topology script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute complete topology extension", e);
+            }
+        }
+    }
+
+    public static void executeCompleteTenantExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing complete tenant extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.COMPLETE_TENANT_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Complete tenant script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute complete tenant extension", e);
+            }
+        }
+    }
+
+    public static void executeSubscriptionDomainAddedExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing subscription domain added extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.SUBSCRIPTION_DOMAIN_ADDED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Subscription domain added script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute subscription domain added extension", e);
+            }
+        }
+    }
+
+    public static void executeSubscriptionDomainRemovedExtension(Map<String, String> envParameters) {
+        try {
+            if (log.isDebugEnabled()) {
+                log.debug("Executing subscription domain removed extension");
+            }
+            String script = System.getProperty(CartridgeAgentConstants.SUBSCRIPTION_DOMAIN_REMOVED_SCRIPT);
+            String command = prepareCommand(script);
+            addPayloadParameters(envParameters);
+            cleanProcessParameters(envParameters);
+            String output = CommandUtils.executeCommand(command, envParameters);
+            if (log.isDebugEnabled()) {
+                log.debug("Subscription domain removed script returned:" + output);
+            }
+        } catch (Exception e) {
+            if (log.isErrorEnabled()) {
+                log.error("Could not execute subscription domain removed extension", e);
+            }
+
+        }
+    }
+
+    public static boolean isTopologyInitialized() {
+        TopologyManager.acquireReadLock();
+        boolean active = TopologyManager.getTopology().isInitialized();
+        TopologyManager.releaseReadLock();
+        return active;
+    }
+
+    public static void waitForCompleteTopology() {
+        while (!isTopologyInitialized()) {
+            if (log.isInfoEnabled()) {
+                log.info("Waiting for complete topology event...");
+            }
+            try {
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+            }
+        }
+    }
+
+    public static boolean checkTopologyConsistency(String serviceName, String clusterId, String memberId){
+        Topology topology = TopologyManager.getTopology();
+        Service service = topology.getService(serviceName);
+        if (service == null) {
+            if (log.isErrorEnabled()) {
+                log.error(String.format("Service not found in topology [service] %s", serviceName));
+            }
+            return false;
+        }
+        Cluster cluster = service.getCluster(clusterId);
+        if (cluster == null) {
+            if (log.isErrorEnabled()) {
+                log.error(String.format("Cluster id not found in topology [cluster] %s", clusterId));
+            }
+            return false;
+        }
+        Member activatedMember = cluster.getMember(memberId);
+        if (activatedMember == null) {
+            if (log.isErrorEnabled()) {
+                log.error(String.format("Member id not found in topology [member] %s", memberId));
+            }
+            return false;
         }
+        return true;
     }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/RestCommandLineService.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/RestCommandLineService.java b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/RestCommandLineService.java
index 10c9d9e..857d1a1 100644
--- a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/RestCommandLineService.java
+++ b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/RestCommandLineService.java
@@ -94,6 +94,8 @@ public class RestCommandLineService {
     private final String deactivateTenantRestEndPoint = "/stratos/admin/tenant/deactivate";
     private final String activateTenantRestEndPoint = "/stratos/admin/tenant/activate";
     private final String listAllTenantRestEndPoint = "/stratos/admin/tenant/list";
+    private final String getListAvailableCartridgeInfoRestEndPoint = "/stratos/admin/cartridge/available/info";
+
 
     private static class SingletonHolder {
 		private final static RestCommandLineService INSTANCE = new RestCommandLineService();
@@ -210,6 +212,84 @@ public class RestCommandLineService {
         this.restClient = restClient;
     }
 
+    public Cartridge listCartridge(String cartridgeType) throws CommandException{
+        DefaultHttpClient httpClient = new DefaultHttpClient();
+        HttpResponse response = null;
+
+        try {
+            String endpoint = restClient.getBaseURL() + getListAvailableCartridgeInfoRestEndPoint + "/" + cartridgeType;
+            response = restClient.doGet(httpClient, endpoint);
+
+            String responseCode = "" + response.getStatusLine().getStatusCode();
+            String resultString = getHttpResponseString(response);
+            if (resultString == null) {
+                return null;
+            }
+
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            Gson gson = gsonBuilder.create();
+
+            if (!responseCode.equals(CliConstants.RESPONSE_OK)) {
+                ExceptionMapper exception = gson.fromJson(resultString, ExceptionMapper.class);
+                System.out.println(exception);
+                return null;
+            }
+
+            String cartridgeString = resultString.substring(13, resultString.length() -1);
+            Cartridge cartridge = gson.fromJson(cartridgeString, Cartridge.class);
+            return cartridge;
+
+        } catch (Exception e) {
+            handleException("Exception in listing cartridge info", e);
+            return null;
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
+    public ArrayList<Cartridge> listCartridges(String serviceGroup) throws CommandException{
+        DefaultHttpClient httpClient = new DefaultHttpClient();
+        HttpResponse response = null;
+
+        try {
+            response = restClient.doGet(httpClient, restClient.getBaseURL() + listAvailableCartridgesRestEndpoint);
+
+            String responseCode = "" + response.getStatusLine().getStatusCode();
+            String resultString = getHttpResponseString(response);
+
+            if (resultString == null) {
+                return null;
+            }
+
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            Gson gson = gsonBuilder.create();
+
+            if (!responseCode.equals(CliConstants.RESPONSE_OK)) {
+                ExceptionMapper exception = gson.fromJson(resultString, ExceptionMapper.class);
+                System.out.println(exception);
+                return null;
+            }
+
+            CartridgeList cartridgeList = gson.fromJson(resultString, CartridgeList.class);
+
+            ArrayList<Cartridge> cartridgesInServiceGroup = new ArrayList<Cartridge>();
+
+            for (int i = 0; i < cartridgeList.getCartridge().size(); i++) {
+                if (serviceGroup.equals(cartridgeList.getCartridge().get(i).getServiceGroup())) {
+                    cartridgesInServiceGroup.add(cartridgeList.getCartridge().get(i));
+                }
+            }
+
+            return cartridgesInServiceGroup;
+
+        } catch (Exception e) {
+            handleException("Exception in listing cartridge info", e);
+            return null;
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
     // List currently available multi tenant and single tenant cartridges
     public void listAvailableCartridges() throws CommandException {
         DefaultHttpClient httpClient = new DefaultHttpClient();
@@ -244,7 +324,14 @@ public class RestCommandLineService {
             ArrayList<Cartridge> multiTenetCartridge = new ArrayList<Cartridge>();
             ArrayList<Cartridge> singleTentCartridge = new ArrayList<Cartridge>();
 
+            HashSet<String> existingServiceGroups = new HashSet<String>();
+
             for (Cartridge cartridge : cartridgeList.getCartridge()) {
+                if(existingServiceGroups.contains(cartridge.getServiceGroup())){
+                    continue;
+                }else{
+                    existingServiceGroups.add(cartridge.getServiceGroup());
+                }
                 if (cartridge.isMultiTenant()) {
                     multiTenetCartridge.add(cartridge);
                 }
@@ -361,7 +448,6 @@ public class RestCommandLineService {
 
             String responseCode = "" + response.getStatusLine().getStatusCode();
             String resultString = getHttpResponseString(response);
-            
             GsonBuilder gsonBuilder = new GsonBuilder();
             Gson gson = gsonBuilder.create();
             
@@ -489,7 +575,7 @@ public class RestCommandLineService {
             System.out.println("\tTenancy Model	: "	+ tenancy);
             System.out.println("\tAlias : "	+ cartridge.getCartridgeAlias());
             System.out.println("\tStatus : "	+ cartridge.getStatus());
-            String instanceCount  = cartridge.isMultiTenant() ? "N/A" : String.valueOf(cartridge.getActiveInstances());
+            String instanceCount  = String.valueOf(cartridge.getActiveInstances());
             System.out.println("\tRunning Instances	: " + instanceCount);
             System.out.println("\tAccess URL(s) : " + getAccessURLs(cartridge));
 			if (cartridge.getRepoURL() != null) {
@@ -534,7 +620,7 @@ public class RestCommandLineService {
             // Invoke  cluster/{clusterId}
             for (String clusterId : lbClusterIdSet) {
 				HttpResponse responseCluster = restClient.doGet(httpClient, restClient.getBaseURL()
-						+ listClusterRestEndpoint + "clusterId/" + clusterId);
+						+ listClusterRestEndpoint + "lb");
 
                 String responseCode = "" + responseCluster.getStatusLine().getStatusCode();
                 String resultStringCluster = getHttpResponseString(responseCluster);
@@ -548,8 +634,8 @@ public class RestCommandLineService {
                     return null;
                 }
 
-                Cluster cluster = getClusterObjectFromString(resultStringCluster);
-
+                ArrayList<Cluster> clusterList = getClusterListObjectFromString(resultStringCluster);
+                Cluster cluster = clusterList.get(0);
                 if (cluster == null) {
                     System.out.println("Subscribe cartridge list is null");
                     return null;
@@ -683,6 +769,14 @@ public class RestCommandLineService {
 		Cluster cluster = gson.fromJson(resultString, Cluster.class);
 		return cluster;
 	}
+	
+	private ArrayList<Cluster> getClusterListObjectFromString(String resultString) {
+		GsonBuilder gsonBuilder = new GsonBuilder();
+		Gson gson = gsonBuilder.create();
+
+		ClusterList clusterlist = gson.fromJson(resultString, ClusterList.class);
+		return clusterlist.getCluster();
+	}
 
     private void printLBs(String resultString) {
     	
@@ -719,6 +813,88 @@ public class RestCommandLineService {
 		}
 	}
 
+    private String getAsPolicyFromServiceDefinition(String cartridgeType) throws CommandException{
+        DefaultHttpClient httpClient = new DefaultHttpClient();
+        try {
+            HttpResponse response = restClient.doGet(httpClient, restClient.getBaseURL()
+                    + listDeployServicesRestEndPoint + "/" + cartridgeType);
+
+            String responseCode = "" + response.getStatusLine().getStatusCode();
+
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            Gson gson = gsonBuilder.create();
+
+            if ( ! responseCode.equals(CliConstants.RESPONSE_OK)) {
+                String resultString = getHttpResponseString(response);
+                ExceptionMapper exception = gson.fromJson(resultString, ExceptionMapper.class);
+                System.out.println(exception);
+                return null;
+            }
+
+            String resultString = getHttpResponseString(response);
+            if (resultString == null) {
+                System.out.println("Response content is empty");
+                return null;
+            }
+
+            String  serviceDefinitionString =  resultString.substring(25, resultString.length() -1);
+            ServiceDefinitionBean serviceDefinition= gson.fromJson(serviceDefinitionString, ServiceDefinitionBean.class);
+            if (serviceDefinition == null) {
+                System.out.println("Deploy service list is empty");
+                return null;
+            }
+
+            return serviceDefinition.getAutoscalingPolicyName();
+
+        } catch (Exception e) {
+            handleException("Exception in listing deploy services", e);
+            return null;
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
+    private String getDeploymentPolicyFromServiceDefinition(String cartridgeType) throws CommandException{
+        DefaultHttpClient httpClient = new DefaultHttpClient();
+        try {
+            HttpResponse response = restClient.doGet(httpClient, restClient.getBaseURL()
+                    + listDeployServicesRestEndPoint + "/" + cartridgeType);
+
+            String responseCode = "" + response.getStatusLine().getStatusCode();
+
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            Gson gson = gsonBuilder.create();
+
+            if ( ! responseCode.equals(CliConstants.RESPONSE_OK)) {
+                String resultString = getHttpResponseString(response);
+                ExceptionMapper exception = gson.fromJson(resultString, ExceptionMapper.class);
+                System.out.println(exception);
+                return null;
+            }
+
+            String resultString = getHttpResponseString(response);
+            if (resultString == null) {
+                System.out.println("Response content is empty");
+                return null;
+            }
+
+            String  serviceDefinitionString =  resultString.substring(25, resultString.length() -1);
+            ServiceDefinitionBean serviceDefinition= gson.fromJson(serviceDefinitionString, ServiceDefinitionBean.class);
+            if (serviceDefinition == null) {
+                System.out.println("Deploy service list is empty");
+                return null;
+            }
+
+            return serviceDefinition.getDeploymentPolicyName();
+
+        } catch (Exception e) {
+            handleException("Exception in listing deploy services", e);
+            return null;
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
+
 	// This method does the cartridge subscription
     public void subscribe(String cartridgeType, String alias, String externalRepoURL, boolean privateRepo, String username,
                           String password,String asPolicy,
@@ -728,25 +904,16 @@ public class RestCommandLineService {
         DefaultHttpClient httpClient = new DefaultHttpClient();
 
         CartridgeInfoBean cartridgeInfoBean = new CartridgeInfoBean();
-        cartridgeInfoBean.setCartridgeType(null);
-        cartridgeInfoBean.setAlias(null);
-        cartridgeInfoBean.setRepoURL(null);
-        cartridgeInfoBean.setPrivateRepo(false);
-        cartridgeInfoBean.setRepoUsername(null);
-        cartridgeInfoBean.setRepoPassword(null);
-        cartridgeInfoBean.setAutoscalePolicy(null);
-        cartridgeInfoBean.setDeploymentPolicy(null);
-        cartridgeInfoBean.setSize(size);
-        cartridgeInfoBean.setRemoveOnTermination(remoOnTermination);
-        cartridgeInfoBean.setPersistanceRequired(persistanceMapping);
-        cartridgeInfoBean.setCommitsEnabled(enableCommits);
-
         GsonBuilder gsonBuilder = new GsonBuilder();
         Gson gson = gsonBuilder.create();
 
-        String jsonSubscribeString = gson.toJson(cartridgeInfoBean, CartridgeInfoBean.class);
-
         try {
+            Cartridge cartridge = listCartridge(cartridgeType);
+            if (cartridge.isMultiTenant()) {
+                asPolicy = getAsPolicyFromServiceDefinition(cartridgeType);
+                depPolicy = getDeploymentPolicyFromServiceDefinition(cartridgeType);
+            }
+
             cartridgeInfoBean.setCartridgeType(cartridgeType);
             cartridgeInfoBean.setAlias(alias);
             cartridgeInfoBean.setRepoURL(externalRepoURL);
@@ -760,7 +927,7 @@ public class RestCommandLineService {
             cartridgeInfoBean.setPersistanceRequired(persistanceMapping);
             cartridgeInfoBean.setCommitsEnabled(enableCommits);
             
-            jsonSubscribeString = gson.toJson(cartridgeInfoBean, CartridgeInfoBean.class);
+            String jsonSubscribeString = gson.toJson(cartridgeInfoBean, CartridgeInfoBean.class);
 
             HttpResponse response = restClient.doPost(httpClient, restClient.getBaseURL() + subscribCartridgeRestEndpoint,
                     jsonSubscribeString);
@@ -1229,14 +1396,12 @@ public class RestCommandLineService {
             }
 
             String resultString = getHttpResponseString(response);
-
             if (resultString == null) {
                 System.out.println("Response content is empty");
                 return;
             }
 
             ServiceDefinitionList definitionList = gson.fromJson(resultString, ServiceDefinitionList.class);
-
             if (definitionList == null) {
                 System.out.println("Deploy service list is empty");
                 return;
@@ -1245,14 +1410,12 @@ public class RestCommandLineService {
             RowMapper<ServiceDefinitionBean> deployServiceMapper = new RowMapper<ServiceDefinitionBean>() {
 
                 public String[] getData(ServiceDefinitionBean definition) {
-                    String[] data = new String[7];
-                    data[0] = definition.getServiceName();
-                    data[1] = definition.getCartridgeType();
-                    data[2] = definition.getDeploymentPolicyName();
-                    data[3] = definition.getAutoscalingPolicyName();
-                    data[4] = definition.getClusterDomain();
-                    data[5] = definition.getClusterSubDomain();
-                    data[6] = definition.getTenantRange();
+                    String[] data = new String[5];
+                    data[0] = definition.getCartridgeType();
+                    data[1] = definition.getDeploymentPolicyName();
+                    data[2] = definition.getAutoscalingPolicyName();
+                    data[3] = definition.getClusterDomain();
+                    data[4] = definition.getTenantRange();
                     return data;
                 }
             };
@@ -1268,17 +1431,10 @@ public class RestCommandLineService {
                 return;
             }
 
-            List<String> headers = new ArrayList<String>();
-            headers.add("Service Name");
-            headers.add("Cartridge Type");
-            headers.add("Deployment Policy Name");
-            headers.add("Autoscaling Policy Name");
-            headers.add("Cluster Domain");
-            headers.add("Cluster Sub Domain");
-            headers.add("Tenant Range");
-
             System.out.println("Available Deploy Services :");
-            CommandLineUtils.printTable(definitionArry, deployServiceMapper, headers.toArray(new String[headers.size()]));
+            CommandLineUtils.printTable(definitionArry, deployServiceMapper, "Cartridge Type", "Deployment Policy Name",
+                    "Autoscaling Policy Name", "Cluster Domain", "Tenant Range");
+            System.out.println();
 
         } catch (Exception e) {
             handleException("Exception in listing deploy services", e);
@@ -1712,18 +1868,18 @@ public class RestCommandLineService {
 
     // This class convert JSON string to servicedefinitionbean object
     private class ServiceDefinitionList {
-        private ArrayList<ServiceDefinitionBean> serviceDefinition;
+        private ArrayList<ServiceDefinitionBean> serviceDefinitionBean;
 
         public ArrayList<ServiceDefinitionBean> getServiceDefinition() {
-            return serviceDefinition;
+            return serviceDefinitionBean;
         }
 
-        public void setServiceDefinition(ArrayList<ServiceDefinitionBean> serviceDefinition) {
-            this.serviceDefinition = serviceDefinition;
+        public void setServiceDefinition(ArrayList<ServiceDefinitionBean> serviceDefinitionBean) {
+            this.serviceDefinitionBean = serviceDefinitionBean;
         }
 
         ServiceDefinitionList() {
-            serviceDefinition = new ArrayList<ServiceDefinitionBean>();
+            serviceDefinitionBean = new ArrayList<ServiceDefinitionBean>();
         }
     }
 
@@ -1778,6 +1934,19 @@ public class RestCommandLineService {
         }
     }
 
+    private class ClusterList{
+        private ArrayList<Cluster> cluster;
+
+        public ArrayList<Cluster> getCluster() {
+            return cluster;
+        }
+
+        public void setCluster(ArrayList<Cluster> clusters) {
+            this.cluster = clusters;
+        }
+        ClusterList(){cluster = new ArrayList<Cluster>();};
+    }
+
     // This will return access url from a given cartridge
     private String getAccessURLs(Cartridge cartridge) {
     	PortMapping[] portMappings = cartridge.getPortMappings();
@@ -1898,4 +2067,53 @@ public class RestCommandLineService {
 		public CartridgeWrapper() {
 		}
 	}
+
+    public boolean isMultiTenant(String type) throws CommandException {
+        DefaultHttpClient httpClient = new DefaultHttpClient();
+        try {
+            HttpResponse response = restClient.doGet(httpClient, restClient.getBaseURL() + listAvailableCartridgesRestEndpoint);
+
+            String responseCode = "" + response.getStatusLine().getStatusCode();
+            String resultString = getHttpResponseString(response);
+            if (resultString == null) {
+                return false;
+            }
+
+            GsonBuilder gsonBuilder = new GsonBuilder();
+            Gson gson = gsonBuilder.create();
+
+            if (!responseCode.equals(CliConstants.RESPONSE_OK)) {
+                ExceptionMapper exception = gson.fromJson(resultString, ExceptionMapper.class);
+                System.out.println(exception);
+                return false;
+            }
+
+            CartridgeList cartridgeList = gson.fromJson(resultString, CartridgeList.class);
+
+            if (cartridgeList == null) {
+                System.out.println("Available cartridge list is null");
+                return false;
+            }
+
+            ArrayList<Cartridge> multiTenetCartridge = new ArrayList<Cartridge>();
+
+            for (Cartridge cartridge : cartridgeList.getCartridge()) {
+                if (cartridge.isMultiTenant() && cartridge.getCartridgeType().equals(type)) {
+                    multiTenetCartridge.add(cartridge);
+                }
+            }
+
+            if (multiTenetCartridge.size() > 0) {
+                return true;
+            } else {
+                return false;
+            }
+
+        } catch (Exception e) {
+            handleException("Exception in listing available cartridges", e);
+            return false;
+        } finally {
+            httpClient.getConnectionManager().shutdown();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/beans/cartridge/Cartridge.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/beans/cartridge/Cartridge.java b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/beans/cartridge/Cartridge.java
index 6331e03..a148a2d 100644
--- a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/beans/cartridge/Cartridge.java
+++ b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/beans/cartridge/Cartridge.java
@@ -49,6 +49,7 @@ public class Cartridge implements Comparable<Cartridge> {
 
     private String[] accessURLs;
     private PortMapping[] portMappings;
+    private String serviceGroup;
 
     public String getDisplayName() {
         return displayName;
@@ -244,4 +245,12 @@ public class Cartridge implements Comparable<Cartridge> {
     public void setLoadBalancer(boolean isLoadBalancer) {
         this.loadBalancer = isLoadBalancer;
     }
+
+    public String getServiceGroup() {
+        return serviceGroup;
+    }
+
+    public void setServiceGroup(String serviceGroup) {
+        this.serviceGroup = serviceGroup;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/commands/SubscribeCommand.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/commands/SubscribeCommand.java b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/commands/SubscribeCommand.java
index 6479a06..c068f65 100644
--- a/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/commands/SubscribeCommand.java
+++ b/components/org.apache.stratos.cli/src/main/java/org/apache/stratos/cli/commands/SubscribeCommand.java
@@ -26,6 +26,7 @@ import org.apache.commons.cli.Options;
 import org.apache.commons.cli.ParseException;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.stratos.cli.RestCommandLineService;
+import org.apache.stratos.cli.beans.cartridge.Cartridge;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.stratos.cli.Command;
@@ -33,28 +34,30 @@ import org.apache.stratos.cli.StratosCommandContext;
 import org.apache.stratos.cli.exception.CommandException;
 import org.apache.stratos.cli.utils.CliConstants;
 
+import java.util.ArrayList;
+
 public class SubscribeCommand implements Command<StratosCommandContext> {
 
-	private static final Logger logger = LoggerFactory.getLogger(ListSubscribedCartridgesCommand.class);
+    private static final Logger logger = LoggerFactory.getLogger(ListSubscribedCartridgesCommand.class);
 
-	private final Options options;
+    private final Options options;
 
-	public SubscribeCommand() {
-		options = constructOptions();
-	}
+    public SubscribeCommand() {
+        options = constructOptions();
+    }
 
-	/**
-	 * Construct Options.
-	 * 
-	 * @return Options expected from command-line.
-	 */
-	private Options constructOptions() {
-		final Options options = new Options();
-		//Option policyOption = new Option(CliConstants.POLICY_OPTION, CliConstants.POLICY_LONG_OPTION, true,
-		//		"Auto-scaling policy.\nPlease use \"" + CliConstants.POLICIES_ACTION
-		//				+ "\" command to view the available policies.");
-		//policyOption.setArgName("policy name");
-		//options.addOption(policyOption);
+    /**
+     * Construct Options.
+     *
+     * @return Options expected from command-line.
+     */
+    private Options constructOptions() {
+        final Options options = new Options();
+        //Option policyOption = new Option(CliConstants.POLICY_OPTION, CliConstants.POLICY_LONG_OPTION, true,
+        //		"Auto-scaling policy.\nPlease use \"" + CliConstants.POLICIES_ACTION
+        //				+ "\" command to view the available policies.");
+        //policyOption.setArgName("policy name");
+        //options.addOption(policyOption);
 
         Option autoscaling = new Option(CliConstants.AUTOSCALING_POLICY_OPTION, CliConstants.AUTOSCALING_POLICY_LONG_OPTION,
                 true, "Auto-scaling policy");
@@ -80,89 +83,86 @@ public class SubscribeCommand implements Command<StratosCommandContext> {
         persistance.setArgName("persistance-volume");
         options.addOption(persistance);
 
-		Option urlOption = new Option(CliConstants.REPO_URL_OPTION, CliConstants.REPO_URL_LONG_OPTION, true,
-				"GIT repository URL");
-		urlOption.setArgName("url");
-		options.addOption(urlOption);
-
-		//options.addOption(CliConstants.PRIVATE_REPO_OPTION, CliConstants.PRIVATE_REPO_LONG_OPTION, false,
-		//		"Private repository");
-
-		Option usernameOption = new Option(CliConstants.USERNAME_OPTION, CliConstants.USERNAME_LONG_OPTION, true,
-				"GIT repository username");
-		usernameOption.setArgName("username");
-		options.addOption(usernameOption);
-
-		Option passwordOption = new Option(CliConstants.PASSWORD_OPTION, CliConstants.PASSWORD_LONG_OPTION, true,
-				"GIT repository password");
-		passwordOption.setArgName("password");
-		passwordOption.setOptionalArg(true);
-		options.addOption(passwordOption);
-		
-		Option upstreamCommitsEnabledOption = new Option(CliConstants.ENABLE_COMMITS_OPTION, CliConstants.ENABLE_COMMITS_LONG_OPTION, true,
-		"Enable Git commit upstream");
-		upstreamCommitsEnabledOption.setArgName("enable-commits");
-		upstreamCommitsEnabledOption.setOptionalArg(true);
-		options.addOption(upstreamCommitsEnabledOption);
+        Option urlOption = new Option(CliConstants.REPO_URL_OPTION, CliConstants.REPO_URL_LONG_OPTION, true,
+                "GIT repository URL");
+        urlOption.setArgName("url");
+        options.addOption(urlOption);
+
+        //options.addOption(CliConstants.PRIVATE_REPO_OPTION, CliConstants.PRIVATE_REPO_LONG_OPTION, false,
+        //		"Private repository");
+
+        Option usernameOption = new Option(CliConstants.USERNAME_OPTION, CliConstants.USERNAME_LONG_OPTION, true,
+                "GIT repository username");
+        usernameOption.setArgName("username");
+        options.addOption(usernameOption);
+
+        Option passwordOption = new Option(CliConstants.PASSWORD_OPTION, CliConstants.PASSWORD_LONG_OPTION, true,
+                "GIT repository password");
+        passwordOption.setArgName("password");
+        passwordOption.setOptionalArg(true);
+        options.addOption(passwordOption);
+
+        Option upstreamCommitsEnabledOption = new Option(CliConstants.ENABLE_COMMITS_OPTION, CliConstants.ENABLE_COMMITS_LONG_OPTION, true,
+                "Enable Git commit upstream");
+        upstreamCommitsEnabledOption.setArgName("enable-commits");
+        upstreamCommitsEnabledOption.setOptionalArg(true);
+        options.addOption(upstreamCommitsEnabledOption);
 
         return options;
-	}
-
-	public String getName() {
-		return CliConstants.SUBSCRIBE_ACTION;
-	}
-
-	public String getDescription() {
-		return "Subscribe to a cartridge";
-	}
-
-	public String getArgumentSyntax() {
-		return "[Cartridge type] [Cartridge alias]";
-	}
-
-	public int execute(StratosCommandContext context, String[] args) throws CommandException {
-		if (logger.isDebugEnabled()) {
-			logger.debug("Executing {} command...", getName());
-		}
-		if (args != null && args.length > 0) {
-			String[] remainingArgs = null;
-			String type = null;
-			String alias = null;
-			String policy = null;
+    }
+
+    public String getName() {
+        return CliConstants.SUBSCRIBE_ACTION;
+    }
+
+    public String getDescription() {
+        return "Subscribe to a cartridge";
+    }
+
+    public String getArgumentSyntax() {
+        return "[Cartridge type] [Cartridge alias]";
+    }
+
+    public int execute(StratosCommandContext context, String[] args) throws CommandException {
+        if (logger.isDebugEnabled()) {
+            logger.debug("Executing {} command...", getName());
+        }
+        if (args != null && args.length > 0) {
+            String[] remainingArgs = null;
+            String type = null;
+            String alias = null;
+            String policy = null;
             String asPolicy = null;
             String depPolicy = null;
-			String repoURL = null, username = "", password = "";
+            String repoURL = null, username = "", password = "";
             String size = null;
 
             boolean removeOnTermination = false;
-			boolean privateRepo = false;
+            boolean privateRepo = false;
             boolean persistanceMapping = false;
             boolean commitsEnabled = false;
+            boolean isMultiTenant = false;
+
+            final CommandLineParser parser = new GnuParser();
+            CommandLine commandLine;
+            try {
+                commandLine = parser.parse(options, args);
+                remainingArgs = commandLine.getArgs();
+                if (remainingArgs != null && remainingArgs.length == 2) {
+                    // Get type
+                    type = remainingArgs[0];
+                    alias = remainingArgs[1];
+                } else {
+                    context.getStratosApplication().printUsage(getName());
+                    return CliConstants.BAD_ARGS_CODE;
+                }
 
-			final CommandLineParser parser = new GnuParser();
-			CommandLine commandLine;
-			try {
-				commandLine = parser.parse(options, args);
-				remainingArgs = commandLine.getArgs();
-				if (remainingArgs != null && remainingArgs.length == 2) {
-					// Get type
-					type = remainingArgs[0];
-					alias = remainingArgs[1];
-				} else {
-					context.getStratosApplication().printUsage(getName());
-					return CliConstants.BAD_ARGS_CODE;
-				}
-
-				if (logger.isDebugEnabled()) {
-					logger.debug("Subscribing to {} cartridge with alias {}", type, alias);
-				}
-
-				//if (commandLine.hasOption(CliConstants.POLICY_OPTION)) {
-				//	if (logger.isTraceEnabled()) {
-				//		logger.trace("Policy option is passed");
-				//	}
-				//	policy = commandLine.getOptionValue(CliConstants.POLICY_OPTION);
-				//}
+                // This will check the subscribe cartridge type is multi tenant or single tenant
+                isMultiTenant = RestCommandLineService.getInstance().isMultiTenant(type);
+
+                if (logger.isDebugEnabled()) {
+                    logger.debug("Subscribing to {} cartridge with alias {}", type, alias);
+                }
                 if (commandLine.hasOption(CliConstants.AUTOSCALING_POLICY_OPTION)) {
                     if (logger.isTraceEnabled()) {
                         logger.trace("Autoscaling policy option is passed");
@@ -175,18 +175,12 @@ public class SubscribeCommand implements Command<StratosCommandContext> {
                     }
                     depPolicy = commandLine.getOptionValue(CliConstants.DEPLOYMENT_POLICY_OPTION);
                 }
-				if (commandLine.hasOption(CliConstants.REPO_URL_OPTION)) {
-					if (logger.isTraceEnabled()) {
-						logger.trace("RepoURL option is passed");
-					}
-					repoURL = commandLine.getOptionValue(CliConstants.REPO_URL_OPTION);
-				}
-				//if (commandLine.hasOption(CliConstants.PRIVATE_REPO_OPTION)) {
-				//	if (logger.isTraceEnabled()) {
-				//		logger.trace("privateRepo option is passed");
-				//	}
-				//	privateRepo = true;
-				//}
+                if (commandLine.hasOption(CliConstants.REPO_URL_OPTION)) {
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("RepoURL option is passed");
+                    }
+                    repoURL = commandLine.getOptionValue(CliConstants.REPO_URL_OPTION);
+                }
                 if (commandLine.hasOption(CliConstants.VOLUME_SIZE_OPTION)) {
                     if (logger.isTraceEnabled()) {
                         logger.trace("Volume size option is passed");
@@ -199,77 +193,124 @@ public class SubscribeCommand implements Command<StratosCommandContext> {
                         logger.trace("Remove on termination option is passed");
 
                     }
-                    removeOnTermination = true;
+
+                    String optionValue = commandLine.getOptionValue(CliConstants.REMOVE_ON_TERMINATION_OPTION);
+                    if (optionValue.equals("true")) {
+                        removeOnTermination = true;
+                    } else if (optionValue.equals("false")) {
+                        removeOnTermination = false;
+                    } else {
+                        if (logger.isTraceEnabled()) {
+                            logger.trace("Invalid remove on termination option value");
+                        }
+                        System.out.println("Invalid remove on termination option value.");
+                        context.getStratosApplication().printUsage(getName());
+                        return CliConstants.BAD_ARGS_CODE;
+                    }
                 }
                 if (commandLine.hasOption(CliConstants.PERSISTANCE_VOLUME_OPTION)) {
                     if (logger.isTraceEnabled()) {
                         logger.trace("Persistance volume option is passed");
 
                     }
-                    persistanceMapping = true;
+                    String optionValue = commandLine.getOptionValue(CliConstants.PERSISTANCE_VOLUME_OPTION);
+                    if (optionValue.equals("true")) {
+                        persistanceMapping = true;
+                    } else if (optionValue.equals("false")) {
+                        persistanceMapping = false;
+                    } else {
+                        if (logger.isTraceEnabled()) {
+                            logger.trace("Invalid persistance mapping option value");
+                        }
+                        System.out.println("Invalid persistance mapping option value.");
+                        context.getStratosApplication().printUsage(getName());
+                        return CliConstants.BAD_ARGS_CODE;
+                    }
+                }
+                if (commandLine.hasOption(CliConstants.USERNAME_OPTION)) {
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("Username option is passed");
+                    }
+                    username = commandLine.getOptionValue(CliConstants.USERNAME_OPTION);
                 }
-				if (commandLine.hasOption(CliConstants.USERNAME_OPTION)) {
-					if (logger.isTraceEnabled()) {
-						logger.trace("Username option is passed");
-					}
-					username = commandLine.getOptionValue(CliConstants.USERNAME_OPTION);
-				}
-				if (commandLine.hasOption(CliConstants.PASSWORD_OPTION)) {
-					if (logger.isTraceEnabled()) {
-						logger.trace("Password option is passed");
-					}
-					password = commandLine.getOptionValue(CliConstants.PASSWORD_OPTION);
-				}
-				if (commandLine.hasOption(CliConstants.ENABLE_COMMITS_OPTION)) {
-					if (logger.isTraceEnabled()) {
-						logger.trace("Upstream git commits are enabled");
-					}
-					commitsEnabled = true;
-				}
-
-                if (depPolicy == null) {
+                if (commandLine.hasOption(CliConstants.PASSWORD_OPTION)) {
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("Password option is passed");
+                    }
+                    password = commandLine.getOptionValue(CliConstants.PASSWORD_OPTION);
+                }
+                if (commandLine.hasOption(CliConstants.ENABLE_COMMITS_OPTION)) {
+                    if (logger.isTraceEnabled()) {
+                        logger.trace("Upstream git commits are enabled");
+                    }
+                    commitsEnabled = true;
+                }
+
+                if ( ! isMultiTenant && depPolicy == null) {
                     System.out.println("Deployment policy is required.");
                     context.getStratosApplication().printUsage(getName());
                     return CliConstants.BAD_ARGS_CODE;
                 }
 
-                if (asPolicy == null) {
+                if ( ! isMultiTenant && asPolicy == null) {
                     System.out.println("Autoscaling policy is required.");
                     context.getStratosApplication().printUsage(getName());
                     return CliConstants.BAD_ARGS_CODE;
                 }
 
-                if ( (! persistanceMapping) && ((size != null) || removeOnTermination)) {
+                if ((!persistanceMapping) && ((size != null) || removeOnTermination)) {
                     System.out.println("You have to enable persistance mapping in cartridge subscription");
                     context.getStratosApplication().printUsage(getName());
                     return CliConstants.BAD_ARGS_CODE;
                 }
-				
-				if (StringUtils.isNotBlank(username) && StringUtils.isBlank(password)) {
-					password = context.getApplication().getInput("GIT Repository Password", '*');
-				}
-
-                RestCommandLineService.getInstance().subscribe(type, alias, repoURL, privateRepo, username,
-                		password, asPolicy, depPolicy, size, removeOnTermination,
-                        persistanceMapping, commitsEnabled);
-
-				return CliConstants.SUCCESSFUL_CODE;
-
-			} catch (ParseException e) {
-				if (logger.isErrorEnabled()) {
-					logger.error("Error parsing arguments", e);
-				}
-				System.out.println(e.getMessage());
-				return CliConstants.BAD_ARGS_CODE;
-			}
-		} else {
-			context.getStratosApplication().printUsage(getName());
-			return CliConstants.BAD_ARGS_CODE;
-		}
-	}
-
-	public Options getOptions() {
-		return options;
-	}
+
+                if (StringUtils.isNotBlank(username) && StringUtils.isBlank(password)) {
+                    password = context.getApplication().getInput("GIT Repository Password", '*');
+                }
+
+                Cartridge cartridge = RestCommandLineService.getInstance().listCartridge(type);
+                if(cartridge == null){
+                    System.out.println("No cartridge found with the type " + type);
+                    return CliConstants.BAD_ARGS_CODE;
+                }
+
+                String serviceGroup = cartridge.getServiceGroup();
+
+                if (serviceGroup == null) {
+                    RestCommandLineService.getInstance().subscribe(type, alias, repoURL, privateRepo, username,
+                            password, asPolicy, depPolicy, size, removeOnTermination,
+                            persistanceMapping, commitsEnabled);
+                } else {
+                    ArrayList<Cartridge> cartridgesInSeriviceGroup = RestCommandLineService.getInstance().listCartridges(serviceGroup);
+                    Cartridge cart = null;
+                    int aliasCount = 1;
+                    for (int i = 0; i < cartridgesInSeriviceGroup.size(); i++, aliasCount++) {
+
+                        cart = cartridgesInSeriviceGroup.get(i);
+                        System.out.println("Subscribing to " + cart.getCartridgeType());
+                        RestCommandLineService.getInstance().subscribe(cart.getCartridgeType(), alias + aliasCount, repoURL, privateRepo, username,
+                                password, asPolicy, depPolicy, size, removeOnTermination,
+                                persistanceMapping, commitsEnabled);
+                    }
+                }
+
+                return CliConstants.SUCCESSFUL_CODE;
+
+            } catch (ParseException e) {
+                if (logger.isErrorEnabled()) {
+                    logger.error("Error parsing arguments", e);
+                }
+                System.out.println(e.getMessage());
+                return CliConstants.BAD_ARGS_CODE;
+            }
+        } else {
+            context.getStratosApplication().printUsage(getName());
+            return CliConstants.BAD_ARGS_CODE;
+        }
+    }
+
+    public Options getOptions() {
+        return options;
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
index 2ae5274..d0c2276 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/concurrent/PartitionValidatorCallable.java
@@ -44,6 +44,10 @@ public class PartitionValidatorCallable implements Callable<IaasProvider> {
 
 	@Override
 	public IaasProvider call() throws Exception {
+		
+		if (log.isDebugEnabled()) {
+			log.debug("Partition validation started for "+partition+" of "+cartridge);
+		}
 		String provider = partition.getProvider();
         IaasProvider iaasProvider = cartridge.getIaasProvider(provider);
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
index 56cc2b0..38a4234 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/impl/CloudControllerServiceImpl.java
@@ -271,11 +271,20 @@ public class CloudControllerServiceImpl implements CloudControllerService {
 
         IaasProvider iaasProvider = cartridge.getIaasProviderOfPartition(partitionId);
         if (iaasProvider == null) {
-            String msg =
-                         "Instance start-up failed. " + "There's no IaaS provided for the partition: " + partitionId +
-                         " and for the Cartridge type: " + cartridgeType+". Only following "
-                  		+ "partitions can be found in this Cartridge: "
-                  		+cartridge.getPartitionToIaasProvider().keySet().toString()+ memberContext.toString() + ". ";
+        	if (log.isDebugEnabled()) {
+        		log.debug("IaasToPartitionMap "+cartridge.hashCode()
+        				+ " for cartridge "+cartridgeType+ " and for partition: "+partitionId);
+        	}
+			String msg = "Instance start-up failed. "
+					+ "There's no IaaS provided for the partition: "
+					+ partitionId
+					+ " and for the Cartridge type: "
+					+ cartridgeType
+					+ ". Only following "
+					+ "partitions can be found in this Cartridge: "
+					+ cartridge.getPartitionToIaasProvider().keySet()
+							.toString() + ". " + memberContext.toString()
+					+ ". ";
             log.fatal(msg);
             throw new InvalidIaasProviderException(msg);
         }
@@ -290,6 +299,14 @@ public class CloudControllerServiceImpl implements CloudControllerService {
             addToPayload(payload, "LB_CLUSTER_ID", memberContext.getLbClusterId());
             addToPayload(payload, "NETWORK_PARTITION_ID", memberContext.getNetworkPartitionId());
             addToPayload(payload, "PARTITION_ID", partitionId);
+            if(memberContext.getProperties() != null) {
+            	org.apache.stratos.cloud.controller.pojo.Properties props1 = memberContext.getProperties();
+                if (props1 != null) {
+                    for (Property prop : props1.getProperties()) {
+                        addToPayload(payload, prop.getName(), prop.getValue());
+                    }
+                }
+            }
 
             Iaas iaas = iaasProvider.getIaas();
             if(ctxt.isVolumeRequired()){
@@ -351,6 +368,11 @@ public class CloudControllerServiceImpl implements CloudControllerService {
             }
             
             NodeMetadata node;
+            
+			if (log.isDebugEnabled()) {
+				log.debug("Cloud Controller is delegating request to start an instance for "
+						+ memberContext + " to Jclouds layer.");
+			}
 
 //            create and start a node
             Set<? extends NodeMetadata> nodes =
@@ -358,9 +380,19 @@ public class CloudControllerServiceImpl implements CloudControllerService {
                                                                                   template);
 
             node = nodes.iterator().next();
+            
+            if (log.isDebugEnabled()) {
+				log.debug("Cloud Controller received a response for the request to start "
+						+ memberContext + " from Jclouds layer.");
+			}
+            
+            
             //Start allocating ip as a new job
 
             ThreadExecutor exec = ThreadExecutor.getInstance();
+            if (log.isDebugEnabled()) {
+				log.debug("Cloud Controller is starting the IP Allocator thread.");
+			}
             exec.execute(new IpAllocator(memberContext, iaasProvider, cartridgeType, node));
 
 
@@ -371,11 +403,12 @@ public class CloudControllerServiceImpl implements CloudControllerService {
                 log.fatal(msg);
                 throw new IllegalStateException(msg);
             }
-                memberContext.setNodeId(nodeId);
-                if(log.isDebugEnabled()) {
-                    log.debug("Node id was set. "+memberContext.toString());
-                }
-                
+            
+			memberContext.setNodeId(nodeId);
+			if (log.isDebugEnabled()) {
+				log.debug("Node id was set. " + memberContext.toString());
+			}
+
                 // attach volumes
 			if (ctxt.isVolumeRequired()) {
 				// remove region prefix
@@ -581,7 +614,9 @@ public class CloudControllerServiceImpl implements CloudControllerService {
             String publicIp = null;
 
             try{
-
+            	if (log.isDebugEnabled()) {
+    				log.debug("IP allocation process started for "+memberContext);
+    			}
                 String autoAssignIpProp =
                                           iaasProvider.getProperty(CloudControllerConstants.AUTO_ASSIGN_IP_PROPERTY);
                 
@@ -669,11 +704,12 @@ public class CloudControllerServiceImpl implements CloudControllerService {
                     // persist in registry
                     persist();
 
-                    String memberID = memberContext.getMemberId();
 
                     // trigger topology
-                    TopologyBuilder.handleMemberSpawned(memberID, cartridgeType, clusterId, memberContext.getNetworkPartitionId(),
-                            partition.getId(), ip, memberContext.getLbClusterId(),publicIp);
+                    TopologyBuilder.handleMemberSpawned(cartridgeType, clusterId, 
+                    		partition.getId(), ip, publicIp, memberContext);
+                    
+                    String memberID = memberContext.getMemberId();
 
                     // update the topology with the newly spawned member
                     // publish data
@@ -685,14 +721,18 @@ public class CloudControllerServiceImpl implements CloudControllerService {
                                                         MemberStatus.Created.toString(),
                                                         node);
                     if (log.isDebugEnabled()) {
-                        log.debug("Node details: \n" + node.toString());
+                        log.debug("Node details: " + node.toString());
                     }
+                    
+                    if (log.isDebugEnabled()) {
+        				log.debug("IP allocation process ended for "+memberContext);
+        			}
 
             } catch (Exception e) {
                 String msg = "Error occurred while allocating an ip address. " + memberContext.toString();
                 log.error(msg, e);
                 throw new CloudControllerException(msg, e);
-            }
+            } 
 
 
         }
@@ -946,6 +986,7 @@ public class CloudControllerServiceImpl implements CloudControllerService {
     @Override
 	public void unregisterService(String clusterId) throws UnregisteredClusterException {
         final String clusterId_ = clusterId;
+        TopologyBuilder.handleClusterMaintenanceMode(dataHolder.getClusterContext(clusterId_));
 
         Runnable terminateInTimeout = new Runnable() {
             @Override
@@ -1048,6 +1089,10 @@ public class CloudControllerServiceImpl implements CloudControllerService {
 
         Map<String, IaasProvider> partitionToIaasProviders =
                                                              new ConcurrentHashMap<String, IaasProvider>();
+        
+        if (log.isDebugEnabled()) {
+			log.debug("Deployment policy validation started for cartridge type: "+cartridgeType);
+		}
 
         Cartridge cartridge = dataHolder.getCartridge(cartridgeType);
 
@@ -1073,6 +1118,9 @@ public class CloudControllerServiceImpl implements CloudControllerService {
             try {
             	// add to a temporary Map
             	partitionToIaasProviders.put(partitionId, job.get());
+				if (log.isDebugEnabled()) {
+					log.debug("Partition "+partitionId+" added to the map.");
+				}
             } catch (Exception e) {
                 log.error(e.getMessage(), e);
                 throw new InvalidPartitionException(e.getMessage(), e);

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Cartridge.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Cartridge.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Cartridge.java
index 46424e7..dafaa2c 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Cartridge.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/Cartridge.java
@@ -19,6 +19,8 @@
 package org.apache.stratos.cloud.controller.pojo;
 
 import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import java.io.Serializable;
 import java.util.*;
@@ -29,6 +31,7 @@ import java.util.concurrent.ConcurrentHashMap;
  */
 public class Cartridge implements Serializable{
 
+	private transient static final Log log = LogFactory.getLog(Cartridge.class);
     private static final long serialVersionUID = 6637409027085059072L;
 
 	private String type;
@@ -53,25 +56,25 @@ public class Cartridge implements Serializable{
     
     private LoadbalancerConfig lbConfig;
     
-    private List<PortMapping> portMappings = new ArrayList<PortMapping>();
+    private List<PortMapping> portMappings;
     
     private Persistence persistence;
     
-    private List<AppType> appTypeMappings = new ArrayList<AppType>();
+    private List<AppType> appTypeMappings;
     
     private String serviceGroup;
     
     /**
      * Property map of this Cartridge.
      */
-    private Map<String, String> properties = new HashMap<String, String>();
+    private Map<String, String> properties;
     
     /**
      * A Cartridge can have 1..n {@link IaasProvider}s
      */
-    private List<IaasProvider> iaases = new ArrayList<IaasProvider>();
+    private List<IaasProvider> iaases;
     
-    private List<String> deploymentDirs = new ArrayList<String>();
+    private List<String> deploymentDirs;
     
     private IaasProvider lastlyUsedIaas;
     
@@ -79,9 +82,11 @@ public class Cartridge implements Serializable{
      * Key - partition id
      * Value - Corresponding IaasProvider.
      */
-    private Map<String, IaasProvider> partitionToIaasProvider = new ConcurrentHashMap<String, IaasProvider>();
+    private Map<String, IaasProvider> partitionToIaasProvider;
     
-    public Cartridge(){}
+    public Cartridge(){
+    	init();
+    }
     
     public Cartridge(String type, String host, String provider, String version, boolean multiTenant) {
         this.type = type;
@@ -89,6 +94,17 @@ public class Cartridge implements Serializable{
         this.provider = provider;
         this.version = version;
         this.multiTenant = multiTenant;
+        init();
+    }
+    
+    private void init() {
+    	partitionToIaasProvider = new ConcurrentHashMap<String, IaasProvider>();
+    	portMappings = new ArrayList<PortMapping>();
+    	portMappings = new ArrayList<PortMapping>();
+    	appTypeMappings = new ArrayList<AppType>();
+    	properties = new HashMap<String, String>();
+    	iaases = new ArrayList<IaasProvider>();
+    	deploymentDirs = new ArrayList<String>();
     }
 
     public String getType() {
@@ -109,10 +125,18 @@ public class Cartridge implements Serializable{
             IaasProvider value = map.get(key);
             
             partitionToIaasProvider.put(key, value);
+            if(log.isDebugEnabled()) {
+            	log.debug("Partition map updated for the Cartridge: "+this.hashCode()+". "
+            			+ "Current Partition List: "+partitionToIaasProvider.keySet().toString());
+            }
         }
     }
     
     public IaasProvider getIaasProviderOfPartition(String partitionId) {
+    	if(log.isDebugEnabled()) {
+        	log.debug("Retrieving partition: "+partitionId+" for the Cartridge: "+this.hashCode()+". "
+        			+ "Current Partition List: "+partitionToIaasProvider.keySet().toString());
+        }
         return partitionToIaasProvider.get(partitionId);
     }
     
@@ -160,7 +184,19 @@ public class Cartridge implements Serializable{
         return iaases;
     }
 
-    public void setIaases(List<IaasProvider> iaases) {
+    @Override
+	public String toString() {
+		return "Cartridge [type=" + type + ", hostName=" + hostName
+				+ ", provider=" + provider + ", version=" + version
+				+ ", multiTenant=" + multiTenant
+				+ ", defaultAutoscalingPolicy=" + defaultAutoscalingPolicy
+				+ ", defaultDeploymentPolicy=" + defaultDeploymentPolicy
+				+ ", serviceGroup=" + serviceGroup + ", properties="
+				+ properties + ", partitionToIaasProvider="
+				+ partitionToIaasProvider + "]";
+	}
+
+	public void setIaases(List<IaasProvider> iaases) {
         this.iaases = iaases;
     }
     

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/CartridgeInfo.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/CartridgeInfo.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/CartridgeInfo.java
index d2d3603..0064b2e 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/CartridgeInfo.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/CartridgeInfo.java
@@ -58,6 +58,8 @@ public class CartridgeInfo {
 
     private Persistence persistence;
 
+    private String serviceGroup;
+
     public CartridgeInfo(){
     	
     }
@@ -206,4 +208,12 @@ public class CartridgeInfo {
     public void setPersistence(Persistence persistence) {
         this.persistence = persistence;
     }
+
+    public String getServiceGroup() {
+        return serviceGroup;
+    }
+
+    public void setServiceGroup(String serviceGroup) {
+        this.serviceGroup = serviceGroup;
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/7b35e29e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/MemberContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/MemberContext.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/MemberContext.java
index 2618bb2..e3d67f1 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/MemberContext.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/MemberContext.java
@@ -54,6 +54,8 @@ public class MemberContext implements Serializable{
     private String lbClusterId;
     //network partition id
     private String networkPartitionId;
+
+    private Properties properties;
     
     public MemberContext(String id, String clusterId, Partition partition) {
         this.memberId = id;
@@ -200,4 +202,12 @@ public class MemberContext implements Serializable{
 	public void setInstanceId(String instanceId) {
 		this.instanceId = instanceId;
 	}
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(Properties properties) {
+        this.properties = properties;
+    }
 }