You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ah...@apache.org on 2013/01/19 01:00:14 UTC

[2/51] [abbrv] Merge branch 'master' into network-refactor-merge2

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cadca5fc/server/src/com/cloud/network/NetworkManagerImpl.java
----------------------------------------------------------------------
diff --cc server/src/com/cloud/network/NetworkManagerImpl.java
index eb20207,0a1fcd7..bb60dcf
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@@ -16,41 -16,12 +16,42 @@@
  // under the License.
  package com.cloud.network;
  
 +import java.net.URI;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.Collections;
 +import java.util.Comparator;
 +import java.util.Date;
 +import java.util.HashMap;
 +import java.util.HashSet;
 +import java.util.List;
 +import java.util.Map;
 +import java.util.Random;
 +import java.util.Set;
 +import java.util.concurrent.Executors;
 +import java.util.concurrent.ScheduledExecutorService;
 +import java.util.concurrent.TimeUnit;
 +
 +import javax.ejb.Local;
 +import javax.naming.ConfigurationException;
 +
++import org.apache.cloudstack.acl.ControlledEntity.ACLType;
++import org.apache.cloudstack.acl.SecurityChecker.AccessType;
 +import org.apache.log4j.Logger;
 +
- import com.cloud.acl.ControlledEntity.ACLType;
- import com.cloud.acl.SecurityChecker.AccessType;
  import com.cloud.agent.AgentManager;
  import com.cloud.agent.Listener;
 -import com.cloud.agent.api.*;
 +import com.cloud.agent.api.AgentControlAnswer;
 +import com.cloud.agent.api.AgentControlCommand;
 +import com.cloud.agent.api.Answer;
 +import com.cloud.agent.api.CheckNetworkAnswer;
 +import com.cloud.agent.api.CheckNetworkCommand;
 +import com.cloud.agent.api.Command;
 +import com.cloud.agent.api.StartupCommand;
 +import com.cloud.agent.api.StartupRoutingCommand;
  import com.cloud.agent.api.to.NicTO;
  import com.cloud.alert.AlertManager;
+ import com.cloud.api.ApiDBUtils;
  import com.cloud.configuration.Config;
  import com.cloud.configuration.ConfigurationManager;
  import com.cloud.configuration.Resource.ResourceType;
@@@ -101,21 -59,11 +102,22 @@@ import com.cloud.network.Networks.Addre
  import com.cloud.network.Networks.BroadcastDomainType;
  import com.cloud.network.Networks.IsolationType;
  import com.cloud.network.Networks.TrafficType;
 -import com.cloud.network.PhysicalNetwork.BroadcastDomainRange;
 -import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
  import com.cloud.network.addr.PublicIp;
 -import com.cloud.network.dao.*;
 -import com.cloud.network.element.*;
 +import com.cloud.network.dao.FirewallRulesDao;
 +import com.cloud.network.dao.IPAddressDao;
 +import com.cloud.network.dao.LoadBalancerDao;
 +import com.cloud.network.dao.NetworkDao;
 +import com.cloud.network.dao.NetworkServiceMapDao;
 +import com.cloud.network.dao.PhysicalNetworkDao;
 +import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
 +import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
 +import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO;
 +import com.cloud.network.element.DhcpServiceProvider;
 +import com.cloud.network.element.IpDeployer;
++import com.cloud.network.element.LoadBalancingServiceProvider;
 +import com.cloud.network.element.NetworkElement;
 +import com.cloud.network.element.StaticNatServiceProvider;
 +import com.cloud.network.element.UserDataServiceProvider;
  import com.cloud.network.guru.NetworkGuru;
  import com.cloud.network.lb.LoadBalancingRule;
  import com.cloud.network.lb.LoadBalancingRule.LbDestination;
@@@ -611,10 -955,10 +613,11 @@@ public class NetworkManagerImpl impleme
      }
  
      @DB
-     public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, DataCenter zone)
++    @Override
+     public IpAddress allocateIp(Account ipOwner, boolean isSystem, Account caller, long callerUserId, DataCenter zone) 
              throws ConcurrentOperationException, ResourceAllocationException,
              InsufficientAddressCapacityException {
-         
+ 
          VlanType vlanType = VlanType.VirtualNetwork;
          boolean assign = false;
  
@@@ -693,18 -1038,18 +696,18 @@@
                      return sourceNatIp;
                  }
              }
 -
 +    
              assert (sourceNatIp != null) : "How do we get a bunch of ip addresses but none of them are source nat? " +
                      "account=" + ownerId + "; networkId=" + networkId;
-         } 
-         
+         }
+ 
          return sourceNatIp;
      }
 -
 +    
      @DB
      @Override
-     public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure) 
-             throws ResourceAllocationException, ResourceUnavailableException, 
+     public IPAddressVO associateIPToGuestNetwork(long ipId, long networkId, boolean releaseOnFailure)
+             throws ResourceAllocationException, ResourceUnavailableException,
      InsufficientAddressCapacityException, ConcurrentOperationException {
          Account caller = UserContext.current().getCaller();
          Account owner = null;
@@@ -753,20 -1083,16 +741,16 @@@
              throw new InvalidParameterValueException("Ip address can be associated to the network with trafficType " + TrafficType.Guest);
          }
  
-         // Check that network belongs to IP owner - skip this check
-         //     - if zone is basic zone as there is just one guest network,
-         //     - if shared network in Advanced zone
-         //     - and it belongs to the system
-         if (network.getAccountId() != owner.getId()) {
-             if (zone.getNetworkType() != NetworkType.Basic && !(zone.getNetworkType() == NetworkType.Advanced && network.getGuestType() == Network.GuestType.Shared)) {
-                 throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
-             }
+         // Check that network belongs to IP owner - skip this check for Basic zone as there is just one guest network,
+         // and it belongs to the system
+         if (zone.getNetworkType() != NetworkType.Basic && network.getAccountId() != owner.getId()) {
+             throw new InvalidParameterValueException("The owner of the network is not the same as owner of the IP");
          }
  
-         // In Advance zone only allow to do IP assoc
-         //      - for Isolated networks with source nat service enabled
-         //      - for shared networks with source nat service enabled
-         if (zone.getNetworkType() == NetworkType.Advanced && (!_networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat))) {
+         // In Advance zone only allow to do IP assoc for Isolated networks with source nat service enabled
+         if (zone.getNetworkType() == NetworkType.Advanced &&
 -            !(network.getGuestType() == GuestType.Isolated && areServicesSupportedInNetwork(network.getId(),
++            !(network.getGuestType() == GuestType.Isolated && _networkModel.areServicesSupportedInNetwork(network.getId(),
+                 Service.SourceNat))) {
              throw new InvalidParameterValueException("In zone of type " + NetworkType.Advanced +
                      " ip address can be associated only to the network of guest type " + GuestType.Isolated + " with the "
                      + Service.SourceNat.getName() + " enabled");
@@@ -1096,10 -1520,10 +1080,10 @@@
  
      @Override
      @DB
 -    public List<NetworkVO> setupNetwork(Account owner, NetworkOfferingVO offering, Network predefined, DeploymentPlan
 +    public List<NetworkVO> setupNetwork(Account owner, NetworkOffering offering, Network predefined, DeploymentPlan 
              plan, String name, String displayText, boolean errorIfAlreadySetup, Long domainId,
              ACLType aclType, Boolean subdomainAccess, Long vpcId) throws ConcurrentOperationException {
-         
+ 
          Account locked = _accountDao.acquireInLockTable(owner.getId());
          if (locked == null) {
              throw new ConcurrentOperationException("Unable to acquire lock on " + owner);
@@@ -1306,14 -1741,14 +1290,14 @@@
          deviceId = applyProfileToNic(vo, profile, deviceId);
  
          vo = _nicDao.persist(vo);
 -
 -        Integer networkRate = getNetworkRate(network.getId(), vm.getId());
 -        NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate,
 -                isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(),
 +    
 +        Integer networkRate = _networkModel.getNetworkRate(network.getId(), vm.getId());
 +        NicProfile vmNic = new NicProfile(vo, network, vo.getBroadcastUri(), vo.getIsolationUri(), networkRate, 
 +                _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vm.getHypervisorType(),
                  network));
-         
+ 
          return new Pair<NicProfile,Integer>(vmNic, Integer.valueOf(deviceId));
-     }    
+     }
  
      protected Integer applyProfileToNic(NicVO vo, NicProfile profile, Integer deviceId) {
          if (profile.getDeviceId() != null) {
@@@ -1397,9 -1832,9 +1381,9 @@@
              to.setDns2(profile.getDns2());
          }
  
 -        Integer networkRate = getNetworkRate(config.getId(), null);
 +        Integer networkRate = _networkModel.getNetworkRate(config.getId(), null);
          to.setNetworkRateMbps(networkRate);
-         
+ 
          to.setUuid(config.getUuid());
  
          return to;
@@@ -1503,9 -1922,9 +1477,9 @@@
  
          boolean sharedSourceNat = offering.getSharedSourceNat();
          DataCenter zone = _dcDao.findById(network.getDataCenterId());
-         if (!sharedSourceNat && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat)
-                 && (network.getGuestType() == Network.GuestType.Isolated ||
-                 (network.getGuestType() == Network.GuestType.Shared && zone.getNetworkType() == NetworkType.Advanced))) {
+         if (network.getGuestType() == Network.GuestType.Isolated
 -                && areServicesSupportedInNetwork(network.getId(), Service.SourceNat)
 -                && !sharedSourceNat) {
++               && _networkModel.areServicesSupportedInNetwork(network.getId(), Service.SourceNat)
++               && !sharedSourceNat) {
  
              List<IPAddressVO> ips = null;
              if (network.getVpcId() != null) {
@@@ -1592,10 -2011,10 +1566,10 @@@
              _networksDao.changeActiveNicsBy(networkId, count);
          }
  
 -        if (nic.getVmType() == VirtualMachine.Type.User || (nic.getVmType() == VirtualMachine.Type.DomainRouter && getNetwork(networkId).getTrafficType() == TrafficType.Guest)) {
 +        if (nic.getVmType() == VirtualMachine.Type.User || (nic.getVmType() == VirtualMachine.Type.DomainRouter && _networksDao.findById(networkId).getTrafficType() == TrafficType.Guest)) {
              _networksDao.setCheckForGc(networkId);
          }
-         
+ 
          txn.commit();
      }
  
@@@ -1628,15 -2047,15 +1602,15 @@@
      }
  
      @Override
-     public NicProfile prepareNic(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, DeployDestination 
+     public NicProfile prepareNic(VirtualMachineProfile<? extends VMInstanceVO> vmProfile, DeployDestination
              dest, ReservationContext context, long nicId, NetworkVO network)
-             throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, 
+             throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException,
              ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
 -
 -        Integer networkRate = getNetworkRate(network.getId(), vmProfile.getId());
 +        
 +        Integer networkRate = _networkModel.getNetworkRate(network.getId(), vmProfile.getId());
          NetworkGuru guru = _networkGurus.get(network.getGuruName());
          NicVO nic = _nicDao.findById(nicId);
-         
+ 
          NicProfile profile = null;
          if (nic.getReservationStrategy() == Nic.ReservationStrategy.Start) {
              nic.setState(Nic.State.Reserving);
@@@ -1649,9 -2068,9 +1623,9 @@@
  
              URI isolationUri = nic.getIsolationUri();
  
-             profile = new NicProfile(nic, network, broadcastUri, isolationUri, 
+             profile = new NicProfile(nic, network, broadcastUri, isolationUri,
  
 -            networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vmProfile.getHypervisorType(), network));
 +            networkRate, _networkModel.isSecurityGroupSupportedInNetwork(network), _networkModel.getNetworkTag(vmProfile.getHypervisorType(), network));
              guru.reserve(profile, network, vmProfile, dest, context);
              nic.setIp4Address(profile.getIp4Address());
              nic.setAddressFormat(profile.getFormat());
@@@ -1776,21 -2195,195 +1750,21 @@@
      }
  
      @Override
 -    public List<? extends Nic> getNics(long vmId) {
 -        return _nicDao.listByVmId(vmId);
 -    }
 +    public void cleanupNics(VirtualMachineProfile<? extends VMInstanceVO> vm) {
 +        if (s_logger.isDebugEnabled()) {
 +            s_logger.debug("Cleaning network for vm: " + vm.getId());
 +        }
  
 -    @Override
 -    public List<NicProfile> getNicProfiles(VirtualMachine vm) {
          List<NicVO> nics = _nicDao.listByVmId(vm.getId());
 -        List<NicProfile> profiles = new ArrayList<NicProfile>();
 -
 -        if (nics != null) {
 -            for (Nic nic : nics) {
 -                NetworkVO network = _networksDao.findById(nic.getNetworkId());
 -                Integer networkRate = getNetworkRate(network.getId(), vm.getId());
 -
 -                NetworkGuru guru = _networkGurus.get(network.getGuruName());
 -                NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
 -                        networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network));
 -                guru.updateNicProfile(profile, network);
 -                profiles.add(profile);
 -            }
 +        for (NicVO nic : nics) {
 +            removeNic(vm, nic);
          }
 -        return profiles;
      }
-     
+ 
      @Override
 -    public NicProfile getNicProfile(VirtualMachine vm, long networkId, String broadcastUri) {
 -        NicVO nic = null;
 -        if (broadcastUri != null) {
 -            nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(networkId, vm.getId(), broadcastUri);
 -        } else {
 -           nic =  _nicDao.findByInstanceIdAndNetworkId(networkId, vm.getId());
 -        }
 -        NetworkVO network = _networksDao.findById(networkId);
 -        Integer networkRate = getNetworkRate(network.getId(), vm.getId());
 -
 -        NetworkGuru guru = _networkGurus.get(network.getGuruName());
 -        NicProfile profile = new NicProfile(nic, network, nic.getBroadcastUri(), nic.getIsolationUri(),
 -                networkRate, isSecurityGroupSupportedInNetwork(network), getNetworkTag(vm.getHypervisorType(), network));
 -        guru.updateNicProfile(profile, network);
 -
 -        return profile;
 -    }
 -
 -    @Override
 -    @DB
 -    @ActionEvent(eventType = EventTypes.EVENT_NET_IP_RELEASE, eventDescription = "disassociating Ip", async = true)
 -    public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException {
 -        Long userId = UserContext.current().getCallerUserId();
 -        Account caller = UserContext.current().getCaller();
 -
 -        // Verify input parameters
 -        IPAddressVO ipVO = _ipAddressDao.findById(ipAddressId);
 -        if (ipVO == null) {
 -            throw new InvalidParameterValueException("Unable to find ip address by id");
 -        }
 -
 -        if (ipVO.getAllocatedTime() == null) {
 -            s_logger.debug("Ip Address id= " + ipAddressId + " is not allocated, so do nothing.");
 -            return true;
 -        }
 -
 -        // verify permissions
 -        if (ipVO.getAllocatedToAccountId() != null) {
 -            _accountMgr.checkAccess(caller, null, true, ipVO);
 -        }
 -
 -        if (ipVO.isSourceNat()) {
 -            throw new IllegalArgumentException("ip address is used for source nat purposes and can not be disassociated.");
 -        }
 -
 -        VlanVO vlan = _vlanDao.findById(ipVO.getVlanId());
 -        if (!vlan.getVlanType().equals(VlanType.VirtualNetwork)) {
 -            throw new IllegalArgumentException("only ip addresses that belong to a virtual network may be disassociated.");
 -        }
 -
 -        // Check for account wide pool. It will have an entry for account_vlan_map.
 -        if (_accountVlanMapDao.findAccountVlanMap(ipVO.getAllocatedToAccountId(), ipVO.getVlanId()) != null) {
 -            //see IPaddressVO.java
 -            InvalidParameterValueException ex = new InvalidParameterValueException("Sepcified IP address uuid belongs to" +
 -                    " Account wide IP pool and cannot be disassociated");
 -            ex.addProxyObject("user_ip_address", ipAddressId, "ipAddressId");
 -            throw ex;
 -        }
 -
 -        // don't allow releasing system ip address
 -        if (ipVO.getSystem()) {
 -            InvalidParameterValueException ex = new InvalidParameterValueException("Can't release system IP address with specified id");
 -            ex.addProxyObject(ipVO, ipVO.getId(), "systemIpAddrId");
 -            throw ex;
 -        }
 -
 -        boolean success = disassociatePublicIpAddress(ipAddressId, userId, caller);
 -
 -        if (success) {
 -            Long networkId = ipVO.getAssociatedWithNetworkId();
 -            if (networkId != null) {
 -                Network guestNetwork = getNetwork(networkId);
 -                NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId());
 -                Long vmId = ipVO.getAssociatedWithVmId();
 -                if (offering.getElasticIp() && vmId != null) {
 -                    _rulesMgr.getSystemIpAndEnableStaticNatForVm(_userVmDao.findById(vmId), true);
 -                    return true;
 -                }
 -            }
 -        } else {
 -            s_logger.warn("Failed to release public ip address id=" + ipAddressId);
 -        }
 -        return success;
 -    }
 -
 -    @Deprecated
 -    // No one is using this method.
 -    public AccountVO getNetworkOwner(long networkId) {
 -        SearchCriteria<AccountVO> sc = AccountsUsingNetworkSearch.create();
 -        sc.setJoinParameters("nc", "config", networkId);
 -        sc.setJoinParameters("nc", "owner", true);
 -        List<AccountVO> accounts = _accountDao.search(sc, null);
 -        return accounts.size() != 0 ? accounts.get(0) : null;
 -    }
 -
 -    @Deprecated
 -    // No one is using this method.
 -    public List<NetworkVO> getNetworksforOffering(long offeringId, long dataCenterId, long accountId) {
 -        return _networksDao.getNetworksForOffering(offeringId, dataCenterId, accountId);
 -    }
 -
 -    @Override
 -    public String getNextAvailableMacAddressInNetwork(long networkId) throws InsufficientAddressCapacityException {
 -        String mac = _networksDao.getNextAvailableMacAddress(networkId);
 -        if (mac == null) {
 -            throw new InsufficientAddressCapacityException("Unable to create another mac address", Network.class, networkId);
 -        }
 -        return mac;
 -    }
 -
 -    @Override
 -    @DB
 -    public Network getNetwork(long id) {
 -        return _networksDao.findById(id);
 -    }
 -
 -    @Override
 -    @DB
 -    public Network getNetwork(String uuid) {
 -        return _networksDao.findByUuid(uuid);
 -    }
 -
 -    @Override
 -    public List<? extends RemoteAccessVPNServiceProvider> getRemoteAccessVpnElements() {
 -        List<RemoteAccessVPNServiceProvider> elements = new ArrayList<RemoteAccessVPNServiceProvider>();
 -        for (NetworkElement element : _networkElements) {
 -            if (element instanceof RemoteAccessVPNServiceProvider) {
 -                RemoteAccessVPNServiceProvider e = (RemoteAccessVPNServiceProvider) element;
 -                elements.add(e);
 -            }
 -        }
 -
 -        return elements;
 -    }
 -
 -    @Override
 -    public List<? extends Site2SiteVpnServiceProvider> getSite2SiteVpnElements() {
 -        List<Site2SiteVpnServiceProvider> elements = new ArrayList<Site2SiteVpnServiceProvider>();
 -        for (NetworkElement element : _networkElements) {
 -            if (element instanceof Site2SiteVpnServiceProvider) {
 -                Site2SiteVpnServiceProvider e = (Site2SiteVpnServiceProvider) element;
 -                elements.add(e);
 -            }
 -        }
 -
 -        return elements;
 -    }
 -
 -    @Override
 -    public void cleanupNics(VirtualMachineProfile<? extends VMInstanceVO> vm) {
 -        if (s_logger.isDebugEnabled()) {
 -            s_logger.debug("Cleaning network for vm: " + vm.getId());
 -        }
 -
 -        List<NicVO> nics = _nicDao.listByVmId(vm.getId());
 -        for (NicVO nic : nics) {
 -            removeNic(vm, nic);
 -        }
 -    }
 -
 -    @Override
 -    public void removeNic(VirtualMachineProfile<? extends VMInstanceVO> vm, Nic nic) {
 -        removeNic(vm, _nicDao.findById(nic.getId()));
 -    }
 +    public void removeNic(VirtualMachineProfile<? extends VMInstanceVO> vm, Nic nic) {
 +        removeNic(vm, _nicDao.findById(nic.getId()));
 +    }
  
      protected void removeNic(VirtualMachineProfile<? extends VMInstanceVO> vm, NicVO nic) {
          nic.setState(Nic.State.Deallocating);
@@@ -1816,9 -2671,9 +1790,9 @@@
  
      @Override
      @DB
 -    public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway,
 +    public Network createGuestNetwork(long networkOfferingId, String name, String displayText, String gateway, 
              String cidr, String vlanId, String networkDomain, Account owner, Long domainId,
-             PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId) 
+             PhysicalNetwork pNtwk, long zoneId, ACLType aclType, Boolean subdomainAccess, Long vpcId)
                      throws ConcurrentOperationException, InsufficientCapacityException, ResourceAllocationException {
  
          NetworkOfferingVO ntwkOff = _networkOfferingDao.findById(networkOfferingId);
@@@ -1938,10 -2792,10 +1911,10 @@@
                  }
          }
          }
-         
+ 
          // If networkDomain is not specified, take it from the global configuration
 -        if (areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
 -            Map<Network.Capability, String> dnsCapabilities = getNetworkOfferingServiceCapabilities
 +        if (_networkModel.areServicesSupportedByNetworkOffering(networkOfferingId, Service.Dns)) {
 +            Map<Network.Capability, String> dnsCapabilities = _networkModel.getNetworkOfferingServiceCapabilities
                      (_configMgr.getNetworkOffering(networkOfferingId), Service.Dns);
              String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
              if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
@@@ -2056,73 -2910,498 +2029,67 @@@
          return network;
      }
  
 -    @Override
 -    public List<? extends Network> searchForNetworks(ListNetworksCmd cmd) {
 -        Long id = cmd.getId();
 -        String keyword = cmd.getKeyword();
 -        Long zoneId = cmd.getZoneId();
 -        Account caller = UserContext.current().getCaller();
 -        Long domainId = cmd.getDomainId();
 -        String accountName = cmd.getAccountName();
 -        String guestIpType = cmd.getGuestIpType();
 -        String trafficType = cmd.getTrafficType();
 -        Boolean isSystem = cmd.getIsSystem();
 -        String aclType = cmd.getAclType();
 -        Long projectId = cmd.getProjectId();
 -        List<Long> permittedAccounts = new ArrayList<Long>();
 -        String path = null;
 -        Long physicalNetworkId = cmd.getPhysicalNetworkId();
 -        List<String> supportedServicesStr = cmd.getSupportedServices();
 -        Boolean restartRequired = cmd.getRestartRequired();
 -        boolean listAll = cmd.listAll();
 -        boolean isRecursive = cmd.isRecursive();
 -        Boolean specifyIpRanges = cmd.getSpecifyIpRanges();
 -        Long vpcId = cmd.getVpcId();
 -        Boolean canUseForDeploy = cmd.canUseForDeploy();
 -        Map<String, String> tags = cmd.getTags();
 -        Boolean forVpc = cmd.getForVpc();
 -
 -        // 1) default is system to false if not specified
 -        // 2) reset parameter to false if it's specified by the regular user
 -        if ((isSystem == null || caller.getType() == Account.ACCOUNT_TYPE_NORMAL) && id == null) {
 -            isSystem = false;
 -        }
 -
 -        // Account/domainId parameters and isSystem are mutually exclusive
 -        if (isSystem != null && isSystem && (accountName != null || domainId != null)) {
 -            throw new InvalidParameterValueException("System network belongs to system, account and domainId parameters can't be specified");
 -        }
 -
 -        if (domainId != null) {
 -            DomainVO domain = _domainDao.findById(domainId);
 -            if (domain == null) {
 -                // see DomainVO.java
 -                throw new InvalidParameterValueException("Specified domain id doesn't exist in the system");
 -            }
 -
 -            _accountMgr.checkAccess(caller, domain);
 -            if (accountName != null) {
 -                Account owner = _accountMgr.getActiveAccountByName(accountName, domainId);
 -                if (owner == null) {
 -                    // see DomainVO.java
 -                    throw new InvalidParameterValueException("Unable to find account " + accountName + " in specified domain");
 -                }
 -
 -                _accountMgr.checkAccess(caller, null, true, owner);
 -                permittedAccounts.add(owner.getId());
 -            }
 -        }
 +    
  
 -        if (!_accountMgr.isAdmin(caller.getType()) || (!listAll && (projectId != null && projectId.longValue() != -1 && domainId == null))) {
 -            permittedAccounts.add(caller.getId());
 -            domainId = caller.getDomainId();
 -        }
 +    @Override
 +    @DB
 +    public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) {
 +        boolean result = false;
-         
+ 
 -        // set project information
 -        boolean skipProjectNetworks = true;
 -        if (projectId != null) {
 -            if (projectId.longValue() == -1) {
 -                if (!_accountMgr.isAdmin(caller.getType())) {
 -                    permittedAccounts.addAll(_projectMgr.listPermittedProjectAccounts(caller.getId()));
 -                }
 -            } else {
 -                permittedAccounts.clear();
 -                Project project = _projectMgr.getProject(projectId);
 -                if (project == null) {
 -                    throw new InvalidParameterValueException("Unable to find project by specified id");
 -                }
 -                if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
 -                    // getProject() returns type ProjectVO.
 -                    InvalidParameterValueException ex = new InvalidParameterValueException("Account " + caller + " cannot access specified project id");
 -                    ex.addProxyObject(project, projectId, "projectId");
 -                    throw ex;
 -                }
 -                permittedAccounts.add(project.getProjectAccountId());
 -            }
 -            skipProjectNetworks = false;
 +        NetworkVO network = _networksDao.lockRow(networkId, true);
 +        if (network == null) {
 +            s_logger.debug("Unable to find network with id: " + networkId);
 +            return false;
          }
 -
 -        if (domainId != null) {
 -            path = _domainDao.findById(domainId).getPath();
 -        } else {
 -        path = _domainDao.findById(caller.getDomainId()).getPath();
 +        if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
 +            s_logger.debug("Network is not implemented: " + network);
 +            return false;
          }
  
 -        if (listAll && domainId == null) {
 -            isRecursive = true;
 -        }
 +        network.setState(Network.State.Shutdown);
 +        _networksDao.update(network.getId(), network);
  
 -        Filter searchFilter = new Filter(NetworkVO.class, "id", false, cmd.getStartIndex(), cmd.getPageSizeVal());
 -        SearchBuilder<NetworkVO> sb = _networksDao.createSearchBuilder();
 +        boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network);
  
 -        if (forVpc != null) {
 -            if (forVpc) {
 -                sb.and("vpc", sb.entity().getVpcId(), Op.NNULL);
 -            } else {
 -                sb.and("vpc", sb.entity().getVpcId(), Op.NULL);
 +        Transaction txn = Transaction.currentTxn();
 +        txn.start();
 +        if (success) {
 +            if (s_logger.isDebugEnabled()) {
 +                s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now.");
              }
 -        }
 +            NetworkGuru guru = _networkGurus.get(network.getGuruName());
 +            NetworkProfile profile = convertNetworkToNetworkProfile(network.getId());
 +            guru.shutdown(profile, _networkOfferingDao.findById(network.getNetworkOfferingId()));
  
 -        // Don't display networks created of system network offerings
 -        SearchBuilder<NetworkOfferingVO> networkOfferingSearch = _networkOfferingDao.createSearchBuilder();
 -        networkOfferingSearch.and("systemOnly", networkOfferingSearch.entity().isSystemOnly(), SearchCriteria.Op.EQ);
 -        if (isSystem != null && isSystem) {
 -            networkOfferingSearch.and("trafficType", networkOfferingSearch.entity().getTrafficType(), SearchCriteria.Op.EQ);
 -        }
 -        sb.join("networkOfferingSearch", networkOfferingSearch, sb.entity().getNetworkOfferingId(), networkOfferingSearch.entity().getId(), JoinBuilder.JoinType.INNER);
 +            applyProfileToNetwork(network, profile);
  
-             DataCenterVO zone = _dcDao.findById(network.getDataCenterId());
-             if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId()) && (zone.getNetworkType() == NetworkType.Advanced)) {
-                 network.setState(Network.State.Setup);
-             } else {
-                 network.setState(Network.State.Allocated);
-             }
- 
 -        SearchBuilder<DataCenterVO> zoneSearch = _dcDao.createSearchBuilder();
 -        zoneSearch.and("networkType", zoneSearch.entity().getNetworkType(), SearchCriteria.Op.EQ);
 -        sb.join("zoneSearch", zoneSearch, sb.entity().getDataCenterId(), zoneSearch.entity().getId(), JoinBuilder.JoinType.INNER);
 -        sb.and("removed", sb.entity().getRemoved(), Op.NULL);
++            network.setState(Network.State.Allocated);
 +            network.setRestartRequired(false);
 +            _networksDao.update(network.getId(), network);
 +            _networksDao.clearCheckForGc(networkId);
 +            result = true;
 +        } else {
 +            network.setState(Network.State.Implemented);
 +            _networksDao.update(network.getId(), network);
 +            result = false;
 +        }
 +        txn.commit();
 +        return result;
 +    }
  
 -        if (tags != null && !tags.isEmpty()) {
 -            SearchBuilder<ResourceTagVO> tagSearch = _resourceTagDao.createSearchBuilder();
 -            for (int count=0; count < tags.size(); count++) {
 -                tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ);
 -                tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ);
 -                tagSearch.cp();
 -            }
 -            tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ);
 -            sb.groupBy(sb.entity().getId());
 -            sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER);
 -        }
 -
 -        if (permittedAccounts.isEmpty()) {
 -            SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
 -            domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
 -            sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
 -        }
 -
 -
 -            SearchBuilder<AccountVO> accountSearch = _accountDao.createSearchBuilder();
 -        accountSearch.and("typeNEQ", accountSearch.entity().getType(), SearchCriteria.Op.NEQ);
 -        accountSearch.and("typeEQ", accountSearch.entity().getType(), SearchCriteria.Op.EQ);
 -
 -
 -            sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER);
 -
 -        List<NetworkVO> networksToReturn = new ArrayList<NetworkVO>();
 -
 -        if (isSystem == null || !isSystem) {
 -            if (!permittedAccounts.isEmpty()) {
 -                //get account level networks
 -                networksToReturn.addAll(listAccountSpecificNetworks(
 -                        buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType,
 -                                physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter,
 -                        permittedAccounts));
 -                //get domain level networks
 -                if (domainId != null) {
 -                    networksToReturn
 -                    .addAll(listDomainLevelNetworks(
 -                            buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType,
 -                                    physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags), searchFilter,
 -                                    domainId, false));
 -                }
 -            } else {
 -                //add account specific networks
 -                networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(
 -                        buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType,
 -                                physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path,
 -                        isRecursive));
 -                //add domain specific networks of domain + parent domains
 -                networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(
 -                        buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType,
 -                                physicalNetworkId, aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags), searchFilter, path,
 -                                isRecursive));
 -                //add networks of subdomains
 -                if (domainId == null) {
 -                    networksToReturn
 -                    .addAll(listDomainLevelNetworks(
 -                            buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType,
 -                                    physicalNetworkId, aclType, true, restartRequired, specifyIpRanges, vpcId, tags), searchFilter,
 -                                    caller.getDomainId(), true));
 -                }
 -            }
 -        } else {
 -            networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId,
 -                    guestIpType, trafficType, physicalNetworkId, null, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags),
 -                    searchFilter);
 -        }
 -
 -        if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) {
 -            List<NetworkVO> supportedNetworks = new ArrayList<NetworkVO>();
 -            Service[] suppportedServices = new Service[supportedServicesStr.size()];
 -            int i = 0;
 -            for (String supportedServiceStr : supportedServicesStr) {
 -                Service service = Service.getService(supportedServiceStr);
 -                if (service == null) {
 -                    throw new InvalidParameterValueException("Invalid service specified " + supportedServiceStr);
 -                } else {
 -                    suppportedServices[i] = service;
 -                }
 -                i++;
 -            }
 -
 -            for (NetworkVO network : networksToReturn) {
 -                if (areServicesSupportedInNetwork(network.getId(), suppportedServices)) {
 -                    supportedNetworks.add(network);
 -                }
 -            }
 -
 -            networksToReturn=supportedNetworks;
 -        }
 -
 -        if (canUseForDeploy != null) {
 -            List<NetworkVO> networksForDeploy = new ArrayList<NetworkVO>();
 -            for (NetworkVO network : networksToReturn) {
 -                if (canUseForDeploy(network) == canUseForDeploy) {
 -                    networksForDeploy.add(network);
 -                }
 -            }
 -
 -            networksToReturn=networksForDeploy;
 -        }
 -
 -            return networksToReturn;
 -        }
 -
 -    @Override
 -    public boolean canUseForDeploy(Network network) {
 -        if (network.getTrafficType() != TrafficType.Guest) {
 -            return false;
 -        }
 -        boolean hasFreeIps = true;
 -        if (network.getGuestType() == GuestType.Shared) {
 -            hasFreeIps = _ipAddressDao.countFreeIPsInNetwork(network.getId()) > 0;
 -        } else {
 -            hasFreeIps = (getAvailableIps(network, null)).size() > 0;
 -        }
 -
 -        return hasFreeIps;
 -    }
 -
 -    private SearchCriteria<NetworkVO> buildNetworkSearchCriteria(SearchBuilder<NetworkVO> sb, String keyword, Long id,
 -            Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId,
 -            String aclType, boolean skipProjectNetworks, Boolean restartRequired, Boolean specifyIpRanges, Long vpcId, Map<String, String> tags) {
 -
 -        SearchCriteria<NetworkVO> sc = sb.create();
 -
 -        if (isSystem != null) {
 -            sc.setJoinParameters("networkOfferingSearch", "systemOnly", isSystem);
 -        }
 -
 -        if (keyword != null) {
 -            SearchCriteria<NetworkVO> ssc = _networksDao.createSearchCriteria();
 -            ssc.addOr("name", SearchCriteria.Op.LIKE, "%" + keyword + "%");
 -            sc.addAnd("name", SearchCriteria.Op.SC, ssc);
 -        }
 -
 -        if (id != null) {
 -            sc.addAnd("id", SearchCriteria.Op.EQ, id);
 -        }
 -
 -        if (zoneId != null) {
 -            sc.addAnd("dataCenterId", SearchCriteria.Op.EQ, zoneId);
 -        }
 -
 -        if (guestIpType != null) {
 -            sc.addAnd("guestType", SearchCriteria.Op.EQ, guestIpType);
 -        }
 -
 -        if (trafficType != null) {
 -            sc.addAnd("trafficType", SearchCriteria.Op.EQ, trafficType);
 -        }
 -
 -        if (aclType != null) {
 -            sc.addAnd("aclType", SearchCriteria.Op.EQ, aclType.toString());
 -        }
 -
 -        if (physicalNetworkId != null) {
 -            sc.addAnd("physicalNetworkId", SearchCriteria.Op.EQ, physicalNetworkId);
 -        }
 -
 -        if (skipProjectNetworks) {
 -            sc.setJoinParameters("accountSearch", "typeNEQ", Account.ACCOUNT_TYPE_PROJECT);
 -        } else {
 -            sc.setJoinParameters("accountSearch", "typeEQ", Account.ACCOUNT_TYPE_PROJECT);
 -        }
 -
 -        if (restartRequired != null) {
 -            sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired);
 -        }
 -
 -        if (specifyIpRanges != null) {
 -            sc.addAnd("specifyIpRanges", SearchCriteria.Op.EQ, specifyIpRanges);
 -        }
 -
 -        if (vpcId != null) {
 -            sc.addAnd("vpcId", SearchCriteria.Op.EQ, vpcId);
 -        }
 -
 -        if (tags != null && !tags.isEmpty()) {
 -            int count = 0;
 -            sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.Network.toString());
 -            for (String key : tags.keySet()) {
 -                sc.setJoinParameters("tagSearch", "key" + String.valueOf(count), key);
 -                sc.setJoinParameters("tagSearch", "value" + String.valueOf(count), tags.get(key));
 -                count++;
 -            }
 -        }
 -
 -        return sc;
 -    }
 -
 -    private List<NetworkVO> listDomainLevelNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, long domainId, boolean parentDomainsOnly) {
 -        List<Long> networkIds = new ArrayList<Long>();
 -        Set<Long> allowedDomains = _domainMgr.getDomainParentIds(domainId);
 -        List<NetworkDomainVO> maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray());
 -
 -        for (NetworkDomainVO map : maps) {
 -            if (map.getDomainId() == domainId && parentDomainsOnly) {
 -                continue;
 -            }
 -            boolean subdomainAccess = (map.isSubdomainAccess() != null) ? map.isSubdomainAccess() : getAllowSubdomainAccessGlobal();
 -            if (map.getDomainId() == domainId || subdomainAccess) {
 -                networkIds.add(map.getNetworkId());
 -            }
 -        }
 -
 -        if (!networkIds.isEmpty()) {
 -            SearchCriteria<NetworkVO> domainSC = _networksDao.createSearchCriteria();
 -            domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray());
 -            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
 -
 -            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
 -            return _networksDao.search(sc, searchFilter);
 -        } else {
 -            return new ArrayList<NetworkVO>();
 -        }
 -    }
 -
 -    private List<NetworkVO> listAccountSpecificNetworks(SearchCriteria<NetworkVO> sc, Filter searchFilter, List<Long> permittedAccounts) {
 -        SearchCriteria<NetworkVO> accountSC = _networksDao.createSearchCriteria();
 -        if (!permittedAccounts.isEmpty()) {
 -            accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray());
 -        }
 -
 -        accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString());
 -
 -        sc.addAnd("id", SearchCriteria.Op.SC, accountSC);
 -        return _networksDao.search(sc, searchFilter);
 -    }
 -
 -    private List<NetworkVO> listAccountSpecificNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter, String path, boolean isRecursive) {
 -        SearchCriteria<NetworkVO> accountSC = _networksDao.createSearchCriteria();
 -        accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString());
 -
 -        if (path != null) {
 -            if (isRecursive) {
 -                sc.setJoinParameters("domainSearch", "path", path + "%");
 -            } else {
 -                sc.setJoinParameters("domainSearch", "path", path);
 -            }
 -        }
 -
 -        sc.addAnd("id", SearchCriteria.Op.SC, accountSC);
 -        return _networksDao.search(sc, searchFilter);
 -    }
 -
 -    private List<NetworkVO> listDomainSpecificNetworksByDomainPath(SearchCriteria<NetworkVO> sc, Filter searchFilter,
 -            String path, boolean isRecursive) {
 -
 -        Set<Long> allowedDomains = new HashSet<Long>();
 -        if (path != null) {
 -            if (isRecursive) {
 -                allowedDomains = _domainMgr.getDomainChildrenIds(path);
 -            } else {
 -                Domain domain = _domainDao.findDomainByPath(path);
 -                allowedDomains.add(domain.getId());
 -            }
 -        }
 -
 -        List<Long> networkIds = new ArrayList<Long>();
 -
 -        List<NetworkDomainVO> maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray());
 -
 -        for (NetworkDomainVO map : maps) {
 -            networkIds.add(map.getNetworkId());
 -        }
 -
 -        if (!networkIds.isEmpty()) {
 -            SearchCriteria<NetworkVO> domainSC = _networksDao.createSearchCriteria();
 -            domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray());
 -            domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString());
 -
 -            sc.addAnd("id", SearchCriteria.Op.SC, domainSC);
 -        return _networksDao.search(sc, searchFilter);
 -        } else {
 -            return new ArrayList<NetworkVO>();
 -        }
 -    }
 -
 -    @Override
 -    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_DELETE, eventDescription = "deleting network", async = true)
 -    public boolean deleteNetwork(long networkId) {
 -
 -        Account caller = UserContext.current().getCaller();
 -
 -        // Verify network id
 -        NetworkVO network = _networksDao.findById(networkId);
 -        if (network == null) {
 -            // see NetworkVO.java
 -
 -            InvalidParameterValueException ex = new InvalidParameterValueException("unable to find network with specified id");
 -            ex.addProxyObject(network, networkId, "networkId");
 -            throw ex;
 -        }
 -
 -        // don't allow to delete system network
 -        if (isNetworkSystem(network)) {
 -            InvalidParameterValueException ex = new InvalidParameterValueException("Network with specified id is system and can't be removed");
 -            ex.addProxyObject(network, network.getId(), "networkId");
 -            throw ex;
 -        }
 -
 -        Account owner = _accountMgr.getAccount(network.getAccountId());
 -
 -        // Perform permission check
 -        _accountMgr.checkAccess(caller, null, true, network);
 -
 -        User callerUser = _accountMgr.getActiveUser(UserContext.current().getCallerUserId());
 -        ReservationContext context = new ReservationContextImpl(null, null, callerUser, owner);
 -
 -        return destroyNetwork(networkId, context);
 -    }
 -
 -    @Override
 -    @DB
 -    public boolean shutdownNetwork(long networkId, ReservationContext context, boolean cleanupElements) {
 -        boolean result = false;
 -
 -        NetworkVO network = _networksDao.lockRow(networkId, true);
 -        if (network == null) {
 -            s_logger.debug("Unable to find network with id: " + networkId);
 -            return false;
 -        }
 -        if (network.getState() != Network.State.Implemented && network.getState() != Network.State.Shutdown) {
 -            s_logger.debug("Network is not implemented: " + network);
 -            return false;
 -        }
 -
 -        network.setState(Network.State.Shutdown);
 -        _networksDao.update(network.getId(), network);
 -
 -        boolean success = shutdownNetworkElementsAndResources(context, cleanupElements, network);
 -
 -        Transaction txn = Transaction.currentTxn();
 -        txn.start();
 -        if (success) {
 -            if (s_logger.isDebugEnabled()) {
 -                s_logger.debug("Network id=" + networkId + " is shutdown successfully, cleaning up corresponding resources now.");
 -            }
 -            NetworkGuru guru = _networkGurus.get(network.getGuruName());
 -            NetworkProfile profile = convertNetworkToNetworkProfile(network.getId());
 -            guru.shutdown(profile, _networkOfferingDao.findById(network.getNetworkOfferingId()));
 -
 -            applyProfileToNetwork(network, profile);
 -
 -            network.setState(Network.State.Allocated);
 -            network.setRestartRequired(false);
 -            _networksDao.update(network.getId(), network);
 -            _networksDao.clearCheckForGc(networkId);
 -            result = true;
 -        } else {
 -            network.setState(Network.State.Implemented);
 -            _networksDao.update(network.getId(), network);
 -            result = false;
 -        }
 -        txn.commit();
 -        return result;
 -    }
 -
 -    private boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean cleanupElements, NetworkVO network) {
 -        // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down
 -        // the elements
 -        boolean cleanupResult = true;
 -        try {
 -            cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId());
 -        } catch (Exception ex) {
 -            s_logger.warn("shutdownNetworkRules failed during the network " + network + " shutdown due to ", ex);
 -        } finally {
 -            // just warn the administrator that the network elements failed to shutdown
 -            if (!cleanupResult) {
 -                s_logger.warn("Failed to cleanup network id=" + network.getId() + " resources as a part of shutdownNetwork");
 +    @Override
 +    public boolean shutdownNetworkElementsAndResources(ReservationContext context, boolean cleanupElements, NetworkVO network) {
 +        // 1) Cleanup all the rules for the network. If it fails, just log the failure and proceed with shutting down
 +        // the elements
 +        boolean cleanupResult = true;
 +        try {
 +            cleanupResult = shutdownNetworkResources(network.getId(), context.getAccount(), context.getCaller().getId());
 +        } catch (Exception ex) {
 +            s_logger.warn("shutdownNetworkRules failed during the network " + network + " shutdown due to ", ex);
 +        } finally {
 +            // just warn the administrator that the network elements failed to shutdown
 +            if (!cleanupResult) {
 +                s_logger.warn("Failed to cleanup network id=" + network.getId() + " resources as a part of shutdownNetwork");
              }
          }
  
@@@ -2761,136 -4459,1458 +2728,128 @@@
          return ip;
      }
  
 -    @Override
 -    public boolean isNetworkAvailableInDomain(long networkId, long domainId) {
 -        Long networkDomainId = null;
 -        Network network = getNetwork(networkId);
 -        if (network.getGuestType() != Network.GuestType.Shared) {
 -            s_logger.trace("Network id=" + networkId + " is not shared");
 -            return false;
 -        }
 +    
  
 -        NetworkDomainVO networkDomainMap = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
 -        if (networkDomainMap == null) {
 -            s_logger.trace("Network id=" + networkId + " is shared, but not domain specific");
 -            return true;
 -        } else {
 -            networkDomainId = networkDomainMap.getDomainId();
 -        }
 +    Random _rand = new Random(System.currentTimeMillis());
  
 -        if (domainId == networkDomainId.longValue()) {
 -            return true;
 +    @Override
 +    @DB
 +    public String acquireGuestIpAddress(Network network, String requestedIp) {
 +        if (requestedIp != null && requestedIp.equals(network.getGateway())) {
 +            s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network);
 +            return null;
          }
  
 -        if (networkDomainMap.subdomainAccess) {
 -            Set<Long> parentDomains = _domainMgr.getDomainParentIds(domainId);
 +        Set<Long> availableIps = _networkModel.getAvailableIps(network, requestedIp);
  
 -            if (parentDomains.contains(domainId)) {
 -                return true;
 -            }
 +        if (availableIps.isEmpty()) {
 +            return null;
          }
  
 -        return false;
 -    }
 +        Long[] array = availableIps.toArray(new Long[availableIps.size()]);
  
 -    @Override
 -    public Long getDedicatedNetworkDomain(long networkId) {
 -        NetworkDomainVO networkMaps = _networkDomainDao.getDomainNetworkMapByNetworkId(networkId);
 -        if (networkMaps != null) {
 -            return networkMaps.getDomainId();
 -        } else {
 -            return null;
 +        if (requestedIp != null) {
 +            // check that requested ip has the same cidr
 +            String[] cidr = network.getCidr().split("/");
 +            boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1]));
 +            if (!isSameCidr) {
 +                s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr");
 +                return null;
 +            } else {
 +                return requestedIp;
 +            }
          }
 -    }
  
 -    private boolean checkForNonStoppedVmInNetwork(long networkId) {
 -        List<UserVmVO> vms = _userVmDao.listByNetworkIdAndStates(networkId, VirtualMachine.State.Starting,
 -                VirtualMachine.State.Running, VirtualMachine.State.Migrating, VirtualMachine.State.Stopping);
 -        return vms.isEmpty();
 +        String result;
 +        do {
 +            result = NetUtils.long2Ip(array[_rand.nextInt(array.length)]);
 +        } while (result.split("\\.")[3].equals("1"));
 +        return result;
      }
  
 +    
      @Override
 -    @DB
 -    @ActionEvent(eventType = EventTypes.EVENT_NETWORK_UPDATE, eventDescription = "updating network", async = true)
 -    public Network updateGuestNetwork(long networkId, String name, String displayText, Account callerAccount,
 -            User callerUser, String domainSuffix, Long networkOfferingId, Boolean changeCidr) {
 -        boolean restartNetwork = false;
 -
 -        // verify input parameters
 -        NetworkVO network = _networksDao.findById(networkId);
 -        if (network == null) {
 -            // see NetworkVO.java
 -            InvalidParameterValueException ex = new InvalidParameterValueException("Specified network id doesn't exist in the system");
 -            ex.addProxyObject("networks", networkId, "networkId");
 -            throw ex;
 -        }
 -
 -        // don't allow to update network in Destroy state
 -        if (network.getState() == Network.State.Destroy) {
 -            throw new InvalidParameterValueException("Don't allow to update network in state " + Network.State.Destroy);
 -        }
 +    public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError) throws ResourceUnavailableException {
 +        Network network = _networksDao.findById(staticNats.get(0).getNetworkId());
 +        boolean success = true;
  
 -        // Don't allow to update system network
 -        NetworkOffering offering = _networkOfferingDao.findByIdIncludingRemoved(network.getNetworkOfferingId());
 -        if (offering.isSystemOnly()) {
 -            throw new InvalidParameterValueException("Can't update system networks");
 +        if (staticNats == null || staticNats.size() == 0) {
 +            s_logger.debug("There are no static nat rules for the network elements");
 +            return true;
          }
  
 -        // allow to upgrade only Guest networks
 -        if (network.getTrafficType() != Networks.TrafficType.Guest) {
 -            throw new InvalidParameterValueException("Can't allow networks which traffic type is not " + TrafficType.Guest);
 +        // get the list of public ip's owned by the network
 +        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
 +        List<PublicIp> publicIps = new ArrayList<PublicIp>();
 +        if (userIps != null && !userIps.isEmpty()) {
 +            for (IPAddressVO userIp : userIps) {
 +                PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
 +                publicIps.add(publicIp);
 +            }
          }
  
 -        _accountMgr.checkAccess(callerAccount, null, true, network);
 -
 -        if (name != null) {
 -            network.setName(name);
 -        }
 +        // static NAT rules can not programmed unless IP is associated with network service provider, so run IP
 +        // association for the network so as to ensure IP is associated before applying rules (in add state)
 +        applyIpAssociations(network, false, continueOnError, publicIps);
  
 -        if (displayText != null) {
 -            network.setDisplayText(displayText);
 +        // get provider
-         String staticNatProvider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.StaticNat);
- 
-         for (NetworkElement ne : _networkElements) {
-             try {
-                 if (!(ne instanceof StaticNatServiceProvider && ne.getName().equalsIgnoreCase(staticNatProvider))) {
-                     continue;
-                 }
- 
-                 boolean handled = ((StaticNatServiceProvider) ne).applyStaticNats(network, staticNats);
-                 s_logger.debug("Static Nat for network " + network.getId() + " were " + (handled ? "" : " not") + " handled by " + ne.getName());
-             } catch (ResourceUnavailableException e) {
-                 if (!continueOnError) {
-                     throw e;
-                 }
-                 s_logger.warn("Problems with " + ne.getName() + " but pushing on", e);
-                 success = false;
++        StaticNatServiceProvider element = getStaticNatProviderForNetwork(network);
++        try {
++            success = element.applyStaticNats(network, staticNats);
++        } catch (ResourceUnavailableException e) {
++            if (!continueOnError) {
++                throw e;
 +            }
++            s_logger.warn("Problems with " + element.getName() + " but pushing on", e);
++            success = false;
          }
  
 -        // network offering and domain suffix can be updated for Isolated networks only in 3.0
 -        if ((networkOfferingId != null || domainSuffix != null) && network.getGuestType() != GuestType.Isolated) {
 -            throw new InvalidParameterValueException("NetworkOffering and domain suffix upgrade can be perfomed for Isolated networks only");
 +        // For revoked static nat IP, set the vm_id to null, indicate it should be revoked
 +        for (StaticNat staticNat : staticNats) {
 +            if (staticNat.isForRevoke()) {
 +                for (PublicIp publicIp : publicIps) {
 +                    if (publicIp.getId() == staticNat.getSourceIpAddressId()) {
 +                        publicIps.remove(publicIp);
 +                        IPAddressVO ip = _ipAddressDao.findByIdIncludingRemoved(staticNat.getSourceIpAddressId());
 +                        // ip can't be null, otherwise something wrong happened
 +                        ip.setAssociatedWithVmId(null);
 +                        publicIp = new PublicIp(ip, _vlanDao.findById(ip.getVlanId()), NetUtils.createSequenceBasedMacAddress(ip.getMacAddress()));
 +                        publicIps.add(publicIp);
 +                        break;
 +                    }
 +                }
 +            }
          }
-         
+ 
 -        boolean networkOfferingChanged = false;
 -
 -        long oldNetworkOfferingId = network.getNetworkOfferingId();
 -        if (networkOfferingId != null) {
 +        // if all the rules configured on public IP are revoked then, dis-associate IP with network service provider
 +        applyIpAssociations(network, true, continueOnError, publicIps);
  
 -            NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
 -            if (networkOffering == null || networkOffering.isSystemOnly()) {
 -                InvalidParameterValueException ex = new InvalidParameterValueException("Unable to find network offering with specified id");
 -                ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId");
 -                throw ex;
 -            }
 -
 -            // network offering should be in Enabled state
 -            if (networkOffering.getState() != NetworkOffering.State.Enabled) {
 -                InvalidParameterValueException ex = new InvalidParameterValueException("Network offering with specified id is not in " + NetworkOffering.State.Enabled + " state, can't upgrade to it");
 -                ex.addProxyObject(networkOffering, networkOfferingId, "networkOfferingId");
 -                throw ex;
 -            }
 -
 -
 -            //can't update from vpc to non-vpc network offering
 -            boolean forVpcNew = _configMgr.isOfferingForVpc(networkOffering);
 -            boolean vorVpcOriginal = _configMgr.isOfferingForVpc(_configMgr.getNetworkOffering(oldNetworkOfferingId));
 -            if (forVpcNew != vorVpcOriginal) {
 -                String errMsg = forVpcNew ? "a vpc offering " : "not a vpc offering";
 -                throw new InvalidParameterValueException("Can't update as the new offering is " + errMsg);
 -            }
 -
 -            if (networkOfferingId != oldNetworkOfferingId) {
 -                NetworkOffering oldNtwkOff = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
 -                Collection<String> newProviders = finalizeServicesAndProvidersForNetwork(networkOffering, network.getPhysicalNetworkId()).values();
 -                Collection<String> oldProviders = finalizeServicesAndProvidersForNetwork(oldNtwkOff, network.getPhysicalNetworkId()).values();
 -                
 -                if (providersConfiguredForExternalNetworking(newProviders) != providersConfiguredForExternalNetworking(oldProviders)
 -                        && !changeCidr) {
 -                    throw new InvalidParameterValueException("Updating network failed since guest CIDR needs to be changed!");
 -                }
 -                if (changeCidr) {
 -                    if (!checkForNonStoppedVmInNetwork(network.getId())) {
 -                        InvalidParameterValueException ex = new InvalidParameterValueException("All user vm of network of specified id should be stopped before changing CIDR!");
 -                        ex.addProxyObject(network, networkId, "networkId");
 -                        throw ex;
 -                    }
 -                }
 -                // check if the network is upgradable
 -                if (!canUpgrade(network, oldNetworkOfferingId, networkOfferingId)) {
 -                    throw new InvalidParameterValueException("Can't upgrade from network offering " + oldNetworkOfferingId + " to " + networkOfferingId + "; check logs for more information");
 -                }
 -                restartNetwork = true;
 -                networkOfferingChanged = true;
 -            }
 -        }
 -        Map<String, String> newSvcProviders = new HashMap<String, String>();
 -        if (networkOfferingChanged) {
 -            newSvcProviders = finalizeServicesAndProvidersForNetwork(_configMgr.getNetworkOffering(networkOfferingId), network.getPhysicalNetworkId());
 -        }
 -
 -        // don't allow to modify network domain if the service is not supported
 -        if (domainSuffix != null) {
 -            // validate network domain
 -            if (!NetUtils.verifyDomainName(domainSuffix)) {
 -                throw new InvalidParameterValueException(
 -                        "Invalid network domain. Total length shouldn't exceed 190 chars. Each domain label must be between 1 and 63 characters long, can contain ASCII letters 'a' through 'z', the digits '0' through '9', "
 -                                + "and the hyphen ('-'); can't start or end with \"-\"");
 -            }
 -
 -            long offeringId = oldNetworkOfferingId;
 -            if (networkOfferingId != null) {
 -                offeringId = networkOfferingId;
 -            }
 -
 -            Map<Network.Capability, String> dnsCapabilities = getNetworkOfferingServiceCapabilities(_configMgr.getNetworkOffering(offeringId), Service.Dns);
 -            String isUpdateDnsSupported = dnsCapabilities.get(Capability.AllowDnsSuffixModification);
 -            if (isUpdateDnsSupported == null || !Boolean.valueOf(isUpdateDnsSupported)) {
 -                // TBD: use uuid instead of networkOfferingId. May need to hardcode tablename in call to addProxyObject().
 -                throw new InvalidParameterValueException("Domain name change is not supported by the network offering id=" + networkOfferingId);
 -            }
 -
 -            network.setNetworkDomain(domainSuffix);
 -            // have to restart the network
 -            restartNetwork = true;
 -        }
 -
 -        ReservationContext context = new ReservationContextImpl(null, null, callerUser, callerAccount);
 -        // 1) Shutdown all the elements and cleanup all the rules. Don't allow to shutdown network in intermediate
 -        // states - Shutdown and Implementing
 -        boolean validStateToShutdown = (network.getState() == Network.State.Implemented || network.getState() == Network.State.Setup || network.getState() == Network.State.Allocated);
 -        if (restartNetwork) {
 -            if (validStateToShutdown) {
 -                if (!changeCidr) {
 -                    s_logger.debug("Shutting down elements and resources for network id=" + networkId + " as a part of network update");
 -
 -                    if (!shutdownNetworkElementsAndResources(context, true, network)) {
 -                        s_logger.warn("Failed to shutdown the network elements and resources as a part of network restart: " + network);
 -                        CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network of specified id");
 -                        ex.addProxyObject(network, networkId, "networkId");
 -                        throw ex;
 -                    }
 -                } else {
 -                    // We need to shutdown the network, since we want to re-implement the network.
 -                    s_logger.debug("Shutting down network id=" + networkId + " as a part of network update");
 -
 -                    if (!shutdownNetwork(network.getId(), context, true)) {
 -                        s_logger.warn("Failed to shutdown the network as a part of update to network with specified id");
 -                        CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network as a part of update of specified network id");
 -                        ex.addProxyObject(network, networkId, "networkId");
 -                        throw ex;
 -                    }
 -                }
 -            } else {
 -                CloudRuntimeException ex = new CloudRuntimeException("Failed to shutdown the network elements and resources as a part of update to network with specified id; network is in wrong state: " + network.getState());
 -                ex.addProxyObject(network, networkId, "networkId");
 -                throw ex;
 -            }
 -        }
 -
 -        // 2) Only after all the elements and rules are shutdown properly, update the network VO
 -        // get updated network
 -        Network.State networkState = _networksDao.findById(networkId).getState();
 -        boolean validStateToImplement = (networkState == Network.State.Implemented || networkState == Network.State.Setup || networkState == Network.State.Allocated);
 -        if (restartNetwork && !validStateToImplement) {
 -            CloudRuntimeException ex = new CloudRuntimeException("Failed to implement the network elements and resources as a part of update to network with specified id; network is in wrong state: " + networkState);
 -            ex.addProxyObject(network, networkId, "networkId");
 -            throw ex;
 -        }
 -
 -        if (networkOfferingId != null) {
 -            if (networkOfferingChanged) {
 -                Transaction txn = Transaction.currentTxn();
 -                txn.start();
 -                network.setNetworkOfferingId(networkOfferingId);
 -                _networksDao.update(networkId, network, newSvcProviders);
 -                // get all nics using this network
 -                // log remove usage events for old offering
 -                // log assign usage events for new offering
 -                List<NicVO> nics = _nicDao.listByNetworkId(networkId);
 -                for (NicVO nic : nics) {
 -                    if (nic.getReservationStrategy() == Nic.ReservationStrategy.PlaceHolder) {
 -                        continue;
 -                    }
 -                    long vmId = nic.getInstanceId();
 -                    VMInstanceVO vm = _vmDao.findById(vmId);
 -                    if (vm == null) {
 -                        s_logger.error("Vm for nic " + nic.getId() + " not found with Vm Id:" + vmId);
 -                        continue;
 -                    }
 -                    long isDefault = (nic.isDefaultNic()) ? 1 : 0;
 -                    UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_REMOVE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), null, oldNetworkOfferingId, null, 0L);
 -                    _usageEventDao.persist(usageEvent);
 -                    usageEvent = new UsageEventVO(EventTypes.EVENT_NETWORK_OFFERING_ASSIGN, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), vm.getHostName(), networkOfferingId, null, isDefault);
 -                    _usageEventDao.persist(usageEvent);
 -                }
 -                txn.commit();
 -            } else {
 -                network.setNetworkOfferingId(networkOfferingId);
 -                _networksDao.update(networkId, network, finalizeServicesAndProvidersForNetwork(_configMgr.getNetworkOffering(networkOfferingId), network.getPhysicalNetworkId()));
 -            }
 -        } else {
 -            _networksDao.update(networkId, network);
 -        }
 -
 -        // 3) Implement the elements and rules again
 -        if (restartNetwork) {
 -            if (network.getState() != Network.State.Allocated) {
 -                DeployDestination dest = new DeployDestination(_dcDao.findById(network.getDataCenterId()), null, null, null);
 -                s_logger.debug("Implementing the network " + network + " elements and resources as a part of network update");
 -                try {
 -                    if (!changeCidr) {
 -                        implementNetworkElementsAndResources(dest, context, network, _networkOfferingDao.findById(network.getNetworkOfferingId()));
 -                    } else {
 -                        implementNetwork(network.getId(), dest, context);
 -                    }
 -                } catch (Exception ex) {
 -                    s_logger.warn("Failed to implement network " + network + " elements and resources as a part of network update due to ", ex);
 -                    CloudRuntimeException e = new CloudRuntimeException("Failed to implement network (with specified id) elements and resources as a part of network update");
 -                    e.addProxyObject(network, networkId, "networkId");
 -                    throw e;
 -                }
 -            }
 -        }
 -
 -        return getNetwork(network.getId());
 -    }
 -
 -    @Override
 -    public Integer getNetworkRate(long networkId, Long vmId) {
 -        VMInstanceVO vm = null;
 -        if (vmId != null) {
 -            vm = _vmDao.findById(vmId);
 -        }
 -        Network network = getNetwork(networkId);
 -        NetworkOffering ntwkOff = _configMgr.getNetworkOffering(network.getNetworkOfferingId());
 -
 -        // For default userVm Default network and domR guest/public network, get rate information from the service
 -        // offering; for other situations get information
 -        // from the network offering
 -        boolean isUserVmsDefaultNetwork = false;
 -        boolean isDomRGuestOrPublicNetwork = false;
 -        if (vm != null) {
 -            Nic nic = _nicDao.findByInstanceIdAndNetworkId(networkId, vmId);
 -            if (vm.getType() == Type.User && nic != null && nic.isDefaultNic()) {
 -                isUserVmsDefaultNetwork = true;
 -            } else if (vm.getType() == Type.DomainRouter && ntwkOff != null && (ntwkOff.getTrafficType() == TrafficType.Public || ntwkOff.getTrafficType() == TrafficType.Guest)) {
 -                isDomRGuestOrPublicNetwork = true;
 -            }
 -        }
 -        if (isUserVmsDefaultNetwork || isDomRGuestOrPublicNetwork) {
 -            return _configMgr.getServiceOfferingNetworkRate(vm.getServiceOfferingId());
 -        } else {
 -            return _configMgr.getNetworkOfferingNetworkRate(ntwkOff.getId());
 -        }
 -    }
 -
 -    Random _rand = new Random(System.currentTimeMillis());
 -
 -    @Override
 -    @DB
 -    public String acquireGuestIpAddress(Network network, String requestedIp) {
 -        if (requestedIp != null && requestedIp.equals(network.getGateway())) {
 -            s_logger.warn("Requested ip address " + requestedIp + " is used as a gateway address in network " + network);
 -            return null;
 -        }
 -
 -        Set<Long> availableIps = getAvailableIps(network, requestedIp);
 -
 -        if (availableIps.isEmpty()) {
 -            return null;
 -        }
 -
 -        Long[] array = availableIps.toArray(new Long[availableIps.size()]);
 -
 -        if (requestedIp != null) {
 -            // check that requested ip has the same cidr
 -            String[] cidr = network.getCidr().split("/");
 -            boolean isSameCidr = NetUtils.sameSubnetCIDR(requestedIp, NetUtils.long2Ip(array[0]), Integer.parseInt(cidr[1]));
 -            if (!isSameCidr) {
 -                s_logger.warn("Requested ip address " + requestedIp + " doesn't belong to the network " + network + " cidr");
 -                return null;
 -            } else {
 -                return requestedIp;
 -            }
 -        }
 -
 -        String result;
 -        do {
 -            result = NetUtils.long2Ip(array[_rand.nextInt(array.length)]);
 -        } while (result.split("\\.")[3].equals("1"));
 -        return result;
 -    }
 -
 -    protected Set<Long> getAvailableIps(Network network, String requestedIp) {
 -        String[] cidr = network.getCidr().split("/");
 -        List<String> ips = _nicDao.listIpAddressInNetwork(network.getId());
 -        Set<Long> allPossibleIps = NetUtils.getAllIpsFromCidr(cidr[0], Integer.parseInt(cidr[1]));
 -        Set<Long> usedIps = new TreeSet<Long>();
 -
 -        for (String ip : ips) {
 -            if (requestedIp != null && requestedIp.equals(ip)) {
 -                s_logger.warn("Requested ip address " + requestedIp + " is already in use in network" + network);
 -                return null;
 -            }
 -
 -            usedIps.add(NetUtils.ip2Long(ip));
 -        }
 -        if (usedIps.size() != 0) {
 -            allPossibleIps.removeAll(usedIps);
 -        }
 -        return allPossibleIps;
 -    }
 -
 -
 -    private String getZoneNetworkDomain(long zoneId) {
 -        return _dcDao.findById(zoneId).getDomain();
 -    }
 -
 -    private String getDomainNetworkDomain(long domainId, long zoneId) {
 -        String networkDomain = null;
 -        Long searchDomainId = domainId;
 -        while(searchDomainId != null){
 -            DomainVO domain = _domainDao.findById(searchDomainId);
 -            if(domain.getNetworkDomain() != null){
 -                networkDomain = domain.getNetworkDomain();
 -                break;
 -            }
 -            searchDomainId = domain.getParent();
 -        }
 -        if (networkDomain == null) {
 -            return getZoneNetworkDomain(zoneId);
 -        }
 -        return networkDomain;
 -    }
 -
 -    @Override
 -    public String getAccountNetworkDomain(long accountId, long zoneId) {
 -        String networkDomain = _accountDao.findById(accountId).getNetworkDomain();
 -
 -        if (networkDomain == null) {
 -            // get domain level network domain
 -            return getDomainNetworkDomain(_accountDao.findById(accountId).getDomainId(), zoneId);
 -        }
 -
 -        return networkDomain;
 -    }
 -
 -    @Override
 -    public String getGlobalGuestDomainSuffix() {
 -        return _networkDomain;
 -    }
 -
 -    @Override
 -    public String getStartIpAddress(long networkId) {
 -        List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(networkId);
 -        if (vlans.isEmpty()) {
 -            return null;
 -        }
 -
 -        String startIP = vlans.get(0).getIpRange().split("-")[0];
 -
 -        for (VlanVO vlan : vlans) {
 -            String startIP1 = vlan.getIpRange().split("-")[0];
 -            long startIPLong = NetUtils.ip2Long(startIP);
 -            long startIPLong1 = NetUtils.ip2Long(startIP1);
 -
 -            if (startIPLong1 < startIPLong) {
 -                startIP = startIP1;
 -            }
 -        }
 -
 -        return startIP;
 -    }
 -
 -    @Override
 -    public boolean applyStaticNats(List<? extends StaticNat> staticNats, boolean continueOnError) throws ResourceUnavailableException {
 -        Network network = _networksDao.findById(staticNats.get(0).getNetworkId());
 -        boolean success = true;
 -
 -        if (staticNats == null || staticNats.size() == 0) {
 -            s_logger.debug("There are no static nat rules for the network elements");
 -            return true;
 -        }
 -
 -        // get the list of public ip's owned by the network
 -        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
 -        List<PublicIp> publicIps = new ArrayList<PublicIp>();
 -        if (userIps != null && !userIps.isEmpty()) {
 -            for (IPAddressVO userIp : userIps) {
 -                PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
 -                publicIps.add(publicIp);
 -            }
 -        }
 -
 -        // static NAT rules can not programmed unless IP is associated with network service provider, so run IP
 -        // association for the network so as to ensure IP is associated before applying rules (in add state)
 -        applyIpAssociations(network, false, continueOnError, publicIps);
 -
 -        // get provider
 -        StaticNatServiceProvider element = getStaticNatProviderForNetwork(network);
 -        try {
 -            success = element.applyStaticNats(network, staticNats);
 -        } catch (ResourceUnavailableException e) {
 -            if (!continueOnError) {
 -                throw e;
 -            }
 -            s_logger.warn("Problems with " + element.getName() + " but pushing on", e);
 -            success = false;
 -        }
 -
 -        // For revoked static nat IP, set the vm_id to null, indicate it should be revoked
 -        for (StaticNat staticNat : staticNats) {
 -            if (staticNat.isForRevoke()) {
 -                for (PublicIp publicIp : publicIps) {
 -                    if (publicIp.getId() == staticNat.getSourceIpAddressId()) {
 -                        publicIps.remove(publicIp);
 -                        IPAddressVO ip = _ipAddressDao.findByIdIncludingRemoved(staticNat.getSourceIpAddressId());
 -                        // ip can't be null, otherwise something wrong happened
 -                        ip.setAssociatedWithVmId(null);
 -                        publicIp = new PublicIp(ip, _vlanDao.findById(ip.getVlanId()), NetUtils.createSequenceBasedMacAddress(ip.getMacAddress()));
 -                        publicIps.add(publicIp);
 -                        break;
 -                    }
 -                }
 -            }
 -        }
 -
 -        // if all the rules configured on public IP are revoked then, dis-associate IP with network service provider
 -        applyIpAssociations(network, true, continueOnError, publicIps);
 -
 -        return success;
 -    }
 -
 -    @Override
 -    public Long getPodIdForVlan(long vlanDbId) {
 -        PodVlanMapVO podVlanMaps = _podVlanMapDao.listPodVlanMapsByVlan(vlanDbId);
 -        if (podVlanMaps == null) {
 -            return null;
 -        } else {
 -            return podVlanMaps.getPodId();
 -        }
 -    }
 -
 -    @DB
 -    @Override
 -    public boolean reallocate(VirtualMachineProfile<? extends VMInstanceVO> vm, DataCenterDeployment dest) throws InsufficientCapacityException, ConcurrentOperationException {
 -        VMInstanceVO vmInstance = _vmDao.findById(vm.getId());
 -        DataCenterVO dc = _dcDao.findById(vmInstance.getDataCenterIdToDeployIn());
 -        if (dc.getNetworkType() == NetworkType.Basic) {
 -            List<NicVO> nics = _nicDao.listByVmId(vmInstance.getId());
 -            NetworkVO network = _networksDao.findById(nics.get(0).getNetworkId());
 -            Pair<NetworkVO, NicProfile> profile = new Pair<NetworkVO, NicProfile>(network, null);
 -            List<Pair<NetworkVO, NicProfile>> profiles = new ArrayList<Pair<NetworkVO, NicProfile>>();
 -            profiles.add(profile);
 -
 -            Transaction txn = Transaction.currentTxn();
 -            txn.start();
 -
 -            try {
 -                this.cleanupNics(vm);
 -                this.allocate(vm, profiles);
 -            } finally {
 -                txn.commit();
 -            }
 -        }
 -        return true;
 -    }
 -
 -    @Override
 -    public Map<Service, Set<Provider>> getNetworkOfferingServiceProvidersMap(long networkOfferingId) {
 -        Map<Service, Set<Provider>> serviceProviderMap = new HashMap<Service, Set<Provider>>();
 -        List<NetworkOfferingServiceMapVO> map = _ntwkOfferingSrvcDao.listByNetworkOfferingId(networkOfferingId);
 -
 -        for (NetworkOfferingServiceMapVO instance : map) {
 -            String service = instance.getService();
 -            Set<Provider> providers;
 -            providers = serviceProviderMap.get(service);
 -            if (providers == null) {
 -                providers = new HashSet<Provider>();
 -            }
 -            providers.add(Provider.getProvider(instance.getProvider()));
 -            serviceProviderMap.put(Service.getService(service), providers);
 -        }
 -
 -        return serviceProviderMap;
 -    }
 -
 -    @Override
 -    public boolean isProviderSupportServiceInNetwork(long networkId, Service service, Provider provider) {
 -        return _ntwkSrvcDao.canProviderSupportServiceInNetwork(networkId, service, provider);
 -    }
 -
 -    protected boolean canUpgrade(Network network, long oldNetworkOfferingId, long newNetworkOfferingId) {
 -        NetworkOffering oldNetworkOffering = _networkOfferingDao.findByIdIncludingRemoved(oldNetworkOfferingId);
 -        NetworkOffering newNetworkOffering = _networkOfferingDao.findById(newNetworkOfferingId);
 -
 -        // can upgrade only Isolated networks
 -        if (oldNetworkOffering.getGuestType() != GuestType.Isolated) {
 -            throw new InvalidParameterValueException("NetworkOfferingId can be upgraded only for the network of type " + GuestType.Isolated);
 -        }
 -
 -        // security group service should be the same
 -        if (areServicesSupportedByNetworkOffering(oldNetworkOfferingId, Service.SecurityGroup) != areServicesSupportedByNetworkOffering(newNetworkOfferingId, Service.SecurityGroup)) {
 -            s_logger.debug("Offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different securityGroupProperty, can't upgrade");
 -            return false;
 -        }
 -
 -        // Type of the network should be the same
 -        if (oldNetworkOffering.getGuestType() != newNetworkOffering.getGuestType()) {
 -            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " are of different types, can't upgrade");
 -            return false;
 -        }
 -
 -        // tags should be the same
 -        if (newNetworkOffering.getTags() != null) {
 -            if (oldNetworkOffering.getTags() == null) {
 -                s_logger.debug("New network offering id=" + newNetworkOfferingId + " has tags and old network offering id=" + oldNetworkOfferingId + " doesn't, can't upgrade");
 -                return false;
 -            }
 -            if (!oldNetworkOffering.getTags().equalsIgnoreCase(newNetworkOffering.getTags())) {
 -                s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different tags, can't upgrade");
 -                return false;
 -            }
 -        }
 -
 -        // Traffic types should be the same
 -        if (oldNetworkOffering.getTrafficType() != newNetworkOffering.getTrafficType()) {
 -            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different traffic types, can't upgrade");
 -            return false;
 -        }
 -
 -        // specify vlan should be the same
 -        if (oldNetworkOffering.getSpecifyVlan() != newNetworkOffering.getSpecifyVlan()) {
 -            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyVlan, can't upgrade");
 -            return false;
 -        }
 -
 -        // specify ipRanges should be the same
 -        if (oldNetworkOffering.getSpecifyIpRanges() != newNetworkOffering.getSpecifyIpRanges()) {
 -            s_logger.debug("Network offerings " + newNetworkOfferingId + " and " + oldNetworkOfferingId + " have different values for specifyIpRangess, can't upgrade");
 -            return false;
 -        }
 -
 -        // Check all ips
 -        List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
 -        List<PublicIp> publicIps = new ArrayList<PublicIp>();
 -        if (userIps != null && !userIps.isEmpty()) {
 -            for (IPAddressVO userIp : userIps) {
 -                PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress()));
 -                publicIps.add(publicIp);
 -            }
 -        }
 -        if (oldNetworkOffering.isConserveMode() && !newNetworkOffering.isConserveMode()) {
 -            if (!canIpsUsedForNonConserve(publicIps)) {
 -                return false;
 -            }
 -        }
 -
 -        return canIpsUseOffering(publicIps, newNetworkOfferingId);
 -    }
 -
 -    protected boolean canUpgradeProviders(long oldNetworkOfferingId, long newNetworkOfferingId) {
 -        // list of services and providers should be the same
 -        Map<Service, Set<Provider>> newServices = getNetworkOfferingServiceProvidersMap(newNetworkOfferingId);
 -        Map<Service, Set<Provider>> oldServices = getNetworkOfferingServiceProvidersMap(oldNetworkOfferingId);
 -
 -        if (newServices.size() < oldServices.size()) {
 -            s_logger.debug("Network offering downgrade is not allowed: number of supported services for the new offering " + newNetworkOfferingId + " is less than the old offering " + oldNetworkOfferingId);
 -            return false;
 -        }
 -
 -        for (Service service : oldServices.keySet()) {
 -
 -            // 1)check that all old services are present in the new network offering
 -            if (!newServices.containsKey(service)) {
 -                s_logger.debug("New service offering doesn't have " + service + " service present in the old service offering, downgrade is not allowed");
 -                return false;
 -            }
 -
 -            Set<Provider> newProviders = newServices.get(service);
 -            Set<Provider> oldProviders = oldServices.get(service);
 -
 -            // 2) Can upgrade only from internal provider to external provider. Any other combinations are not allowed
 -            for (Provider oldProvider : oldProviders) {
 -                if (newProviders.contains(oldProvider)) {
 -                    s_logger.trace("New list of providers contains provider " + oldProvider);
 -                    continue;
 -                }
 -                // iterate through new providers and check that the old provider can upgrade
 -                for (Provider newProvider : newProviders) {
 -                    if (!(!oldProvider.isExternal() && newProvider.isExternal())) {
 -                        s_logger.debug("Can't downgrade from network offering " + oldNetworkOfferingId + " to the new networkOffering " + newNetworkOfferingId);
 -                        return false;
 -                    }
 -                }
 -            }
 -        }
 -        return true;
 -    }
 -
 -    @Override
 -    @DB
 -    @ActionEvent(eventType = EventTypes.EVENT_PHYSICAL_NETWORK_CREATE, eventDescription = "Creating Physical Network", create = true)
 -    public PhysicalNetwork createPhysicalNetwork(Long zoneId, String vnetRange, String networkSpeed, List<String>
 -    isolationMethods, String broadcastDomainRangeStr, Long domainId, List<String> tags, String name) {
 -
 -        // Check if zone exists
 -        if (zoneId == null) {
 -            throw new InvalidParameterValueException("Please specify a valid zone.");
 -        }
 -
 -        DataCenterVO zone = _dcDao.findById(zoneId);
 -       

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/cadca5fc/server/src/com/cloud/network/element/VirtualRouterElement.java
----------------------------------------------------------------------