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 2014/05/31 09:45:03 UTC

git commit: STRATOS-659: Improved domain mapping functionality to re-write URLs with given application contexts in load balancer

Repository: incubator-stratos
Updated Branches:
  refs/heads/master 5cca68700 -> bf1ee1d1a


STRATOS-659: Improved domain mapping functionality to re-write URLs with given application contexts in load balancer


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

Branch: refs/heads/master
Commit: bf1ee1d1ae0b0861b61babb8acca7068643d259d
Parents: 5cca687
Author: Imesh Gunaratne <im...@apache.org>
Authored: Sat May 31 13:14:46 2014 +0530
Committer: Imesh Gunaratne <im...@apache.org>
Committed: Sat May 31 13:14:46 2014 +0530

----------------------------------------------------------------------
 .../LoadBalancerTenantEventReceiver.java        | 15 ++++++
 .../balancer/context/LoadBalancerContext.java   |  7 +++
 .../context/LoadBalancerContextUtil.java        | 55 +++++++++++++++++++-
 .../context/map/HostNameAppContextMap.java      | 51 ++++++++++++++++++
 .../context/map/HostNameClusterMap.java         |  2 +-
 .../TenantAwareLoadBalanceEndpoint.java         | 47 +++++++++++++----
 6 files changed, 165 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/bf1ee1d1/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerTenantEventReceiver.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerTenantEventReceiver.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerTenantEventReceiver.java
index 6ff4fef..058553b 100644
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerTenantEventReceiver.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/LoadBalancerTenantEventReceiver.java
@@ -74,6 +74,9 @@ public class LoadBalancerTenantEventReceiver implements Runnable {
                                         subscription.getServiceName(),
                                         subscription.getClusterIds(),
                                         subscriptionDomain.getDomainName());
+
+                                LoadBalancerContextUtil.addAppContextAgainstDomain(subscriptionDomain.getDomainName(),
+                                        subscriptionDomain.getApplicationContext());
                             }
                         }
                     }
@@ -123,6 +126,10 @@ public class LoadBalancerTenantEventReceiver implements Runnable {
                         tenantUnSubscribedEvent.getServiceName(),
                         tenantUnSubscribedEvent.getTenantId(),
                         tenantUnSubscribedEvent.getClusterIds());
+
+                LoadBalancerContextUtil.removeAppContextAgainstAllDomains(
+                        tenantUnSubscribedEvent.getServiceName(),
+                        tenantUnSubscribedEvent.getTenantId());
             }
         });
         tenantEventReceiver.addEventListener(new SubscriptionDomainsAddedEventListener() {
@@ -142,6 +149,10 @@ public class LoadBalancerTenantEventReceiver implements Runnable {
                         subscriptionDomainAddedEvent.getServiceName(),
                         subscriptionDomainAddedEvent.getClusterIds(),
                         subscriptionDomainAddedEvent.getDomainName());
+
+                LoadBalancerContextUtil.addAppContextAgainstDomain(
+                        subscriptionDomainAddedEvent.getDomainName(),
+                        subscriptionDomainAddedEvent.getApplicationContext());
             }
         });
         tenantEventReceiver.addEventListener(new SubscriptionDomainsRemovedEventListener() {
@@ -156,10 +167,14 @@ public class LoadBalancerTenantEventReceiver implements Runnable {
                             subscriptionDomainRemovedEvent.getClusterIds(),
                             subscriptionDomainRemovedEvent.getDomainName()));
                 }
+
                 LoadBalancerContextUtil.removeClustersAgainstDomain(
                         subscriptionDomainRemovedEvent.getServiceName(),
                         subscriptionDomainRemovedEvent.getClusterIds(),
                         subscriptionDomainRemovedEvent.getDomainName());
+
+                LoadBalancerContextUtil.removeAppContextAgainstDomain(
+                        subscriptionDomainRemovedEvent.getDomainName());
             }
         });
     }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/bf1ee1d1/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContext.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContext.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContext.java
index fe341d7..67d63ee 100644
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContext.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContext.java
@@ -62,6 +62,8 @@ public class LoadBalancerContext {
     // Map<Host/Domain-Name, Cluster>
     // Keep tack of all clusters
     private HostNameClusterMap hostNameClusterMap;
+    // Map<Host/Domain-Name, AppContext>
+    private HostNameAppContextMap hostNameAppContextMap;
     // Map<HostName, Map<TenantId, Cluster>>
     // Keep track of multi-tenant service clusters
     private MultiTenantClusterMap multiTenantClusterMap;
@@ -72,6 +74,7 @@ public class LoadBalancerContext {
         clusterIdClusterContextMap = new ClusterIdClusterContextMap();
         clusterIdClusterMap = new ClusterIdClusterMap();
         hostNameClusterMap = new HostNameClusterMap();
+        hostNameAppContextMap = new HostNameAppContextMap();
         multiTenantClusterMap = new MultiTenantClusterMap();
     }
 
@@ -182,6 +185,10 @@ public class LoadBalancerContext {
         return hostNameClusterMap;
     }
 
+    public HostNameAppContextMap getHostNameAppContextMap() {
+        return hostNameAppContextMap;
+    }
+
     public MultiTenantClusterMap getMultiTenantClusterMap() {
        return multiTenantClusterMap;
     }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/bf1ee1d1/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContextUtil.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContextUtil.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContextUtil.java
index a25d815..5761428 100644
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContextUtil.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/LoadBalancerContextUtil.java
@@ -357,7 +357,7 @@ public class LoadBalancerContextUtil {
                                 log.debug(String.format("Removing cluster from host/domain name -> cluster map: [service] %s " +
                                         "[tenant-id] %d [domains] %s", serviceName, tenantId, subscription.getSubscriptionDomains()));
                             }
-                            for(SubscriptionDomain subscriptionDomain : subscription.getSubscriptionDomains()) {
+                            for (SubscriptionDomain subscriptionDomain : subscription.getSubscriptionDomains()) {
                                 removeClusterAgainstDomain(cluster, subscriptionDomain.getDomainName());
                             }
                         } else {
@@ -424,4 +424,57 @@ public class LoadBalancerContextUtil {
             clusterMap.put(tenantId, cluster);
         }
     }
+
+    public static void addAppContextAgainstDomain(String domainName, String appContext) {
+        LoadBalancerContext.getInstance().getHostNameAppContextMap().addAppContext(domainName, appContext);
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Application context added against domain name: [domain-name] %s [app-context] %s",
+                    domainName, appContext));
+        }
+    }
+
+    public static void removeAppContextAgainstDomain(String domainName) {
+        LoadBalancerContext.getInstance().getHostNameAppContextMap().removeAppContext(domainName);
+        if (log.isDebugEnabled()) {
+            log.debug(String.format("Application context removed against domain name: [domain-name] %s",
+                    domainName));
+        }
+    }
+
+    public static void removeAppContextAgainstAllDomains(String serviceName, int tenantId) {
+        try {
+            TenantManager.acquireReadLock();
+            TopologyManager.acquireReadLock();
+
+            Service service = TopologyManager.getTopology().getService(serviceName);
+            if (service == null) {
+                if (log.isErrorEnabled()) {
+                    log.error(String.format("Service not found in topology: [service] %s", serviceName));
+                }
+                return;
+            }
+
+            Tenant tenant = TenantManager.getInstance().getTenant(tenantId);
+            if (tenant != null) {
+                for (Subscription subscription : tenant.getSubscriptions()) {
+                    if (subscription.getServiceName().equals(serviceName)) {
+                        if (log.isDebugEnabled()) {
+                            log.debug(String.format("Removing appContext against domain name: [service] %s " +
+                                    "[tenant-id] %d [domains] %s", serviceName, tenantId, subscription.getSubscriptionDomains()));
+                        }
+                        for (SubscriptionDomain subscriptionDomain : subscription.getSubscriptionDomains()) {
+                            removeAppContextAgainstDomain(subscriptionDomain.getDomainName());
+                        }
+                    } else {
+                        if (log.isDebugEnabled()) {
+                            log.debug(String.format("Tenant not subscribed to service: %s", serviceName));
+                        }
+                    }
+                }
+            }
+        } finally {
+            TopologyManager.releaseReadLock();
+            TenantManager.releaseReadLock();
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/bf1ee1d1/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameAppContextMap.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameAppContextMap.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameAppContextMap.java
new file mode 100644
index 0000000..e2ccfa3
--- /dev/null
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameAppContextMap.java
@@ -0,0 +1,51 @@
+/*
+ * 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.context.map;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Host/domain name application context map.
+ */
+public class HostNameAppContextMap {
+    private ConcurrentHashMap<String, String> concurrentHashMap;
+
+    public HostNameAppContextMap() {
+        concurrentHashMap = new ConcurrentHashMap<String, String>();
+    }
+
+    public void addAppContext(String hostName, String appContext) {
+        concurrentHashMap.put(hostName, appContext);
+    }
+
+    public String getAppContext(String hostName) {
+        return concurrentHashMap.get(hostName);
+    }
+
+    public void removeAppContext(String hostName) {
+        if(contains(hostName)) {
+            concurrentHashMap.remove(hostName);
+        }
+    }
+
+    public boolean contains(String hostName) {
+        return concurrentHashMap.containsKey(hostName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/bf1ee1d1/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameClusterMap.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameClusterMap.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameClusterMap.java
index e1c52f8..c855dd3 100644
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameClusterMap.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/context/map/HostNameClusterMap.java
@@ -24,7 +24,7 @@ import org.apache.stratos.messaging.domain.topology.Cluster;
 import java.util.concurrent.ConcurrentHashMap;
 
 /**
- * Host name cluster map for accessing clusters using host name:
+ * Host/domain name cluster map for accessing clusters using host name:
  * Map[HostName, Cluster]
  */
 public class HostNameClusterMap {

http://git-wip-us.apache.org/repos/asf/incubator-stratos/blob/bf1ee1d1/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/endpoint/TenantAwareLoadBalanceEndpoint.java
----------------------------------------------------------------------
diff --git a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/endpoint/TenantAwareLoadBalanceEndpoint.java b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/endpoint/TenantAwareLoadBalanceEndpoint.java
index 0dd0bd9..67af463 100644
--- a/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/endpoint/TenantAwareLoadBalanceEndpoint.java
+++ b/components/org.apache.stratos.load.balancer/src/main/java/org/apache/stratos/load/balancer/endpoint/TenantAwareLoadBalanceEndpoint.java
@@ -560,8 +560,7 @@ public class TenantAwareLoadBalanceEndpoint extends org.apache.synapse.endpoints
     }
 
     private EndpointReference getEndpointReferenceAfterURLRewrite(MessageContext synCtx, org.apache.axis2.clustering.Member currentMember,
-                                                                  String transport,
-                                                                  String address) {
+                                                                  String transport) {
         try {
             if (transport.startsWith(Constants.HTTPS)) {
                 transport = Constants.HTTPS;
@@ -573,11 +572,13 @@ public class TenantAwareLoadBalanceEndpoint extends org.apache.synapse.endpoints
                 throwSynapseException(synCtx, 500, msg);
             }
 
-            // URL Rewrite
+            String address = synCtx.getTo().getAddress();
             if (address.startsWith(Constants.HTTP + "://") || address.startsWith(Constants.HTTPS + "://")) {
+                // Remove protocol, hostname and port found in address
                 try {
-                    String _address = address.indexOf("?") > 0 ? address.substring(address.indexOf("?"), address.length()) : "";
-                    address = new URL(address).getPath() + _address;
+                    URL addressUrl = new URL(address);
+                    address = addressUrl.getPath() + (StringUtils.isNotBlank(addressUrl.getQuery()) ?
+                            "?" + addressUrl.getQuery() : "");
                 } catch (MalformedURLException e) {
                     String msg = String.format("URL is malformed: %s", address);
                     log.error(msg, e);
@@ -585,9 +586,24 @@ public class TenantAwareLoadBalanceEndpoint extends org.apache.synapse.endpoints
                 }
             }
 
-            String hostName = currentMember.getHostName();
-            int port = (transport.startsWith(Constants.HTTPS)) ? currentMember.getHttpsPort() : currentMember.getHttpPort();
-            return new EndpointReference(new URL(transport, hostName, port, address).toString());
+            String hostName = extractTargetHost(synCtx);
+            if (LoadBalancerContext.getInstance().getHostNameAppContextMap().contains(hostName)) {
+                String appContext = LoadBalancerContext.getInstance().getHostNameAppContextMap().getAppContext(hostName);
+                if(StringUtils.isNotBlank(appContext)) {
+                    if (log.isDebugEnabled()) {
+                        log.debug(String.format("Application context found: [domain-name] %s [app-context] %s", hostName, appContext));
+                        log.debug(String.format("Incoming request address: %s", address));
+                    }
+                    address = "/" + cleanURLPath(appContext) + "/" + cleanURLPath(address);
+                    if (log.isDebugEnabled()) {
+                        log.debug(String.format("Outgoing request address: %s", address));
+                    }
+                }
+            }
+
+            String memberHostName = currentMember.getHostName();
+            int memberPort = (transport.startsWith(Constants.HTTPS)) ? currentMember.getHttpsPort() : currentMember.getHttpPort();
+            return new EndpointReference(new URL(transport, memberHostName, memberPort, address).toString());
 
         } catch (MalformedURLException e) {
             if (log.isErrorEnabled()) {
@@ -598,6 +614,18 @@ public class TenantAwareLoadBalanceEndpoint extends org.apache.synapse.endpoints
         }
     }
 
+    private String cleanURLPath(String path) {
+        if(StringUtils.isNotBlank(path)) {
+            if(path.startsWith("/")) {
+                path = path.replaceFirst("/", "");
+            }
+            if(path.endsWith("/")) {
+                path = path.substring(0, path.length() - 2);
+            }
+        }
+        return path;
+    }
+
     /*
      * Preparing the endpoint sequence for a new session establishment request
      */
@@ -643,8 +671,7 @@ public class TenantAwareLoadBalanceEndpoint extends org.apache.synapse.endpoints
         axis2MsgCtx.removeProperty(NhttpConstants.REST_URL_POSTFIX);
 
         String transport = axis2MsgCtx.getTransportIn().getName();
-        String address = synCtx.getTo().getAddress();
-        EndpointReference to = getEndpointReferenceAfterURLRewrite(synCtx, currentMember, transport, address);
+        EndpointReference to = getEndpointReferenceAfterURLRewrite(synCtx, currentMember, transport);
         synCtx.setTo(to);
 
         Endpoint endpoint = getEndpoint(to, currentMember, synCtx);