Updated Branches:
  refs/heads/internallb af6201257 -> c113ea184

InternalLbVm: destroy the internal lb vm when the last rule for the ip is being 
revoked


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

Branch: refs/heads/internallb
Commit: 78c9db79dae3bc38699050b05baae32fd02204f6
Parents: af62012
Author: Alena Prokharchyk <[email protected]>
Authored: Fri Apr 12 10:05:28 2013 -0700
Committer: Alena Prokharchyk <[email protected]>
Committed: Fri Apr 12 11:07:00 2013 -0700

----------------------------------------------------------------------
 .../element/InternalLoadBalancerElement.java       |  105 +++++++++++----
 .../network/lb/InternalLoadBalancerManager.java    |    5 +-
 .../lb/InternalLoadBalancerManagerImpl.java        |   28 +++--
 .../network/lb/LoadBalancingRulesManagerImpl.java  |    2 +-
 4 files changed, 97 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/78c9db79/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
 
b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
index f3fb00f..0c662a8 100644
--- 
a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
+++ 
b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/element/InternalLoadBalancerElement.java
@@ -19,6 +19,7 @@ package org.apache.cloudstack.network.element;
 
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -64,7 +65,9 @@ import com.cloud.network.router.VirtualRouter.Role;
 import com.cloud.network.rules.FirewallRule;
 import com.cloud.network.rules.LoadBalancerContainer;
 import com.cloud.offering.NetworkOffering;
+import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
+import com.cloud.user.User;
 import com.cloud.utils.component.AdapterBase;
 import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.db.SearchCriteria2;
@@ -162,13 +165,13 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
         boolean result = true;
         for (DomainRouterVO internalLbVm : internalLbVms) {
             result = result && 
_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(),
-                    context.getAccount(), context.getCaller().getId()) != null;
+                    context.getAccount(), context.getCaller().getId());
             if (cleanup) {
                 if (!result) {
                     s_logger.warn("Failed to stop internal lb element " + 
internalLbVm + ", but would try to process clean up anyway.");
                 }
                 result = 
(_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(),
-                        context.getAccount(), context.getCaller().getId()) != 
null);
+                        context.getAccount(), context.getCaller().getId()));
                 if (!result) {
                     s_logger.warn("Failed to clean up internal lb element " + 
internalLbVm);
                 }
@@ -186,7 +189,7 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
         boolean result = true;
         for (DomainRouterVO internalLbVm : internalLbVms) {
             result = result && 
(_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(),
-                    context.getAccount(), context.getCaller().getId()) != 
null);
+                    context.getAccount(), context.getCaller().getId()));
         }
         return result;
     }
@@ -214,7 +217,7 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
         boolean result = true;
         for (DomainRouterVO internalLbVm : internalLbVms) {
             result = result && 
(_internalLbMgr.destroyInternalLbVm(internalLbVm.getId(),
-                    context.getAccount(), context.getCaller().getId()) != 
null);
+                    context.getAccount(), context.getCaller().getId()));
         }
         _vrProviderDao.remove(elementId);
         
@@ -240,31 +243,47 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
     public boolean applyLBRules(Network network, List<LoadBalancingRule> 
rules) throws ResourceUnavailableException {
         
         Map<Ip, List<LoadBalancingRule>> rulesToApply = 
getLbRulesToApply(rules);
+        Set<Ip> vmsToDestroy = getVmsToDestroy(rules);
         
         for (Ip sourceIp : rulesToApply.keySet()) {
-            //2.1 Start Internal LB vm per IP address
-            List<DomainRouterVO> internalLbVms;
-            try {
-                DeployDestination dest = new 
DeployDestination(_configMgr.getZone(network.getDataCenterId()), null, null, 
null); 
-                internalLbVms = _internalLbMgr.deployInternalLbVm(network, 
sourceIp, dest, _accountMgr.getAccount(network.getAccountId()), null);
-            } catch (InsufficientCapacityException e) {
-                s_logger.warn("Failed to apply lb rule(s) on the element " + 
this.getName() + " due to:", e);
-                return false;
-            } catch (ConcurrentOperationException e) {
-                s_logger.warn("Failed to apply lb rule(s) on the element " + 
this.getName() + " due to:", e);
-                return false;
-            }
-            
-            if ((internalLbVms == null) || (internalLbVms.size() == 0)) {
-                throw new ResourceUnavailableException("Can't find/deploy 
internal lb vm to handle LB rules",
-                        DataCenter.class, network.getDataCenterId());
-            }
-             
-            //2.2 Apply Internal LB rules on the VM
-            if (!_internalLbMgr.applyLoadBalancingRules(network, rules, 
internalLbVms)) {
-                throw new CloudRuntimeException("Failed to apply load 
balancing rules in network " + network.getId() + " on element " + 
this.getName());
+            if (vmsToDestroy.contains(sourceIp)) {
+                //2.1 Destroy internal lb vm
+                List<DomainRouterVO> vms = 
_internalLbMgr.findInternalLbVms(network.getId(), sourceIp);
+                //only one internal lb per IP exists
+                try {
+                    s_logger.debug("Destroying internal lb vm for ip " + 
sourceIp.addr() + " as all the rules for this vm are in Revoke state");
+                    return 
_internalLbMgr.destroyInternalLbVm(vms.get(0).getId(), 
_accountMgr.getAccount(Account.ACCOUNT_ID_SYSTEM),
+                            
_accountMgr.getUserIncludingRemoved(User.UID_SYSTEM).getId());
+                } catch (ConcurrentOperationException e) {
+                    s_logger.warn("Failed to apply lb rule(s) for ip " + 
sourceIp.addr() + " on the element " + this.getName() + " due to:", e);
+                    return false;
+                }
             } else {
-                return true;
+                //2.2 Start Internal LB vm per IP address
+                List<DomainRouterVO> internalLbVms;
+                try {
+                    DeployDestination dest = new 
DeployDestination(_configMgr.getZone(network.getDataCenterId()), null, null, 
null); 
+                    internalLbVms = _internalLbMgr.deployInternalLbVm(network, 
sourceIp, dest, _accountMgr.getAccount(network.getAccountId()), null);
+                } catch (InsufficientCapacityException e) {
+                    s_logger.warn("Failed to apply lb rule(s) for ip " + 
sourceIp.addr() + "on the element " + this.getName() + " due to:", e);
+                    return false;
+                } catch (ConcurrentOperationException e) {
+                    s_logger.warn("Failed to apply lb rule(s) for ip " + 
sourceIp.addr() + "on the element " + this.getName() + " due to:", e);
+                    return false;
+                }
+                
+                if ((internalLbVms == null) || (internalLbVms.size() == 0)) {
+                    throw new ResourceUnavailableException("Can't find/deploy 
internal lb vm to handle LB rules",
+                            DataCenter.class, network.getDataCenterId());
+                }
+                 
+                //2.3 Apply Internal LB rules on the VM
+                if (!_internalLbMgr.applyLoadBalancingRules(network, 
rulesToApply.get(sourceIp), internalLbVms)) {
+                    throw new CloudRuntimeException("Failed to apply load 
balancing rules for ip " + sourceIp.addr() + 
+                            " in network " + network.getId() + " on element " 
+ this.getName());
+                } else {
+                    return true;
+                }
             }
         }
 
@@ -275,7 +294,7 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
         //1) Group rules by the source ip address as NetworkManager always 
passes the entire network lb config to the element
         Map<Ip, List<LoadBalancingRule>> groupedRules = groupBySourceIp(rules);
 
-        //2) Apply only set containing LB rules in transition state 
(Add/Revoke)
+        //2) Apply only sets containing LB rules in transition state 
(Add/Revoke).
         Map<Ip, List<LoadBalancingRule>> rulesToApply = new HashMap<Ip, 
List<LoadBalancingRule>>();
         
         for (Ip sourceIp : groupedRules.keySet()) {
@@ -287,14 +306,42 @@ public class InternalLoadBalancerElement extends 
AdapterBase implements LoadBala
                     break;
                 }
             }
+            
             if (apply) {
                 rulesToApply.put(sourceIp, rulesToCheck);
             } else {
-                s_logger.debug("Not applying the lb rules for soure ip " + 
sourceIp + " on element " + this.getName() + " as there are no rules in 
transition state");
+                s_logger.debug("Not applying the lb rules for soure ip " + 
sourceIp + " on element " + this.getName()
+                        + " as there are no rules in transition state");
             }
-        }
+        }        
         return rulesToApply;
     }
+    
+    
+    
+    protected Set<Ip> getVmsToDestroy(List<LoadBalancingRule> rules) {
+        //1) Group rules by the source ip address as NetworkManager always 
passes the entire network lb config to the element
+        Map<Ip, List<LoadBalancingRule>> groupedRules = groupBySourceIp(rules);
+
+        //2) Count rules in revoke state
+        Set<Ip> vmsToDestroy = new HashSet<Ip>();
+        
+        for (Ip sourceIp : groupedRules.keySet()) {
+            List<LoadBalancingRule> rulesToCheck = groupedRules.get(sourceIp);
+            int revoke = 0;
+            for (LoadBalancingRule ruleToCheck : rulesToCheck) {
+                if (ruleToCheck.getState() == FirewallRule.State.Revoke){
+                    revoke++;
+                }
+            }
+            
+            if (revoke == rulesToCheck.size()) {
+                s_logger.debug("Have to destroy internal lb vm for source ip " 
+ sourceIp);
+                vmsToDestroy.add(sourceIp);
+            } 
+        }        
+        return vmsToDestroy;
+    }
 
     protected Map<Ip, List<LoadBalancingRule>> 
groupBySourceIp(List<LoadBalancingRule> rules) {
         Map<Ip, List<LoadBalancingRule>> groupedRules = new HashMap<Ip, 
List<LoadBalancingRule>>();

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/78c9db79/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManager.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManager.java
 
b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManager.java
index fd22285..0d817de 100644
--- 
a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManager.java
+++ 
b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManager.java
@@ -44,7 +44,7 @@ public interface InternalLoadBalancerManager extends Manager{
      * @throws ResourceUnavailableException
      * @throws ConcurrentOperationException
      */
-    VirtualRouter destroyInternalLbVm(long vmId, Account caller, Long 
callerUserId) 
+    boolean destroyInternalLbVm(long vmId, Account caller, Long callerUserId) 
             throws ResourceUnavailableException, ConcurrentOperationException;
     
    
@@ -107,4 +107,7 @@ public interface InternalLoadBalancerManager extends 
Manager{
     boolean applyLoadBalancingRules(Network network, List<LoadBalancingRule> 
rules, List<? extends VirtualRouter> internalLbVms)
             throws ResourceUnavailableException;
 
+
+    List<DomainRouterVO> findInternalLbVms(long guestNetworkId, Ip 
requestedGuestIp);
+
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/78c9db79/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManagerImpl.java
 
b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManagerImpl.java
index d45784e..c371892 100644
--- 
a/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManagerImpl.java
+++ 
b/plugins/network-elements/internal-loadbalancer/src/org/apache/cloudstack/network/lb/InternalLoadBalancerManagerImpl.java
@@ -16,6 +16,7 @@
 // under the License.
 package org.apache.cloudstack.network.lb;
 
+import java.lang.Thread.State;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -522,7 +523,7 @@ InternalLoadBalancerManager, 
VirtualMachineGuru<DomainRouterVO> {
     }
 
     @Override
-    public VirtualRouter destroyInternalLbVm(long vmId, Account caller, Long 
callerUserId)
+    public boolean destroyInternalLbVm(long vmId, Account caller, Long 
callerUserId)
             throws ResourceUnavailableException, ConcurrentOperationException {
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Attempting to destroy Internal LB vm " + vmId);
@@ -530,17 +531,12 @@ InternalLoadBalancerManager, 
VirtualMachineGuru<DomainRouterVO> {
 
         DomainRouterVO internalLbVm = _routerDao.findById(vmId);
         if (internalLbVm == null) {
-            return null;
+            return true;
         }
 
         _accountMgr.checkAccess(caller, null, true, internalLbVm);
 
-        boolean result = _itMgr.expunge(internalLbVm, 
_accountMgr.getActiveUser(callerUserId), caller);
-
-        if (result) {
-            return internalLbVm;
-        }
-        return null;
+        return _itMgr.expunge(internalLbVm, 
_accountMgr.getActiveUser(callerUserId), caller); 
     }
 
     @Override
@@ -582,12 +578,13 @@ InternalLoadBalancerManager, 
VirtualMachineGuru<DomainRouterVO> {
         }
 
         for (DomainRouterVO internalLbVm : internalLbVms) {
-            internalLbVm = startInternalLbVm(internalLbVm, 
_accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params);
+            if (internalLbVm.getState() != VirtualMachine.State.Running) {
+                internalLbVm = startInternalLbVm(internalLbVm, 
_accountMgr.getSystemUser(), _accountMgr.getSystemAccount(), params);
+            }
             
             if (internalLbVm != null) {
                 runningInternalLbVms.add(internalLbVm);
             }
-            
         }
         return runningInternalLbVms;
     }
@@ -699,6 +696,14 @@ InternalLoadBalancerManager, 
VirtualMachineGuru<DomainRouterVO> {
     protected Pair<DeploymentPlan, List<DomainRouterVO>> 
getDeploymentPlanAndInternalLbVms(DeployDestination dest, long guestNetworkId, 
Ip requestedGuestIp) {
         long dcId = dest.getDataCenter().getId();
         DeploymentPlan plan = new DataCenterDeployment(dcId);
+        List<DomainRouterVO> internalLbVms = findInternalLbVms(guestNetworkId, 
requestedGuestIp);
+
+        return new Pair<DeploymentPlan, List<DomainRouterVO>>(plan, 
internalLbVms);
+    
+    }
+
+    @Override
+    public List<DomainRouterVO> findInternalLbVms(long guestNetworkId, Ip 
requestedGuestIp) {
         List<DomainRouterVO> internalLbVms = 
_routerDao.listByNetworkAndRole(guestNetworkId, Role.INTERNAL_LB_VM); 
         if (requestedGuestIp != null) {
             Iterator<DomainRouterVO> it = internalLbVms.iterator();
@@ -710,8 +715,7 @@ InternalLoadBalancerManager, 
VirtualMachineGuru<DomainRouterVO> {
                 }
             }
         }
-
-        return new Pair<DeploymentPlan, List<DomainRouterVO>>(plan, 
internalLbVms);
+        return internalLbVms;
     }
     
     

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/78c9db79/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java 
b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
index 0a9c5b6..59ff435 100755
--- a/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
+++ b/server/src/com/cloud/network/lb/LoadBalancingRulesManagerImpl.java
@@ -1602,7 +1602,7 @@ public class LoadBalancingRulesManagerImpl<Type> extends 
ManagerBase implements
                 }
 
                 txn.commit();
-                if (checkForReleaseElasticIp) {
+                if (checkForReleaseElasticIp && lb.getSourceIpAddressId() != 
null) {
                     boolean success = true;
                     long count = 
_firewallDao.countRulesByIpId(lb.getSourceIpAddressId());
                     if (count == 0) {

Reply via email to