diff --git a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java index c58463ac708..0fa5a0d6db3 100644 --- a/server/src/main/java/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/main/java/com/cloud/network/NetworkServiceImpl.java @@ -36,7 +36,6 @@ 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; @@ -76,6 +75,7 @@ import org.apache.cloudstack.network.NetworkPermissionVO; import org.apache.cloudstack.network.dao.NetworkPermissionDao; import org.apache.cloudstack.network.element.InternalLoadBalancerElementService; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.EnumUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -2197,6 +2197,9 @@ 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(); @@ -2282,7 +2285,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C isRecursive = true; } - Filter searchFilter = new Filter(NetworkVO.class, "id", false, null, null); + Long offset = cmd.getStartIndex(); + Long limit = cmd.getPageSizeVal(); + if (applyManualPagination) { + offset = null; + limit = null; + } + Filter searchFilter = new Filter(NetworkVO.class, "id", false, offset, limit); SearchBuilder sb = _networksDao.createSearchBuilder(); if (forVpc != null) { @@ -2321,14 +2330,14 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C if (permittedAccounts.isEmpty()) { SearchBuilder 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); + sb.join("domain", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER); } SearchBuilder 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); + sb.join("account", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinBuilder.JoinType.INNER); if (associatedNetworkId != null) { SearchBuilder associatedNetworkSearch = _networkDetailsDao.createSearchBuilder(); @@ -2337,113 +2346,138 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C sb.join("associatedNetworkSearch", associatedNetworkSearch, sb.entity().getId(), associatedNetworkSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - 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 - 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 - 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 - 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 - 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 - 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) { - 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 - 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); - } - } + Pair, Integer> result = new Pair<>(new ArrayList<>(), 0); + if (BooleanUtils.isTrue(isSystem)) { + SearchCriteria sc = createNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, + physicalNetworkId, networkOfferingId, null, restartRequired, specifyIpRanges, + vpcId, tags, display, vlanId, associatedNetworkId); + addProjectNetworksConditionToSearch(sc, true); + result = _networksDao.searchAndCount(sc, searchFilter); } else { - networksToReturn = _networksDao.search(buildNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, trafficType, physicalNetworkId, networkOfferingId, - null, true, restartRequired, specifyIpRanges, vpcId, tags, display, vlanId, associatedNetworkId), searchFilter); + SearchCriteria additionalSC = _networksDao.createSearchCriteria(); + + addAccountSpecificNetworksToSearch(additionalSC, sb, networkFilter, skipProjectNetworks, permittedAccounts, path, isRecursive); + addDomainSpecificNetworksToSearch(additionalSC, sb, networkFilter, permittedAccounts, domainId, path, isRecursive); + addSharedNetworksToSearch(additionalSC, sb, networkFilter, permittedAccounts, path, isRecursive); + + if (CollectionUtils.isNotEmpty(additionalSC.getValues())) { + SearchCriteria sc = createNetworkSearchCriteria(sb, keyword, id, isSystem, zoneId, guestIpType, + trafficType, physicalNetworkId, networkOfferingId, aclType, restartRequired, specifyIpRanges, vpcId, + tags, display, vlanId, associatedNetworkId); + sc.addAnd("id", SearchCriteria.Op.SC, additionalSC); + result = _networksDao.searchAndCount(sc, searchFilter); + } } + List networksToReturn = result.first(); if (supportedServicesStr != null && !supportedServicesStr.isEmpty() && !networksToReturn.isEmpty()) { - List supportedNetworks = new ArrayList(); - Service[] suppportedServices = new Service[supportedServicesStr.size()]; + List supportedNetworks = new ArrayList<>(); + Service[] supportedServices = 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; + supportedServices[i] = service; } i++; } - for (NetworkVO network : networksToReturn) { - if (areServicesSupportedInNetwork(network.getId(), suppportedServices)) { + if (areServicesSupportedInNetwork(network.getId(), supportedServices)) { 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; } - //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; + 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()); } - return new Pair, Integer>(networksToReturn, networksToReturn.size()); + return new Pair<>(result.first(), result.second()); } - 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 void addAccountSpecificNetworksToSearch(SearchCriteria additionalSC, SearchBuilder sb, + Network.NetworkFilter networkFilter, boolean skipProjectNetworks, + List permittedAccounts, String path, boolean isRecursive) { + if (!Arrays.asList(Network.NetworkFilter.Account, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { + return; + } + + SearchCriteria accountSC = sb.create(); + accountSC.addAnd("aclType", SearchCriteria.Op.EQ, ACLType.Account.toString()); + if (permittedAccounts.isEmpty()) { + if (path != null) { + // accountSC's WHERE clause gets OR-included in additionalSC's WHERE clause, which then gets AND-included + // in the main search criteria's WHERE clause. If we added the path filter as join parameters, it would not + // be present in the main search criteria. This is a way to add a condition that would normally go to accountSC's + // join parameters to its WHERE clause. + accountSC.getJoin("domain").addAnd("path", SearchCriteria.Op.LIKE, isRecursive ? path + "%" : path); + accountSC.addAnd("id", SearchCriteria.Op.SC, accountSC.getJoin("domain")); + } + } else { + accountSC.addAnd("accountId", SearchCriteria.Op.IN, permittedAccounts.toArray()); + } + addProjectNetworksConditionToSearch(accountSC, skipProjectNetworks); + additionalSC.addOr("id", SearchCriteria.Op.SC, accountSC); } - 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) { + private void addDomainSpecificNetworksToSearch(SearchCriteria additionalSC, SearchBuilder sb, Network.NetworkFilter networkFilter, + List permittedAccounts, Long domainId, String path, boolean isRecursive) { + if (!Arrays.asList(Network.NetworkFilter.Domain, Network.NetworkFilter.AccountDomain, Network.NetworkFilter.All).contains(networkFilter)) { + return; + } + + if (permittedAccounts.isEmpty()) { + // Add domain specific networks of domain + parent domains + addDomainNetworksByDomainPathToSearch(additionalSC, sb, path, isRecursive); + if (domainId == null) { + // Add networks of subdomains + Account caller = CallContext.current().getCallingAccount(); + addDomainLevelNetworksToSearch(additionalSC, sb, caller.getDomainId(), true); + } + } else { + if (domainId != null) { + // Add domain level networks + addDomainLevelNetworksToSearch(additionalSC, sb, domainId, false); + } + } + } + + private void addSharedNetworksToSearch(SearchCriteria additionalSC, SearchBuilder sb, Network.NetworkFilter networkFilter, + List permittedAccounts, String path, boolean isRecursive) { + if (!Arrays.asList(Network.NetworkFilter.Shared, Network.NetworkFilter.All).contains(networkFilter)) { + return; + } + + if (permittedAccounts.isEmpty()) { + addSharedNetworksByDomainPathToSearch(additionalSC, sb, path, isRecursive); + } else { + addSharedNetworksByAccountsToSearch(additionalSC, sb, permittedAccounts); + } + } + + 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) { SearchCriteria sc = sb.create(); @@ -2485,12 +2519,6 @@ 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); } @@ -2531,8 +2559,9 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C return sc; } - private List listDomainLevelNetworks(SearchCriteria sc, Filter searchFilter, long domainId, boolean parentDomainsOnly) { - List networkIds = new ArrayList(); + private void addDomainLevelNetworksToSearch(SearchCriteria additionalSC, SearchBuilder sb, + long domainId, boolean parentDomainsOnly) { + List networkIds = new ArrayList<>(); Set allowedDomains = _domainMgr.getDomainParentIds(domainId); List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); @@ -2547,48 +2576,17 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } if (!networkIds.isEmpty()) { - SearchCriteria domainSC = _networksDao.createSearchCriteria(); + SearchCriteria domainSC = sb.create(); 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(); + addProjectNetworksConditionToSearch(domainSC, true); + additionalSC.addOr("id", SearchCriteria.Op.SC, domainSC); } } - 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()); - - sc.addAnd("id", SearchCriteria.Op.SC, accountSC); - return _networksDao.search(sc, searchFilter); - } - - 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) { - 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 listDomainSpecificNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { - - Set allowedDomains = new HashSet(); + private void addDomainNetworksByDomainPathToSearch(SearchCriteria additionalSC, SearchBuilder sb, + String path, boolean isRecursive) { + Set allowedDomains = new HashSet<>(); if (path != null) { if (isRecursive) { allowedDomains = _domainMgr.getDomainChildrenIds(path); @@ -2598,39 +2596,40 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C } } - List networkIds = new ArrayList(); + List networkIds = new ArrayList<>(); List maps = _networkDomainDao.listDomainNetworkMapByDomain(allowedDomains.toArray()); - for (NetworkDomainVO map : maps) { networkIds.add(map.getNetworkId()); } if (!networkIds.isEmpty()) { - SearchCriteria domainSC = _networksDao.createSearchCriteria(); + SearchCriteria domainSC = sb.create(); 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(); + addProjectNetworksConditionToSearch(domainSC, true); + additionalSC.addOr("id", SearchCriteria.Op.SC, domainSC); } } - private List listSharedNetworks(SearchCriteria sc, Filter searchFilter, List permittedAccounts) { + private void addProjectNetworksConditionToSearch(SearchCriteria sc, boolean skipProjectNetworks) { + sc.getJoin("account").addAnd("type", skipProjectNetworks ? Op.NEQ : Op.EQ, Account.Type.PROJECT); + sc.addAnd("id", Op.SC, sc.getJoin("account")); + } + + private void addSharedNetworksByAccountsToSearch(SearchCriteria additionalSC, SearchBuilder sb, + List permittedAccounts) { List sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(permittedAccounts); if (!sharedNetworkIds.isEmpty()) { - SearchCriteria ssc = _networksDao.createSearchCriteria(); + SearchCriteria ssc = sb.create(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - sc.addAnd("id", SearchCriteria.Op.SC, ssc); - return _networksDao.search(sc, searchFilter); + addProjectNetworksConditionToSearch(ssc, true); + additionalSC.addOr("id", SearchCriteria.Op.SC, ssc); } - return new ArrayList(); } - private List listSharedNetworksByDomainPath(SearchCriteria sc, Filter searchFilter, String path, boolean isRecursive) { - Set allowedDomains = new HashSet(); + private void addSharedNetworksByDomainPathToSearch(SearchCriteria additionalSC, SearchBuilder sb, String path, boolean isRecursive) { + Set allowedDomains = new HashSet<>(); if (path != null) { if (isRecursive) { allowedDomains = _domainMgr.getDomainChildrenIds(path); @@ -2639,7 +2638,7 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C allowedDomains.add(domain.getId()); } } - List allowedDomainsList = new ArrayList(allowedDomains); + List allowedDomainsList = new ArrayList<>(allowedDomains); if (!allowedDomainsList.isEmpty()) { GenericSearchBuilder accountIdSearch = _accountDao.createSearchBuilder(Long.class); @@ -2652,13 +2651,12 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService, C List sharedNetworkIds = _networkPermissionDao.listPermittedNetworkIdsByAccounts(allowedAccountsList); if (!sharedNetworkIds.isEmpty()) { - SearchCriteria ssc = _networksDao.createSearchCriteria(); + SearchCriteria ssc = sb.create(); ssc.addAnd("id", SearchCriteria.Op.IN, sharedNetworkIds.toArray()); - sc.addAnd("id", SearchCriteria.Op.SC, ssc); - return _networksDao.search(sc, searchFilter); + addProjectNetworksConditionToSearch(ssc, true); + additionalSC.addOr("id", SearchCriteria.Op.SC, ssc); } } - return new ArrayList(); } @Override