You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by is...@apache.org on 2014/10/08 17:39:27 UTC

git commit: refactoring Group and Application to a common super type 'ParentComponent'

Repository: stratos
Updated Branches:
  refs/heads/4.0.0-grouping 1e7c6006f -> d100cd0ee


refactoring Group and Application to a common super type 'ParentComponent'


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

Branch: refs/heads/4.0.0-grouping
Commit: d100cd0ee6ff6cdbd8f8a1eb44d0fee3deef3051
Parents: 1e7c600
Author: Isuru Haththotuwa <is...@apache.org>
Authored: Wed Oct 8 21:05:13 2014 +0530
Committer: Isuru Haththotuwa <is...@apache.org>
Committed: Wed Oct 8 21:05:13 2014 +0530

----------------------------------------------------------------------
 .../grouping/dependency/DependencyBuilder.java  |  14 +-
 .../context/ApplicationContextFactory.java      |   4 +-
 .../AutoscalerTopologyEventReceiver.java        |  12 +-
 .../stratos/autoscaler/monitor/Monitor.java     |  11 +-
 .../monitor/application/ApplicationMonitor.java |   2 +-
 .../status/checker/StatusChecker.java           |   2 +-
 .../controller/topology/TopologyBuilder.java    |  10 +-
 .../StratosManagerTopologyEventReceiver.java    |   6 +-
 .../messaging/domain/topology/Application.java  | 143 ++----------
 .../messaging/domain/topology/Group.java        | 114 +---------
 .../domain/topology/ParentBehavior.java         | 116 ----------
 .../domain/topology/ParentComponent.java        | 222 +++++++++++++++++++
 .../messaging/domain/topology/Topology.java     |   4 +-
 .../event/topology/ApplicationCreatedEvent.java |   2 +-
 .../ApplicationCreatedMessageProcessor.java     |   8 +-
 .../CompleteTopologyMessageProcessor.java       |   2 +-
 16 files changed, 281 insertions(+), 391 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java
index 59b9bf8..a4f9b54 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/DependencyBuilder.java
@@ -53,20 +53,16 @@ public class DependencyBuilder {
      * @param component it will give the necessary information to build the tree
      * @return the dependency tree out of the dependency orders
      */
-    public DependencyTree buildDependency(ParentBehavior component) {
-        String alias = null;
-        if(component instanceof Application) {
-            alias = ((Application)component).getId();
-        } else if(component instanceof Group) {
-            alias = ((Group) component).getAlias();
-        }
-        DependencyTree dependencyTree = new DependencyTree(alias);
+    public DependencyTree buildDependency(ParentComponent component) {
+
+        String identifier = component.getUniqueIdentifier();
+        DependencyTree dependencyTree = new DependencyTree(identifier);
         DependencyOrder dependencyOrder = component.getDependencyOrder();
 
         if (dependencyOrder != null) {
             if (log.isDebugEnabled()) {
                 log.debug("Building dependency for the Application/Group " +
-                        alias);
+                        identifier);
             }
 
             //Parsing the kill behaviour

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/context/ApplicationContextFactory.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/context/ApplicationContextFactory.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/context/ApplicationContextFactory.java
index 737a27d..dfd8fa9 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/context/ApplicationContextFactory.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/dependency/context/ApplicationContextFactory.java
@@ -19,7 +19,7 @@
 package org.apache.stratos.autoscaler.grouping.dependency.context;
 
 import org.apache.stratos.autoscaler.grouping.dependency.DependencyTree;
-import org.apache.stratos.messaging.domain.topology.ParentBehavior;
+import org.apache.stratos.messaging.domain.topology.ParentComponent;
 
 /**
  * Factory to create new GroupContext or ClusterContext
@@ -27,7 +27,7 @@ import org.apache.stratos.messaging.domain.topology.ParentBehavior;
 public class ApplicationContextFactory {
 
     public static ApplicationContext getApplicationContext(String startOrder,
-                                                           ParentBehavior component,
+                                                           ParentComponent component,
                                                            DependencyTree dependencyTree) {
         String id;
         ApplicationContext applicationContext = null;

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/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 4064510..d4616b2 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
@@ -120,7 +120,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
 
                 //acquire read lock
                 //TopologyManager.acquireReadLock();
-                TopologyManager.acquireReadLockForApplication(applicationCreatedEvent.getApplication().getId());
+                TopologyManager.acquireReadLockForApplication(applicationCreatedEvent.getApplication().getUniqueIdentifier());
 
                 try {
                     //start the application monitor
@@ -129,7 +129,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
 
                 } finally {
                     //release read lock
-                    TopologyManager.releaseReadLockForApplication(applicationCreatedEvent.getApplication().getId());
+                    TopologyManager.releaseReadLockForApplication(applicationCreatedEvent.getApplication().getUniqueIdentifier());
                     //TopologyManager.releaseReadLock();
                 }
 
@@ -582,7 +582,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
     protected synchronized void startApplicationMonitor(Application application) {
         Thread th = null;
         if (!AutoscalerContext.getInstance()
-                .appMonitorExist(application.getId())) {
+                .appMonitorExist(application.getUniqueIdentifier())) {
             th = new Thread(
                     new ApplicationMonitorAdder(application));
         }
@@ -596,7 +596,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
             if (log.isDebugEnabled()) {
                 log.debug(String
                         .format("Application monitor thread has been started successfully: " +
-                                        "[application] %s ", application.getId()));
+                                        "[application] %s ", application.getUniqueIdentifier()));
             }
         }
     }
@@ -621,7 +621,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
                     long start = System.currentTimeMillis();
                     if(log.isDebugEnabled()) {
                         log.debug("application monitor is going to be started for [application] " +
-                                application.getId());
+                                application.getUniqueIdentifier());
                     }
                     applicationMonitor = AutoscalerUtil.getApplicationMonitor(application);
                     long end = System.currentTimeMillis();
@@ -637,7 +637,7 @@ public class AutoscalerTopologyEventReceiver implements Runnable {
 
             if (applicationMonitor == null) {
                 String msg = "Application monitor creation failed, even after retrying for 5 times, "
-                        + "for Application: " + application.getId();
+                        + "for Application: " + application.getUniqueIdentifier();
                 log.error(msg);
                 throw new RuntimeException(msg);
             }

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java
index 0554406..5728583 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/Monitor.java
@@ -34,7 +34,6 @@ import org.apache.stratos.autoscaler.monitor.events.MonitorStatusEvent;
 import org.apache.stratos.autoscaler.monitor.group.GroupMonitor;
 import org.apache.stratos.autoscaler.util.AutoscalerUtil;
 import org.apache.stratos.messaging.domain.topology.*;
-import org.apache.stratos.messaging.event.application.status.StatusEvent;
 import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
 
 import java.util.*;
@@ -58,11 +57,11 @@ public abstract class Monitor implements EventHandler {
     //The monitors dependency tree with all the startable/killable dependencies
     protected DependencyTree dependencyTree;
     //application/group reference from the Topology
-    protected ParentBehavior component;
+    protected ParentComponent component;
     //status of the monitor whether it is running/in_maintainable/terminated
     protected Status status;
 
-    public Monitor(ParentBehavior component) {
+    public Monitor(ParentComponent component) {
         aliasToGroupMonitorsMap = new HashMap<String, GroupMonitor>();
         clusterIdToClusterMonitorsMap = new HashMap<String, AbstractClusterMonitor>();
         //preOrderTraverse = new LinkedList<String>();
@@ -165,7 +164,7 @@ public abstract class Monitor implements EventHandler {
         }
     }
 
-    protected synchronized void startGroupMonitor(Monitor parent, String dependency, ParentBehavior component) {
+    protected synchronized void startGroupMonitor(Monitor parent, String dependency, ParentComponent component) {
         ScheduledExecutorService adder = Executors.newSingleThreadScheduledExecutor();
 
         if (!this.aliasToGroupMonitorsMap.containsKey(dependency)) {
@@ -294,9 +293,9 @@ public abstract class Monitor implements EventHandler {
     private class GroupMonitorAdder implements Runnable {
         private String dependency;
         private Monitor parent;
-        private ParentBehavior component;
+        private ParentComponent component;
 
-        public GroupMonitorAdder(Monitor parent, String dependency, ParentBehavior group) {
+        public GroupMonitorAdder(Monitor parent, String dependency, ParentComponent group) {
             this.dependency = dependency;
             this.parent = parent;
             this.component = group;

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java
index a0f0a39..13967d2 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/monitor/application/ApplicationMonitor.java
@@ -40,7 +40,7 @@ public class ApplicationMonitor extends Monitor {
 
     public ApplicationMonitor(Application application) {
         super(application);
-        this.id = application.getId();
+        this.id = application.getUniqueIdentifier();
         startDependency();
     }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/status/checker/StatusChecker.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/status/checker/StatusChecker.java b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/status/checker/StatusChecker.java
index 7f17955..bb9c016 100644
--- a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/status/checker/StatusChecker.java
+++ b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/status/checker/StatusChecker.java
@@ -157,7 +157,7 @@ public class StatusChecker {
     }
 
     private boolean updateChildStatus(String appId, String id, Map<String, Group> groups,
-                                      Map<String, ClusterDataHolder> clusterData, ParentBehavior parent) {
+                                      Map<String, ClusterDataHolder> clusterData, ParentComponent parent) {
         boolean groupActive = false;
         boolean clustersActive;
         boolean groupsActive;

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/topology/TopologyBuilder.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/topology/TopologyBuilder.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/topology/TopologyBuilder.java
index 4aa7023..0913c00 100644
--- a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/topology/TopologyBuilder.java
+++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/topology/TopologyBuilder.java
@@ -617,15 +617,15 @@ public class TopologyBuilder {
         try {
             TopologyManager.acquireWriteLock();
 
-            if (topology.applicationExists(application.getId())) {
-                log.warn("Application with id [ " + application.getId() + " ] already exists in Topology");
+            if (topology.applicationExists(application.getUniqueIdentifier())) {
+                log.warn("Application with id [ " + application.getUniqueIdentifier() + " ] already exists in Topology");
                 return;
             }
             List<Cluster> clusters = new ArrayList<Cluster>();
             for (ApplicationClusterContext applicationClusterContext : applicationClusterContexts) {
                 Cluster cluster = new Cluster(applicationClusterContext.getCartridgeType(),
                         applicationClusterContext.getClusterId(), applicationClusterContext.getDeploymentPolicyName(),
-                        applicationClusterContext.getAutoscalePolicyName(), application.getId());
+                        applicationClusterContext.getAutoscalePolicyName(), application.getUniqueIdentifier());
                 cluster.setStatus(Status.Created);
                 cluster.addHostName(applicationClusterContext.getHostName());
                 cluster.setTenantRange(applicationClusterContext.getTenantRange());
@@ -634,7 +634,7 @@ public class TopologyBuilder {
                 Service service = topology.getService(applicationClusterContext.getCartridgeType());
                 if (service != null) {
                     service.addCluster(cluster);
-                    log.info("Added Cluster " + cluster.toString() + " to Topology for Application with id: " + application.getId());
+                    log.info("Added Cluster " + cluster.toString() + " to Topology for Application with id: " + application.getUniqueIdentifier());
                 } else {
                     log.error("Service " + applicationClusterContext.getCartridgeType() + " not found");
                     return;
@@ -645,7 +645,7 @@ public class TopologyBuilder {
             topology.addApplication(application);
             TopologyManager.updateTopology(topology);
 
-            log.info("Application with id [ " + application.getId() + " ] added to Topology successfully");
+            log.info("Application with id [ " + application.getUniqueIdentifier() + " ] added to Topology successfully");
 
             TopologyEventPublisher.sendApplicationCreatedEvent(application ,clusters);
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/topology/receiver/StratosManagerTopologyEventReceiver.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/topology/receiver/StratosManagerTopologyEventReceiver.java b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/topology/receiver/StratosManagerTopologyEventReceiver.java
index d61f474..e7bc5a2 100644
--- a/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/topology/receiver/StratosManagerTopologyEventReceiver.java
+++ b/components/org.apache.stratos.manager/src/main/java/org/apache/stratos/manager/topology/receiver/StratosManagerTopologyEventReceiver.java
@@ -319,13 +319,13 @@ public class StratosManagerTopologyEventReceiver implements Runnable {
 
                 try {
                     //TopologyManager.acquireReadLock();
-                    TopologyManager.acquireReadLockForApplication(appCreateEvent.getApplication().getId());
+                    TopologyManager.acquireReadLockForApplication(appCreateEvent.getApplication().getUniqueIdentifier());
                     
                     // create and persist Application subscritpion
                     CartridgeSubscriptionManager cartridgeSubscriptionManager = new CartridgeSubscriptionManager();
                     ApplicationSubscription compositeAppSubscription;
                     Application app = appCreateEvent.getApplication();
-                    String appId = app.getId();
+                    String appId = app.getUniqueIdentifier();
                     int tenantId = app.getTenantId();
                     String domain = app.getTenantDomain();
                     
@@ -350,7 +350,7 @@ public class StratosManagerTopologyEventReceiver implements Runnable {
                     }
                 } finally {
                     //TopologyManager.releaseReadLock();
-                    TopologyManager.releaseReadLockForApplication(appCreateEvent.getApplication().getId());
+                    TopologyManager.releaseReadLockForApplication(appCreateEvent.getApplication().getUniqueIdentifier());
                 }
             }
         });

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Application.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Application.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Application.java
index dd7d6ea..c30d5b7 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Application.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Application.java
@@ -27,7 +27,7 @@ import java.util.*;
  * Represents an Application in the Topology
  */
 
-public class Application implements ParentBehavior {
+public class Application extends ParentComponent {
 
     private static final long serialVersionUID = -5092959597171649688L;
     // Unique id for the Application, defined in Application Definition
@@ -40,126 +40,14 @@ public class Application implements ParentBehavior {
     private String tenantDomain;
     // tenant admin user
     private String tenantAdminUserName;
-    // Dependency Order
-    private DependencyOrder dependencyOrder;
-    // Group Map, key = Group.alias
-    private Map<String, Group> aliasToGroupMap;
-    // Cluster Id map, key = subscription alias for the cartridge type
-    private Map<String, ClusterDataHolder> aliasToClusterDataMap;
-    // Application status
-    private Status status;
 
     public Application (String id) {
+        super();
         this.id = id;
         this.key = RandomStringUtils.randomAlphanumeric(16);
-        this.status = Status.Created;
-        aliasToGroupMap = new HashMap<String, Group>();
-        aliasToClusterDataMap = new HashMap<String, ClusterDataHolder>();
     }
 
-    @Override
-    public void addGroup(Group group) {
-        aliasToGroupMap.put(group.getName(), group);
-    }
-
-    @Override
-    public void setGroups(Map<String, Group> groupAliasToGroup) {
-        aliasToGroupMap.putAll(groupAliasToGroup);
-    }
-
-    @Override
-    public Group getGroup(String groupAlias) {
-        return aliasToGroupMap.get(groupAlias);
-    }
-
-    @Override
-    public Map<String, Group> getAliasToGroupMap() {
-        return this.aliasToGroupMap;
-    }
-
-    @Override
-    public Map<String, ClusterDataHolder> getClusterDataMap() {
-        return this.aliasToClusterDataMap;
-    }
-
-    public Set<ClusterDataHolder> getClusterDataRecursively () {
-
-        Set<ClusterDataHolder> appClusterData = new HashSet<ClusterDataHolder>();
-
-        // get top level Cluster Data
-        if (this.aliasToClusterDataMap != null && !this.aliasToClusterDataMap.isEmpty()) {
-            appClusterData.addAll(this.aliasToClusterDataMap.values());
-        }
-
-        // find other nested Cluster Data (in the Groups)
-        if (getGroups() != null) {
-            getClusterData(appClusterData, getGroups());
-        }
-
-        return appClusterData;
-    }
-
-    private void getClusterData (Set<ClusterDataHolder> clusterData, Collection<Group> groups) {
-
-        for (Group group : groups) {
-            if (group.getClusterDataMap() != null && !group.getClusterDataMap().isEmpty()) {
-                clusterData.addAll(group.getClusterDataMap().values());
-                if (group.getGroups() != null) {
-                    getClusterData(clusterData, group.getGroups());
-                }
-            }
-        }
-    }
-
-    @Override
-    public Group getGroupRecursively(String groupAlias) {
-
-        return travereAndCheckRecursively(aliasToGroupMap, groupAlias);
-    }
-
-    private Group travereAndCheckRecursively (Map<String,Group> aliasToGroupMap, String groupAlias) {
-
-        if (aliasToGroupMap.containsKey(groupAlias)) {
-            synchronized (aliasToGroupMap) {
-                if (aliasToGroupMap.containsKey(groupAlias)) {
-                    return aliasToGroupMap.get(groupAlias);
-                }
-            }
-        } else {
-            for (Group group : aliasToGroupMap.values()) {
-                travereAndCheckRecursively(group.getAliasToGroupMap(), groupAlias);
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public Collection<Group> getGroups() {
-        return aliasToGroupMap.values();
-    }
-
-    @Override
-    public void setDependencyOrder(DependencyOrder dependencyOrder) {
-        this.dependencyOrder = dependencyOrder;
-    }
-
-    @Override
-    public DependencyOrder getDependencyOrder() {
-        return dependencyOrder;
-    }
-
-    @Override
-    public void setClusterData(Map<String, ClusterDataHolder> aliasToClusterData) {
-        this.aliasToClusterDataMap.putAll(aliasToClusterData);
-    }
-
-    @Override
-    public ClusterDataHolder getClusterData(String alias) {
-        return aliasToClusterDataMap.get(alias);
-    }
-
-    public String getId() {
+    public String getUniqueIdentifier() {
         return id;
     }
 
@@ -167,14 +55,6 @@ public class Application implements ParentBehavior {
         return key;
     }
 
-    public Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(Status status) {
-        this.status = status;
-    }
-
     public int getTenantId() {
         return tenantId;
     }
@@ -198,4 +78,21 @@ public class Application implements ParentBehavior {
     public void setTenantAdminUserName(String tenantAdminUserName) {
         this.tenantAdminUserName = tenantAdminUserName;
     }
+
+    public boolean equals(Object other) {
+        if(other == null || !(other instanceof Application)) {
+            return false;
+        }
+
+        if(this == other) {
+            return true;
+        }
+
+        Application that = (Application)other;
+        return this.id.equals(that.id);
+    }
+
+    public int hashCode () {
+        return id.hashCode();
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Group.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Group.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Group.java
index cd849b6..17e1a90 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Group.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Group.java
@@ -19,13 +19,11 @@
 
 package org.apache.stratos.messaging.domain.topology;
 
-import java.util.*;
-
 /**
  * Represents a Group/nested Group in an Application/Group
  */
 
-public class Group implements ParentBehavior {
+public class Group extends ParentComponent {
 
     private static final long serialVersionUID = 8347096598203655846L;
     // Name of the Group, specified in Group Definition
@@ -36,113 +34,14 @@ public class Group implements ParentBehavior {
     private String deploymentPolicy;
     // Group level autoscaling policy
     private String autoscalingPolicy;
-    // Dependency Order
-    private DependencyOrder dependencyOrder;
-    // Sub Group Map, key = Group.alias
-    private Map<String, Group> aliasToGroupMap;
-    // Cluster Id map, key = subscription alias for the cartridge type
-    private Map<String, ClusterDataHolder> aliasToClusterDataMap;
-    // Group status
-    private Status status;
 
     public Group (String name, String alias) {
+        super();
         this.name = name;
         this.alias = alias;
-        this.status = Status.Created;
-        aliasToGroupMap = new HashMap<String, Group>();
-        aliasToClusterDataMap = new HashMap<String, ClusterDataHolder>();
-    }
-
-    @Override
-    public void addGroup(Group group) {
-        aliasToGroupMap.put(group.name, group);
-    }
-
-    @Override
-    public void setGroups(Map<String, Group> groupAliasToGroup) {
-        aliasToGroupMap.putAll(groupAliasToGroup);
-    }
-
-    @Override
-    public Group getGroup(String groupAlias) {
-        return aliasToGroupMap.get(groupAlias);
-    }
-
-    @Override
-    public Map<String, Group> getAliasToGroupMap() {
-        return this.aliasToGroupMap;
-    }
-
-    @Override
-    public Map<String, ClusterDataHolder> getClusterDataMap() {
-        return this.aliasToClusterDataMap;
-    }
-
-    @Override
-    public Group getGroupRecursively(String groupAlias) {
-
-        return travereAndCheckRecursively(aliasToGroupMap, groupAlias);
     }
 
-    private Group travereAndCheckRecursively (Map<String,Group> aliasToGroupMap, String groupAlias) {
-
-        if (aliasToGroupMap.containsKey(groupAlias)) {
-            synchronized (aliasToGroupMap) {
-                if (aliasToGroupMap.containsKey(groupAlias)) {
-                    return aliasToGroupMap.get(groupAlias);
-                }
-            }
-        } else {
-            for (Group group : aliasToGroupMap.values()) {
-                travereAndCheckRecursively(group.getAliasToGroupMap(), groupAlias);
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public Collection<Group> getGroups() {
-        return aliasToGroupMap.values();
-    }
-
-    @Override
-    public void setDependencyOrder(DependencyOrder dependencyOrder) {
-        this.dependencyOrder = dependencyOrder;
-    }
-
-    @Override
-    public DependencyOrder getDependencyOrder() {
-        return dependencyOrder;
-    }
-
-//    @Override
-//    public void addClusterId(String serviceName, String clusterId) {
-//
-//        synchronized (serviceNameToClusterIdsMap) {
-//            if (serviceNameToClusterIdsMap.get(serviceName) == null) {
-//                // not found, create
-//                Set<String> clusterIds = new HashSet<String>();
-//                clusterIds.add(clusterId);
-//                serviceNameToClusterIdsMap.put(serviceName, clusterIds);
-//            } else {
-//                // the cluster id set already exists, update
-//                serviceNameToClusterIdsMap.get(serviceName).add(clusterId);
-//            }
-//        }
-//    }
-
-    @Override
-    public void setClusterData(Map<String, ClusterDataHolder> aliasToClusterData) {
-        this.aliasToClusterDataMap.putAll(aliasToClusterData);
-    }
-
-    @Override
-    public ClusterDataHolder getClusterData(String alias) {
-        return aliasToClusterDataMap.get(alias);
-    }
-
-    public String getName() {
+    public String getUniqueIdentifier() {
         return name;
     }
 
@@ -183,11 +82,4 @@ public class Group implements ParentBehavior {
         return name.hashCode() + alias.hashCode();
     }
 
-    public Status getStatus() {
-        return status;
-    }
-
-    public void setStatus(Status status) {
-        this.status = status;
-    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentBehavior.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentBehavior.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentBehavior.java
deleted file mode 100644
index 5fbdf0c..0000000
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentBehavior.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.stratos.messaging.domain.topology;
-
-import java.io.Serializable;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * Abstraction for a an entity that can have child entities
- * in an Application withing the Topology
- */
-
-public interface ParentBehavior extends Serializable {
-
-    /**
-     * Adds a group
-     *
-     * @param group Group instance to be added
-     */
-    public void addGroup (Group group);
-
-    /**
-     * Setter for Group alias to Group map
-     *
-     * @param groupAliasToGroup Map, key = alias given to the Group, value = Group
-     */
-    public void setGroups (Map<String, Group> groupAliasToGroup);
-
-    /**
-     * Get the Group for the given alias in the context of the parent entity.
-     * Will not search recursively in the nested levels.
-     *
-     * @param groupAlias alias of the Group
-     * @return Group, if exists for the given alias, else null
-     */
-    public Group getGroup (String groupAlias);
-
-    /**
-     * Get the Group for the given alias in the context of the parent entity.
-     * Will search recursively in the nested levels.
-     *
-     * @param groupAlias alias of the Group
-     * @return Group, if exists for the given alias, else null
-     */
-    public Group getGroupRecursively (String groupAlias);
-
-    /**
-     * Getter for alias to Group map
-     * Will not search recursively in the nested levels.
-     *
-     * @return Map, key = alias given to the Group, value = Group
-     */
-    public Map<String, Group> getAliasToGroupMap();
-
-    /**
-     * Getter for cluster alias to ClusterData map for this level
-     *
-     * @return Map, key = alias given to the cluster, value =  ClusterData object
-     */
-    public Map<String, ClusterDataHolder> getClusterDataMap();
-
-    /**
-     * Collection of Groups in this level
-     *
-     * @return Group Collection object, empty if no Groups are found
-     */
-    public Collection<Group> getGroups ();
-
-    /**
-     * Setter for Dependency Order
-     *
-     * @param dependencyOrder Dependency Order object
-     */
-    public void setDependencyOrder (DependencyOrder dependencyOrder);
-
-    /**
-     * Getter for Dependency Order for this level
-     *
-     * @return Dependency Order object
-     */
-    public DependencyOrder getDependencyOrder ();
-
-    /**
-     * Setter for alias to Cluster Data map
-     *
-     * @param aliasToClusterData Map, key = alias given to the cluster, value =  ClusterData object
-     */
-    public void setClusterData (Map<String, ClusterDataHolder> aliasToClusterData);
-
-    /**
-     * Getter for Cluster Data instance for the given alias
-     * Will not search recursively in the nested levels.
-     *
-     * @param alias
-     * @return
-     */
-    public ClusterDataHolder getClusterData (String alias);
-}

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentComponent.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentComponent.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentComponent.java
new file mode 100644
index 0000000..d76663c
--- /dev/null
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/ParentComponent.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.stratos.messaging.domain.topology;
+
+import java.io.Serializable;
+import java.util.*;
+
+/**
+ * Abstraction for a an entity that can have child entities
+ * in an Application withing the Topology
+ */
+
+public abstract class ParentComponent implements Serializable {
+
+    // Dependency Order
+    private DependencyOrder dependencyOrder;
+    // Group Map, key = Group.alias
+    private Map<String, Group> aliasToGroupMap;
+    // Cluster Id map, key = subscription alias for the cartridge type
+    private Map<String, ClusterDataHolder> aliasToClusterDataMap;
+    // Application status
+    private Status status;
+
+    public ParentComponent () {
+        this.status = Status.Created;
+        aliasToGroupMap = new HashMap<String, Group>();
+        aliasToClusterDataMap = new HashMap<String, ClusterDataHolder>();
+    }
+
+    /**
+     * This method should be implemented in each concrete child class
+     * to return the unique identifier for each implementation
+     * ex.: group alias for a Group, app id for an Application
+     *
+     * @return unique identifier String
+     */
+    public abstract String getUniqueIdentifier ();
+
+    /**
+     * Adds a group
+     *
+     * @param group Group instance to be added
+     */
+    public void addGroup(Group group) {
+        aliasToGroupMap.put(group.getUniqueIdentifier(), group);
+    }
+
+    /**
+     * Setter for Group alias to Group map
+     *
+     * @param groupAliasToGroup Map, key = alias given to the Group, value = Group
+     */
+    public void setGroups(Map<String, Group> groupAliasToGroup) {
+        aliasToGroupMap.putAll(groupAliasToGroup);
+    }
+
+    /**
+     * Get the Group for the given alias in the context of the parent entity.
+     * Will not search recursively in the nested levels.
+     *
+     * @param groupAlias alias of the Group
+     * @return Group, if exists for the given alias, else null
+     */
+    public Group getGroup(String groupAlias) {
+        return aliasToGroupMap.get(groupAlias);
+    }
+
+    /**
+     * Get the Group for the given alias in the context of the parent entity.
+     * Will search recursively in the nested levels.
+     *
+     * @param groupAlias alias of the Group
+     * @return Group, if exists for the given alias, else null
+     */
+    public Group getGroupRecursively(String groupAlias) {
+
+        return travereAndCheckRecursively(aliasToGroupMap, groupAlias);
+    }
+
+    private Group travereAndCheckRecursively (Map<String,Group> aliasToGroupMap, String groupAlias) {
+
+        if (aliasToGroupMap.containsKey(groupAlias)) {
+            synchronized (aliasToGroupMap) {
+                if (aliasToGroupMap.containsKey(groupAlias)) {
+                    return aliasToGroupMap.get(groupAlias);
+                }
+            }
+        } else {
+            for (Group group : aliasToGroupMap.values()) {
+                travereAndCheckRecursively(group.getAliasToGroupMap(), groupAlias);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Getter for alias to Group map
+     * Will not search recursively in the nested levels.
+     *
+     * @return Map, key = alias given to the Group, value = Group
+     */
+    public Map<String, Group> getAliasToGroupMap() {
+        return this.aliasToGroupMap;
+    }
+
+    /**
+     * Getter for cluster alias to ClusterData map for this level
+     *
+     * @return Map, key = alias given to the cluster, value =  ClusterData object
+     */
+    public Map<String, ClusterDataHolder> getClusterDataMap() {
+        return this.aliasToClusterDataMap;
+    }
+
+    /**
+     * Collection of Groups in this level
+     *
+     * @return Group Collection object, empty if no Groups are found
+     */
+    public Collection<Group> getGroups() {
+        return aliasToGroupMap.values();
+    }
+
+    /**
+     * Setter for Dependency Order
+     *
+     * @param dependencyOrder Dependency Order object
+     */
+    public void setDependencyOrder(DependencyOrder dependencyOrder) {
+        this.dependencyOrder = dependencyOrder;
+    }
+
+    /**
+     * Getter for Dependency Order for this level
+     *
+     * @return Dependency Order object
+     */
+    public DependencyOrder getDependencyOrder() {
+        return dependencyOrder;
+    }
+
+    /**
+     * Setter for alias to Cluster Data map
+     *
+     * @param aliasToClusterData Map, key = alias given to the cluster, value =  ClusterData object
+     */
+    public void setClusterData(Map<String, ClusterDataHolder> aliasToClusterData) {
+        this.aliasToClusterDataMap.putAll(aliasToClusterData);
+    }
+
+    /**
+     * Getter for Cluster Data instance for the given alias
+     * Will not search recursively in the nested levels.
+     *
+     * @param alias
+     * @return
+     */
+    public ClusterDataHolder getClusterData(String alias) {
+        return aliasToClusterDataMap.get(alias);
+    }
+
+    /**
+     * Collects the Cluster Data for the parent component and all the
+     * child components recursively
+     *
+     * @return Set of ClusterDataHolder objects if available, else null
+     */
+    public Set<ClusterDataHolder> getClusterDataRecursively () {
+
+        Set<ClusterDataHolder> appClusterData = new HashSet<ClusterDataHolder>();
+
+        // get top level Cluster Data
+        if (this.aliasToClusterDataMap != null && !this.aliasToClusterDataMap.isEmpty()) {
+            appClusterData.addAll(this.aliasToClusterDataMap.values());
+        }
+
+        // find other nested Cluster Data (in the Groups)
+        if (getGroups() != null) {
+            getClusterData(appClusterData, getGroups());
+        }
+
+        return appClusterData;
+    }
+
+    private void getClusterData (Set<ClusterDataHolder> clusterData, Collection<Group> groups) {
+
+        for (Group group : groups) {
+            if (group.getClusterDataMap() != null && !group.getClusterDataMap().isEmpty()) {
+                clusterData.addAll(group.getClusterDataMap().values());
+                if (group.getGroups() != null) {
+                    getClusterData(clusterData, group.getGroups());
+                }
+            }
+        }
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Topology.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Topology.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Topology.java
index dabf611..76d73fe 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Topology.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/domain/topology/Topology.java
@@ -53,8 +53,8 @@ public class Topology implements Serializable {
     }
 
     public void addApplication (Application application) {
-        this.applicationMap.put(application.getId(), application);
-        TopologyLockHierarchy.getInstance().addApplicationLock(application.getId(), new TopologyLock());
+        this.applicationMap.put(application.getUniqueIdentifier(), application);
+        TopologyLockHierarchy.getInstance().addApplicationLock(application.getUniqueIdentifier(), new TopologyLock());
     }
 
     public Application getApplication (String applicationId) {

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ApplicationCreatedEvent.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ApplicationCreatedEvent.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ApplicationCreatedEvent.java
index a36e65f..23f115f 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ApplicationCreatedEvent.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/event/topology/ApplicationCreatedEvent.java
@@ -40,7 +40,7 @@ public class ApplicationCreatedEvent extends TopologyEvent {
     }
 
     public String toString() {
-        return "ApplicationCreatedEvent [app id= " + application.getId() + ", groups= " + application.getGroups() + ", clusters= " +
+        return "ApplicationCreatedEvent [app id= " + application.getUniqueIdentifier() + ", groups= " + application.getGroups() + ", clusters= " +
                 application.getClusterDataMap().values() + "]";
     }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ApplicationCreatedMessageProcessor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ApplicationCreatedMessageProcessor.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ApplicationCreatedMessageProcessor.java
index 587d6f3..34ed3ef 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ApplicationCreatedMessageProcessor.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/ApplicationCreatedMessageProcessor.java
@@ -96,15 +96,15 @@ public class ApplicationCreatedMessageProcessor extends MessageProcessor {
             throw new RuntimeException(errorMsg);
         }
 
-        if (event.getApplication().getId() == null || event.getApplication().getId().isEmpty()) {
-            String errorMsg = "App id of application created event is invalid: [ " + event.getApplication().getId() + " ]";
+        if (event.getApplication().getUniqueIdentifier() == null || event.getApplication().getUniqueIdentifier().isEmpty()) {
+            String errorMsg = "App id of application created event is invalid: [ " + event.getApplication().getUniqueIdentifier() + " ]";
             log.error(errorMsg);
             throw new RuntimeException(errorMsg);
         }
 
         // check if an Application with same name exists in topology
-        if (topology.applicationExists(event.getApplication().getId())) {
-            log.warn("Application with id [ " + event.getApplication().getId() + " ] already exists in Topology");
+        if (topology.applicationExists(event.getApplication().getUniqueIdentifier())) {
+            log.warn("Application with id [ " + event.getApplication().getUniqueIdentifier() + " ] already exists in Topology");
 
         } else {
             // add application and the clusters to Topology

http://git-wip-us.apache.org/repos/asf/stratos/blob/d100cd0e/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/CompleteTopologyMessageProcessor.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/CompleteTopologyMessageProcessor.java b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/CompleteTopologyMessageProcessor.java
index 6d5cb8f..74daa48 100644
--- a/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/CompleteTopologyMessageProcessor.java
+++ b/components/org.apache.stratos.messaging/src/main/java/org/apache/stratos/messaging/message/processor/topology/CompleteTopologyMessageProcessor.java
@@ -147,7 +147,7 @@ public class CompleteTopologyMessageProcessor extends MessageProcessor {
             for (Application application : applications) {
                 topology.addApplication(application);
                 if (log.isDebugEnabled()) {
-                    log.debug("Application with id [ " +  application.getId() + " ] added to Topology");
+                    log.debug("Application with id [ " +  application.getUniqueIdentifier() + " ] added to Topology");
                 }
             }
         } else {