bug 7892: introducing recursive listings for various artifacts based on the domain id and the isRecursive flag

This commit is contained in:
abhishek 2011-01-21 15:24:36 -08:00
parent 26b6d17ec6
commit 61ce43bdff
7 changed files with 137 additions and 14 deletions

View File

@ -26,6 +26,7 @@ import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.AccountResponse;
import com.cloud.api.response.ListResponse;
import com.cloud.user.Account;
@ -57,7 +58,9 @@ public class ListAccountsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.STATE, type=CommandType.STRING, description="list accounts by state. Valid states are enabled, disabled, and locked.")
private String state;
@Parameter(name=ApiConstants.IS_RECURSIVE, type=CommandType.BOOLEAN, description="defaults to false, but if true, lists all accounts from the parent specified by the domain id till leaves.")
private Boolean recursive;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -85,6 +88,10 @@ public class ListAccountsCmd extends BaseListCmd {
public String getState() {
return state;
}
public Boolean isRecursive() {
return recursive;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////

View File

@ -26,6 +26,7 @@ import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.SnapshotResponse;
import com.cloud.async.AsyncJob;
@ -62,6 +63,8 @@ public class ListSnapshotsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.VOLUME_ID, type=CommandType.LONG, description="the ID of the disk volume")
private Long volumeId;
@Parameter(name=ApiConstants.IS_RECURSIVE, type=CommandType.BOOLEAN, description="defaults to false, but if true, lists all snapshots from the parent specified by the domain id till leaves.")
private Boolean recursive;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -94,6 +97,10 @@ public class ListSnapshotsCmd extends BaseListCmd {
return volumeId;
}
public Boolean isRecursive() {
return recursive;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -47,6 +47,9 @@ public class ListVMsCmd extends BaseListCmd {
@Parameter(name=ApiConstants.DOMAIN_ID, type=CommandType.LONG, description="the domain ID. If used with the account parameter, lists virtual machines for the specified account in this domain.")
private Long domainId;
@Parameter(name=ApiConstants.IS_RECURSIVE, type=CommandType.BOOLEAN, description="defaults to false, but if true, lists all vms from the parent specified by the domain id till leaves.")
private Boolean recursive;
@Parameter(name=ApiConstants.GROUP_ID, type=CommandType.LONG, description="the group ID")
private Long groupId;
@ -126,6 +129,9 @@ public class ListVMsCmd extends BaseListCmd {
return networkId;
}
public Boolean isRecursive() {
return recursive;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -26,6 +26,7 @@ import com.cloud.api.ApiConstants;
import com.cloud.api.BaseListCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.BaseCmd.CommandType;
import com.cloud.api.response.ListResponse;
import com.cloud.api.response.VolumeResponse;
import com.cloud.async.AsyncJob;
@ -68,6 +69,9 @@ public class ListVolumesCmd extends BaseListCmd {
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="the ID of the availability zone")
private Long zoneId;
@Parameter(name=ApiConstants.IS_RECURSIVE, type=CommandType.BOOLEAN, description="defaults to false, but if true, lists all volumes from the parent specified by the domain id till leaves.")
private Boolean recursive;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
@ -108,6 +112,10 @@ public class ListVolumesCmd extends BaseListCmd {
return zoneId;
}
public Boolean isRecursive() {
return recursive;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////

View File

@ -1738,7 +1738,11 @@ public class ManagementServerImpl implements ManagementServer {
Long domainId = cmd.getDomainId();
Long accountId = cmd.getId();
String accountName = null;
Boolean isRecursive = cmd.isRecursive();
if(isRecursive == null)
isRecursive = false;
if(accountId != null && accountId == 1){
//system account should NOT be searchable
List<AccountVO> emptyList = new ArrayList<AccountVO>();
@ -1750,6 +1754,7 @@ public class ManagementServerImpl implements ManagementServer {
if (domainId == null) {
// default domainId to the admin's domain
domainId = ((account == null) ? DomainVO.ROOT_DOMAIN : account.getDomainId());
isRecursive = true;
} else if (account != null) {
if (!_domainDao.isChildDomain(account.getDomainId(), domainId)) {
throw new ServerApiException(BaseCmd.PARAM_ERROR, "Invalid domain id (" + domainId + ") given, unable to list accounts");
@ -1775,13 +1780,21 @@ public class ManagementServerImpl implements ManagementServer {
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
sb.and("needsCleanup", sb.entity().getNeedsCleanup(), SearchCriteria.Op.EQ);
if ((accountId == null) && (domainId != null)) {
// if accountId isn't specified, we can do a domain match for the admin case
if ((accountId == null) && (domainId != null) && isRecursive) {
// if accountId isn't specified, we can do a domain LIKE match for the admin case if isRecursive is true
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);
}
} else if ((accountId == null) && (domainId != null) && !isRecursive) {
// if accountId isn't specified, we can do a domain EXACT match for the admin case if isRecursive is true
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.EQ);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
SearchCriteria<AccountVO> sc = sb.create();
if (keyword != null) {
SearchCriteria<AccountVO> ssc = _accountDao.createSearchCriteria();
@ -1801,7 +1814,11 @@ public class ManagementServerImpl implements ManagementServer {
DomainVO domain = _domainDao.findById(domainId);
// I want to join on user_vm.domain_id = domain.id where domain.path like 'foo%'
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
if(isRecursive)
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
else
sc.setJoinParameters("domainSearch", "path", domain.getPath());
sc.setParameters("nid", 1L);
} else {
sc.setParameters("nid", 1L);
@ -2276,6 +2293,11 @@ public class ManagementServerImpl implements ManagementServer {
String accountName = cmd.getAccountName();
Long accountId = null;
boolean isAdmin = false;
Boolean isRecursive = cmd.isRecursive();
if(isRecursive == null)
isRecursive = false;
if ((account == null) || isAdmin(account.getType())) {
isAdmin = true;
if (domainId != null) {
@ -2292,6 +2314,7 @@ public class ManagementServerImpl implements ManagementServer {
}
} else {
domainId = ((account == null) ? DomainVO.ROOT_DOMAIN : account.getDomainId());
isRecursive = true;
}
} else {
accountId = account.getId();
@ -2339,12 +2362,16 @@ public class ManagementServerImpl implements ManagementServer {
// Only return volumes that are not destroyed
sb.and("destroyed", sb.entity().getDestroyed(), SearchCriteria.Op.EQ);
if ((accountId == null) && (domainId != null)) {
// if accountId isn't specified, we can do a domain match for the admin case
if (((accountId == null) && (domainId != null) && isRecursive)) {
// if accountId isn't specified, we can do a domain match for the admin case if isRecursive is true
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);
}
} else if((accountId == null) && (domainId != null) && !isRecursive) {
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.EQ);
sb.join("domainSearch", domainSearch, sb.entity().getDomainId(), domainSearch.entity().getId(), JoinBuilder.JoinType.INNER);
}
// now set the SC criteria...
SearchCriteria<VolumeVO> sc = sb.create();
@ -2368,7 +2395,10 @@ public class ManagementServerImpl implements ManagementServer {
sc.setParameters("accountIdEQ", accountId);
} else if (domainId != null) {
DomainVO domain = _domainDao.findById(domainId);
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
if(isRecursive)
sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
else
sc.setJoinParameters("domainSearch", "path", domain.getPath());
}
if (type != null) {
sc.setParameters("volumeType", "%" + type + "%");

View File

@ -777,7 +777,8 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
@Override
public List<SnapshotVO> listSnapshots(ListSnapshotsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException {
Long volumeId = cmd.getVolumeId();
Boolean isRecursive = cmd.isRecursive();
// Verify parameters
if(volumeId != null){
VolumeVO volume = _volsDao.findById(volumeId);
@ -798,7 +799,7 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
}
} else if ((account != null) && (account.getType() == Account.ACCOUNT_TYPE_DOMAIN_ADMIN)) {
domainId = account.getDomainId();
}
}
if (domainId != null && accountName != null) {
Account userAccount = _accountDao.findActiveAccount(accountName, domainId);
@ -810,6 +811,9 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
accountId = account.getId();
}
if(isRecursive == null)
isRecursive = false;
Object name = cmd.getSnapshotName();
Object id = cmd.getId();
Object keyword = cmd.getKeyword();
@ -831,7 +835,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId(), JoinType.INNER);
SearchBuilder<DomainVO> domainSearch = _domainDao.createSearchBuilder();
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
if(isRecursive)
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE);
else
domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.EQ);
accountSearch.join("domainSearch", domainSearch, accountSearch.entity().getDomainId(), domainSearch.entity().getId(), JoinType.INNER);
}
@ -863,7 +870,10 @@ public class SnapshotManagerImpl implements SnapshotManager, SnapshotService, Ma
} else if (domainId != null) {
DomainVO domain = _domainDao.findById(domainId);
SearchCriteria<?> joinSearch = sc.getJoin("accountSearch");
joinSearch.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
if(isRecursive)
joinSearch.setJoinParameters("domainSearch", "path", domain.getPath() + "%");
else
joinSearch.setJoinParameters("domainSearch", "path", domain.getPath());
}
if (snapshotTypeStr != null) {

View File

@ -2347,6 +2347,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
Long domainId = cmd.getDomainId();
String accountName = cmd.getAccountName();
Long accountId = null;
Boolean isRecursive = cmd.isRecursive();
List<DomainVO> domainsToSearchForVms = new ArrayList<DomainVO>();
boolean isAdmin = false;
String path = null;
if ((account == null) || isAdmin(account.getType())) {
@ -2374,6 +2376,23 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
accountId = account.getId();
}
if(isRecursive == null)
isRecursive = false;
if(isRecursive && domainId != null) {
DomainVO parentDomain = _domainDao.findById(domainId);
if(parentDomain.getName().equals("ROOT")) {
domainsToSearchForVms.addAll(_domainDao.listAll());
return recursivelySearchForVms(cmd, path, isAdmin, domainsToSearchForVms, accountId);
}else {
domainsToSearchForVms.add(parentDomain);
domainsToSearchForVms.addAll(_domainDao.findAllChildren(parentDomain.getPath(), parentDomain.getId()));
return recursivelySearchForVms(cmd, path, isAdmin, domainsToSearchForVms, accountId);
}
} else if(isRecursive && domainId == null){
throw new ServerApiException(BaseCmd.MALFORMED_PARAMETER_ERROR, "Please enter a parent domain id for listing vms recursively");
}
Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(), cmd.getPageSizeVal());
c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
c.addCriteria(Criteria.ID, cmd.getId());
@ -2403,6 +2422,42 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return searchForUserVMs(c);
}
private List<UserVmVO> recursivelySearchForVms(ListVMsCmd cmd, String path, boolean isAdmin, List<DomainVO> domainToSearchWithin, Long accountId) {
List<UserVmVO> result = new ArrayList<UserVmVO>();
for(DomainVO domain : domainToSearchWithin) {
Criteria c = new Criteria("id", Boolean.TRUE, cmd.getStartIndex(), cmd.getPageSizeVal());
c.addCriteria(Criteria.KEYWORD, cmd.getKeyword());
c.addCriteria(Criteria.ID, cmd.getId());
c.addCriteria(Criteria.NAME, cmd.getInstanceName());
c.addCriteria(Criteria.STATE, cmd.getState());
c.addCriteria(Criteria.DATACENTERID, cmd.getZoneId());
c.addCriteria(Criteria.GROUPID, cmd.getGroupId());
c.addCriteria(Criteria.FOR_VIRTUAL_NETWORK, cmd.getForVirtualNetwork());
c.addCriteria(Criteria.NETWORKID, cmd.getNetworkId());
if (path != null) {
c.addCriteria(Criteria.PATH, path);
}
// ignore these search requests if it's not an admin
if (isAdmin == true) {
c.addCriteria(Criteria.DOMAINID, domain.getId());
c.addCriteria(Criteria.PODID, cmd.getPodId());
c.addCriteria(Criteria.HOSTID, cmd.getHostId());
}
if (accountId != null) {
c.addCriteria(Criteria.ACCOUNTID, new Object[] {accountId});
}
c.addCriteria(Criteria.ISADMIN, isAdmin);
result.addAll(searchForUserVMs(c));
}
return result;
}
@Override
public List<UserVmVO> searchForUserVMs(Criteria c) {
Filter searchFilter = new Filter(UserVmVO.class, c.getOrderBy(), c.getAscending(), c.getOffset(), c.getLimit());