Fixing Bug 1858 and Bug 1673 with changes in net-virt package 10/11210/6
authorSrini Seetharaman <srini.seetharaman@gmail.com>
Mon, 15 Sep 2014 20:36:02 +0000 (13:36 -0700)
committerSrini Seetharaman <srini.seetharaman@gmail.com>
Tue, 16 Sep 2014 21:17:15 +0000 (14:17 -0700)
1. Adding support for pool-id based on fix that went into the controller/
northbound/networkconfig/neutron for fixing Bug 1673

2. Fixing issue where LB pool member creation / deletion fails when VIP
isn't created yet

3. Incorrect handling of the events (missing "break" in switch statement)

4. Adding missing Activator .setInterface for LBaaS handlers

Change-Id: Ied854fe4f44c839a1e46036e625b7fb3cf3111cc
Signed-off-by: Srini Seetharaman <srini.seetharaman@gmail.com>
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java [changed mode: 0755->0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NorthboundEvent.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java

index 347631f4294f4d1ace315e592cfdfb31a0fe1fe8..da8c9d5daaca6745c8ded8e902e62d7a6f149bf3 100644 (file)
@@ -250,8 +250,10 @@ public class Activator extends ComponentActivatorAbstractBase {
             Properties lbaasHandlerProperties = new Properties();
             lbaasHandlerProperties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY,
                     AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER);
-            c.setInterface(new String[] {INeutronLoadBalancerAware.class.getName()},
-                                         lbaasHandlerProperties);
+            c.setInterface(new String[] {INeutronLoadBalancerAware.class.getName(),
+                    IInventoryListener.class.getName(),
+                    AbstractHandler.class.getName()},
+                    lbaasHandlerProperties);
             c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true));
             c.add(createServiceDependency().setService(INeutronPortCRUD.class).setRequired(true));
             c.add(createServiceDependency().setService(INeutronLoadBalancerCRUD.class).setRequired(true));
@@ -265,8 +267,9 @@ public class Activator extends ComponentActivatorAbstractBase {
             Properties lbaasPoolMemberHandlerProperties = new Properties();
             lbaasPoolMemberHandlerProperties.put(Constants.EVENT_HANDLER_TYPE_PROPERTY,
                     AbstractEvent.HandlerType.NEUTRON_LOAD_BALANCER_POOL_MEMBER);
-            c.setInterface(new String[] {INeutronLoadBalancerPoolMemberAware.class.getName()},
-                                         lbaasPoolMemberHandlerProperties);
+            c.setInterface(new String[] {INeutronLoadBalancerPoolMemberAware.class.getName(),
+                    AbstractHandler.class.getName()},
+                    lbaasPoolMemberHandlerProperties);
             c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true));
             c.add(createServiceDependency().setService(INeutronPortCRUD.class).setRequired(true));
             c.add(createServiceDependency().setService(INeutronLoadBalancerCRUD.class).setRequired(true));
old mode 100755 (executable)
new mode 100644 (file)
index 3cd8818..cfb39aa
@@ -64,23 +64,25 @@ public class LBaaSHandler extends AbstractHandler
             return HttpURLConnection.HTTP_OK;
     }
 
-    /**
-     * Assuming that the pool information is fully populated before this call is made,
-     * we go with creating the LoadBalancerConfiguration object for this call with
-     * all information that is necessary to insert flow_mods
-     */
     @Override
     public void neutronLoadBalancerCreated(NeutronLoadBalancer neutronLB) {
         logger.debug("Neutron LB Creation : {}", neutronLB.toString());
         enqueueEvent(new NorthboundEvent(neutronLB, Action.ADD));
     }
 
+    /**
+     * Assuming that the pool information is fully populated before this call is made,
+     * we go with creating the LoadBalancerConfiguration object for this call with
+     * all information that is necessary to insert flow_mods
+     */
     private void doNeutronLoadBalancerCreate(NeutronLoadBalancer neutronLB) {
         Preconditions.checkNotNull(loadBalancerProvider);
         LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
 
         if (!lbConfig.isValid()) {
             logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+        } else if (this.switchManager.getNodes().size() == 0) {
+            logger.trace("Noop with LB {} creation because no nodes available.", lbConfig.getName());
         } else {
             for (Node node: this.switchManager.getNodes())
                 loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.ADD);
@@ -89,19 +91,23 @@ public class LBaaSHandler extends AbstractHandler
 
     @Override
     public int canUpdateNeutronLoadBalancer(NeutronLoadBalancer delta, NeutronLoadBalancer original) {
-        return HttpURLConnection.HTTP_OK;
+        LoadBalancerConfiguration lbConfig = extractLBConfiguration(delta);
+        if (!lbConfig.isValid())
+            return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
+        else
+            return HttpURLConnection.HTTP_OK;
     }
 
     @Override
     public void neutronLoadBalancerUpdated(NeutronLoadBalancer neutronLB) {
+        logger.debug("Neutron LB Update : {}", neutronLB.toString());
         enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
-        return;
     }
 
     @Override
     public int canDeleteNeutronLoadBalancer(NeutronLoadBalancer neutronLB) {
         LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
-        if (!lbConfig.isValid())
+        if (lbConfig == null)
             return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
         else
             return HttpURLConnection.HTTP_OK;
@@ -119,6 +125,8 @@ public class LBaaSHandler extends AbstractHandler
 
         if (!lbConfig.isValid()) {
             logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+        } else if (this.switchManager.getNodes().size() == 0) {
+            logger.trace("Noop with LB {} deletion because no nodes available.", lbConfig.getName());
         } else {
             for (Node node: this.switchManager.getNodes())
                 loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
@@ -133,6 +141,7 @@ public class LBaaSHandler extends AbstractHandler
      */
     @Override
     public void processEvent(AbstractEvent abstractEvent) {
+        logger.debug("Processing Loadbalancer event " + abstractEvent);
         if (!(abstractEvent instanceof NorthboundEvent)) {
             logger.error("Unable to process abstract event " + abstractEvent);
             return;
@@ -141,8 +150,14 @@ public class LBaaSHandler extends AbstractHandler
         switch (ev.getAction()) {
             case ADD:
                 doNeutronLoadBalancerCreate(ev.getLoadBalancer());
+                break;
             case DELETE:
+                try {
                 doNeutronLoadBalancerDelete(ev.getLoadBalancer());
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+                break;
             case UPDATE:
                 /**
                  * Currently member update requires delete and re-adding
@@ -167,13 +182,15 @@ public class LBaaSHandler extends AbstractHandler
         String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
         LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
 
-        String memberID, memberIP, memberMAC, memberProtocol;
+        String memberID, memberIP, memberMAC, memberProtocol, memberSubnetID;
         Integer memberPort;
+        Boolean memberAdminStateIsUp;
 
         for (NeutronLoadBalancerPool neutronLBPool: neutronLBPoolCache.getAllNeutronLoadBalancerPools()) {
-            List<? extends NeutronLoadBalancerPoolMember> members =
-                (List<? extends NeutronLoadBalancerPoolMember>)neutronLBPool.getLoadBalancerPoolMembers();
+            List<NeutronLoadBalancerPoolMember> members = neutronLBPool.getLoadBalancerPoolMembers();
             memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
+            if (memberProtocol == null)
+                continue;
             /*
              * Only HTTP and HTTPS are supported as of this version
              * TODO: Support all TCP load-balancers
@@ -182,8 +199,11 @@ public class LBaaSHandler extends AbstractHandler
                   memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
                 continue;
             for (NeutronLoadBalancerPoolMember neutronLBPoolMember: members) {
-                if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID) &&
-                    neutronLBPoolMember.getPoolMemberAdminStateIsUp()) {
+                memberAdminStateIsUp = neutronLBPoolMember.getPoolMemberAdminStateIsUp();
+                memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
+                if (memberSubnetID == null || memberAdminStateIsUp == null)
+                    continue;
+                else if (memberSubnetID.equals(loadBalancerSubnetID) && memberAdminStateIsUp.booleanValue()) {
                     memberID = neutronLBPoolMember.getPoolMemberID();
                     memberIP = neutronLBPoolMember.getPoolMemberAddress();
                     memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
@@ -207,13 +227,15 @@ public class LBaaSHandler extends AbstractHandler
         logger.debug("notifyNode: Node {} update {} from Controller's inventory Service", node, type);
         Preconditions.checkNotNull(loadBalancerProvider);
 
-        if (type.equals(UpdateType.ADDED)) {
-            for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
-                LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
-                if (!lbConfig.isValid())
-                    logger.trace("Neutron LB configuration invalid for {} ", lbConfig.getName());
-                else
+        for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
+            LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLB);
+            if (!lbConfig.isValid())
+                logger.trace("Neutron LB configuration invalid for {} ", lbConfig.getName());
+            else {
+               if (type.equals(UpdateType.ADDED))
                     loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.ADD);
+               else if (type.equals(UpdateType.REMOVED))
+                    loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
             }
         }
     }
index b51cb644357552836be216159b1bc85462d78b25..eeac77ef4f8c14d240e40fa543de17ff641035e3 100755 (executable)
@@ -28,7 +28,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Preconditions;
 
 import java.net.HttpURLConnection;
-import java.util.List;
 
 /**
  * Handle requests for OpenStack Neutron v2.0 LBaaS API calls for
@@ -58,25 +57,28 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
             return HttpURLConnection.HTTP_OK;
     }
 
-    /**
-     * Assuming that the pool information is fully populated before this call is made,
-     * we go with creating the LoadBalancerConfiguration object for this call with
-     * all information that is necessary to insert flow_mods
-     */
     @Override
     public void neutronLoadBalancerPoolMemberCreated(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
         logger.debug("Neutron LB Pool Member Creation : {}", neutronLBPoolMember.toString());
         enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.ADD));
     }
 
+    /**
+     * Assuming that the pool information is fully populated before this call is made,
+     * we go with creating the LoadBalancerConfiguration object for this call with
+     * all information that is necessary to insert flow_mods
+     */
     private void doNeutronLoadBalancerPoolMemberCreate(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
         Preconditions.checkNotNull(loadBalancerProvider);
         LoadBalancerConfiguration lbConfig = extractLBConfiguration(neutronLBPoolMember);
         if (lbConfig == null) {
             logger.trace("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
-        }
-        else if (!lbConfig.isValid()) {
+        } else if (lbConfig.getVip() == null) {
+            logger.trace("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+        } else if (!lbConfig.isValid()) {
             logger.trace("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
+        } else if (this.switchManager.getNodes().size() == 0) {
+            logger.trace("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getPoolMemberID());
         } else {
             for (Node node: this.switchManager.getNodes())
                 loadBalancerProvider.programLoadBalancerPoolMemberRules(node, lbConfig,
@@ -86,13 +88,19 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
 
     @Override
     public int canUpdateNeutronLoadBalancerPoolMember(NeutronLoadBalancerPoolMember delta, NeutronLoadBalancerPoolMember original) {
-        return HttpURLConnection.HTTP_OK;
+        LoadBalancerConfiguration lbConfig = extractLBConfiguration(delta);
+        if (lbConfig == null)
+            return HttpURLConnection.HTTP_BAD_REQUEST;
+        else if (!lbConfig.isValid())
+            return HttpURLConnection.HTTP_NOT_ACCEPTABLE;
+        else
+            return HttpURLConnection.HTTP_OK;
     }
 
     @Override
     public void neutronLoadBalancerPoolMemberUpdated(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
+        logger.debug("Neutron LB Pool Member Update : {}", neutronLBPoolMember.toString());
         enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.UPDATE));
-        return;
     }
 
     @Override
@@ -109,17 +117,7 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
     @Override
     public void neutronLoadBalancerPoolMemberDeleted(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
         logger.debug("Neutron LB Pool Member Deletion : {}", neutronLBPoolMember.toString());
-
-        /* As of now, deleting a member involves recomputing member indices.
-         * This is best done through a complete update of the load balancer instance.
-         */
-        for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
-            String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
-            if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
-                enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
-                break;
-            }
-        }
+        enqueueEvent(new NorthboundEvent(neutronLBPoolMember, Action.DELETE));
     }
 
     /**
@@ -138,8 +136,20 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
         switch (ev.getAction()) {
             case ADD:
                 doNeutronLoadBalancerPoolMemberCreate(ev.getLoadBalancerPoolMember());
+                break;
             case DELETE:
-                logger.warn("Load balancer pool member delete event should not have been triggered");
+                /* As of now, deleting a member involves recomputing member indices.
+                 * This is best done through a complete update of the load balancer instance.
+                 */
+                for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
+                    String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
+                    if (ev.getLoadBalancerPoolMember()
+                                         .getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
+                        enqueueEvent(new NorthboundEvent(neutronLB, Action.UPDATE));
+                        break;
+                    }
+                }
+                break;
             case UPDATE:
                 /**
                  * Typical upgrade involves changing weights. Since weights are not
@@ -158,47 +168,44 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
      * configuration from the neutron LB cache based on member info
      */
     public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
+        String memberID = neutronLBPoolMember.getPoolMemberID();
         String memberIP = neutronLBPoolMember.getPoolMemberAddress();
         String memberMAC = NeutronCacheUtils.getMacAddress(neutronPortsCache, memberIP);
-        if (memberMAC == null)
+        if (memberMAC == null) {
+            logger.trace("Neutron LB pool member {} MAC address unavailable", memberID);
             return null;
-
-        String memberID = neutronLBPoolMember.getPoolMemberID();
+        }
+        String memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
         Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
+        String memberPoolID = neutronLBPoolMember.getPoolID();
         String memberProtocol = null;
-        boolean found = false;
-
-        for (NeutronLoadBalancerPool neutronLBPool: neutronLBPoolCache.getAllNeutronLoadBalancerPools()) {
-            List<? extends NeutronLoadBalancerPoolMember> members =
-                    (List<? extends NeutronLoadBalancerPoolMember>)neutronLBPool.getLoadBalancerPoolMembers();
-            for (NeutronLoadBalancerPoolMember member: members) {
-                //TODO: Allow member to be present in more than 1 pool
-                if (member.getPoolMemberID().equals(neutronLBPoolMember.getPoolMemberID())) {
-                    found = true;
-                    memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
-                    if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) ||
-                            memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
-                        memberProtocol = null;
-                    break;
-                }
-            }
-            if (found)
-                break;
+
+        if (memberSubnetID == null || memberID == null || memberPoolID == null) {
+            logger.trace("Neutron LB pool member details incomplete [id={}, pool_id={},subnet_id={}",
+                    memberID, memberPoolID, memberSubnetID);
+            return null;
         }
-        if (memberProtocol == null)
+        NeutronLoadBalancerPool neutronLBPool = neutronLBPoolCache.getNeutronLoadBalancerPool(memberPoolID);
+        memberProtocol = neutronLBPool.getLoadBalancerPoolProtocol();
+        if (!(memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTP) ||
+                memberProtocol.equalsIgnoreCase(LoadBalancerConfiguration.PROTOCOL_HTTPS)))
             return null;
 
-        String loadBalancerSubnetID, loadBalancerVip, loadBalancerName;
+        String loadBalancerSubnetID, loadBalancerVip=null, loadBalancerName=null;
         for (NeutronLoadBalancer neutronLB: neutronLBCache.getAllNeutronLoadBalancers()) {
             loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
-            if (neutronLBPoolMember.getPoolMemberSubnetID().equals(loadBalancerSubnetID)) {
+            if (memberSubnetID.equals(loadBalancerSubnetID)) {
                 loadBalancerName = neutronLB.getLoadBalancerName();
                 loadBalancerVip = neutronLB.getLoadBalancerVipAddress();
-                LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
-                lbConfig.addMember(memberID, memberIP, memberMAC, memberProtocol, memberPort);
-                return lbConfig;
+                break;
             }
         }
-        return null;
+        /**
+         * It is possible that the VIP has not been created yet.
+         * In that case, we create dummy configuration that will not program rules.
+         */
+        LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
+        lbConfig.addMember(memberID, memberIP, memberMAC, memberProtocol, memberPort);
+        return lbConfig;
     }
 }
index 57fa0b250f7d5cd645b782b236a00e48f396079b..a901e3da6ce396930991988a5e85a0dcfe31bf66 100644 (file)
@@ -116,6 +116,9 @@ public class NorthboundEvent extends AbstractEvent {
                + ", routerInterface=" + routerInterface
                + ", floatingIP=" + neutronFloatingIP
                + ", network=" + neutronNetwork
+               + ", loadBalancer=" + loadBalancer
+               + ", loadBalancerPool=" + loadBalancerPool
+               + ", loadBalancerPoolMember=" + loadBalancerPoolMember
                + "]";
     }
 
index 9c7e16eb57e60975b764bea44cbd3d8030c8c503..f5a0281835357c31d31ef9617cf80fd436af6386 100755 (executable)
@@ -150,4 +150,10 @@ public class LoadBalancerConfiguration {
     public String getName() {
         return this.name;
     }
+
+    @Override
+    public String toString() {
+        return "LoadBalancerConfiguration [name=" + name + ", vip=" + vip +
+                ", members=" + members + "]";
+    }
 }