cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From alena1...@apache.org
Subject [2/3] git commit: updated refs/heads/internallb to f4c2b53
Date Thu, 11 Apr 2013 21:00:08 GMT
InternalLB: added logic for acquiring guest ip address for the Internal LB rule


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

Branch: refs/heads/internallb
Commit: 76a4b1cf81610d931d6098ca94fa509c9ba2e274
Parents: 915e39f
Author: Alena Prokharchyk <alena.prokharchyk@citrix.com>
Authored: Thu Apr 11 11:41:47 2013 -0700
Committer: Alena Prokharchyk <alena.prokharchyk@citrix.com>
Committed: Thu Apr 11 12:09:56 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/network/NetworkModel.java        |    2 +
 .../network/lb/ApplicationLoadBalancerService.java |    3 +-
 .../lb/InternalLoadBalancerManagerImpl.java        |    3 +-
 server/src/com/cloud/network/NetworkModelImpl.java |   25 +-
 .../lb/ApplicationLoadBalancerManagerImpl.java     |  303 +++++++++++++--
 .../lb/dao/ApplicationLoadBalancerRuleDao.java     |    6 +-
 .../lb/dao/ApplicationLoadBalancerRuleDaoImpl.java |   55 +++-
 7 files changed, 353 insertions(+), 44 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/api/src/com/cloud/network/NetworkModel.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/NetworkModel.java b/api/src/com/cloud/network/NetworkModel.java
index 6842ebb..6260d37 100644
--- a/api/src/com/cloud/network/NetworkModel.java
+++ b/api/src/com/cloud/network/NetworkModel.java
@@ -266,4 +266,6 @@ public interface NetworkModel {
     
     IpAddress getPublicIpAddress(String ipAddress, long zoneId);
 
+    List<String> getUsedIpsInNetwork(Network network);
+
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
index 0d9620b..88196a3 100644
--- a/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
+++ b/api/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerService.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd;
 
 import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
 import com.cloud.exception.NetworkRuleConflictException;
 import com.cloud.network.rules.LoadBalancerContainer.Scheme;
 import com.cloud.utils.Pair;
@@ -30,7 +31,7 @@ public interface ApplicationLoadBalancerService {
     
     ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, String description,
Scheme scheme, long sourceIpNetworkId, String sourceIp,
             int sourcePort, int instancePort, String algorithm, long networkId, long lbOwnerId)
throws InsufficientAddressCapacityException,
-            NetworkRuleConflictException;
+            NetworkRuleConflictException, InsufficientVirtualNetworkCapcityException;
     
     boolean deleteApplicationLoadBalancer(long id);
     

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/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 d6d3adb..5ca5474 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
@@ -81,7 +81,6 @@ import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.router.VirtualRouter.RedundantState;
 import com.cloud.network.router.VirtualRouter.Role;
 import com.cloud.network.rules.FirewallRule;
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
 import com.cloud.offering.NetworkOffering;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.offerings.dao.NetworkOfferingDao;
@@ -437,7 +436,7 @@ InternalLoadBalancerManager, VirtualMachineGuru<DomainRouterVO>
{
     
     protected void finalizeLbRulesForIp(Commands cmds, DomainRouterVO internalLbVm, Provider
provider, Ip sourceIp, long guestNtwkId) {
         s_logger.debug("Resending load balancing rules as a part of start for " + internalLbVm);
-        List<ApplicationLoadBalancerRuleVO> lbs = _lbDao.listBySrcIpSrcNtwkIdAndScheme(sourceIp,
guestNtwkId, Scheme.Internal);
+        List<ApplicationLoadBalancerRuleVO> lbs = _lbDao.listBySrcIpSrcNtwkId(sourceIp,
guestNtwkId);
         List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>();
         if (_ntwkModel.isProviderSupportServiceInNetwork(guestNtwkId, Service.Lb, provider))
{
             // Re-apply load balancing rules

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/server/src/com/cloud/network/NetworkModelImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/NetworkModelImpl.java b/server/src/com/cloud/network/NetworkModelImpl.java
index 0a82e09..75d8bc1 100644
--- a/server/src/com/cloud/network/NetworkModelImpl.java
+++ b/server/src/com/cloud/network/NetworkModelImpl.java
@@ -32,6 +32,7 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import org.apache.cloudstack.network.lb.dao.ApplicationLoadBalancerRuleDao;
 import org.apache.log4j.Logger;
 import org.springframework.stereotype.Component;
 
@@ -177,7 +178,9 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel
{
     @Inject
     UserIpv6AddressDao _ipv6Dao;
     @Inject
-    NicSecondaryIpDao _nicSecondaryIpDao;;
+    NicSecondaryIpDao _nicSecondaryIpDao;
+    @Inject
+    ApplicationLoadBalancerRuleDao _appLbRuleDao;
 
 
     private final HashMap<String, NetworkOfferingVO> _systemNetworks = new HashMap<String,
NetworkOfferingVO>(5);
@@ -1644,10 +1647,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel
{
     @Override
     public Set<Long> getAvailableIps(Network network, String requestedIp) {
         String[] cidr = network.getCidr().split("/");
-        List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
-        List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId());
-        ips.addAll(secondaryIps);
-        Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
+        List<String> ips = getUsedIpsInNetwork(network);
         Set<Long> usedIps = new TreeSet<Long>(); 
         
         for (String ip : ips) {
@@ -1658,6 +1658,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel
{
     
             usedIps.add(NetUtils.ip2Long(ip));
         }
+        
+        Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
         if (usedIps.size() != 0) {
             allPossibleIps.removeAll(usedIps);
         }
@@ -1668,6 +1670,19 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel
{
 
         return allPossibleIps;
     }
+    
+    @Override
+    public List<String> getUsedIpsInNetwork(Network network) {
+        //Get all ips used by vms nics
+        List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
+        //Get all secondary ips for nics
+        List<String> secondaryIps = _nicSecondaryIpDao.listSecondaryIpAddressInNetwork(network.getId());
+        ips.addAll(secondaryIps);
+        //Get ips used by load balancers
+        List<String> lbIps = _appLbRuleDao.listLbIpsBySourceIpNetworkId(network.getId());
+        ips.addAll(lbIps);
+        return ips;
+    }
 
     @Override
     public String getDomainNetworkDomain(long domainId, long zoneId) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
index d48ce77..f904ef0 100644
--- a/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
+++ b/server/src/org/apache/cloudstack/network/lb/ApplicationLoadBalancerManagerImpl.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import javax.ejb.Local;
 import javax.inject.Inject;
 
+import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 import org.apache.cloudstack.api.command.user.loadbalancer.ListApplicationLoadBalancersCmd;
 import org.apache.cloudstack.network.lb.dao.ApplicationLoadBalancerRuleDao;
 import org.apache.log4j.Logger;
@@ -33,17 +34,23 @@ import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.event.UsageEventUtils;
 import com.cloud.exception.InsufficientAddressCapacityException;
+import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.NetworkRuleConflictException;
+import com.cloud.exception.UnsupportedServiceException;
 import com.cloud.network.Network;
+import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Service;
+import com.cloud.network.NetworkManager;
 import com.cloud.network.NetworkModel;
+import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.dao.FirewallRulesDao;
 import com.cloud.network.lb.LoadBalancingRule;
 import com.cloud.network.lb.LoadBalancingRule.LbDestination;
 import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
 import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy;
 import com.cloud.network.lb.LoadBalancingRulesManager;
+import com.cloud.network.rules.FirewallRule.State;
 import com.cloud.network.rules.LoadBalancerContainer.Scheme;
 import com.cloud.projects.Project.ListProjectResourcesCriteria;
 import com.cloud.server.ResourceTag.TaggedResourceType;
@@ -55,6 +62,7 @@ import com.cloud.user.UserContext;
 import com.cloud.utils.Pair;
 import com.cloud.utils.Ternary;
 import com.cloud.utils.component.ManagerBase;
+import com.cloud.utils.db.DB;
 import com.cloud.utils.db.Filter;
 import com.cloud.utils.db.JoinBuilder;
 import com.cloud.utils.db.SearchBuilder;
@@ -75,71 +83,89 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements
A
     @Inject LoadBalancingRulesManager _lbMgr;
     @Inject FirewallRulesDao _firewallDao;
     @Inject ResourceTagDao _resourceTagDao;
+    @Inject NetworkManager _ntwkMgr;
     
     
     @Override
     @ActionEvent(eventType = EventTypes.EVENT_LOAD_BALANCER_CREATE, eventDescription = "creating
load balancer")
     public ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, String
description, Scheme scheme, long sourceIpNetworkId, String sourceIp,
             int sourcePort, int instancePort, String algorithm, long networkId, long lbOwnerId)
throws InsufficientAddressCapacityException,
-            NetworkRuleConflictException {
+            NetworkRuleConflictException, InsufficientVirtualNetworkCapcityException {
         
-        if (!NetUtils.isValidPort(instancePort)) {
-            throw new InvalidParameterValueException("Invalid value for instance port: "
+ instancePort);
+        //Validate LB rule guest network
+        Network guestNtwk = _networkModel.getNetwork(networkId);
+        if (guestNtwk == null) {
+            throw new InvalidParameterValueException("Can't find network by id");
         }
         
+        Account caller = UserContext.current().getCaller();
+        _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, guestNtwk);
         
-        if (!NetUtils.isValidPort(instancePort)) {
-            throw new InvalidParameterValueException("Invalid value for source port: " +
sourcePort);
-        }
-       
-        if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
-            throw new InvalidParameterValueException("Invalid algorithm: " + algorithm);
-        }
-        
-        Network network = _networkModel.getNetwork(networkId);
-        // verify that lb service is supported by the network
-        if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) {
-            InvalidParameterValueException ex = new InvalidParameterValueException(
-                    "LB service is not supported in specified network id");
-            ex.addProxyObject(network, networkId, "networkId");
-            throw ex;
+        Network sourceIpNtwk = _networkModel.getNetwork(sourceIpNetworkId);
+        if (sourceIpNtwk == null) {
+            throw new InvalidParameterValueException("Can't find source ip network by id");
         }
         
         Account lbOwner = _accountMgr.getAccount(lbOwnerId);
         if (lbOwner == null) {
             throw new InvalidParameterValueException("Can't find the lb owner account");
         }
-
-        //TODO - assign guest ip address here//add validation for the source ip address/network
id
-        ApplicationLoadBalancerRuleVO newRule = new ApplicationLoadBalancerRuleVO(name, description,
sourcePort, instancePort, algorithm, networkId,
-                lbOwner.getId(), lbOwner.getDomainId(), new Ip(sourceIp), sourceIpNetworkId,
scheme);
         
+        return createApplicationLoadBalancer(name, description, scheme, sourceIpNtwk, sourceIp,
sourcePort, instancePort, algorithm, lbOwner, guestNtwk);
+    }
 
-        // verify rule is supported by Lb provider of the network
+    
+    protected ApplicationLoadBalancerRule createApplicationLoadBalancer(String name, String
description, Scheme scheme, Network sourceIpNtwk, String sourceIp, int sourcePort, int instancePort,
String algorithm,
+            Account lbOwner, Network guestNtwk) throws NetworkRuleConflictException, InsufficientVirtualNetworkCapcityException
{
+        
+        //Only Internal scheme is supported in this release
+        if (scheme != Scheme.Internal) {
+            throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal
+ " is supported");
+        }
+        
+        //1) Validate LB rule's parameters
+        validateLbRuleParameters(sourcePort, instancePort, algorithm, guestNtwk);
+        
+        //2) Get source ip address
+        sourceIp = getSourceIp(scheme, sourceIpNtwk, sourceIp);
+               
+        ApplicationLoadBalancerRuleVO newRule = new ApplicationLoadBalancerRuleVO(name, description,
sourcePort, instancePort, algorithm, guestNtwk.getId(),
+                lbOwner.getId(), lbOwner.getDomainId(), new Ip(sourceIp), sourceIpNtwk.getId(),
scheme);
+        
+        //3) Validate Load Balancing rule on the providers
         LoadBalancingRule loadBalancing = new LoadBalancingRule(newRule, new ArrayList<LbDestination>(),
                 new ArrayList<LbStickinessPolicy>(), new ArrayList<LbHealthCheckPolicy>(),
new Ip(sourceIp));
-        
         if (!_lbMgr.validateLbRule(loadBalancing)) {
             throw new InvalidParameterValueException("LB service provider cannot support
this rule");
         }
+        
 
+        //4) Persist Load Balancer rule
+        return persistLbRule(newRule, sourceIp, guestNtwk);
+    }
+
+    
+    @DB
+    protected ApplicationLoadBalancerRule persistLbRule(ApplicationLoadBalancerRuleVO newRule,
String sourceIp, Network guestNtwk) throws NetworkRuleConflictException {
+        
         Transaction txn = Transaction.currentTxn();
         txn.start();
         
+        //1) Persist the rule
         newRule = _lbDao.persist(newRule);
         boolean success = true;
 
         try {
-            //TODO - add validation for the LB rule against other lb rules
-            
+            //2) Detect conflicts
+            detectLbRulesConflicts(newRule);
             if (!_firewallDao.setStateToAdd(newRule)) {
                 throw new CloudRuntimeException("Unable to update the state to add for "
+ newRule);
             }
-            s_logger.debug("Load balancer " + newRule.getId() + " for Ip address " + sourceIp
+ ", source port "
-                    + sourcePort + ", instance port " + instancePort + " is added successfully.");
+            s_logger.debug("Load balancer " + newRule.getId() + " for Ip address " + newRule
+ ", source port "
+                    + newRule.getSourcePortStart() + ", instance port " + newRule.getDefaultPortStart()
+ " is added successfully.");
             UserContext.current().setEventDetails("Load balancer Id: " + newRule.getId());
-            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, lbOwnerId,
-                    network.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(),
+            UsageEventUtils.publishUsageEvent(EventTypes.EVENT_LOAD_BALANCER_CREATE, newRule.getAccountId(),
+                    guestNtwk.getDataCenterId(), newRule.getId(), null, LoadBalancingRule.class.getName(),
                     newRule.getUuid());
             txn.commit();
 
@@ -153,11 +179,173 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase
implements A
         } finally {
             if (!success && newRule != null) {
                 _lbMgr.removeLBRule(newRule);
-                //TODO - unassign the guest ip address here
             }
         }
     }
 
+    /**
+     * Validates Lb rule parameters
+     * @param sourcePort
+     * @param instancePort
+     * @param algorithm
+     * @param networkId
+     * @param network
+     */
+    protected void validateLbRuleParameters(int sourcePort, int instancePort, String algorithm,
Network network) {
+        // verify that lb service is supported by the network
+        if (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.Lb)) {
+            InvalidParameterValueException ex = new InvalidParameterValueException(
+                    "LB service is not supported in specified network id");
+            ex.addProxyObject(network, network.getId(), "networkId");
+            throw ex;
+        }
+        
+        Map<Network.Capability, String> caps = _networkModel.getNetworkServiceCapabilities(network.getId(),
Service.Lb);
+        String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
+        if (!supportedProtocols.contains(NetUtils.TCP_PROTO.toLowerCase())) {
+            throw new InvalidParameterValueException("Protocol " + NetUtils.TCP_PROTO.toLowerCase()
+ " is not supported in zone " + network.getDataCenterId());
+        }
+        
+        //Validate rule parameters
+        if (!NetUtils.isValidPort(instancePort)) {
+            throw new InvalidParameterValueException("Invalid value for instance port: "
+ instancePort);
+        }
+        
+        if (!NetUtils.isValidPort(instancePort)) {
+            throw new InvalidParameterValueException("Invalid value for source port: " +
sourcePort);
+        }
+       
+        if ((algorithm == null) || !NetUtils.isValidAlgorithm(algorithm)) {
+            throw new InvalidParameterValueException("Invalid algorithm: " + algorithm);
+        }
+    }
+    
+
+    /**
+     * Gets source ip address based on the LB rule scheme/source IP network/requested IP
address
+     * @param scheme
+     * @param sourceIpNtwk
+     * @param requestedIp
+     * @return
+     * @throws InsufficientVirtualNetworkCapcityException
+     */
+    protected String getSourceIp(Scheme scheme, Network sourceIpNtwk, String requestedIp)
throws InsufficientVirtualNetworkCapcityException {
+        //Get source IP address
+        if (requestedIp != null) {
+            validateRequestedSourceIpForLbRule(sourceIpNtwk, new Ip(requestedIp), scheme);
+        } else {
+            requestedIp = allocateSourceIpForLbRule(scheme, sourceIpNtwk);
+        }
+        
+        if (requestedIp == null) {
+            throw new InsufficientVirtualNetworkCapcityException("Unable to acquire IP address
for network " + sourceIpNtwk, Network.class, sourceIpNtwk.getId());
+        }
+        return requestedIp;
+    }
+
+
+    /**
+     * Allocates new Source IP address for the Load Balancer rule based on LB rule scheme/sourceNetwork
+     * @param scheme
+     * @param sourceIp
+     * @param sourceIpNtwk
+     * @return
+     */
+    protected String allocateSourceIpForLbRule(Scheme scheme, Network sourceIpNtwk) {
+        String sourceIp = null;
+        if (scheme != Scheme.Internal) {
+            throw new InvalidParameterValueException("Only scheme " + Scheme.Internal + "
is supported");
+        } else {
+            sourceIp = allocateSourceIpForInternalLbRule(sourceIpNtwk);
+        }
+        return sourceIp;
+    }
+    
+
+    /**
+     * Allocates sourceIp for the Internal LB rule
+     * @param sourceIpNtwk
+     * @return
+     */
+    protected String allocateSourceIpForInternalLbRule(Network sourceIpNtwk) {
+        return _ntwkMgr.acquireGuestIpAddress(sourceIpNtwk, null);
+    }
+
+    
+    /**
+     * Validates requested source ip address of the LB rule based on Lb rule scheme/sourceNetwork
+     * @param sourceIpNtwk
+     * @param requestedSourceIp
+     * @param scheme
+     */
+    private void validateRequestedSourceIpForLbRule(Network sourceIpNtwk, Ip requestedSourceIp,
Scheme scheme) {
+        //only Internal scheme is supported in this release
+        if (scheme != Scheme.Internal) {
+            throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal
+ " is supported");
+        } else {
+            //validate guest source ip
+            validateRequestedSourceIpForInternalLbRule(sourceIpNtwk, requestedSourceIp);
+        }
+    }
+
+    
+    /**
+     * Validates requested source IP address of Internal Lb rule against sourceNetworkId
+     * @param sourceIpNtwk
+     * @param requestedSourceIp
+     */
+    private void validateRequestedSourceIpForInternalLbRule(Network sourceIpNtwk, Ip requestedSourceIp)
{
+        //Check if the IP address used by the load balancer or other nics
+        if (_lbDao.countBySourceIp(requestedSourceIp, sourceIpNtwk.getId()) > 0)  {
+            s_logger.debug("IP address " + requestedSourceIp.addr() + " is already used by
existing LB rule, skipping the validation");
+            return;
+        } else {
+            List<String> usedIps = _networkModel.getUsedIpsInNetwork(sourceIpNtwk);
+            if (usedIps.size() > 0) {
+                throw new InvalidParameterValueException("Ip address " + requestedSourceIp.addr()
+ " is already in use");
+            }
+        }
+    }
+
+    
+    /**
+     * Validates source IP network for the LB rule
+     * @param sourceNtwk
+     * @param scheme
+     * @return
+     */
+    protected Network validateSourceIpNtwkForLbRule(Network sourceNtwk, Scheme scheme) {
+        //only Internal scheme is supported in this release
+        if (scheme != Scheme.Internal) {
+            throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal
+ " is supported");
+        } else {
+            //validate source ip network
+            return validateSourceIpNtwkForInternalLbRule(sourceNtwk);
+        }
+        
+    }
+
+    /**
+     * Validates source IP network for the Internal LB rule
+     * @param sourceIpNtwk
+     * @return
+     */
+    protected Network validateSourceIpNtwkForInternalLbRule(Network sourceIpNtwk) {
+        if (sourceIpNtwk.getTrafficType() != TrafficType.Guest) {
+            throw new InvalidParameterValueException("Only traffic type " + TrafficType.Guest
+ " is supported");
+        } 
+        
+        //Can't create the LB rule if the network's cidr is NULL
+        String ntwkCidr = sourceIpNtwk.getCidr();
+        if (ntwkCidr == null) {
+            throw new InvalidParameterValueException("Can't create the application load balancer
rule for the network having NULL cidr");
+        }
+        
+        //check if the requested ip address is within the cidr
+        return sourceIpNtwk;
+    }
+
+    
     @Override
     public boolean deleteApplicationLoadBalancer(long id) {
         return _lbMgr.deleteLoadBalancerRule(id, true);
@@ -266,5 +454,58 @@ public class ApplicationLoadBalancerManagerImpl extends ManagerBase implements
A
     public ApplicationLoadBalancerRule findById(long ruleId) {
         return _lbDao.findById(ruleId);
     }
+   
+    
+    /**
+     * Detects lb rule conflicts against other rules
+     * @param newLbRule
+     * @throws NetworkRuleConflictException
+     */
+    protected void detectLbRulesConflicts(ApplicationLoadBalancerRule newLbRule) throws NetworkRuleConflictException
{
+        if (newLbRule.getScheme() != Scheme.Internal) {
+            throw new UnsupportedServiceException("Only scheme of type " + Scheme.Internal
+ " is supported");
+        } else {
+            detectInternalLbRulesConflict(newLbRule);
+        }
+    }
+    
+    
+    /**
+     * Detects Internal Lb Rules conflicts
+     * @param newLbRule
+     * @throws NetworkRuleConflictException
+     */
+    protected void detectInternalLbRulesConflict(ApplicationLoadBalancerRule newLbRule) throws
NetworkRuleConflictException {
+        List<ApplicationLoadBalancerRuleVO> lbRules = _lbDao.listBySourceIpAndNotRevoked(newLbRule.getSourceIp(),
newLbRule.getSourceIpNetworkId());
+
+        for (ApplicationLoadBalancerRuleVO lbRule : lbRules) {
+            if (lbRule.getId() == newLbRule.getId()) {
+                continue; // Skips my own rule.
+            }
+
+            if (lbRule.getNetworkId() != newLbRule.getNetworkId() && lbRule.getState()
!= State.Revoke) {
+                throw new NetworkRuleConflictException("New rule is for a different network
than what's specified in rule "
+                        + lbRule.getXid());
+            }
+
+          if ((lbRule.getSourcePortStart().intValue() <= newLbRule.getSourcePortStart().intValue()

+                  && lbRule.getSourcePortEnd().intValue() >= newLbRule.getSourcePortStart().intValue())
+                  || (lbRule.getSourcePortStart().intValue() <= newLbRule.getSourcePortEnd().intValue()

+                  && lbRule.getSourcePortEnd().intValue() >= newLbRule.getSourcePortEnd().intValue())
+                  || (newLbRule.getSourcePortStart().intValue() <= lbRule.getSourcePortStart().intValue()

+                  && newLbRule.getSourcePortEnd().intValue() >= lbRule.getSourcePortStart().intValue())
+                  || (newLbRule.getSourcePortStart().intValue() <= lbRule.getSourcePortEnd().intValue()

+                  && newLbRule.getSourcePortEnd().intValue() >= lbRule.getSourcePortEnd().intValue()))
{
+
+
+                    throw new NetworkRuleConflictException("The range specified, " + newLbRule.getSourcePortStart()
+ "-" + newLbRule.getSourcePortEnd() + ", conflicts with rule " + lbRule.getId()
+                            + " which has " + lbRule.getSourcePortStart() + "-" + lbRule.getSourcePortEnd());
+            }
+        }
+
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("No network rule conflicts detected for " + newLbRule + " against
" + (lbRules.size() - 1) + " existing rules");
+        }
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDao.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDao.java
b/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDao.java
index 6209949..c702987 100644
--- a/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDao.java
+++ b/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDao.java
@@ -21,10 +21,12 @@ import java.util.List;
 
 import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRuleVO;
 
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
 import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.net.Ip;
 
 public interface ApplicationLoadBalancerRuleDao extends GenericDao<ApplicationLoadBalancerRuleVO,
Long>{
-    List<ApplicationLoadBalancerRuleVO> listBySrcIpSrcNtwkIdAndScheme(Ip sourceIp,
long sourceNetworkId, Scheme scheme);
+    List<ApplicationLoadBalancerRuleVO> listBySrcIpSrcNtwkId(Ip sourceIp, long sourceNetworkId);
+    List<String> listLbIpsBySourceIpNetworkId(long sourceIpNetworkId);
+    long countBySourceIp(Ip sourceIp, long sourceIpNetworkId);
+    List<ApplicationLoadBalancerRuleVO> listBySourceIpAndNotRevoked(Ip sourceIp, long
sourceNetworkId);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/76a4b1cf/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
b/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
index ff6d38b..a3d2ca9 100644
--- a/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
+++ b/server/src/org/apache/cloudstack/network/lb/dao/ApplicationLoadBalancerRuleDaoImpl.java
@@ -24,16 +24,24 @@ import javax.ejb.Local;
 import org.apache.cloudstack.network.lb.ApplicationLoadBalancerRuleVO;
 import org.springframework.stereotype.Component;
 
-import com.cloud.network.rules.LoadBalancerContainer.Scheme;
+import com.cloud.network.rules.FirewallRule;
 import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.GenericSearchBuilder;
 import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Func;
+import com.cloud.utils.db.SearchCriteria.Op;
 import com.cloud.utils.net.Ip;
 
 @Component
 @Local(value = { ApplicationLoadBalancerRuleDao.class })
 public class ApplicationLoadBalancerRuleDaoImpl extends GenericDaoBase<ApplicationLoadBalancerRuleVO,
Long> implements ApplicationLoadBalancerRuleDao{
     protected final SearchBuilder<ApplicationLoadBalancerRuleVO> AllFieldsSearch;
+    final GenericSearchBuilder<ApplicationLoadBalancerRuleVO, String> listIps;
+    final GenericSearchBuilder<ApplicationLoadBalancerRuleVO, Long> CountBy;
+    protected final SearchBuilder<ApplicationLoadBalancerRuleVO> NotRevokedSearch;
+
+
     
     protected ApplicationLoadBalancerRuleDaoImpl() {
         AllFieldsSearch = createSearchBuilder();
@@ -42,14 +50,55 @@ public class ApplicationLoadBalancerRuleDaoImpl extends GenericDaoBase<Applicati
         AllFieldsSearch.and("networkId", AllFieldsSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
         AllFieldsSearch.and("scheme", AllFieldsSearch.entity().getScheme(), SearchCriteria.Op.EQ);
         AllFieldsSearch.done();
+        
+        listIps = createSearchBuilder(String.class);
+        listIps.select(null, Func.DISTINCT, listIps.entity().getSourceIp());
+        listIps.and("sourceIpNetworkId", listIps.entity().getSourceIpNetworkId(), Op.EQ);
+        listIps.done();
+        
+        CountBy = createSearchBuilder(Long.class);
+        CountBy.select(null, Func.COUNT, CountBy.entity().getId());
+        CountBy.and("sourceIp", CountBy.entity().getSourceIp(), Op.EQ);
+        CountBy.and("sourceIpNetworkId", CountBy.entity().getSourceIpNetworkId(), Op.EQ);
+        CountBy.done();
+        
+        NotRevokedSearch = createSearchBuilder();
+        NotRevokedSearch.and("sourceIp", AllFieldsSearch.entity().getSourceIp(), SearchCriteria.Op.EQ);
+        NotRevokedSearch.and("sourceIpNetworkId", AllFieldsSearch.entity().getSourceIpNetworkId(),
SearchCriteria.Op.EQ);
+        NotRevokedSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.NEQ);
+        NotRevokedSearch.done();
     }
 
     @Override
-    public List<ApplicationLoadBalancerRuleVO> listBySrcIpSrcNtwkIdAndScheme(Ip sourceIp,
long sourceNetworkId, Scheme scheme) {
+    public List<ApplicationLoadBalancerRuleVO> listBySrcIpSrcNtwkId(Ip sourceIp, long
sourceNetworkId) {
         SearchCriteria<ApplicationLoadBalancerRuleVO> sc = AllFieldsSearch.create();
         sc.setParameters("sourceIp", sourceIp);
         sc.setParameters("sourceIpNetworkId", sourceNetworkId);
-        sc.setParameters("scheme", scheme);
+        return listBy(sc);
+    }
+
+    @Override
+    public List<String> listLbIpsBySourceIpNetworkId(long sourceIpNetworkId) {
+        SearchCriteria<String> sc = listIps.create();
+        sc.setParameters("sourceIpNetworkId", sourceIpNetworkId);
+        return customSearch(sc, null);
+    }
+
+    @Override
+    public long countBySourceIp(Ip sourceIp, long sourceIpNetworkId) {
+        SearchCriteria<Long> sc = CountBy.create();
+        sc.setParameters("sourceIp", sourceIp);
+        sc.setParameters("sourceIpNetworkId", sourceIpNetworkId);
+        List<Long> results = customSearch(sc, null);
+        return results.get(0);
+    }
+
+    @Override
+    public List<ApplicationLoadBalancerRuleVO> listBySourceIpAndNotRevoked(Ip sourceIp,
long sourceNetworkId) {
+        SearchCriteria<ApplicationLoadBalancerRuleVO> sc = NotRevokedSearch.create();
+        sc.setParameters("sourceIp", sourceIp);
+        sc.setParameters("sourceIpNetworkId", sourceNetworkId);
+        sc.setParameters("state", FirewallRule.State.Revoke);
         return listBy(sc);
     }
 


Mime
View raw message