You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by im...@apache.org on 2013/11/29 10:09:10 UTC

[2/2] git commit: Initial implementation of the load balancer configuration

Initial implementation of the load balancer configuration


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

Branch: refs/heads/master
Commit: fb679a6b3bbfdea5e302efa0ab7b86614a4fb0f7
Parents: 867dcfe
Author: Imesh Gunaratne <im...@apache.org>
Authored: Fri Nov 29 14:38:58 2013 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Fri Nov 29 14:38:58 2013 +0530

----------------------------------------------------------------------
 .../load/balancer/LoadBalancerContext.java      |   28 +-
 .../conf/LoadBalancerConfiguration.java         | 1358 ++++--------------
 .../load/balancer/conf/structure/Node.java      |   15 +-
 .../balancer/conf/structure/NodeBuilder.java    |   80 +-
 .../load/balancer/conf/util/Constants.java      |   11 -
 .../load/balancer/conf/util/HostContext.java    |  161 ---
 .../conf/util/LoadBalancerConfigUtil.java       |  305 ----
 .../balancer/conf/util/TenantDomainContext.java |   80 --
 .../InvalidConfigurationException.java          |   33 +
 .../internal/LoadBalancerServiceComponent.java  |   57 +-
 .../test/LoadBalancerConfigUtilTest.java        |   48 -
 .../test/LoadBalancerConfigurationTest.java     |  179 +--
 .../load/balancer/test/NodeBuilderTest.java     |  123 --
 .../src/test/resources/loadbalancer.conf        |   84 --
 .../src/test/resources/loadbalancer1.conf       |   60 -
 .../src/test/resources/loadbalancer2.conf       |   50 -
 .../sample/configuration/loadbalancer1.conf     |   66 +
 .../distribution/src/main/bin/stratos.bat       |    2 +-
 .../distribution/src/main/bin/stratos.sh        |    2 +-
 .../src/main/conf/loadbalancer.conf             |   45 +
 20 files changed, 524 insertions(+), 2263 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/fb679a6b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerContext.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerContext.java
index fd68479..e9080e7 100644
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerContext.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerContext.java
@@ -33,6 +33,7 @@ import org.wso2.carbon.user.core.service.RealmService;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Defines load balancer context information.
@@ -50,7 +51,7 @@ public class LoadBalancerContext {
     private DependencyManagementService dependencyManager;
 
     // <TenantId, SynapseEnvironmentService> Map
-    private Map<Integer, SynapseEnvironmentService> synapseEnvironmentServices;
+    private Map<Integer, SynapseEnvironmentService> synapseEnvironmentServiceMap;
     // <ServiceName, ServiceContext> Map
     private Map<String, ServiceContext> serviceContextMap;
     // <ClusterId, ClusterContext> Map
@@ -59,10 +60,10 @@ public class LoadBalancerContext {
     private Map<String, Cluster> clusterMap;
 
     private LoadBalancerContext() {
-        synapseEnvironmentServices = new HashMap<Integer, SynapseEnvironmentService>();
-        serviceContextMap = new HashMap<String, ServiceContext>();
-        clusterContextMap = new HashMap<String, ClusterContext>();
-        clusterMap = new HashMap<String, Cluster>();
+        synapseEnvironmentServiceMap = new ConcurrentHashMap<Integer, SynapseEnvironmentService>();
+        serviceContextMap = new ConcurrentHashMap<String, ServiceContext>();
+        clusterContextMap = new ConcurrentHashMap<String, ClusterContext>();
+        clusterMap = new ConcurrentHashMap<String, Cluster>();
     }
 
     public static synchronized LoadBalancerContext getInstance() {
@@ -76,6 +77,13 @@ public class LoadBalancerContext {
         return instance;
     }
 
+    public void clear() {
+        synapseEnvironmentServiceMap.clear();
+        serviceContextMap.clear();
+        clusterContextMap.clear();
+        clusterMap.clear();
+    }
+
     public RealmService getRealmService() {
         return realmService;
     }
@@ -138,19 +146,19 @@ public class LoadBalancerContext {
     }
 
     public SynapseEnvironmentService getSynapseEnvironmentService(int tenantId) {
-        return synapseEnvironmentServices.get(tenantId);
+        return synapseEnvironmentServiceMap.get(tenantId);
     }
 
     public void addSynapseEnvironmentService(int tenantId, SynapseEnvironmentService synapseEnvironmentService) {
-        synapseEnvironmentServices.put(tenantId, synapseEnvironmentService);
+        synapseEnvironmentServiceMap.put(tenantId, synapseEnvironmentService);
     }
 
     public void removeSynapseEnvironmentService(int tenantId) {
-        synapseEnvironmentServices.remove(tenantId);
+        synapseEnvironmentServiceMap.remove(tenantId);
     }
 
-    public Map<Integer, SynapseEnvironmentService> getSynapseEnvironmentServices() {
-        return synapseEnvironmentServices;
+    public Map<Integer, SynapseEnvironmentService> getSynapseEnvironmentServiceMap() {
+        return synapseEnvironmentServiceMap;
     }
 
     public ConfigurationContext getConfigCtxt() {

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/fb679a6b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/LoadBalancerConfiguration.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/LoadBalancerConfiguration.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/LoadBalancerConfiguration.java
old mode 100755
new mode 100644
index 747ba5b..2cdd97f
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/LoadBalancerConfiguration.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/LoadBalancerConfiguration.java
@@ -1,1202 +1,362 @@
-/**
- *  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.
+/*
+ * 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.load.balancer.conf;
 
-import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.apache.synapse.commons.util.PropertyHelper;
+import org.apache.stratos.load.balancer.LoadBalancerContext;
+import org.apache.stratos.load.balancer.conf.domain.Algorithm;
 import org.apache.stratos.load.balancer.conf.structure.Node;
 import org.apache.stratos.load.balancer.conf.structure.NodeBuilder;
-import org.apache.stratos.load.balancer.conf.util.Constants;
-import org.apache.stratos.load.balancer.conf.util.HostContext;
-import org.apache.stratos.load.balancer.conf.util.LoadBalancerConfigUtil;
-import org.apache.stratos.load.balancer.conf.util.TenantDomainContext;
-import java.io.*;
-import java.net.URL;
+import org.apache.stratos.load.balancer.exception.InvalidConfigurationException;
+import org.apache.stratos.messaging.domain.topology.Cluster;
+import org.apache.stratos.messaging.domain.topology.Member;
+import org.apache.stratos.messaging.domain.topology.Port;
+import org.apache.stratos.messaging.domain.topology.Service;
+import org.apache.stratos.messaging.message.receiver.topology.TopologyManager;
+
+import java.io.File;
 import java.util.*;
 
 /**
- * Data object which hold configuration data of the load analyzer task
+ * Load balancer configuration definition.
  */
-@SuppressWarnings("unused")
-public class LoadBalancerConfiguration implements Serializable {
-
-    protected static final long serialVersionUID = -5553545217542808233L;
-
+public class LoadBalancerConfiguration {
     private static final Log log = LogFactory.getLog(LoadBalancerConfiguration.class);
+    private static volatile LoadBalancerConfiguration instance;
+
+    private String defaultAlgorithmName;
+    private boolean failOver;
+    private boolean sessionAffinity;
+    private long sessionTimeout;
+    private boolean cepStatsPublisherEnabled;
+    private String mbIp;
+    private int mbPort;
+    private String cepIp;
+    private int cepPort;
+    private boolean topologyEventListenerEnabled;
+    private boolean usePublicIpAddresses;
+    private Map<String, Algorithm> algorithmMap;
 
     /**
-     * This map is there to speed up the lookup time.
-     * Key: domain
-     * <p/>
-     * Value: A map whose key is sub domain and value is ServiceConfiguration
+     * Load balancer configuration is singleton.
      */
-    private Map<String, Map<String, ServiceConfiguration>> serviceConfigurations =
-            new HashMap<String, Map<String, ServiceConfiguration>>();
-    
-    /**
-     * Key - host name
-     * Value - {@link org.apache.stratos.load.balancer.conf.util.HostContext}
-     */
-    private transient Map<String, HostContext> hostCtxt = new HashMap<String, HostContext>();
-    
-    /**
-     * This map is there to speed up the lookup time.
-     * Key: service name/cartridge type (Stratos2). NOTE: that this is not the service cluster domain.
-     * Value: list of {@link org.apache.stratos.load.balancer.conf.LoadBalancerConfiguration.ServiceConfiguration} - corresponding objects under a service name.
-     */
-	private Map<String, List<ServiceConfiguration>> serviceNameToServiceConfigurations =
-			new HashMap<String, List<ServiceConfiguration>>();
-
-    /**
-     * This list will be used to identify host name duplications among different services.
-     * Within a service there can be duplications, but among different services you can't have duplications.
-     * Key - service name
-     * Value - hosts under the respective service.
-     */
-    private Map<String, Set<String>> hostNamesTracker = new HashMap<String, Set<String>>();
-
-    protected ServiceConfiguration defaultServiceConfig;
-    protected LBConfiguration lbConfig;
-
-    /**
-     * LBConfig file as a String
-     */
-    protected String lbConfigString;
-
-    /**
-     * Root node object for loadbalancer.conf
-     */
-    protected Node rootNode;
-
-    private LoadBalancerConfiguration(){
-        init(System.getProperty("loadbalancer.conf"));
+    private LoadBalancerConfiguration() {
+        this.algorithmMap = new HashMap<String, Algorithm>();
     }
 
-    private static LoadBalancerConfiguration instance ;
-    
-    public static LoadBalancerConfiguration getInstance(){
-        if(instance == null){
-            instance = new LoadBalancerConfiguration();
+    public static synchronized LoadBalancerConfiguration getInstance() {
+        if (instance == null) {
+            synchronized (LoadBalancerConfiguration.class) {
+                if (instance == null) {
+                    // Clear load balancer context
+                    LoadBalancerContext.getInstance().clear();
+                    // Read load balancer configuration from file
+                    LoadBalancerConfigurationReader reader = new LoadBalancerConfigurationReader();
+                    instance = reader.readConfigurationFromFile();
+                }
+            }
         }
         return instance;
     }
 
-    /**
-     * Sample loadbalancer.conf:
-     * <p/>
-     * loadbalancer {
-     * # minimum number of load balancer instances
-     * instances           1;
-     * # whether autoscaling enable or not
-     * enable_autoscaler   true;
-     * # End point reference of the Autoscaler Service
-     * autoscaler_service_epr  https://10.100.3.81:9443/services/AutoscalerService/;
-     * # interval between two task executions in milliseconds
-     * autoscaler_task_interval 1000;
-     * # after an instance booted up, task will wait till this much of time and let the server started up
-     * server_startup_delay 15000;
-     * }
-     * <p/>
-     * services {
-     * defaults {
-     * min_app_instances       1;
-     * max_app_instances       5;
-     * queue_length_per_node   400;
-     * rounds_to_average       10;
-     * instances_per_scale_up  1;
-     * message_expiry_time     60000;
-     * }
-     * <p/>
-     * appserver {
-     * hosts                   appserver.cloud-test.wso2.com,as.cloud-test.wso2.com;
-     * domains   {
-     * wso2.as1.domain {
-     * tenant_range    1-100;
-     * }
-     * wso2.as2.domain {
-     * tenant_range    101-200;
-     * }
-     * wso2.as3.domain {
-     * tenant_range    *;
-     * }
-     * }
-     * }
-     * }
-     *
-     * @param configURL URL of the load balancer config
-     */
-    public void init(String configURL) {
-
-        if(configURL == null){
-            String msg = "Cannot locate the location of the loadbalancer.conf file." +
-                   " You need to set the 'loadbalancer.conf' system property.";
-            log.error(msg);
-            throw new RuntimeException(msg);
-        }
-        
-        if (configURL.startsWith("$system:")) {
-            configURL = System.getProperty(configURL.substring("$system:".length()));
-        }
-
-        try {
-
-            // get loadbalancer.conf file as a String
-            if (configURL.startsWith(File.separator)) {
-                lbConfigString = createLBConfigString(configURL);
-            } else {
-                lbConfigString = createLBConfigString(new URL(configURL).openStream());
-            }
-
-        } catch (Exception e) {
-            String msg = "Cannot read configuration file from " + configURL;
-            log.error(msg, e);
-            throw new RuntimeException(msg, e);
-        }
-
-        // build a Node object for whole loadbalancer.conf
-        rootNode = new Node();
-        rootNode.setName("root");
-        rootNode = NodeBuilder.buildNode(rootNode, lbConfigString);
-
-        // load 'loadbalancer' node
-        Node lbConfigNode = rootNode.findChildNodeByName(Constants.LOAD_BALANCER_ELEMENT);
-
-        if(lbConfigNode != null){
-        	createConfiguration(lbConfig = new LBConfiguration(), lbConfigNode);
-        }
-
-        // load services node
-        Node servicesConfigNode = rootNode.findChildNodeByName(Constants.SERVICES_ELEMENT);
-
-        if (servicesConfigNode == null) {
-            String msg = "Mandatory " + Constants.SERVICES_ELEMENT +
-                    " element can not be found in the configuration file.";
-            log.error(msg);
-            throw new RuntimeException(msg);
-        }
-
-        // Set services configuration
-        createServicesConfig(servicesConfigNode);
-
+    public String getDefaultAlgorithmName() {
+        return defaultAlgorithmName;
     }
 
-
-    /**
-     * Process the content of the following 'services' element
-     * <p/>
-     * services {
-     * defaults {
-     * min_app_instances       1;
-     * max_app_instances       5;
-     * queue_length_per_node   400;
-     * rounds_to_average       10;
-     * instances_per_scale_up  1;
-     * message_expiry_time     60000;
-     * }
-     * <p/>
-     * appserver {
-     * hosts                   appserver.cloud-test.wso2.com,as.cloud-test.wso2.com;
-     * domains   {
-     * wso2.as1.domain {
-     * tenant_range    1-100;
-     * }
-     * wso2.as2.domain {
-     * tenant_range    101-200;
-     * }
-     * wso2.as3.domain {
-     * tenant_range    *;
-     * }
-     * }
-     * }
-     * }
-     *
-     * @param servicesConfigNode services element's Node
-     */
-    public List<ServiceConfiguration> createServicesConfig(Node servicesConfigNode) {
-
-        // current list of service configs
-        List<ServiceConfiguration> currentServiceConfigs = new ArrayList<ServiceConfiguration>();
-        
-        // Building default configuration
-        Node defaultNode = servicesConfigNode.findChildNodeByName(Constants.DEFAULTS_ELEMENT);
-
-        if (defaultNode != null) {
-
-            createConfiguration(defaultServiceConfig = new ServiceConfiguration(), defaultNode);
-        }
-
-        // Building custom services configuration
-        for (Node serviceNode : servicesConfigNode.getChildNodes()) {
-            //skip default node
-            if (serviceNode != defaultNode) {
-
-                String serviceName = serviceNode.getName();
-
-                // reading domains
-
-                Node domainsNode;
-
-                if (serviceNode.getChildNodes().isEmpty() ||
-                        !(domainsNode = serviceNode.getChildNodes().get(0)).getName().equals(
-                                Constants.DOMAIN_ELEMENT)) {
-
-                    String msg = "The mandatory domains element, child of the " + serviceName +
-                            " element is not specified in the configuration file. \n"+
-                            serviceNode.toString();
-                    log.error(msg);
-                    throw new RuntimeException(msg);
-                }
-
-                if (domainsNode.getChildNodes().isEmpty()) {
-                    // this is probably a mistake, so we don't proceed
-                    String msg = "No domain is specified under " + Constants.DOMAIN_ELEMENT +
-                            " of " + serviceName + " element.";
-                    log.error(msg);
-                    throw new RuntimeException(msg);
-                }
-
-                ServiceConfiguration serviceConfig;
-
-                // iterates through all the service domain specified in this service element. 
-                for (Node domain : domainsNode.getChildNodes()) {
-
-                    // create a new service configuration
-                    serviceConfig = new ServiceConfiguration();
-
-                    // set service name
-                    serviceConfig.setServiceName(serviceName);
-                    
-                    // set domain name
-                    serviceConfig.setDomain(domain.getName());
-
-                    // let's set properties common to all domains specified in this service element.
-                    createConfiguration(serviceConfig, serviceNode);
-
-                    // load properties specified under this service domain element.
-                    createConfiguration(serviceConfig, domain);
-
-                    // check host name duplication 
-                    if(isDuplicatedHost(serviceNode.getName(), serviceConfig)){
-                        // this is probably a mistake, so we don't proceed
-                        String msg = "Duplicated host names detected for different service domains.\n" +
-                                "Element: \n"+serviceNode.toString();
-                        log.error(msg);
-                        throw new RuntimeException(msg);
-                    }
-                    
-                    currentServiceConfigs.add(serviceConfig);
-
-                }
-            }
-        }
-
-        for (ServiceConfiguration serviceConfiguration : currentServiceConfigs) {
-            
-            // add the built ServiceConfiguration, to the map
-            addServiceConfiguration(serviceConfiguration);
-            
-        }
-        
-        return currentServiceConfigs;
-
+    public void setDefaultAlgorithmName(String defaultAlgorithmName) {
+        this.defaultAlgorithmName = defaultAlgorithmName;
     }
 
-
-    public boolean addServiceConfiguration(ServiceConfiguration serviceConfig) {
-
-        Map<String, ServiceConfiguration> map;
-        String domain = serviceConfig.getDomain();
-        
-        if(domain == null){
-            String msg = "Domain of a Service Configuration cannot be null. Hence this " +
-            		"Configuration will be neglected.";
-            log.error(msg);
-            return false;
-        }
-        
-        String subDomain = serviceConfig.getSubDomain();
-
-        if (serviceConfigurations.containsKey(domain)) {
-            map = serviceConfigurations.get(domain);
-        } else {
-            map = new HashMap<String, ServiceConfiguration>();
-        }
-        // put this serviceConfig
-        map.put(subDomain, serviceConfig);
-
-        // update the parent map
-        serviceConfigurations.put(domain, map);
-        
-        // add to serviceNameToServiceConfiguration map
-        List<ServiceConfiguration> configs;
-        if(serviceNameToServiceConfigurations.get(serviceConfig.getServiceName()) == null){
-        	configs = new ArrayList<ServiceConfiguration>();
-        	
-        }else{
-        	configs = serviceNameToServiceConfigurations.get(serviceConfig.getServiceName());
-        }
-        
-        if(!configs.contains(serviceConfig)){
-        	configs.add(serviceConfig);
-        }
-        serviceNameToServiceConfigurations.put(serviceConfig.getServiceName(), configs);
-        
-        return true;
+    public boolean isFailOver() {
+        return failOver;
     }
-    
-    public ServiceConfiguration removeServiceConfiguration(String domain, String subDomain) {
 
-        Map<String, ServiceConfiguration> map;
-        ServiceConfiguration serviceConfig = null;
-        
-        if(domain == null){
-            String msg = "Domain of a Service Configuration cannot be null. Hence this " +
-            		"Configuration will be neglected.";
-            log.error(msg);
-            return null;
-        }
-
-        if (serviceConfigurations.containsKey(domain)) {
-            map = serviceConfigurations.get(domain);
-            
-            if(map != null){
-            	serviceConfig = map.remove(subDomain);
-            }
-        } 
-        
-        if(serviceConfig == null){
-        	String msg = "No matching service configuration found for domain: "+domain+
-        			", sub domain: "+subDomain;
-            log.error(msg);
-        	return null;
-        }
-        
-        String serviceName = serviceConfig.getServiceName();
-        
-        if (serviceName != null && serviceNameToServiceConfigurations.containsKey(serviceName)) {
-            if(serviceConfig != null){
-            	List<ServiceConfiguration> list = serviceNameToServiceConfigurations.get(serviceName);
-            	
-            	list.remove(serviceConfig);
-            	
-            	serviceNameToServiceConfigurations.put(serviceName, list);
-            }
-        } 
-        
-        Set<String> allHosts;
-
-        if (hostNamesTracker.containsKey(serviceName)) {
-            allHosts = hostNamesTracker.get(serviceName);
-            
-            for (String hostName : serviceConfig.getHosts()) {
-	            
-				if (hostName != null) {
-					
-					allHosts.remove(hostName);
-
-					hostCtxt.remove(hostName);
-				}
-            }
-        }
-        
-        return serviceConfig;
-    }
-    
-    public void resetData(){
-    	serviceConfigurations =
-                new HashMap<String, Map<String, ServiceConfiguration>>();
-    	
-    	serviceNameToServiceConfigurations =
-    			new HashMap<String, List<ServiceConfiguration>>();
-    	
+    public void setFailOver(boolean failOver) {
+        this.failOver = failOver;
     }
 
-
-    /**
-     * Duplications can only be seen, when you traverse down the configuration file.
-     * 
-     */
-    public boolean isDuplicatedHost(String name, ServiceConfiguration serviceConfig) {
-
-        /**
-         * This will be populated with host names of all other services other than the
-         * service subjected to the test.
-         */
-        List<String> hostsOtherThanMine = new ArrayList<String>(hostNamesTracker.values().size());
-
-        for (Map.Entry<String, Set<String>> entry : hostNamesTracker.entrySet()) {
-            if (!entry.getKey().equals(name)) {
-                hostsOtherThanMine.addAll(entry.getValue());
-            }
-        }
-
-        for (String host : serviceConfig.getHosts()) {
-            if (!hostsOtherThanMine.isEmpty() && hostsOtherThanMine.contains(host)) {
-                return true;
-            }
-        }
-
-        addToHostNameTrackerMap(name, serviceConfig.getHosts());
-
-        return false;
+    public boolean isSessionAffinity() {
+        return sessionAffinity;
     }
 
-
-    public void addToHostNameTrackerMap(String name, List<String> hosts) {
-
-        Set<String> allHosts;
-
-        if (hostNamesTracker.containsKey(name)) {
-            allHosts = hostNamesTracker.get(name);
-            allHosts.addAll(hosts);
-        } else {
-            allHosts = new HashSet<String>(hosts);
-        }
-        hostNamesTracker.put(name, allHosts);
+    public void setSessionAffinity(boolean sessionAffinity) {
+        this.sessionAffinity = sessionAffinity;
     }
-    
-    public void addToHostContextMap(String hostName, HostContext ctxt) {
 
-        if (hostName != null && ctxt != null) {
-            hostCtxt.put(hostName, ctxt);
-        }
+    public long getSessionTimeout() {
+        return sessionTimeout;
     }
-    
-    /**
-     * Return a map of {@link org.apache.stratos.load.balancer.conf.util.HostContext}.
-     * @return
-     */
-    public Map<String, HostContext> getHostContextMap() {
-
-        List<Integer> tenantIds;
-        Map<String, String> URLSuffixes;
-
-        // FIXME if possible! I couldn't think of any other way to do this, at this moment.
-        // Note: some of these for-loops are pretty small, thus no considerable performance overhead.
-        // iterate through each service
-        for (Iterator<Set<String>> it = hostNamesTracker.values().iterator(); it.hasNext();) {
-
-            // iterate through host names of this service
-            for (String hostName : ((Set<String>) it.next())) {
-                                                                  
-                // building HostContext
-                HostContext ctxt = new HostContext(hostName);
-
-                // iterate through domains of this host
-                for (Map.Entry<String, Map<String, ServiceConfiguration>> parentMap : serviceConfigurations.entrySet()) {
-
-                    // iterate through sub domain of this domain
-                    for (Map.Entry<String, ServiceConfiguration> childMap : parentMap.getValue()
-                            .entrySet()) {
-                        // iterate through hosts of this
-                        for (String host : childMap.getValue().getHosts()) {
-                            // if a matching Service configuration is found.
-                            if (host.equals(hostName)) {
-                                
-                                String tenantRange = childMap.getValue().getTenantRange();
-                                String domain = parentMap.getKey();
-                                String subDomain = childMap.getKey();
-                                          
-                                ctxt.addTenantDomainContexts(LoadBalancerConfigUtil.getTenantDomainContexts(tenantRange, domain, subDomain));
-
-                                break;
-                            }
-                        }
-                        
-                        //iterate through URL suffixes
-                        for(Map.Entry<String, String> entry : childMap.getValue().getUrl_suffix().entrySet()) {
-                            if(entry.getKey().equals(hostName)) {
-                                
-                                ctxt.setUrlSuffix(entry.getValue());
-                                
-                                break;
-                            }
-
-                        }
-                    }
-                }
-
-                // add this hostCtxt
-                hostCtxt.put(hostName, ctxt);
-            }
-
-        }
-
-        return hostCtxt;
 
+    public void setSessionTimeout(long sessionTimeout) {
+        this.sessionTimeout = sessionTimeout;
     }
 
-    protected void createConfiguration(Configuration config, Node node) {
-
-        if (node == null) {
-            String msg = "The configuration element for " +
-                    config.getClass().getName() + " is null.";
-            throw new RuntimeException(msg);
-        }
-
-        try {
-            // load properties
-            for (Map.Entry<String, String> entry : node.getProperties().entrySet()) {
-                String key = entry.getKey();
-                String value = entry.getValue();
-
-                PropertyHelper.setInstanceProperty(key, value, config);
-            }
-
-        } catch (Exception e) {
-            String msg = "Error setting values to " + config.getClass().getName();
-            log.error(msg, e);
-            throw new RuntimeException(msg, e);
-        }
+    public boolean isCepStatsPublisherEnabled() {
+        return cepStatsPublisherEnabled;
     }
 
-    public LBConfiguration getLoadBalancerConfig() {
-        return lbConfig;
+    public void setCepStatsPublisherEnabled(boolean cepStatsPublisherEnabled) {
+        this.cepStatsPublisherEnabled = cepStatsPublisherEnabled;
     }
 
-    public String[] getServiceDomains() {
-
-        Object[] objs = serviceConfigurations.keySet().toArray();
-
-        return Arrays.copyOf(objs, objs.length, String[].class);
-
+    public String getMbIp() {
+        return mbIp;
     }
 
-    public String[] getServiceSubDomains(String domain) {
-
-        if (serviceConfigurations.get(domain) != null) {
-            Object[] objs = serviceConfigurations.get(domain).keySet().toArray();
-            return Arrays.copyOf(objs, objs.length, String[].class);
-        }
-
-        return new String[0];
+    public void setMbIp(String mbIp) {
+        this.mbIp = mbIp;
     }
 
-    public ServiceConfiguration getServiceConfig(String domain, String subDomain) {
-        if (serviceConfigurations.get(domain) != null) {
-            return serviceConfigurations.get(domain).get(subDomain);
-        }
-        return null;
-    }
-    
-    
-    public List<ServiceConfiguration> getServiceConfigs(String serviceName) {
-        return serviceNameToServiceConfigurations.get(serviceName);
+    public int getMbPort() {
+        return mbPort;
     }
 
-    /**
-     * Convert given configuration file to a single String
-     *
-     * @param configFileName - file name to convert
-     * @return String with complete lb configuration
-     * @throws java.io.FileNotFoundException
-     */
-    public String createLBConfigString(String configFileName) throws FileNotFoundException {
-        StringBuilder lbConfigString = new StringBuilder("");
-
-        File configFile = new File(configFileName);
-        Scanner scanner;
-
-        scanner = new Scanner(configFile);
-
-        while (scanner.hasNextLine()) {
-            lbConfigString.append(scanner.nextLine().trim() + "\n");
-        }
-
-        return lbConfigString.toString().trim();
+    public void setMbPort(int mbPort) {
+        this.mbPort = mbPort;
     }
 
-    public String createLBConfigString(InputStream configFileName) throws IOException {
-
-        // read the stream with BufferedReader
-        BufferedReader br = new BufferedReader(new InputStreamReader(configFileName));
-
-        StringBuilder sb = new StringBuilder();
-
-        String line;
-        while ((line = br.readLine()) != null) {
-            sb.append(line.trim() + "\n");
-        }
-
-        return sb.toString().trim();
+    public String getCepIp() {
+        return cepIp;
     }
 
-    public abstract class Configuration implements Serializable {
-
-        private static final long serialVersionUID = -5433889427746551250L;
-        protected String imageId = System.getenv("ami_id");
-        protected String payload;
-        protected boolean payloadSet;
-
-        protected String availability_zone = "us-east-1c";
-        protected boolean availabilityZoneSet;
-
-        protected String[] security_groups = new String[]{"default"};
-        protected boolean securityGroupsSet;
-
-        protected String instance_type = "m1.large";
-        protected boolean instanceTypeSet;
-
-        protected String additional_info;
-
-        public String getImageId() {
-            return imageId;
-        }
-
-        public String getAdditionalInfo() {
-            return additional_info;
-        }
-
-        public String getAvailability_zone() {
-            if (this instanceof LBConfiguration) {
-                return availability_zone;
-            }
-            if (availabilityZoneSet) {
-                return availability_zone;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.availabilityZoneSet) {
-                return defaultServiceConfig.availability_zone;
-            }
-            return availability_zone;
-        }
-
-        public String[] getSecurityGroups() {
-            if (this instanceof LBConfiguration) {
-                return security_groups;
-            }
-            if (securityGroupsSet) {
-                return security_groups;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.securityGroupsSet) {
-                return defaultServiceConfig.security_groups;
-            }
-            return security_groups;
-        }
-
-        public String getInstanceType() {
-            if (this instanceof LBConfiguration) {
-                return instance_type;
-            }
-            if (instanceTypeSet) {
-                return instance_type;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.instanceTypeSet) {
-                return defaultServiceConfig.instance_type;
-            }
-            return instance_type;
-        }
-
-
-        public String getUserData() {
-            if (payload == null) {
-                payload = LoadBalancerConfigUtil.getUserData("resources/cluster_node.zip");
-            }
-            if (this instanceof LBConfiguration) {
-                return payload;
-            }
-            if (payloadSet) {
-                return payload;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.payloadSet) {
-                return defaultServiceConfig.payload;
-            }
-            return payload;
-        }
-
-        public void setPayload(String payload) {
-            this.payload = LoadBalancerConfigUtil.getUserData(LoadBalancerConfigUtil.replaceVariables(payload));
-            this.payloadSet = true;
-        }
-
-        public void setAvailability_zone(String availabilityZone) {
-            this.availability_zone = LoadBalancerConfigUtil.replaceVariables(availabilityZone);
-            this.availabilityZoneSet = true;
-        }
-
-        public void setSecurity_groups(String securityGroups) {
-            this.security_groups = LoadBalancerConfigUtil.replaceVariables(securityGroups).split(",");
-            this.securityGroupsSet = true;
-        }
-
-        public void setInstance_type(String instanceType) {
-            this.instance_type = LoadBalancerConfigUtil.replaceVariables(instanceType);
-            this.instanceTypeSet = true;
-        }
-
+    public void setCepIp(String cepIp) {
+        this.cepIp = cepIp;
     }
 
-    public class LBConfiguration extends Configuration implements Serializable {
-
-        private static final long serialVersionUID = 1357143883932816418L;
-        private String elasticIP;//= LoadBalancerConfigUtil.replaceVariables("${ELASTIC_IP}");
-        private int instances = 1;
-        private boolean isAutoscaleEnabled;
-        private int autoscalerTaskInterval = 30000;
-        private String autoscalerServiceEpr;
-        private int serverStartupDelay = 60000;
-        private int sizeOfCache = 0 ;
-        private boolean failOver;
-        private int sessionTimeOut = -1;
-        private String groupManagementAgentClass;
-        private String autoscalerTaskClass;
-        private String mbServerUrl;
-        private boolean useEmbeddedAutoscaler = true;
-        private String algorithm = "org.apache.synapse.endpoints.algorithms.RoundRobin";
-
-        public String getElasticIP() {
-            return elasticIP;
-        }
-
-        public int getInstances() {
-            return instances;
-        }
-
-        public boolean isAutoscaleEnabled() {
-            return isAutoscaleEnabled;
-        }
-        
-        public boolean useEmbeddedAutoscaler() {
-            return useEmbeddedAutoscaler;
-        }
-        
-        public boolean getFailOver() {
-            return failOver;
-        }
-
-        public String getAutoscalerServiceEpr() {
-            return autoscalerServiceEpr;
-        }
-
-        public int getAutoscalerTaskInterval() {
-            return autoscalerTaskInterval;
-        }
-
-        public int getServerStartupDelay() {
-            return serverStartupDelay;
-        }
-        
-        public int getSessionTimeOut() {
-            return sessionTimeOut;
-        }
-
-        public void setElasticIP(String elasticIP) {
-            this.elasticIP = LoadBalancerConfigUtil.replaceVariables(elasticIP);
-        }
-
-        public void setInstances(int instances) {
-            this.instances = instances;
-        }
-
-        public void setEnable_autoscaler(String isEnabled) {
-            this.isAutoscaleEnabled = Boolean.parseBoolean(isEnabled);
-        }
-        
-        public void setUse_embedded_autoscaler(String use) {
-            this.useEmbeddedAutoscaler = Boolean.parseBoolean(use);
-        }
-        
-        public void setFail_over(String isEnabled) {
-            this.failOver = Boolean.parseBoolean(isEnabled);
-        }
-
-        public void setAutoscaler_service_epr(String epr) {
-            this.autoscalerServiceEpr = epr;
-        }
-
-        public void setMb_server_url(String url) {
-            this.mbServerUrl = url;
-        }
-        
-        public String getMbServerUrl() {
-        	return mbServerUrl;
-        }
-
-		public void setAutoscaler_task_interval(String interval) {
-            this.autoscalerTaskInterval = Integer.parseInt(interval);
-        }
-
-        public void setServer_startup_delay(String delay) {
-            this.serverStartupDelay = Integer.parseInt(delay);
-        }
-        
-        public void setSession_timeout(String timeout) {
-            this.sessionTimeOut = Integer.parseInt(timeout);
-        }
-
-        public String getAlgorithm() {
-            return algorithm;
-        }
-
-        public void setAlgorithm(String algorithm) {
-            if (algorithm != null) {
-                this.algorithm = algorithm;
-            }
-        }
-
-        public int getSizeOfCache() {
-            return sizeOfCache;
-        }
-
-        public void setSize_of_cache(int sizeOfCache) {
-            this.sizeOfCache = sizeOfCache;
-        }
-
-        public String getGroupManagementAgentClass() {
-            return groupManagementAgentClass;
-        }
-        
-        public String getAutoscalerTaskClass() {
-            return autoscalerTaskClass;
-        }
-
-        public void setGroup_mgt_agent(String groupManagementAgentClass){
-            this.groupManagementAgentClass = groupManagementAgentClass;
-        }
-        
-        public void setAutoscaler_task(String autoscalerTaskClass){
-            this.autoscalerTaskClass = autoscalerTaskClass;
-        }
+    public int getCepPort() {
+        return cepPort;
     }
 
-    public class ServiceConfiguration extends Configuration implements Serializable {
-
-    	private String serviceName;
-    	
-        public String getServiceName() {
-        	return serviceName;
-        }
-
-		public void setServiceName(String name) {
-        	this.serviceName = name;
-        }
-		
-		public String getPublicIp() {
-        	return publicIp;
-        }
-
-		public void setPublic_ip(String publicIp) {
-        	this.publicIp = publicIp;
-        }
-
-		private String publicIp;
-
-		private static final long serialVersionUID = 8707314702788040116L;
-        private int minAppInstances = 1;
-        private boolean minAppInstancesSet;
+    public void setCepPort(int cepPort) {
+        this.cepPort = cepPort;
+    }
 
-        private int maxAppInstances = 3;
-        private boolean maxAppInstancesSet;
+    public boolean isTopologyEventListenerEnabled() {
+        return topologyEventListenerEnabled;
+    }
 
-        private int maxRequestsPerSecond = 100;
-        private boolean maxRequestsPerSecondSet;
-        
-        private double alarmingUpperRate = 0.7;
-        private boolean alarmingUpperRateSet;
+    public void setTopologyEventListenerEnabled(boolean topologyEventListenerEnabled) {
+        this.topologyEventListenerEnabled = topologyEventListenerEnabled;
+    }
 
-        private double alarmingLowerRate = 0.2;
-        private boolean alarmingLowerRateSet;
-        
-        private double scaleDownFactor = 0.25;
-        private boolean scaleDownFactorSet;
-        
-        private int roundsToAverage = 10;
-        private boolean roundsToAverageSet;
+    public boolean isUsePublicIpAddresses() {
+        return usePublicIpAddresses;
+    }
 
-        private int instancesPerScaleUp = 1;
-        private boolean instancesPerScaleUpSet;
+    public void setUsePublicIpAddresses(boolean usePublicIpAddresses) {
+        this.usePublicIpAddresses = usePublicIpAddresses;
+    }
 
-        private int messageExpiryTime = 60000; // milliseconds
-        private boolean messageExpiryTimeSet;
+    public Collection<Algorithm> getAlgorithms() {
+        return algorithmMap.values();
+    }
 
-        private List<String> hosts = new ArrayList<String>();
-        private Map<String, String> urlSuffixes = new HashMap<String, String>();
-        private boolean hostsSet;
+    public Algorithm getAlgorithm(String algorithmName) {
+        return algorithmMap.get(algorithmName);
+    }
 
-        private String domain;
+    void addAlgorithm(Algorithm algorithm) {
+        algorithmMap.put(algorithm.getName(), algorithm);
+    }
 
-        private String tenantRange;
-        private boolean tenantRangeSet;
+    private static class LoadBalancerConfigurationReader {
 
-        private String subDomain = Constants.DEFAULT_SUB_DOMAIN;
-        private boolean subDomainSet;
+        private String property;
 
-        public String getTenantRange() {
-            if (tenantRangeSet) {
-                return tenantRange;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.tenantRangeSet) {
-                return defaultServiceConfig.tenantRange;
+        public LoadBalancerConfiguration readConfigurationFromFile() {
+            String configFilePath = System.getProperty("loadbalancer.conf.file");
+            if(configFilePath == null){
+                throw new RuntimeException("loadbalancer.conf.file' system property is not set");
             }
-            return tenantRange;
-        }
 
-        public String getDomain() {
-            return domain;
-        }
+            try {
+                // Read load balancer configuraiton file
+                StringBuilder configFileContent = new StringBuilder();
+                File configFile = new File(configFilePath);
+                Scanner scanner = new Scanner(configFile);
+                while (scanner.hasNextLine()) {
+                    configFileContent.append(scanner.nextLine().trim() + "\n");
+                }
 
-        public List<String> getHosts() {
-            if (hostsSet) {
-                return hosts;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.hostsSet) {
-                return defaultServiceConfig.hosts;
+                Node loadBalancerNode = NodeBuilder.buildNode(configFileContent.toString());
+                // Transform node structure to configuration
+                LoadBalancerConfiguration configuration = transform(loadBalancerNode);
+                return configuration;
+            } catch (Exception e) {
+                throw new InvalidConfigurationException(String.format("Could not read load balancer configuration: %s", configFilePath), e);
             }
-            return hosts;
         }
 
-        public int getMinAppInstances() {
-            if (minAppInstancesSet) {
-                return minAppInstances;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.minAppInstancesSet) {
-                return defaultServiceConfig.minAppInstances;
+        private LoadBalancerConfiguration transform(Node loadBalancerNode) {
+            LoadBalancerConfiguration configuration = new LoadBalancerConfiguration();
+            if(loadBalancerNode == null) {
+                throw new InvalidConfigurationException("loadbalancer node was not found");
             }
-            return minAppInstances;
-        }
 
-        public int getMaxAppInstances() {
-            if (maxAppInstancesSet) {
-                return maxAppInstances;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.maxAppInstancesSet) {
-                return defaultServiceConfig.maxAppInstances;
+            // Set load balancer properties
+            String defaultAlgorithm = loadBalancerNode.getProperty("algorithm");
+            if(StringUtils.isBlank(defaultAlgorithm)) {
+                throw new InvalidConfigurationException("algorithm property was not found in loadbalancer node");
             }
-            return maxAppInstances;
-        }
+            configuration.setDefaultAlgorithmName(defaultAlgorithm);
 
-        public int getMaxRequestsPerSecond() {
-            if (maxRequestsPerSecondSet) {
-                return maxRequestsPerSecond;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.maxRequestsPerSecondSet) {
-                return defaultServiceConfig.maxRequestsPerSecond;
+            String failOver = loadBalancerNode.getProperty("failover");
+            if(StringUtils.isNotBlank(failOver)) {
+                configuration.setFailOver(Boolean.parseBoolean(failOver));
             }
-            return maxRequestsPerSecond;
-        }
 
-        public int getRoundsToAverage() {
-            if (roundsToAverageSet) {
-                return roundsToAverage;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.roundsToAverageSet) {
-                return defaultServiceConfig.roundsToAverage;
+            String sessionAffinity = loadBalancerNode.getProperty("session-affinity");
+            if(StringUtils.isNotBlank(sessionAffinity)) {
+                configuration.setSessionAffinity(Boolean.parseBoolean(sessionAffinity));
             }
-            return roundsToAverage;
-        }
-
-        public int getInstancesPerScaleUp() {
-            if (instancesPerScaleUpSet) {
-                return instancesPerScaleUp;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.instancesPerScaleUpSet) {
-                return defaultServiceConfig.instancesPerScaleUp;
+            String sessionTimeout =  loadBalancerNode.getProperty("session-timeout");
+            if(StringUtils.isNotBlank(sessionTimeout)) {
+                configuration.setSessionTimeout(Long.parseLong(sessionTimeout));
             }
-            return instancesPerScaleUp;
-        }
-
-        public int getMessageExpiryTime() {
-            if (messageExpiryTimeSet) {
-                return messageExpiryTime;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.messageExpiryTimeSet) {
-                return defaultServiceConfig.messageExpiryTime;
+            else {
+                // Session timeout is not found, set default value
+                configuration.setSessionTimeout(90000);
             }
-            return messageExpiryTime;
-        }
-
-        public String getSubDomain() {
-            if (subDomainSet) {
-                return subDomain;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.subDomainSet) {
-                return defaultServiceConfig.subDomain;
+            String topologyEventListenerEnabled = loadBalancerNode.getProperty("topology-event-listener-enabled");
+            if(StringUtils.isNotBlank(topologyEventListenerEnabled)) {
+                configuration.setTopologyEventListenerEnabled(Boolean.parseBoolean(topologyEventListenerEnabled));
+            }
+            String statsPublisherEnabled = loadBalancerNode.getProperty("cep-stats-publisher-enabled");
+            if(StringUtils.isNotBlank(statsPublisherEnabled)) {
+                configuration.setCepStatsPublisherEnabled(Boolean.parseBoolean(statsPublisherEnabled));
             }
-            return subDomain;
-        }
 
-        public void setMin_app_instances(int minAppInstances) {
-            this.minAppInstances = minAppInstances;
-            this.minAppInstancesSet = true;
-        }
+            // Read mb ip and port if topology event listener is enabled
+            if(configuration.isTopologyEventListenerEnabled()) {
+                String mbIp = loadBalancerNode.getProperty("mb-ip");
+                String mbPort = loadBalancerNode.getProperty("mb-port");
+                if(StringUtils.isBlank(mbIp)) {
+                    throw new InvalidConfigurationException("mb-ip property was not found in loadbalancer node");
+                }
+                if(StringUtils.isBlank(mbPort)) {
+                    throw new InvalidConfigurationException("mb-port property was not found in loadbalancer node");
+                }
 
-        public void setMax_app_instances(int maxAppInstances) {
-            if (maxAppInstances < 1) {
-                LoadBalancerConfigUtil.handleException("maxAppInstances in the autoscaler task configuration " +
-                        "should be at least 1");
+                configuration.setMbIp(mbIp);
+                configuration.setMbPort(Integer.parseInt(mbPort));
             }
-            this.maxAppInstances = maxAppInstances;
-            this.maxAppInstancesSet = true;
-        }
-        
-		public void setAlarming_upper_rate(double rate) {
-			if (rate > 0 && rate <= 1) {
-				this.alarmingUpperRate = rate;
-				this.alarmingUpperRateSet = true;
-			}
-		}
-
-        public void setAlarming_lower_rate(double rate) {
-			if (rate > 0 && rate <= 1) {
-				this.alarmingLowerRate = rate;
-				this.alarmingLowerRateSet = true;
-			}
-        }
-        
-		public void setScale_down_factor(double factor) {
-			if (factor > 0 && factor <= 1) {
-				this.scaleDownFactor = factor;
-				this.scaleDownFactorSet = true;
-			}
-		}
-        
-        public void setMax_requests_per_second(int rps) {
-            this.maxRequestsPerSecond = rps;
-            this.maxRequestsPerSecondSet = true;
-        }
 
-        public void setRounds_to_average(int roundsToAverage) {
-            this.roundsToAverage = roundsToAverage;
-            this.roundsToAverageSet = true;
-        }
+            // Read cep ip and port if cep stats publisher is enabled
+            if(configuration.isCepStatsPublisherEnabled()) {
+                String cepIp = loadBalancerNode.getProperty("cep-ip");
+                String cepPort = loadBalancerNode.getProperty("cep-port");
+                if(StringUtils.isBlank(cepIp)) {
+                    throw new InvalidConfigurationException("cep-ip property was not found in loadbalancer node");
+                }
+                if(StringUtils.isBlank(cepPort)) {
+                    throw new InvalidConfigurationException("cep-port property was not found in loadbalancer node");
+                }
 
-        public void setInstances_per_scale_up(int instancesPerScaleUp) {
-            if (instancesPerScaleUp < 1) {
-                LoadBalancerConfigUtil.handleException("instancesPerScaleUp in the autoscaler task configuration " +
-                        "should be at least 1");
+                configuration.setCepIp(cepIp);
+                configuration.setCepPort(Integer.parseInt(cepPort));
             }
-            this.instancesPerScaleUp = instancesPerScaleUp;
-            this.instancesPerScaleUpSet = true;
-        }
 
-        public void setMessage_expiry_time(int messageExpiryTime) {
-            if (messageExpiryTime < 1) {
-                LoadBalancerConfigUtil.handleException("messageExpiryTime in the autoscaler task configuration " +
-                        "should be at least 1");
+            Node algorithmsNode = loadBalancerNode.findChildNodeByName("algorithms");
+            if(loadBalancerNode == null) {
+                throw new RuntimeException("algorithms node was node found");
             }
-            this.messageExpiryTime = messageExpiryTime;
-            this.messageExpiryTimeSet = true;
-        }
-
-        public void setHosts(String hostsStr) {
-            // clear all unnecessary values --> property will get overwritten
-            hosts = new ArrayList<String>();
-            // there can be multiple hosts, let's find out.
-            String[] host = hostsStr.split(Constants.HOSTS_DELIMITER);
-
-            for (String string : host) {
-                if (!string.isEmpty()) {
-                    this.hosts.add(string);
+            for(Node algorithmNode : algorithmsNode.getChildNodes()) {
+                String className = algorithmNode.getProperty("class-name");
+                if(StringUtils.isBlank(className)) {
+                    throw new InvalidConfigurationException(String.format("class-name property was not found in algorithm %s", algorithmNode.getName()));
                 }
+                Algorithm algorithm = new Algorithm(algorithmNode.getName(), className);
+                configuration.addAlgorithm(algorithm);
             }
 
-        }
-
-        public void setUrl_suffix(String suffix) {
-            // clear all unnecessary values --> property will get overwritten
-            //hosts = new ArrayList<String>();
-            // there can be multiple hosts, let's find out.
-            String[] suffixes = suffix.split(Constants.HOSTS_DELIMITER);
-            int count = 0;
-            if(suffixes.length == this.hosts.size()) {
-                for (String string : suffixes) {
-                    if (!string.isEmpty()) {
-                        this.urlSuffixes.put(this.hosts.get(count), string);
-                        count++;
-                    }
+            if(!configuration.isTopologyEventListenerEnabled()) {
+                Node servicesNode = loadBalancerNode.findChildNodeByName("services");
+                if(loadBalancerNode == null) {
+                    throw new RuntimeException("services node was not found");
                 }
-            
-            } else {
-                //Error
-            }
-        }
-
-        public Map<String, String> getUrl_suffix() {
-            return this.urlSuffixes;
-        }
 
-        public void setTenant_range(String range) {
-            this.tenantRange = range;
-        }
+                for(Node serviceNode : servicesNode.getChildNodes()) {
+                    Service service = new Service(serviceNode.getName());
+                    Node clustersNode = serviceNode.findChildNodeByName("clusters");
 
-        public void setSub_domain(String subDomain) {
-            this.subDomain = subDomain;
-            this.subDomainSet = true;
-        }
+                    for(Node clusterNode : clustersNode.getChildNodes()) {
+                        String clusterId = clusterNode.getName();
+                        Cluster cluster = new Cluster(service.getServiceName(), clusterId, null);
+                        String hosts = clusterNode.getProperty("hosts");
+                        if(StringUtils.isBlank(hosts)) {
+                            throw new InvalidConfigurationException(String.format("hosts node was not found in cluster %s", clusterNode.getName()));
+                        }
+                        String[] hostsArray = hosts.split(",");
+                        // TODO: Add multiple host-names to cluster
+                        cluster.setHostName(hostsArray[0]);
 
-        public void setDomain(String domain) {
-            this.domain = domain;
-        }
-        
-        public boolean equals(ServiceConfiguration config) {
-            return this.domain.equals(config.getDomain()) &&
-                    this.subDomain.equals(config.getSubDomain());
-        }
-        
-        public int hashCode() {
-            return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
-                    append(domain).
-                    append(subDomain).
-                    toHashCode();
-        }
+                        Node membersNode = clusterNode.findChildNodeByName("members");
+                        if(membersNode == null) {
+                            throw new InvalidConfigurationException(String.format("members node was not found in cluster %s", clusterId));
+                        }
 
-        public double getAlarmingUpperRate() {
-            if (alarmingUpperRateSet) {
-                return alarmingUpperRate;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.alarmingUpperRateSet) {
-                return defaultServiceConfig.alarmingUpperRate;
-            }
-            return alarmingUpperRate;
-        }
+                        for(Node memberNode : membersNode.getChildNodes()) {
+                            String memberId = memberNode.getName();
+                            Member member = new Member(cluster.getServiceName(), cluster.getClusterId(), memberId);
+                            String ip = memberNode.getProperty("ip");
+                            if(StringUtils.isBlank(ip)) {
+                                throw new InvalidConfigurationException(String.format("ip property was not found in member %s", memberId));
+                            }
+                            member.setMemberIp(ip);
+                            Node portsNode = memberNode.findChildNodeByName("ports");
+                            if(portsNode == null) {
+                                throw new InvalidConfigurationException(String.format("ports node was not found in member %s", memberId));
+                            }
+                            for(Node portNode : portsNode.getChildNodes()) {
+                                String value = portNode.getProperty("value");
+                                if(StringUtils.isBlank(value)) {
+                                    throw new InvalidConfigurationException(String.format("value property was not found in port %s in member %s", portNode.getName(), memberId));
+                                }
+                                String proxy = portNode.getProperty("proxy");
+                                if(StringUtils.isBlank(proxy)) {
+                                    throw new InvalidConfigurationException(String.format("proxy property was not found in port %s in member %s", portNode.getName(), memberId));
+                                }
+                                Port port = new Port(portNode.getName(), Integer.valueOf(value), Integer.valueOf(proxy));
+                                member.addPort(port);
+                            }
+                            cluster.addMember(member);
+                        }
+                        service.addCluster(cluster);
 
-        public double getAlarmingLowerRate() {
-            if (alarmingLowerRateSet) {
-                return alarmingLowerRate;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.alarmingLowerRateSet) {
-                return defaultServiceConfig.alarmingLowerRate;
-            }
-            return alarmingLowerRate;
-        }
+                        // Add cluster to load balancer context Map<Hostname,Cluster>
+                        LoadBalancerContext.getInstance().addCluster(cluster);
+                    }
 
-        public double getScaleDownFactor() {
-            if (scaleDownFactorSet) {
-                return scaleDownFactor;
-            } else if (defaultServiceConfig != null && defaultServiceConfig.scaleDownFactorSet) {
-                return defaultServiceConfig.scaleDownFactor;
+                    // Add service to topology manager
+                    try {
+                        TopologyManager.acquireWriteLock();
+                        TopologyManager.getTopology().addService(service);
+                    }
+                    finally {
+                        TopologyManager.releaseWriteLock();
+                    }
+                }
             }
-            return scaleDownFactor;
+            return configuration;
         }
     }
-
-    public Map<String, Set<String>> getHostNamesTracker() {
-        return hostNamesTracker;
-    }
-
-
-    public Map<String, Map<String, ServiceConfiguration>> getServiceConfigurations() {
-        return serviceConfigurations;
-    }
-
-
-    public Node getRootNode() {
-        return rootNode;
-    }
-
-
-    public void setRootNode(Node rootNode) {
-        this.rootNode = rootNode;
-    }
-
-    public static void setInstance(LoadBalancerConfiguration instance) {
-        LoadBalancerConfiguration.instance = instance;
-    }
-
-	public Map<String, List<ServiceConfiguration>> getServiceNameToServiceConfigurations() {
-    	return serviceNameToServiceConfigurations;
-    }
-	
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/fb679a6b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/Node.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/Node.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/Node.java
index c4820a7..dc24172 100755
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/Node.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/Node.java
@@ -133,13 +133,13 @@ public class Node implements Serializable{
      * Returns all the properties of this Node as a String.
      * Key and value of the property is separated by a tab (\t) character and
      * each property is separated by a new line character.
-     * @param indentation relative number of tabs 
+     * @param indentation relative number of tabs
      * @return properties of this node as a String.
      */
     public String propertiesToString(int indentation) {
-        
+
         String indent = getIndentation(indentation);
-        
+
         StringBuilder sb = new StringBuilder();
         for (Entry<String, String> entry : properties.entrySet()) {
             // hack to get a quick fix in.
@@ -149,7 +149,7 @@ public class Node implements Serializable{
         }
         return sb.toString();
     }
-    
+
     /**
      * Removes the first occurrence of a node having the given name
      * and returns the removed {@link org.apache.stratos.load.balancer.conf.structure.Node}.
@@ -158,13 +158,13 @@ public class Node implements Serializable{
      */
     public Node removeChildNode(String name) {
         Node aNode = findChildNodeByName(name);
-        
+
         if(aNode != null){
             if(childNodes.remove(aNode)){
                 return aNode;
             }
         }
-        
+
         return null;
     }
 
@@ -187,7 +187,7 @@ public class Node implements Serializable{
     }
 
     /**
-     * Appends a child node at the end of the List of child nodes of this Node, if 
+     * Appends a child node at the end of the List of child nodes of this Node, if
      * a similar node is not already present as a child node.
      * @param aNode child Node to be appended.
      */
@@ -352,5 +352,4 @@ public class Node implements Serializable{
                 
         return indent.toString();
     }
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/fb679a6b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/NodeBuilder.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/NodeBuilder.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/NodeBuilder.java
index 168492d..8cf610a 100755
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/NodeBuilder.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/structure/NodeBuilder.java
@@ -23,7 +23,7 @@ import org.apache.commons.logging.LogFactory;
 import org.apache.stratos.load.balancer.conf.util.Constants;
 
 /**
- * This responsible for build up a Node object from a given content.
+ * Responsible for build up a Node object from a given content.
  * Every closing brace should be in a new line.
  */
 public class NodeBuilder {
@@ -31,29 +31,33 @@ public class NodeBuilder {
     private static final Log log = LogFactory.getLog(NodeBuilder.class);
 
     /**
-     * This method is useful when you do not have a root node in your content.
-     * @param aNode
-     *            Node object whose name set.
+     * Construct a node structure for the given content.
      * @param content
-     *            should be something similar to following.
-     * 
-     *            abc d;
-     *            efg h;
-     *            # comment 
-     *            ij { # comment
-     *              klm n;
-     * 
-     *              pq {
-     *                  rst u;
+     *            Sample content format:
+     *
+     *            # comment
+     *            property_1 value1;
+     *            property_2 value2;
+     *
+     *            node1 { # comment
+     *              property_3 value3;
+     *              property_4 value4;
+     *
+     *              node2 {
+     *                  property_5 value5;
      *              }
      *            }
-     * 
-     * @return fully constructed Node
+     *
+     * @return fully constructed root node
      */
-    public static Node buildNode(Node aNode, String content) {
+    public static Node buildNode(String content) {
+        return buildNode(null, content);
+    }
+
+    private static Node buildNode(Node node, String content) {
 
     	if(content == null || content.isEmpty()){
-    		return aNode;
+    		return node;
     	}
     	
         String[] lines = content.split("\n");
@@ -61,24 +65,22 @@ public class NodeBuilder {
         for (int i = 0; i < lines.length; i++) {
             String line = lines[i].trim();
 
-            // avoid line comments
+            // Skip line comments
             if (!line.startsWith(Constants.NGINX_COMMENT)) {
-                
-                // skip comments in-line 
+
+                // Skip inline comments
                 if(line.contains(Constants.NGINX_COMMENT)){
                     line = line.substring(0, line.indexOf(Constants.NGINX_COMMENT));
                 }
                 
-                // another node is detected and it is not a variable starting from $
-                if (line.contains(Constants.NGINX_NODE_START_BRACE) && 
-                        !line.contains(Constants.NGINX_VARIABLE)) {
+                // A node is detected and it is not a variable starting from $
+                if (line.contains(Constants.NGINX_NODE_START_BRACE) && !line.contains(Constants.NGINX_VARIABLE)) {
                     
                     try {
                         Node childNode = new Node();
                         childNode.setName(line.substring(0, line.indexOf(Constants.NGINX_NODE_START_BRACE)).trim());
 
                         StringBuilder sb = new StringBuilder();
-
                         int matchingBraceTracker = 1;
 
                         while (!line.contains(Constants.NGINX_NODE_END_BRACE) || matchingBraceTracker != 0) {
@@ -87,40 +89,40 @@ public class NodeBuilder {
                                 break;
                             }
                             line = lines[i];
+                            sb.append(line + "\n");
+
                             if (line.contains(Constants.NGINX_NODE_START_BRACE)) {
                                 matchingBraceTracker++;
                             }
                             if (line.contains(Constants.NGINX_NODE_END_BRACE)) {
                                 matchingBraceTracker--;
                             }
-                            sb.append(line + "\n");
                         }
 
                         childNode = buildNode(childNode, sb.toString());
-						if (aNode == null) {
-							aNode = childNode;
+						if (node == null) {
+							node = childNode;
 						} else {
-							aNode.appendChild(childNode);
+							node.appendChild(childNode);
 						}
 
                     } catch (Exception e) {
-                        String msg = "Malformatted element is defined in the configuration file. [" +
-                                i + "] \n";
+                        String msg = "Malformed element found in configuration: [" + i + "] \n";
                         log.error(msg , e);
                         throw new RuntimeException(msg + line, e);
                     }
 
                 }
-                // this is a property
                 else {
                     if (!line.isEmpty() && !Constants.NGINX_NODE_END_BRACE.equals(line)) {
+                        // Add property
                         String[] prop = line.split(Constants.NGINX_SPACE_REGEX);
+                        String key = prop[0].replace(":", "");
                         String value = line.substring(prop[0].length(), line.indexOf(Constants.NGINX_LINE_DELIMITER)).trim();
                         try {
-                            aNode.addProperty(prop[0], value);
+                            node.addProperty(key, value);
                         } catch (Exception e) {
-                            String msg = "Malformatted property is defined in the configuration file. [" +
-                                    i + "] \n";
+                            String msg = "Malformed property found in configuration: [" + i + "] \n";
                             log.error(msg, e);
                             throw new RuntimeException(msg + line, e);
                         }
@@ -129,12 +131,6 @@ public class NodeBuilder {
             
             }
         }
-
-        return aNode;
-
-    }
-    
-    public static Node buildNode(String content) {
-	    return buildNode(null, content);
+        return node;
     }
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/fb679a6b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/Constants.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/Constants.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/Constants.java
index 31e172d..8b77ece 100755
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/Constants.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/Constants.java
@@ -28,23 +28,12 @@ public class Constants {
     public static final String DEFAULTS_ELEMENT = "defaults";
     public static final String HOSTS_ELEMENT = "hosts";
     public static final String HOSTS_DELIMITER = ",";
-    public static final String DOMAIN_ELEMENT = "domains";
-    public static final String TENANT_RANGE_ELEMENT = "tenant_range";
-    public static final String SUB_DOMAIN_ELEMENT = "sub_domain";
-    public static final String TENANT_RANGE_DELIMITER = "-";
-    public static final String UNLIMITED_TENANT_RANGE = "*";
-    public static final String AUTOSCALER_ENABLE_ELEMENT = "enable_autoscaler";
-    public static final String SUB_DOMAIN_DELIMITER = "#";
-    public static final String DEFAULT_SUB_DOMAIN = "__$default";
     
     /* Nginx format related constants */
-    
     public static final String NGINX_COMMENT = "#";
     public static final String NGINX_NODE_START_BRACE = "{";
     public static final String NGINX_NODE_END_BRACE = "}";
     public static final String NGINX_VARIABLE = "${";
     public static final String NGINX_LINE_DELIMITER = ";";
     public static final String NGINX_SPACE_REGEX = "[\\s]+";
-    
-    
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/fb679a6b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/HostContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/HostContext.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/HostContext.java
deleted file mode 100755
index ecd952a..0000000
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/conf/util/HostContext.java
+++ /dev/null
@@ -1,161 +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.load.balancer.conf.util;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.synapse.endpoints.algorithms.AlgorithmContext;
-import org.apache.synapse.endpoints.algorithms.LoadbalanceAlgorithm;
-
-/**
- * For each unique host name defined in loadbalancer configuration, we'll generate
- * this object. 
- */
-public class HostContext {
-    
-    /**
-     * A unique identifier to identify this {@link #HostContext()}
-     */
-    private String hostName;
-    
-    /**
-     * Key - tenant id
-     * Value - <code>TenantDomainContext</code> of the corresponding tenant
-     */
-    private Map<Integer, TenantDomainContext> tenantIdToTenantDomainContextMap = new HashMap<Integer, TenantDomainContext>();
-    
-    /**
-     * AlgorithmContext of this host
-     */
-    private AlgorithmContext algorithmContext;
-    
-    /**
-     * Load balance algorithm of this host
-     */
-    private LoadbalanceAlgorithm algorithm;
-    
-    private String urlSuffix;
-    
-    public HostContext(String hostName) {
-        this.hostName = hostName;
-    }
-    
-    public void addTenantDomainContexts(List<TenantDomainContext> ctxts) {
-        
-        for (TenantDomainContext tenantDomainContext : ctxts) {
-            tenantIdToTenantDomainContextMap.put(tenantDomainContext.getTenantId(), tenantDomainContext);
-        }
-    }
-    
-    @Deprecated
-    public void addTenantDomainContext(TenantDomainContext ctxt) {
-        tenantIdToTenantDomainContextMap.put(ctxt.getTenantId(), ctxt);
-    }
-    
-    public TenantDomainContext getTenantDomainContext(int tenantId) {
-        return tenantIdToTenantDomainContextMap.get(tenantId);
-    }
-    
-    /**
-     * Returns all the {@link org.apache.stratos.load.balancer.conf.util.TenantDomainContext} entries.
-     */
-    public Collection<TenantDomainContext> getTenantDomainContexts() {
-        return tenantIdToTenantDomainContextMap.values();
-    }
-    
-    /**
-     * Given a tenant id, this will return its domain.
-     * @param tenantId 
-     * @return domain if this tenant has a dedicated one, it will be returned.
-     * If not, and there's a default (*) domain, it will be returned.
-     * If neither of the above is defined, null will be returned.
-     */
-    public String getDomainFromTenantId(int tenantId) {
-        if (tenantIdToTenantDomainContextMap.get(tenantId) == null) {
-            // if there's no specific domain for this tenant, we will redirect it to the default
-            // cluster
-            
-            if(tenantIdToTenantDomainContextMap.get(0) == null){
-                return null;
-            }
-            
-            return tenantIdToTenantDomainContextMap.get(0).getDomain();
-        }
-
-        return tenantIdToTenantDomainContextMap.get(tenantId).getDomain();
-    }
-    
-    /**
-     * Given a tenant id, this will return its sub domain.
-     * @param tenantId 
-     * @return sub_domain if this tenant has a dedicated one, it will be returned.
-     * If not, and there's a default (*) sub domain, it will be returned.
-     * If neither of the above is defined, null will be returned.
-     */
-    public String getSubDomainFromTenantId(int tenantId) {
-        if (tenantIdToTenantDomainContextMap.get(tenantId) == null) {
-            // if there's no specific domain for this tenant, we will redirect it to the default
-            // cluster
-            
-            if(tenantIdToTenantDomainContextMap.get(0) == null){
-                return null;
-            }
-            
-            return tenantIdToTenantDomainContextMap.get(0).getSubDomain();
-        }
-
-        return tenantIdToTenantDomainContextMap.get(tenantId).getSubDomain();
-    }
-
-    public String getHostName() {
-        return hostName;
-    }
-    
-    public LoadbalanceAlgorithm getAlgorithm() {
-        return algorithm;
-    }
-
-    public AlgorithmContext getAlgorithmContext() {
-        return algorithmContext;
-    }
-
-    public void setAlgorithmContext(AlgorithmContext algorithmContext) {
-        this.algorithmContext = algorithmContext;
-    }
-
-    public void setAlgorithm(LoadbalanceAlgorithm algorithm) {
-        this.algorithm = algorithm;
-    }
-
-    public Map<Integer, TenantDomainContext> getTenantIdToTenantDomainContextMap() {
-        return tenantIdToTenantDomainContextMap;
-    }
-    
-    public void setUrlSuffix(String suffix)  {
-        this.urlSuffix = suffix;
-    }
-
-    public String getUrlSuffix() {
-        return this.urlSuffix;
-    }
-
-}