diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index 83ef8b1b213..c58463ac708 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -36,6 +36,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; +import java.util.stream.Collectors; import javax.inject.Inject; import javax.naming.ConfigurationException; @@ -2196,9 +2197,6 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C Long associatedNetworkId = cmd.getAssociatedNetworkId(); String networkFilterStr = cmd.getNetworkFilter(); - boolean applyManualPagination = CollectionUtils.isNotEmpty(supportedServicesStr) || - Boolean.TRUE.equals(canUseForDeploy); - String vlanId = null; if (cmd instanceof ListNetworksCmdByAdmin) { vlanId = ((ListNetworksCmdByAdmin)cmd).getVlan(); @@ -2284,13 +2282,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C isRecursive = true; } - Long offset = cmd.getStartIndex(); - Long limit = cmd.getPageSizeVal(); - if (applyManualPagination) { - offset = null; - limit = null; - } - Filter searchFilter = new Filter(NetworkVO.class, "id", false, offset, limit); + Filter searchFilter = new Filter(NetworkVO.class, "id", false, null, null); SearchBuilder sb = _networksDao.createSearchBuilder(); if (forVpc != null) { @@ -2345,123 +2337,113 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C sb.join("associatedNetworkSearch", associatedNetworkSearch, sb.entity().getId(), associatedNetworkSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - SearchCriteria mainSearchCriteria = createNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, - guestIpType, trafficType, physicalNetworkId, networkOfferingId, aclType, restartRequired, - specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId); - SearchCriteria additionalSearchCriteria = _networksDao.createSearchCriteria(); + List networksToReturn = new ArrayList(); if (isSystem == null || !isSystem) { if (!permittedAccounts.isEmpty()) { if (Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //get account level networks - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, - getAccountSpecificNetworksSearchCriteria(sb, permittedAccounts, skipProjectNetworks)); + networksToReturn.addAll(listAccountSpecificNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, permittedAccounts)); } if (domainId != null && Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //get domain level networks - SearchCriteria domainLevelSC = getDomainLevelNetworksSearchCriteria(sb, domainId, false); - if (domainLevelSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, domainLevelSC); - } + networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, domainId, false)); } if (Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) { // get shared networks - SearchCriteria sharedNetworksSC = getSharedNetworksSearchCriteria(sb, permittedAccounts); - if (sharedNetworksSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, sharedNetworksSC); - } + List sharedNetworks = listSharedNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, permittedAccounts); + addNetworksToReturnIfNotExist(networksToReturn, sharedNetworks); + } } else { if (Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //add account specific networks - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, - getAccountSpecificNetworksByDomainPathSearchCriteria(sb, path, isRecursive, - skipProjectNetworks)); + networksToReturn.addAll(listAccountSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, skipProjectNetworks, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive)); } if (Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { //add domain specific networks of domain + parent domains - SearchCriteria domainSpecificNetworksByDomainPathSC = - getDomainSpecificNetworksByDomainPathSearchCriteria(sb, path, isRecursive); - if (domainSpecificNetworksByDomainPathSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, domainSpecificNetworksByDomainPathSC); - } + networksToReturn.addAll(listDomainSpecificNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive)); //add networks of subdomains if (domainId == null) { - SearchCriteria domainLevelSC = getDomainLevelNetworksSearchCriteria(sb, caller.getDomainId(), true); - if (domainLevelSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, domainLevelSC); - } + networksToReturn.addAll(listDomainLevelNetworks(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, caller.getDomainId(), true)); } } if (Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) { // get shared networks - SearchCriteria sharedNetworksSC = getSharedNetworksByDomainPathSearchCriteria(sb, path, isRecursive); - if (sharedNetworksSC != null) { - additionalSearchCriteria.addOr("id", SearchCriteria.Op.SC, sharedNetworksSC); - } + List sharedNetworks = listSharedNetworksByDomainPath(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + aclType, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter, path, isRecursive); + addNetworksToReturnIfNotExist(networksToReturn, sharedNetworks); } } - if (CollectionUtils.isNotEmpty(additionalSearchCriteria.getValues())) { - mainSearchCriteria.addAnd("id", SearchCriteria.Op.SC, additionalSearchCriteria); - } } else { - if (skipProjectNetworks) { - mainSearchCriteria.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); - } else { - mainSearchCriteria.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); - } + networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, + null, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter); } - Pair, Integer> result = _networksDao.searchAndCount(mainSearchCriteria, searchFilter); - List networksToReturn = result.first(); if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) { - List supportedNetworks = new ArrayList<>(); - Service[] supportedServices = new Service[supportedServicesStr.size()]; + List supportedNetworks = new ArrayList(); + 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 { - supportedServices[i] = service; + suppportedServices[i] = service; } i++; } + for (NetworkVO network : networksToReturn) { - if (areServicesSupportedInNetwork(network.getId(), supportedServices)) { + if (areServicesSupportedInNetwork(network.getId(), suppportedServices)) { supportedNetworks.add(network); } } + networksToReturn = supportedNetworks; } if (canUseForDeploy != null) { - List networksForDeploy = new ArrayList<>(); + List networksForDeploy = new ArrayList(); for (NetworkVO network : networksToReturn) { if (_networkModel.canUseForDeploy(network) == canUseForDeploy) { networksForDeploy.add(network); } } + networksToReturn = networksForDeploy; } - if (applyManualPagination) { - //Now apply pagination - List wPagination = com.cloud.utils.StringUtils.applyPagination(networksToReturn, cmd.getStartIndex(), cmd.getPageSizeVal()); - if (wPagination != null) { - Pair, Integer> listWPagination = new Pair<>(wPagination, networksToReturn.size()); - return listWPagination; - } - return new Pair<>(networksToReturn, networksToReturn.size()); + //Now apply pagination + List wPagination = com.cloud.utils.StringUtils.applyPagination(networksToReturn, cmd.getStartIndex(), cmd.getPageSizeVal()); + if (wPagination != null) { + Pair, Integer> listWPagination = new Pair, Integer>(wPagination, networksToReturn.size()); + return listWPagination; } - return new Pair<>(result.first(), result.second()); + return new Pair, Integer>(networksToReturn, networksToReturn.size()); } - private SearchCriteria createNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, - Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, - Long networkOfferingId, String aclType, Boolean restartRequired, - Boolean specifyIpRanges, Long vpcId, Map tags, Boolean display, String vlanId, Long associatedNetworkId) { + private void addNetworksToReturnIfNotExist(final List networksToReturn, final List sharedNetworks) { + Set networkIds = networksToReturn.stream() + .map(NetworkVO::getId) + .collect(Collectors.toSet()); + List sharedNetworksToReturn = sharedNetworks.stream() + .filter(network -> ! networkIds.contains(network.getId())) + .collect(Collectors.toList()); + networksToReturn.addAll(sharedNetworksToReturn); + } + + private SearchCriteria buildNetworkSearchCriteria(SearchBuilder sb, String keyword, Long id, + Boolean isSystem, Long zoneId, String guestIpType, String trafficType, Long physicalNetworkId, + Long networkOfferingId, String aclType, boolean skipProjectNetworks, Boolean restartRequired, + Boolean specifyIpRanges, Long vpcId, Map tags, Boolean display, String vlanId, Long associatedNetworkId) { SearchCriteria sc = sb.create(); @@ -2503,6 +2485,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C sc.addAnd("physicalNetworkId", SearchCriteria.Op.EQ, physicalNetworkId); } + if (skipProjectNetworks) { + sc.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + } else { + sc.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); + } + if (restartRequired != null) { sc.addAnd("restartRequired", SearchCriteria.Op.EQ, restartRequired); } @@ -2543,8 +2531,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C return sc; } - private SearchCriteria getDomainLevelNetworksSearchCriteria(SearchBuilder sb, long domainId, boolean parentDomainsOnly) { - List networkIds = new ArrayList<>(); + private List listDomainLevelNetworks(SearchCriteria sc, Filter searchFilter, long domainId, boolean parentDomainsOnly) { + List networkIds = new ArrayList(); Set allowedDomains = _domainMgr.getDomainParentIds(domainId); List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); @@ -2559,55 +2547,48 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } if (!networkIds.isEmpty()) { - SearchCriteria domainSC = sb.create(); - domainSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria domainSC = _networksDao.createSearchCriteria(); domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); - return domainSC; + + sc.addAnd("id", SearchCriteria.Op.SC, domainSC); + return _networksDao.search(sc, searchFilter); + } else { + return new ArrayList(); } - return null; } - private SearchCriteria getAccountSpecificNetworksSearchCriteria(SearchBuilder sb, - List permittedAccounts, boolean skipProjectNetworks) { - SearchCriteria accountSC = sb.create(); - if (skipProjectNetworks) { - accountSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); - } else { - accountSC.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); - } + private List listAccountSpecificNetworks(SearchCriteria sc, Filter searchFilter, List permittedAccounts) { + SearchCriteria accountSC = _networksDao.createSearchCriteria(); if (!permittedAccounts.isEmpty()) { accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); } + accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); - return accountSC; + + sc.addAnd("id", SearchCriteria.Op.SC, accountSC); + return _networksDao.search(sc, searchFilter); } - private SearchCriteria getAccountSpecificNetworksByDomainPathSearchCriteria(SearchBuilder sb, - String path, boolean isRecursive, boolean skipProjectNetworks) { - SearchCriteria accountSC = sb.create(); - if (skipProjectNetworks) { - accountSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); - } else { - accountSC.setJoinParameters("accountSearch", "typeEQ", Account.Type.PROJECT); - } + private List listAccountSpecificNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { + SearchCriteria accountSC = _networksDao.createSearchCriteria(); accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); if (path != null) { if (isRecursive) { - accountSC.setJoinParameters("domainSearch", "path", path + "%"); + sc.setJoinParameters("domainSearch", "path", path + "%"); } else { - accountSC.setJoinParameters("domainSearch", "path", path); + sc.setJoinParameters("domainSearch", "path", path); } } - return accountSC; + sc.addAnd("id", SearchCriteria.Op.SC, accountSC); + return _networksDao.search(sc, searchFilter); } - private SearchCriteria getDomainSpecificNetworksByDomainPathSearchCriteria(SearchBuilder sb, - String path, boolean isRecursive) { + private List listDomainSpecificNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { - Set allowedDomains = new HashSet<>(); + Set allowedDomains = new HashSet(); if (path != null) { if (isRecursive) { allowedDomains = _domainMgr.getDomainChildrenIds(path); @@ -2617,7 +2598,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } } - List networkIds = new ArrayList<>(); + List networkIds = new ArrayList(); List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); @@ -2626,28 +2607,30 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } if (!networkIds.isEmpty()) { - SearchCriteria domainSC = sb.create(); - domainSC.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria domainSC = _networksDao.createSearchCriteria(); domainSC.addAnd("id", SearchCriteria.Op.IN, networkIds.toArray()); domainSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Domain.toString()); - return domainSC; + + sc.addAnd("id", SearchCriteria.Op.SC, domainSC); + return _networksDao.search(sc, searchFilter); + } else { + return new ArrayList(); } - return null; } - private SearchCriteria getSharedNetworksSearchCriteria(SearchBuilder sb, List permittedAccounts) { + private List listSharedNetworks(SearchCriteria sc, Filter searchFilter, List permittedAccounts) { List sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(permittedAccounts); if (!sharedNetworkIds.isEmpty()) { - SearchCriteria ssc = sb.create(); - ssc.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria ssc = _networksDao.createSearchCriteria(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - return ssc; + sc.addAnd("id", SearchCriteria.Op.SC, ssc); + return _networksDao.search(sc, searchFilter); } - return null; + return new ArrayList(); } - private SearchCriteria getSharedNetworksByDomainPathSearchCriteria(SearchBuilder sb, String path, boolean isRecursive) { - Set allowedDomains = new HashSet<>(); + private List listSharedNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { + Set allowedDomains = new HashSet(); if (path != null) { if (isRecursive) { allowedDomains = _domainMgr.getDomainChildrenIds(path); @@ -2669,13 +2652,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C List sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(allowedAccountsList); if (!sharedNetworkIds.isEmpty()) { - SearchCriteria ssc = sb.create(); - ssc.setJoinParameters("accountSearch", "typeNEQ", Account.Type.PROJECT); + SearchCriteria ssc = _networksDao.createSearchCriteria(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - return ssc; + sc.addAnd("id", SearchCriteria.Op.SC, ssc); + return _networksDao.search(sc, searchFilter); } } - return null; + return new ArrayList(); } @Override diff --git a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java index 71693f20403..5ec453af485 100644 --- a/server/src/test/java/com/cloud/user/AccountManagerImplTest.java +++ b/server/src/test/java/com/cloud/user/AccountManagerImplTest.java @@ -61,6 +61,7 @@ import com.cloud.vm.UserVmManagerImpl; import com.cloud.vm.UserVmVO; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.snapshot.VMSnapshotVO; +import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.api.command.admin.user.GetUserKeysCmd; import org.apache.cloudstack.api.command.admin.user.UpdateUserCmd;