Repository: stratos
Updated Branches:
  refs/heads/4.0.0-grouping 9677d15aa -> b2a254895


allowing multiple same type Cartridges and Groups at the top level


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

Branch: refs/heads/4.0.0-grouping
Commit: f6584b46fda8486a6b95df26032baa8cad656009
Parents: de369d9
Author: Isuru Haththotuwa <[email protected]>
Authored: Tue Sep 23 19:21:17 2014 +0530
Committer: Isuru Haththotuwa <[email protected]>
Committed: Tue Sep 23 19:21:17 2014 +0530

----------------------------------------------------------------------
 .../autoscaler/grouping/DependencyBuilder.java  | 10 ++-
 .../stratos/autoscaler/monitor/Monitor.java     | 23 +++---
 .../status/checker/StatusChecker.java           | 25 +++---
 .../parser/DefaultApplicationParser.java        | 34 ++++++--
 .../controller/pojo/ClusterDataHolder.java      |  8 +-
 .../controller/topology/TopologyBuilder.java    | 11 ++-
 .../messaging/domain/topology/Application.java  | 86 ++++++++++----------
 .../messaging/domain/topology/Group.java        | 86 ++++++++++----------
 .../domain/topology/ParentBehavior.java         | 15 ++--
 .../event/topology/ApplicationCreatedEvent.java |  2 +-
 10 files changed, 166 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/DependencyBuilder.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/DependencyBuilder.java
 
b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/DependencyBuilder.java
index ebb683c..a021ce3 100644
--- 
a/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/DependencyBuilder.java
+++ 
b/components/org.apache.stratos.autoscaler/src/main/java/org/apache/stratos/autoscaler/grouping/DependencyBuilder.java
@@ -59,15 +59,17 @@ public class DependencyBuilder {
             }
         }
         //TODO adding all the missed groups or clusters as the top child to 
the list
-        for(Group group: component.getGroupMap().values()) {
+        for(Group group: component.getAliasToGroupMap().values()) {
             if(!startup.contains(group.getAlias())) {
                 startup.add(group.getAlias());
             }
         }
 
-        for(String clusterId: component.getClusterIdMap().values()) {
-            if(!startup.contains(clusterId)) {
-                startup.add(clusterId);
+        for(Set<String> clusterIds: 
component.getServiceNameToClusterIdsMap().values()) {
+            for (String clusterId : clusterIds) {
+                if(!startup.contains(clusterId)) {
+                    startup.add(clusterId);
+                }
             }
         }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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 ef0d750..6b299ef 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
@@ -27,10 +27,8 @@ import 
org.apache.stratos.autoscaler.grouping.DependencyBuilder;
 import org.apache.stratos.autoscaler.monitor.cluster.ClusterMonitor;
 import org.apache.stratos.autoscaler.monitor.cluster.LbClusterMonitor;
 import org.apache.stratos.autoscaler.monitor.group.GroupMonitor;
-import org.apache.stratos.autoscaler.status.checker.StatusChecker;
 import org.apache.stratos.autoscaler.util.AutoscalerUtil;
 import org.apache.stratos.messaging.domain.topology.Cluster;
-import org.apache.stratos.messaging.domain.topology.Group;
 import org.apache.stratos.messaging.domain.topology.ParentBehavior;
 import org.apache.stratos.messaging.event.Event;
 import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
@@ -124,15 +122,18 @@ public abstract class Monitor extends Observable 
implements Observer {
             if (dependency.contains("group")) {
                 startGroupMonitor(this, dependency, component);
             } else if (dependency.contains("cartridge")) {
-                String clusterId = component.getClusterId(dependency);
-                Cluster cluster = null;
-                TopologyManager.acquireReadLock();
-                cluster = 
TopologyManager.getTopology().getService(dependency).getCluster(clusterId);
-                TopologyManager.releaseReadLock();
-                if (cluster != null) {
-                    startClusterMonitor(cluster);
-                } else {
-                    //TODO throw exception since Topology is inconsistent
+
+                Set<String> clusterIds = component.getClusterIds(dependency);
+                for (String clusterId : clusterIds) {
+                    Cluster cluster = null;
+                    TopologyManager.acquireReadLock();
+                    cluster = 
TopologyManager.getTopology().getService(dependency).getCluster(clusterId);
+                    TopologyManager.releaseReadLock();
+                    if (cluster != null) {
+                        startClusterMonitor(cluster);
+                    } else {
+                        //TODO throw exception since Topology is inconsistent
+                    }
                 }
             }
         } else {

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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 79da514..e410259 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
@@ -30,6 +30,7 @@ import 
org.apache.stratos.messaging.domain.topology.util.GroupStatus;
 import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
 
 import java.util.Map;
+import java.util.Set;
 
 /**
  * This will be used to evaluate the status of a group
@@ -105,8 +106,8 @@ public class StatusChecker {
         Runnable exGroup = new Runnable() {
             public void run() {
                 Application application = 
TopologyManager.getTopology().getApplication(appId);
-                Map<String, String> clusterIds = application.getClusterMap();
-                Map<String, Group> groups = application.getGroupMap();
+                Map<String, Set<String>> clusterIds = 
application.getClusterMap();
+                Map<String, Group> groups = application.getAliasToGroupMap();
                 updateChildStatus(clusterId, groups, clusterIds, application);
             }
         };
@@ -154,7 +155,7 @@ public class StatusChecker {
     }
 
 
-    private boolean updateChildStatus(String id, Map<String, Group> groups, 
Map<String, String> clusterIds, ParentBehavior parent) {
+    private boolean updateChildStatus(String id, Map<String, Group> groups, 
Map<String, Set<String>> clusterIds, ParentBehavior parent) {
         boolean groupActive = false;
         boolean clustersActive = false;
         boolean groupsActive = false;
@@ -185,7 +186,7 @@ public class StatusChecker {
         } else {
             if(!groups.isEmpty()) {
                 for(Group group: groups.values()) {
-                    return updateChildStatus(id, group.getGroupMap(), 
group.getClusterMap(), group);
+                    return updateChildStatus(id, group.getAliasToGroupMap(), 
group.getClusterMap(), group);
 
                 }
             }
@@ -206,14 +207,16 @@ public class StatusChecker {
 
     }
 
-    private boolean getClusterStatus(Map<String, String> clusterIds) {
+    private boolean getClusterStatus(Map<String, Set<String>> clusterIds) {
         boolean clusterActiveStatus = false;
-        for(Map.Entry<String, String> clusterId: clusterIds.entrySet()) {
-            Service service = 
TopologyManager.getTopology().getService(clusterId.getKey());
-            
if(service.getCluster(clusterId.getValue()).getStatus().equals(ClusterStatus.Active))
 {
-                clusterActiveStatus = true;
-            } else {
-                clusterActiveStatus = false;
+        for(Map.Entry<String, Set<String>> clusterIdsEntry: 
clusterIds.entrySet()) {
+            Service service = 
TopologyManager.getTopology().getService(clusterIdsEntry.getKey());
+            for (String clusterId : clusterIdsEntry.getValue()) {
+                
if(service.getCluster(clusterId).getStatus().equals(ClusterStatus.Active)) {
+                    clusterActiveStatus = true;
+                } else {
+                    clusterActiveStatus = false;
+                }
             }
         }
         return clusterActiveStatus;

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/application/parser/DefaultApplicationParser.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/application/parser/DefaultApplicationParser.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/application/parser/DefaultApplicationParser.java
index e1cd35c..a693942 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/application/parser/DefaultApplicationParser.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/application/parser/DefaultApplicationParser.java
@@ -252,10 +252,11 @@ public class DefaultApplicationParser implements 
ApplicationParser {
 
         for (GroupContext groupCtxt : groupCtxts) {
             Group group = getGroup(appId, tenantId, key, clusterDataHolder, 
groupCtxt, subscribableInformation, definedGroupCtxts);
-            if(groupNameToGroup.put(group.getName(), group) != null) {
-                // Application Definition has same Group multiple times at the 
top-level
-                handleError("Group [ " + group.getName() + " ] appears twice 
in the Application Definition's top level");
-            }
+            groupNameToGroup.put(group.getName(), group);
+//            if(groupNameToGroup.put(group.getName(), group) != null) {
+//                // Application Definition has same Group multiple times at 
the top-level
+//                handleError("Group [ " + group.getName() + " ] appears twice 
in the Application Definition's top level");
+//            }
         }
 
         //Set<GroupContext> topLevelGroupContexts = 
getTopLevelGroupContexts(groupNameToGroup);
@@ -447,7 +448,7 @@ public class DefaultApplicationParser implements 
ApplicationParser {
                                                      Map<String, 
SubscribableInfoContext> subscribableInfoCtxts)
             throws ApplicationDefinitionException {
 
-        Map<String, String> clusterIdMap = new HashMap<String, String>();
+        Map<String, Set<String>> clusterIdMap = new HashMap<String, 
Set<String>>();
         Set<Cluster> clusters = new HashSet<Cluster>();
         Set<PayloadDataHolder> payloadDataHolders = new 
HashSet<PayloadDataHolder>();
 
@@ -473,11 +474,13 @@ public class DefaultApplicationParser implements 
ApplicationParser {
             }
 
             Cluster cluster = getCluster(subscribableCtxt, 
subscribableInfoCtxt, cartridge);
+            addClusterId(clusterIdMap, subscribableCtxt.getType(), 
cluster.getClusterId());
+            //clusterIdMap.put(subscribableCtxt.getType(), 
cluster.getClusterId());
             clusters.add(cluster);
-            if (clusterIdMap.put(subscribableCtxt.getType(), 
cluster.getClusterId()) != null) {
-                // Application Definition has same cartridge multiple times at 
the top-level
-                handleError("Cartridge [ " + subscribableCtxt.getType() + " ] 
appears twice in the Application Definition's top level");
-            }
+//            if (clusterIdMap.put(subscribableCtxt.getType(), 
cluster.getClusterId()) != null) {
+//                // Application Definition has same cartridge multiple times 
at the top-level
+//                handleError("Cartridge [ " + subscribableCtxt.getType() + " 
] appears twice in the Application Definition's top level");
+//            }
 
             
payloadDataHolders.add(ApplicationUtils.getClusterLevelPayloadData(appId, 
groupName, tenantId, key, cluster,
                     subscribableCtxt, subscribableInfoCtxt, cartridge));
@@ -491,6 +494,19 @@ public class DefaultApplicationParser implements 
ApplicationParser {
         return clusterDataHolder;
     }
 
+    public void addClusterId (Map<String, Set<String>> 
serviceNameToClusterIdsMap, String serviceName, String clusterId) {
+
+        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);
+        }
+    }
+
     private void createClusterContext (String appId, String groupName, String 
serviceType, String clusterId,
                                               String hostName) throws 
ApplicationDefinitionException {
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterDataHolder.java
----------------------------------------------------------------------
diff --git 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterDataHolder.java
 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterDataHolder.java
index 313265e..af81c8e 100644
--- 
a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterDataHolder.java
+++ 
b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/pojo/ClusterDataHolder.java
@@ -28,8 +28,8 @@ import java.util.Set;
 
 public class ClusterDataHolder {
 
-    // Cluster Id map, key = service name
-    private Map<String, String> clusterIdMap;
+    // Cluster Ids map, key = service name
+    private Map<String, Set<String>> clusterIdMap;
 
     // Cluster object collection
     private Set<Cluster> clusters;
@@ -37,12 +37,12 @@ public class ClusterDataHolder {
     // payload related information
     private Set<PayloadDataHolder> payloadDataHolders;
 
-   public ClusterDataHolder (Map<String, String> clusterIdMap, Set<Cluster> 
clusters) {
+   public ClusterDataHolder (Map<String, Set<String>> clusterIdMap, 
Set<Cluster> clusters) {
        this.clusterIdMap = clusterIdMap;
        this.clusters = clusters;
    }
 
-    public Map<String, String> getClusterIdMap() {
+    public Map<String, Set<String>> getClusterIdMap() {
         return clusterIdMap;
     }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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 3974d55..c958ec2 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
@@ -46,6 +46,7 @@ import org.apache.stratos.messaging.util.Constants;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
 
 /**
  * this is to manipulate the received events by cloud controller
@@ -659,14 +660,16 @@ public class TopologyBuilder {
             } else {
                 Application application = 
topology.getApplication(applicationId);
                 // remove clusters
-                for (Map.Entry<String,String> clusterIdMapEntry : 
application.getClusterIdMap().entrySet()) {
-                    Service service = 
topology.getService(clusterIdMapEntry.getKey());
-                    service.removeCluster(clusterIdMapEntry.getValue());
+                for (Map.Entry<String, Set<String>> 
serviceNameToClusterIdEntry:
+                        
application.getServiceNameToClusterIdsMap().entrySet()) {
+                    Service service = 
topology.getService(serviceNameToClusterIdEntry.getKey());
+                    for (String clusterId : 
serviceNameToClusterIdEntry.getValue()) {
+                        service.removeCluster(clusterId);
+                    }
                 }
 
                 // remove application
                 topology.removeApplication(applicationId);
-
                 TopologyManager.updateTopology(topology);
 
                 log.info("Removed application [ " + applicationId + " ] from 
Topology");

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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 1f83888..55e37e6 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
@@ -21,9 +21,7 @@ package org.apache.stratos.messaging.domain.topology;
 
 import org.apache.commons.lang3.RandomStringUtils;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 public class Application implements ParentBehavior {
 
@@ -40,10 +38,10 @@ public class Application implements ParentBehavior {
     private String tenantAdminUserName;
     // Dependency Order
     private DependencyOrder dependencyOrder;
-    // Group Map, key = Group.name
-    private Map<String, Group> groupMap;
+    // Group Map, key = Group.alias
+    private Map<String, Group> aliasToGroupMap;
     // Cluster Id map, key = service name
-    private Map<String, String> clusterIdMap;
+    private Map<String, Set<String>> serviceNameToClusterIdsMap;
     // Application status
     private Status status;
 
@@ -51,53 +49,53 @@ public class Application implements ParentBehavior {
         this.id = id;
         this.key = RandomStringUtils.randomAlphanumeric(16);
         this.status = Status.Created;
-        groupMap = new HashMap<String, Group>();
-        clusterIdMap = new HashMap<String, String>();
+        aliasToGroupMap = new HashMap<String, Group>();
+        serviceNameToClusterIdsMap = new HashMap<String, Set<String>>();
     }
 
     @Override
     public void addGroup(Group group) {
-        groupMap.put(group.getName(), group);
+        aliasToGroupMap.put(group.getName(), group);
     }
 
     @Override
     public void setGroups(Map<String, Group> groupNameToGroup) {
-        groupMap.putAll(groupNameToGroup);
+        aliasToGroupMap.putAll(groupNameToGroup);
     }
 
     @Override
     public Group getGroup(String groupName) {
-        return groupMap.get(groupName);
+        return aliasToGroupMap.get(groupName);
     }
 
     @Override
-    public Map<String, Group> getGroupMap() {
-        return this.groupMap;
+    public Map<String, Group> getAliasToGroupMap() {
+        return this.aliasToGroupMap;
     }
 
     @Override
-    public Map<String, String> getClusterMap() {
-        return this.clusterIdMap;
+    public Map<String, Set<String>> getClusterMap() {
+        return this.serviceNameToClusterIdsMap;
     }
 
     @Override
     public Group getGroupRecursively(String groupAlias) {
 
-        return travereAndCheckRecursively(groupMap.values(), groupAlias);
+        return travereAndCheckRecursively(aliasToGroupMap, groupAlias);
     }
 
-    private Group travereAndCheckRecursively (Collection<Group> groups, String 
groupAlias) {
+    private Group travereAndCheckRecursively (Map<String,Group> 
aliasToGroupMap, String groupAlias) {
 
-        for (Group group : groups) {
-            // check if alias is equal, if so, return
-            if (groupAlias.equals(group.getAlias())) {
-                return group;
-            } else {
-                // check if this Group has nested sub Groups. If so, traverse 
them as well
-                if (group.getGroups() != null) {
-                    return travereAndCheckRecursively(group.getGroups(), 
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;
@@ -105,7 +103,7 @@ public class Application implements ParentBehavior {
 
     @Override
     public Collection<Group> getGroups() {
-        return groupMap.values();
+        return aliasToGroupMap.values();
     }
 
     @Override
@@ -118,28 +116,34 @@ public class Application implements ParentBehavior {
         return dependencyOrder;
     }
 
-    @Override
-    public void addClusterId(String serviceName, String clusterId) {
-        clusterIdMap.put(serviceName, clusterId);
-    }
-
-    @Override
-    public void setClusterIds(Map<String, String> serviceNameToClusterId) {
-        clusterIdMap.putAll(serviceNameToClusterId);
-    }
+//    @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 String getClusterId(String serviceName) {
-        return clusterIdMap.get(serviceName);
+    public void setClusterIds(Map<String, Set<String>> 
serviceNameToClusterIds) {
+        serviceNameToClusterIdsMap.putAll(serviceNameToClusterIds);
     }
 
     @Override
-    public Collection<String> getClusterIds() {
-        return clusterIdMap.values();
+    public Set<String> getClusterIds(String serviceName) {
+        return serviceNameToClusterIdsMap.get(serviceName);
     }
 
-    public Map<String, String> getClusterIdMap () {
-        return clusterIdMap;
+    public Map<String, Set<String>> getServiceNameToClusterIdsMap() {
+        return serviceNameToClusterIdsMap;
     }
 
     public String getId() {

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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 c6c1f78..548aabd 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,9 +19,7 @@
 
 package org.apache.stratos.messaging.domain.topology;
 
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.*;
 
 public class Group implements ParentBehavior {
 
@@ -36,10 +34,10 @@ public class Group implements ParentBehavior {
     private String autoscalingPolicy;
     // Dependency Order
     private DependencyOrder dependencyOrder;
-    // Sub Group Map, key = Group.name
-    private Map<String, Group> groupMap;
+    // Sub Group Map, key = Group.alias
+    private Map<String, Group> aliasToGroupMap;
     // Cluster id map, key = service name
-    private Map<String, String> clusterIdMap;
+    private Map<String, Set<String>> serviceNameToClusterIdsMap;
     // Group status
     private Status status;
 
@@ -47,53 +45,53 @@ public class Group implements ParentBehavior {
         this.name = name;
         this.alias = alias;
         this.status = Status.Created;
-        groupMap = new HashMap<String, Group>();
-        clusterIdMap = new HashMap<String, String>();
+        aliasToGroupMap = new HashMap<String, Group>();
+        serviceNameToClusterIdsMap = new HashMap<String, Set<String>>();
     }
 
     @Override
     public void addGroup(Group group) {
-        groupMap.put(group.name, group);
+        aliasToGroupMap.put(group.name, group);
     }
 
     @Override
     public void setGroups(Map<String, Group> groupNameToGroup) {
-        groupMap.putAll(groupNameToGroup);
+        aliasToGroupMap.putAll(groupNameToGroup);
     }
 
     @Override
     public Group getGroup(String groupName) {
-        return groupMap.get(groupName);
+        return aliasToGroupMap.get(groupName);
     }
 
     @Override
-    public Map<String, Group> getGroupMap() {
-        return this.groupMap;
+    public Map<String, Group> getAliasToGroupMap() {
+        return this.aliasToGroupMap;
     }
 
     @Override
-    public Map<String, String> getClusterMap() {
-        return this.clusterIdMap;
+    public Map<String,Set<String>> getClusterMap() {
+        return this.serviceNameToClusterIdsMap;
     }
 
     @Override
     public Group getGroupRecursively(String groupAlias) {
 
-        return travereAndCheckRecursively(groupMap.values(), groupAlias);
+        return travereAndCheckRecursively(aliasToGroupMap, groupAlias);
     }
 
-    private Group travereAndCheckRecursively (Collection<Group> groups, String 
groupAlias) {
+    private Group travereAndCheckRecursively (Map<String,Group> 
aliasToGroupMap, String groupAlias) {
 
-        for (Group group : groups) {
-            // check if alias is equal, if so, return
-            if (groupAlias.equals(group.getAlias())) {
-                return group;
-            } else {
-                // check if this Group has nested sub Groups. If so, traverse 
them as well
-                if (group.getGroups() != null) {
-                    return travereAndCheckRecursively(group.getGroups(), 
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;
@@ -101,7 +99,7 @@ public class Group implements ParentBehavior {
 
     @Override
     public Collection<Group> getGroups() {
-        return groupMap.values();
+        return aliasToGroupMap.values();
     }
 
     @Override
@@ -114,28 +112,34 @@ public class Group implements ParentBehavior {
         return dependencyOrder;
     }
 
-    @Override
-    public void addClusterId(String serviceName, String clusterId) {
-        clusterIdMap.put(serviceName, clusterId);
-    }
-
-    @Override
-    public void setClusterIds(Map<String, String> serviceNameToClusterId) {
-        clusterIdMap.putAll(serviceNameToClusterId);
-    }
+//    @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 String getClusterId(String serviceName) {
-        return clusterIdMap.get(serviceName);
+    public void setClusterIds(Map<String, Set<String>> 
serviceNameToClusterIds) {
+        serviceNameToClusterIdsMap.putAll(serviceNameToClusterIds);
     }
 
     @Override
-    public Collection<String> getClusterIds() {
-        return clusterIdMap.values();
+    public Set<String> getClusterIds(String serviceName) {
+        return serviceNameToClusterIdsMap.get(serviceName);
     }
 
-    public Map<String, String> getClusterIdMap () {
-        return clusterIdMap;
+    public Map<String, Set<String>> getServiceNameToClusterIdsMap() {
+        return serviceNameToClusterIdsMap;
     }
 
     public String getName() {

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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
index a958ea8..bfad2ae 100644
--- 
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
@@ -22,6 +22,7 @@ package org.apache.stratos.messaging.domain.topology;
 import java.io.Serializable;
 import java.util.Collection;
 import java.util.Map;
+import java.util.Set;
 
 public interface ParentBehavior extends Serializable {
 
@@ -31,9 +32,9 @@ public interface ParentBehavior extends Serializable {
 
     public Group getGroup (String groupName);
 
-    public Map<String, Group> getGroupMap();
+    public Map<String, Group> getAliasToGroupMap();
 
-    public Map<String, String> getClusterMap();
+    public Map<String,Set<String>> getClusterMap();
 
     public Group getGroupRecursively (String groupAlias);
 
@@ -43,13 +44,11 @@ public interface ParentBehavior extends Serializable {
 
     public DependencyOrder getDependencyOrder ();
 
-    public void addClusterId (String serviceName, String clusterId);
+//    public void addClusterId (String serviceName, String clusterId);
 
-    public void setClusterIds (Map<String,String> serviceNameToClusterId);
+    public void setClusterIds (Map<String,Set<String>> 
serviceNameToClusterIds);
 
-    public String getClusterId (String serviceName);
+    public Set<String> getClusterIds(String serviceName);
 
-    public Collection<String> getClusterIds ();
-
-    public Map<String, String> getClusterIdMap ();
+    public Map<String, Set<String>> getServiceNameToClusterIdsMap();
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/f6584b46/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 b336d9a..3674eb3 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
@@ -35,6 +35,6 @@ public class ApplicationCreatedEvent extends TopologyEvent {
 
     public String toString() {
         return "ApplicationCreatedEvent [app id= " + application.getId() + ", 
groups= " + application.getGroups() + ", clusters= " +
-                application.getClusterIds() + "]";
+                application.getClusterMap().values() + "]";
     }
 }

Reply via email to