Skip to content

Commit ebfb90e

Browse files
committed
Create DB view for Account to speed up ListAccountsCmd, and add missing async job information for some response objects.
Signed-off-by: Min Chen <min.chen@citrix.com>
1 parent bc8e0af commit ebfb90e

38 files changed

Lines changed: 1398 additions & 341 deletions

api/src/com/cloud/user/AccountService.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,6 @@ UserAccount createUserAccount(String userName, String password, String firstName
192192

193193
public String[] createApiKeyAndSecretKey(RegisterCmd cmd);
194194

195-
Pair<List<? extends Account>, Integer> searchForAccounts(ListAccountsCmd cmd);
196-
197-
198-
199195
UserAccount getUserByApiKey(String apiKey);
200196

201197
void checkAccess(Account account, Domain domain) throws PermissionDeniedException;

api/src/com/cloud/user/ResourceLimitService.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,16 @@ public interface ResourceLimitService {
8080
*/
8181
public long findCorrectResourceLimitForAccount(Account account, ResourceType type);
8282

83+
/**
84+
* This call should be used when we have already queried resource limit for an account. This is to handle
85+
* some corner cases where queried limit may be null.
86+
* @param accountType
87+
* @param limit
88+
* @param type
89+
* @return
90+
*/
91+
public long findCorrectResourceLimitForAccount(short accountType, Long limit, ResourceType type);
92+
8393
/**
8494
* Finds the resource limit for a specified domain and type. If the domain has an infinite limit, will check
8595
* up the domain hierarchy

api/src/org/apache/cloudstack/api/command/user/account/ListAccountsCmd.java

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
import org.apache.cloudstack.api.Parameter;
2828
import org.apache.cloudstack.api.response.AccountResponse;
2929
import org.apache.cloudstack.api.response.ListResponse;
30+
import org.apache.cloudstack.api.response.UserResponse;
31+
3032
import com.cloud.user.Account;
3133
import com.cloud.utils.Pair;
3234

@@ -91,17 +93,8 @@ public String getCommandName() {
9193

9294
@Override
9395
public void execute(){
94-
Pair<List<? extends Account>, Integer> accounts = _accountService.searchForAccounts(this);
95-
ListResponse<AccountResponse> response = new ListResponse<AccountResponse>();
96-
List<AccountResponse> accountResponses = new ArrayList<AccountResponse>();
97-
for (Account account : accounts.first()) {
98-
AccountResponse acctResponse = _responseGenerator.createAccountResponse(account);
99-
acctResponse.setObjectName("account");
100-
accountResponses.add(acctResponse);
101-
}
102-
response.setResponses(accountResponses, accounts.second());
96+
ListResponse<AccountResponse> response = _queryService.searchForAccounts(this);
10397
response.setResponseName(getCommandName());
104-
10598
this.setResponseObject(response);
10699
}
107100
}

api/src/org/apache/cloudstack/query/QueryService.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
2020
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
2121
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
22+
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
2223
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
2324
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
2425
import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
@@ -28,6 +29,7 @@
2829
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
2930
import org.apache.cloudstack.api.command.user.vmgroup.ListVMGroupsCmd;
3031
import org.apache.cloudstack.api.command.user.volume.ListVolumesCmd;
32+
import org.apache.cloudstack.api.response.AccountResponse;
3133
import org.apache.cloudstack.api.response.DomainRouterResponse;
3234
import org.apache.cloudstack.api.response.EventResponse;
3335
import org.apache.cloudstack.api.response.HostResponse;
@@ -76,4 +78,6 @@ public interface QueryService {
7678
public ListResponse<HostResponse> searchForServers(ListHostsCmd cmd);
7779

7880
public ListResponse<VolumeResponse> searchForVolumes(ListVolumesCmd cmd);
81+
82+
public ListResponse<AccountResponse> searchForAccounts(ListAccountsCmd cmd);
7983
}

server/src/com/cloud/api/ApiDBUtils.java

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import org.apache.cloudstack.api.ApiConstants.HostDetails;
2626
import org.apache.cloudstack.api.ApiConstants.VMDetails;
27+
import org.apache.cloudstack.api.response.AccountResponse;
2728
import org.apache.cloudstack.api.response.DomainRouterResponse;
2829
import org.apache.cloudstack.api.response.EventResponse;
2930
import org.apache.cloudstack.api.response.HostResponse;
@@ -37,6 +38,7 @@
3738
import org.apache.cloudstack.api.response.UserVmResponse;
3839
import org.apache.cloudstack.api.response.VolumeResponse;
3940

41+
import com.cloud.api.query.dao.AccountJoinDao;
4042
import com.cloud.api.query.dao.DomainRouterJoinDao;
4143
import com.cloud.api.query.dao.HostJoinDao;
4244
import com.cloud.api.query.dao.InstanceGroupJoinDao;
@@ -45,8 +47,10 @@
4547
import com.cloud.api.query.dao.ProjectJoinDao;
4648
import com.cloud.api.query.dao.ResourceTagJoinDao;
4749
import com.cloud.api.query.dao.SecurityGroupJoinDao;
50+
import com.cloud.api.query.dao.UserAccountJoinDao;
4851
import com.cloud.api.query.dao.UserVmJoinDao;
4952
import com.cloud.api.query.dao.VolumeJoinDao;
53+
import com.cloud.api.query.vo.AccountJoinVO;
5054
import com.cloud.api.query.vo.DomainRouterJoinVO;
5155
import com.cloud.api.query.vo.EventJoinVO;
5256
import com.cloud.api.query.vo.HostJoinVO;
@@ -213,7 +217,6 @@
213217
import com.cloud.user.UserVO;
214218
import com.cloud.user.dao.AccountDao;
215219
import com.cloud.user.dao.SSHKeyPairDao;
216-
import com.cloud.user.dao.UserAccountJoinDao;
217220
import com.cloud.user.dao.UserDao;
218221
import com.cloud.user.dao.UserStatisticsDao;
219222
import com.cloud.uservm.UserVm;
@@ -318,6 +321,7 @@ public class ApiDBUtils {
318321
private static ProjectInvitationJoinDao _projectInvitationJoinDao;
319322
private static HostJoinDao _hostJoinDao;
320323
private static VolumeJoinDao _volJoinDao;
324+
private static AccountJoinDao _accountJoinDao;
321325

322326
private static PhysicalNetworkTrafficTypeDao _physicalNetworkTrafficTypeDao;
323327
private static PhysicalNetworkServiceProviderDao _physicalNetworkServiceProviderDao;
@@ -406,6 +410,7 @@ public class ApiDBUtils {
406410
_projectInvitationJoinDao = locator.getDao(ProjectInvitationJoinDao.class);
407411
_hostJoinDao = locator.getDao(HostJoinDao.class);
408412
_volJoinDao = locator.getDao(VolumeJoinDao.class);
413+
_accountJoinDao = locator.getDao(AccountJoinDao.class);
409414

410415
_physicalNetworkTrafficTypeDao = locator.getDao(PhysicalNetworkTrafficTypeDao.class);
411416
_physicalNetworkServiceProviderDao = locator.getDao(PhysicalNetworkServiceProviderDao.class);
@@ -491,6 +496,10 @@ public static long findCorrectResourceLimit(ResourceType type, long accountId) {
491496
return _resourceLimitMgr.findCorrectResourceLimitForAccount(account, type);
492497
}
493498

499+
public static long findCorrectResourceLimit(Long limit, short accountType, ResourceType type) {
500+
return _resourceLimitMgr.findCorrectResourceLimitForAccount(accountType, limit, type);
501+
}
502+
494503
public static AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId) {
495504
return _asyncMgr.findInstancePendingAsyncJob(instanceType, instanceId);
496505
}
@@ -589,7 +598,7 @@ public static DomainVO findDomainById(Long domainId) {
589598
public static DomainVO findDomainByIdIncludingRemoved(Long domainId) {
590599
return _domainDao.findByIdIncludingRemoved(domainId);
591600
}
592-
601+
593602
public static boolean isChildDomain(long parentId, long childId) {
594603
return _domainDao.isChildDomain(parentId, childId);
595604
}
@@ -1344,4 +1353,15 @@ public static List<VolumeJoinVO> newVolumeView(Volume vr){
13441353
return _volJoinDao.newVolumeView(vr);
13451354
}
13461355

1356+
public static AccountResponse newAccountResponse(AccountJoinVO ve) {
1357+
return _accountJoinDao.newAccountResponse(ve);
1358+
}
1359+
1360+
public static AccountJoinVO newAccountView(Account e){
1361+
return _accountJoinDao.newAccountView(e);
1362+
}
1363+
1364+
public static AccountJoinVO findAccountViewById(Long accountId) {
1365+
return _accountJoinDao.findByIdIncludingRemoved(accountId);
1366+
}
13471367
}

server/src/com/cloud/api/ApiResponseHelper.java

Lines changed: 4 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.apache.cloudstack.api.response.AccountResponse;
4646

4747
import com.cloud.api.query.ViewResponseHelper;
48+
import com.cloud.api.query.vo.AccountJoinVO;
4849
import com.cloud.api.query.vo.ControlledViewEntity;
4950
import com.cloud.api.query.vo.DomainRouterJoinVO;
5051
import com.cloud.api.query.vo.EventJoinVO;
@@ -275,162 +276,13 @@ public UserResponse createUserResponse(User user) {
275276
// this method is used for response generation via createAccount (which creates an account + user)
276277
@Override
277278
public AccountResponse createUserAccountResponse(UserAccount user) {
278-
return createAccountResponse(ApiDBUtils.findAccountById(user.getAccountId()));
279+
return ApiDBUtils.newAccountResponse(ApiDBUtils.findAccountViewById(user.getAccountId()));
279280
}
280281

281282
@Override
282283
public AccountResponse createAccountResponse(Account account) {
283-
boolean accountIsAdmin = (account.getType() == Account.ACCOUNT_TYPE_ADMIN);
284-
AccountResponse accountResponse = new AccountResponse();
285-
accountResponse.setId(account.getUuid());
286-
accountResponse.setName(account.getAccountName());
287-
accountResponse.setAccountType(account.getType());
288-
Domain domain = ApiDBUtils.findDomainById(account.getDomainId());
289-
if (domain != null) {
290-
accountResponse.setDomainId(domain.getUuid());
291-
accountResponse.setDomainName(domain.getName());
292-
}
293-
accountResponse.setState(account.getState().toString());
294-
accountResponse.setNetworkDomain(account.getNetworkDomain());
295-
DataCenter dc = ApiDBUtils.findZoneById(account.getDefaultZoneId());
296-
if (dc != null) {
297-
accountResponse.setDefaultZone(dc.getUuid());
298-
}
299-
300-
// get network stat
301-
List<UserStatisticsVO> stats = ApiDBUtils.listUserStatsBy(account.getId());
302-
if (stats == null) {
303-
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Internal error searching for user stats");
304-
}
305-
306-
Long bytesSent = 0L;
307-
Long bytesReceived = 0L;
308-
for (UserStatisticsVO stat : stats) {
309-
Long rx = stat.getNetBytesReceived() + stat.getCurrentBytesReceived();
310-
Long tx = stat.getNetBytesSent() + stat.getCurrentBytesSent();
311-
bytesReceived = bytesReceived + Long.valueOf(rx);
312-
bytesSent = bytesSent + Long.valueOf(tx);
313-
}
314-
accountResponse.setBytesReceived(bytesReceived);
315-
accountResponse.setBytesSent(bytesSent);
316-
317-
// Get resource limits and counts
318-
319-
Long vmLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.user_vm, account.getId());
320-
String vmLimitDisplay = (accountIsAdmin || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit);
321-
Long vmTotal = ApiDBUtils.getResourceCount(ResourceType.user_vm, account.getId());
322-
String vmAvail = (accountIsAdmin || vmLimit == -1) ? "Unlimited" : String.valueOf(vmLimit - vmTotal);
323-
accountResponse.setVmLimit(vmLimitDisplay);
324-
accountResponse.setVmTotal(vmTotal);
325-
accountResponse.setVmAvailable(vmAvail);
326-
327-
Long ipLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.public_ip, account.getId());
328-
String ipLimitDisplay = (accountIsAdmin || ipLimit == -1) ? "Unlimited" : String.valueOf(ipLimit);
329-
Long ipTotal = ApiDBUtils.getResourceCount(ResourceType.public_ip, account.getId());
330-
331-
Long ips = ipLimit - ipTotal;
332-
// check how many free ips are left, and if it's less than max allowed number of ips from account - use this
333-
// value
334-
Long ipsLeft = ApiDBUtils.countFreePublicIps();
335-
boolean unlimited = true;
336-
if (ips.longValue() > ipsLeft.longValue()) {
337-
ips = ipsLeft;
338-
unlimited = false;
339-
}
340-
341-
String ipAvail = ((accountIsAdmin || ipLimit == -1) && unlimited) ? "Unlimited" : String.valueOf(ips);
342-
343-
accountResponse.setIpLimit(ipLimitDisplay);
344-
accountResponse.setIpTotal(ipTotal);
345-
accountResponse.setIpAvailable(ipAvail);
346-
347-
Long volumeLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.volume, account.getId());
348-
String volumeLimitDisplay = (accountIsAdmin || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit);
349-
Long volumeTotal = ApiDBUtils.getResourceCount(ResourceType.volume, account.getId());
350-
String volumeAvail = (accountIsAdmin || volumeLimit == -1) ? "Unlimited" : String.valueOf(volumeLimit - volumeTotal);
351-
accountResponse.setVolumeLimit(volumeLimitDisplay);
352-
accountResponse.setVolumeTotal(volumeTotal);
353-
accountResponse.setVolumeAvailable(volumeAvail);
354-
355-
Long snapshotLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.snapshot, account.getId());
356-
String snapshotLimitDisplay = (accountIsAdmin || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit);
357-
Long snapshotTotal = ApiDBUtils.getResourceCount(ResourceType.snapshot, account.getId());
358-
String snapshotAvail = (accountIsAdmin || snapshotLimit == -1) ? "Unlimited" : String.valueOf(snapshotLimit - snapshotTotal);
359-
accountResponse.setSnapshotLimit(snapshotLimitDisplay);
360-
accountResponse.setSnapshotTotal(snapshotTotal);
361-
accountResponse.setSnapshotAvailable(snapshotAvail);
362-
363-
Long templateLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.template, account.getId());
364-
String templateLimitDisplay = (accountIsAdmin || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit);
365-
Long templateTotal = ApiDBUtils.getResourceCount(ResourceType.template, account.getId());
366-
String templateAvail = (accountIsAdmin || templateLimit == -1) ? "Unlimited" : String.valueOf(templateLimit - templateTotal);
367-
accountResponse.setTemplateLimit(templateLimitDisplay);
368-
accountResponse.setTemplateTotal(templateTotal);
369-
accountResponse.setTemplateAvailable(templateAvail);
370-
371-
// Get stopped and running VMs
372-
int vmStopped = 0;
373-
int vmRunning = 0;
374-
375-
List<Long> permittedAccounts = new ArrayList<Long>();
376-
permittedAccounts.add(account.getId());
377-
378-
List<UserVmJoinVO> virtualMachines = ApiDBUtils.searchForUserVMs(new Criteria(), permittedAccounts);
379-
380-
// get Running/Stopped VMs
381-
for (Iterator<UserVmJoinVO> iter = virtualMachines.iterator(); iter.hasNext();) {
382-
// count how many stopped/running vms we have
383-
UserVmJoinVO vm = iter.next();
384-
385-
if (vm.getState() == State.Stopped) {
386-
vmStopped++;
387-
} else if (vm.getState() == State.Running) {
388-
vmRunning++;
389-
}
390-
}
391-
392-
accountResponse.setVmStopped(vmStopped);
393-
accountResponse.setVmRunning(vmRunning);
394-
accountResponse.setObjectName("account");
395-
396-
//get resource limits for projects
397-
Long projectLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.project, account.getId());
398-
String projectLimitDisplay = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit);
399-
Long projectTotal = ApiDBUtils.getResourceCount(ResourceType.project, account.getId());
400-
String projectAvail = (accountIsAdmin || projectLimit == -1) ? "Unlimited" : String.valueOf(projectLimit - projectTotal);
401-
accountResponse.setProjectLimit(projectLimitDisplay);
402-
accountResponse.setProjectTotal(projectTotal);
403-
accountResponse.setProjectAvailable(projectAvail);
404-
405-
//get resource limits for networks
406-
Long networkLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.network, account.getId());
407-
String networkLimitDisplay = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit);
408-
Long networkTotal = ApiDBUtils.getResourceCount(ResourceType.network, account.getId());
409-
String networkAvail = (accountIsAdmin || networkLimit == -1) ? "Unlimited" : String.valueOf(networkLimit - networkTotal);
410-
accountResponse.setNetworkLimit(networkLimitDisplay);
411-
accountResponse.setNetworkTotal(networkTotal);
412-
accountResponse.setNetworkAvailable(networkAvail);
413-
414-
//get resource limits for vpcs
415-
Long vpcLimit = ApiDBUtils.findCorrectResourceLimit(ResourceType.vpc, account.getId());
416-
String vpcLimitDisplay = (accountIsAdmin || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit);
417-
Long vpcTotal = ApiDBUtils.getResourceCount(ResourceType.vpc, account.getId());
418-
String vpcAvail = (accountIsAdmin || vpcLimit == -1) ? "Unlimited" : String.valueOf(vpcLimit - vpcTotal);
419-
accountResponse.setNetworkLimit(vpcLimitDisplay);
420-
accountResponse.setNetworkTotal(vpcTotal);
421-
accountResponse.setNetworkAvailable(vpcAvail);
422-
423-
// adding all the users for an account as part of the response obj
424-
List<UserVO> usersForAccount = ApiDBUtils.listUsersByAccount(account.getAccountId());
425-
List<UserResponse> userResponseList = new ArrayList<UserResponse>();
426-
for (UserVO user : usersForAccount) {
427-
UserResponse userResponse = createUserResponse(user);
428-
userResponseList.add(userResponse);
429-
}
430-
431-
accountResponse.setUsers(userResponseList);
432-
accountResponse.setDetails(ApiDBUtils.getAccountDetails(account.getId()));
433-
return accountResponse;
284+
AccountJoinVO vUser = ApiDBUtils.newAccountView(account);
285+
return ApiDBUtils.newAccountResponse(vUser);
434286
}
435287

436288

server/src/com/cloud/api/ApiServer.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import javax.servlet.http.HttpSession;
5252

5353
import org.apache.cloudstack.api.*;
54+
import org.apache.cloudstack.api.command.user.account.ListAccountsCmd;
5455
import org.apache.cloudstack.api.command.user.account.ListProjectAccountsCmd;
5556
import org.apache.cloudstack.api.command.user.event.ListEventsCmd;
5657
import org.apache.cloudstack.api.command.user.vm.ListVMsCmd;
@@ -88,6 +89,7 @@
8889

8990
import org.apache.cloudstack.api.command.admin.host.ListHostsCmd;
9091
import org.apache.cloudstack.api.command.admin.router.ListRoutersCmd;
92+
import org.apache.cloudstack.api.command.admin.user.ListUsersCmd;
9193
import org.apache.cloudstack.api.command.user.project.ListProjectInvitationsCmd;
9294
import org.apache.cloudstack.api.command.user.project.ListProjectsCmd;
9395
import org.apache.cloudstack.api.command.user.securitygroup.ListSecurityGroupsCmd;
@@ -466,7 +468,10 @@ private String queueCommand(BaseCmd cmdObj, Map<String, String> params) {
466468
&& !(cmdObj instanceof ListProjectAccountsCmd)
467469
&& !(cmdObj instanceof ListProjectInvitationsCmd)
468470
&& !(cmdObj instanceof ListHostsCmd)
469-
&& !(cmdObj instanceof ListVolumesCmd)) {
471+
&& !(cmdObj instanceof ListVolumesCmd)
472+
&& !(cmdObj instanceof ListUsersCmd)
473+
&& !(cmdObj instanceof ListAccountsCmd)
474+
) {
470475
buildAsyncListResponse((BaseListCmd) cmdObj, caller);
471476
}
472477

0 commit comments

Comments
 (0)