Updated Branches: refs/heads/master-6-17-stable 8ff565860 -> 4d02dbe6d
CLOUDSTACK-3062. Dedication of a guest vlan range that extends 2 ranges dedicated to different accounts removes an old dedication Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/4d02dbe6 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/4d02dbe6 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/4d02dbe6 Branch: refs/heads/master-6-17-stable Commit: 4d02dbe6dfbd352bd35d2d981cfa7c7baff0fc8f Parents: 8ff5658 Author: Likitha Shetty <likitha.she...@citrix.com> Authored: Mon Jun 17 18:50:56 2013 +0530 Committer: Likitha Shetty <likitha.she...@citrix.com> Committed: Wed Jun 19 17:02:10 2013 +0530 ---------------------------------------------------------------------- .../com/cloud/network/NetworkServiceImpl.java | 70 +++++++++++++------- .../network/DedicateGuestVlanRangesTest.java | 4 +- 2 files changed, 49 insertions(+), 25 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4d02dbe6/server/src/com/cloud/network/NetworkServiceImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index aace68d..6796adc 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -27,6 +27,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -2949,6 +2951,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { String updatedVlanRange = null; long guestVlanMapId = 0; long guestVlanMapAccountId = 0; + long vlanOwnerId = 0; // Verify account is valid Account vlanOwner = null; @@ -2969,6 +2972,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { throw new InvalidParameterValueException("Unable to find account by name " + accountName); } } + vlanOwnerId = vlanOwner.getAccountId(); // Verify physical network isolation type is VLAN PhysicalNetworkVO physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); @@ -3024,40 +3028,59 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } List<AccountGuestVlanMapVO> guestVlanMaps = _accountGuestVlanMapDao.listAccountGuestVlanMapsByPhysicalNetwork(physicalNetworkId); + // Verify if vlan range is already dedicated for (AccountGuestVlanMapVO guestVlanMap : guestVlanMaps) { List<Integer> vlanTokens = getVlanFromRange(guestVlanMap.getGuestVlanRange()); int dedicatedStartVlan = vlanTokens.get(0).intValue(); int dedicatedEndVlan = vlanTokens.get(1).intValue(); - guestVlanMapId = guestVlanMap.getId(); - guestVlanMapAccountId = guestVlanMap.getAccountId(); + if ((startVlan < dedicatedStartVlan & endVlan >= dedicatedStartVlan) || + (startVlan >= dedicatedStartVlan & startVlan <= dedicatedEndVlan)) { + throw new InvalidParameterValueException("Vlan range is already dedicated. Cannot" + + " dedicate guest vlan range " + vlan); + } + } - // Verify if range is already dedicated - if (startVlan >= dedicatedStartVlan && endVlan <= dedicatedEndVlan) { - if (guestVlanMap.getAccountId() != vlanOwner.getAccountId()) { - throw new InvalidParameterValueException("Vlan range is already dedicated to another account. Cannot dedicate guest vlan range " + vlan); - } else { - s_logger.debug("Vlan range " + vlan +" is already dedicated to the specified account" + accountName); - return guestVlanMap; - } + // Sort the existing dedicated vlan ranges + Collections.sort(guestVlanMaps, new Comparator<AccountGuestVlanMapVO>() { + @Override + public int compare( AccountGuestVlanMapVO obj1 , AccountGuestVlanMapVO obj2) { + List<Integer> vlanTokens1 = getVlanFromRange(obj1.getGuestVlanRange()); + List<Integer> vlanTokens2 = getVlanFromRange(obj2.getGuestVlanRange()); + return vlanTokens1.get(0).compareTo(vlanTokens2.get(0)); } - // Verify if range overlaps with an existing range - if (startVlan < dedicatedStartVlan & endVlan+1 >= dedicatedStartVlan & endVlan <= dedicatedEndVlan) { // extend to the left - updatedVlanRange = startVlan + "-" + dedicatedEndVlan; - break; - } else if (startVlan >= dedicatedStartVlan & startVlan-1 <= dedicatedEndVlan & endVlan > dedicatedEndVlan) { // extend to right - updatedVlanRange = dedicatedStartVlan + "-" + endVlan; + }); + + // Verify if vlan range extends an already dedicated range + for (int i=0; i < guestVlanMaps.size(); i++) { + guestVlanMapId = guestVlanMaps.get(i).getId(); + guestVlanMapAccountId = guestVlanMaps.get(i).getAccountId(); + List<Integer> vlanTokens1 = getVlanFromRange(guestVlanMaps.get(i).getGuestVlanRange()); + // Range extends a dedicated vlan range to the left + if (endVlan == (vlanTokens1.get(0).intValue()-1)) { + if(guestVlanMapAccountId == vlanOwnerId) { + updatedVlanRange = startVlan + "-" + vlanTokens1.get(1).intValue(); + } break; - } else if (startVlan < dedicatedStartVlan & endVlan > dedicatedEndVlan){ // extend to the left and right - updatedVlanRange = startVlan + "-" + endVlan; + } + // Range extends a dedicated vlan range to the right + if (startVlan == (vlanTokens1.get(1).intValue()+1) & guestVlanMapAccountId == vlanOwnerId) { + if (i != (guestVlanMaps.size()-1)) { + List<Integer> vlanTokens2 = getVlanFromRange(guestVlanMaps.get(i+1).getGuestVlanRange()); + // Range extends 2 vlan ranges, both to the right and left + if (endVlan == (vlanTokens2.get(0).intValue()-1) & guestVlanMaps.get(i+1).getAccountId() == vlanOwnerId) { + _datacneter_vnet.releaseDedicatedGuestVlans(guestVlanMaps.get(i+1).getId()); + _accountGuestVlanMapDao.remove(guestVlanMaps.get(i+1).getId()); + updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + vlanTokens2.get(1).intValue(); + break; + } + } + updatedVlanRange = vlanTokens1.get(0).intValue() + "-" + endVlan; break; } } - + // Dedicate vlan range AccountGuestVlanMapVO accountGuestVlanMapVO; if (updatedVlanRange != null) { - if (guestVlanMapAccountId != vlanOwner.getAccountId()) { - throw new InvalidParameterValueException("Vlan range is partially dedicated to another account. Cannot dedicate guest vlan range " + vlan); - } accountGuestVlanMapVO = _accountGuestVlanMapDao.findById(guestVlanMapId); accountGuestVlanMapVO.setGuestVlanRange(updatedVlanRange); _accountGuestVlanMapDao.update(guestVlanMapId, accountGuestVlanMapVO); @@ -3070,7 +3093,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { txn.commit(); } // For every guest vlan set the corresponding account guest vlan map id - for (int i = startVlan; i <= endVlan; i++) { + List<Integer> finaVlanTokens = getVlanFromRange(accountGuestVlanMapVO.getGuestVlanRange()); + for (int i = finaVlanTokens.get(0).intValue(); i <= finaVlanTokens.get(1).intValue(); i++) { List<DataCenterVnetVO> dataCenterVnet = _datacneter_vnet.findVnet(physicalNetwork.getDataCenterId(),((Integer)i).toString()); dataCenterVnet.get(0).setAccountGuestVlanMapId(accountGuestVlanMapVO.getId()); _datacneter_vnet.update(dataCenterVnet.get(0).getId(), dataCenterVnet.get(0)); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/4d02dbe6/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java ---------------------------------------------------------------------- diff --git a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java index e81d722..e5d3329 100644 --- a/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java +++ b/server/test/com/cloud/network/DedicateGuestVlanRangesTest.java @@ -291,7 +291,7 @@ public class DedicateGuestVlanRangesTest { try { networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd); } catch (Exception e) { - Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated to another account")); + Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated")); } finally { txn.close("runDedicateGuestVlanRangeDedicatedRange"); } @@ -320,7 +320,7 @@ public class DedicateGuestVlanRangesTest { try { networkService.dedicateGuestVlanRange(dedicateGuestVlanRangesCmd); } catch (Exception e) { - Assert.assertTrue(e.getMessage().contains("Vlan range is partially dedicated to another account")); + Assert.assertTrue(e.getMessage().contains("Vlan range is already dedicated")); } finally { txn.close("runDedicateGuestVlanRangePartiallyDedicated"); }