From 68275debc0b76aa0d02b01180ac4d1518c519b18 Mon Sep 17 00:00:00 2001 From: Kris McQueen Date: Thu, 26 Aug 2010 18:29:58 -0700 Subject: [PATCH] Refactor listAsyncJobs to new API framework, consolidating parameter and criteria packing/unpacking into just command unpacking to simplify building the search criteria. --- .../cloud/api/commands/ListAsyncJobsCmd.java | 124 +++++------------ .../cloud/api/response/AsyncJobResponse.java | 129 ++++++++++++++++++ .../com/cloud/server/ManagementServer.java | 11 +- .../cloud/server/ManagementServerImpl.java | 76 ++++++++--- 4 files changed, 228 insertions(+), 112 deletions(-) create mode 100644 server/src/com/cloud/api/response/AsyncJobResponse.java diff --git a/server/src/com/cloud/api/commands/ListAsyncJobsCmd.java b/server/src/com/cloud/api/commands/ListAsyncJobsCmd.java index 2a7563dfee4..6db38f731bd 100644 --- a/server/src/com/cloud/api/commands/ListAsyncJobsCmd.java +++ b/server/src/com/cloud/api/commands/ListAsyncJobsCmd.java @@ -15,38 +15,23 @@ * along with this program. If not, see . * */ - package com.cloud.api.commands; - import java.util.ArrayList; import java.util.Date; import java.util.List; -import java.util.Map; -import com.cloud.api.BaseCmd; +import com.cloud.api.BaseListCmd; +import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; +import com.cloud.api.response.AsyncJobResponse; import com.cloud.async.AsyncJobVO; -import com.cloud.server.Criteria; -import com.cloud.user.Account; -import com.cloud.utils.Pair; - -public class ListAsyncJobsCmd extends BaseCmd { +import com.cloud.serializer.SerializerHelper; + +@Implementation(method="searchForAsyncJobs") +public class ListAsyncJobsCmd extends BaseListCmd { private static final String s_name = "listasyncjobsresponse"; - - private static final List> s_properties = new ArrayList>(); - - static { - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_ID, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.START_TZDATE, Boolean.FALSE)); - - s_properties.add(new Pair(BaseCmd.Properties.PAGE, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.PAGESIZE, Boolean.FALSE)); - } - ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// ///////////////////////////////////////////////////// @@ -81,80 +66,33 @@ public class ListAsyncJobsCmd extends BaseCmd { /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// + @Override public String getName() { return s_name; } - - public List> getProperties() { - return s_properties; - } - - public List> execute(Map params) { - Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName()); - Integer page = (Integer)params.get(BaseCmd.Properties.PAGE.getName()); - Integer pageSize = (Integer)params.get(BaseCmd.Properties.PAGESIZE.getName()); - Long accountId = (Long)params.get(BaseCmd.Properties.ACCOUNT_ID.getName()); - Date startDate = (Date)params.get(BaseCmd.Properties.START_TZDATE.getName()); - - Long startIndex = Long.valueOf(0); - int pageSizeNum = 50; - if (pageSize != null) { - pageSizeNum = pageSize.intValue(); - } - if (page != null) { - int pageNum = page.intValue(); - if (pageNum > 0) { - startIndex = Long.valueOf(pageSizeNum * (pageNum-1)); - } - } - - Criteria c = new Criteria("id", Boolean.TRUE, startIndex, Long.valueOf(pageSizeNum)); - if(account == null) { - if(accountId != null) - c.addCriteria(Criteria.ACCOUNTID, accountId.longValue()); - } else { - if(account.getType() == Account.ACCOUNT_TYPE_ADMIN) { - // for root admins, can take arbitrary account id from input - if(accountId != null) - c.addCriteria(Criteria.ACCOUNTID, accountId.longValue()); - } else { - // for normal accounts, they can only query jobs of their own - c.addCriteria(Criteria.ACCOUNTID, account.getId()); - } + + @Override @SuppressWarnings("unchecked") + public String getResponse() { + List jobs = (List)getResponseObject(); + + List response = new ArrayList(); + for (AsyncJobVO job : jobs) { + AsyncJobResponse jobResponse = new AsyncJobResponse(); + jobResponse.setAccountId(job.getAccountId()); + jobResponse.setCmd(job.getCmd()); + jobResponse.setCreated(job.getCreated()); + jobResponse.setId(job.getId()); + jobResponse.setJobInstanceId(job.getInstanceId()); + jobResponse.setJobInstanceType(job.getInstanceType()); + jobResponse.setJobProcStatus(job.getProcessStatus()); + jobResponse.setJobResult(job.getResult()); + jobResponse.setJobResultCode(job.getResultCode()); + jobResponse.setJobStatus(job.getStatus()); + jobResponse.setUserId(job.getUserId()); + + response.add(jobResponse); } - - if(startDate != null) { - c.addCriteria(Criteria.STARTDATE, startDate); - } - - List jobs = getManagementServer().searchForAsyncJobs(c); - if (jobs == null) { - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "unable to find async jobs"); - } - - List> jobTags = new ArrayList>(); - Object[] sTag = new Object[jobs.size()]; - int i = 0; - for(AsyncJobVO job : jobs) { - List> jobData = new ArrayList>(); - jobData.add(new Pair(BaseCmd.Properties.ID.getName(), job.getId().toString())); - jobData.add(new Pair(BaseCmd.Properties.ACCOUNT_ID.getName(), String.valueOf(job.getAccountId()))); - jobData.add(new Pair(BaseCmd.Properties.USER_ID.getName(), String.valueOf(job.getUserId()))); - jobData.add(new Pair(BaseCmd.Properties.CMD.getName(), job.getCmd())); - jobData.add(new Pair(BaseCmd.Properties.JOB_STATUS.getName(), String.valueOf(job.getStatus()))); - jobData.add(new Pair(BaseCmd.Properties.JOB_PROCESS_STATUS.getName(), String.valueOf(job.getProcessStatus()))); - jobData.add(new Pair(BaseCmd.Properties.JOB_RESULT_CODE.getName(), String.valueOf(job.getResultCode()))); - jobData.add(new Pair(BaseCmd.Properties.JOB_RESULT.getName(), job.getResult())); - jobData.add(new Pair(BaseCmd.Properties.JOB_INSTANCE_TYPE.getName(), job.getInstanceType())); - jobData.add(new Pair(BaseCmd.Properties.JOB_INSTANCE_ID.getName(), String.valueOf(job.getInstanceId()))); - jobData.add(new Pair(BaseCmd.Properties.CREATED.getName(), getDateString(job.getCreated()))); - - sTag[i++] = jobData; - } - - Pair jobTag = new Pair("asyncjobs", sTag); - jobTags.add(jobTag); - - return jobTags; + + return SerializerHelper.toSerializedString(response); } } diff --git a/server/src/com/cloud/api/response/AsyncJobResponse.java b/server/src/com/cloud/api/response/AsyncJobResponse.java new file mode 100644 index 00000000000..5af7fbb5dde --- /dev/null +++ b/server/src/com/cloud/api/response/AsyncJobResponse.java @@ -0,0 +1,129 @@ +package com.cloud.api.response; + +import java.util.Date; + +import com.cloud.api.ResponseObject; +import com.cloud.serializer.Param; + +public class AsyncJobResponse implements ResponseObject { + @Param(name="id") + private Long id; + + @Param(name="accountid") + private Long accountId; + + @Param(name="userid") + private Long userId; + + @Param(name="cmd") + private String cmd; + + @Param(name="jobstatus") + private Integer jobStatus; + + @Param(name="jobprocstatus") + private Integer jobProcStatus; + + @Param(name="jobresultcode") + private Integer jobResultCode; + + @Param(name="jobresult") + private String jobResult; + + @Param(name="jobinstancetype") + private String jobInstanceType; + + @Param(name="jobinstanceid") + private Long jobInstanceId; + + @Param(name="created") + private Date created; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getCmd() { + return cmd; + } + + public void setCmd(String cmd) { + this.cmd = cmd; + } + + public Integer getJobStatus() { + return jobStatus; + } + + public void setJobStatus(Integer jobStatus) { + this.jobStatus = jobStatus; + } + + public Integer getJobProcStatus() { + return jobProcStatus; + } + + public void setJobProcStatus(Integer jobProcStatus) { + this.jobProcStatus = jobProcStatus; + } + + public Integer getJobResultCode() { + return jobResultCode; + } + + public void setJobResultCode(Integer jobResultCode) { + this.jobResultCode = jobResultCode; + } + + public String getJobResult() { + return jobResult; + } + + public void setJobResult(String jobResult) { + this.jobResult = jobResult; + } + + public String getJobInstanceType() { + return jobInstanceType; + } + + public void setJobInstanceType(String jobInstanceType) { + this.jobInstanceType = jobInstanceType; + } + + public Long getJobInstanceId() { + return jobInstanceId; + } + + public void setJobInstanceId(Long jobInstanceId) { + this.jobInstanceId = jobInstanceId; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } +} diff --git a/server/src/com/cloud/server/ManagementServer.java b/server/src/com/cloud/server/ManagementServer.java index 136e4f3f188..66b62ad801f 100644 --- a/server/src/com/cloud/server/ManagementServer.java +++ b/server/src/com/cloud/server/ManagementServer.java @@ -32,6 +32,7 @@ import com.cloud.api.commands.EnableAccountCmd; import com.cloud.api.commands.EnableUserCmd; import com.cloud.api.commands.GetCloudIdentifierCmd; import com.cloud.api.commands.ListAlertsCmd; +import com.cloud.api.commands.ListAsyncJobsCmd; import com.cloud.api.commands.LockAccountCmd; import com.cloud.api.commands.LockUserCmd; import com.cloud.api.commands.RebootSystemVmCmd; @@ -1649,9 +1650,13 @@ public interface ManagementServer { AsyncJobResult queryAsyncJobResult(long jobId) throws PermissionDeniedException; AsyncJobVO findInstancePendingAsyncJob(String instanceType, long instanceId); AsyncJobVO findAsyncJobById(long jobId); - - List searchForAsyncJobs(Criteria c); - + + /** + * Search for async jobs by account and/or startDate + * @param cmd the command specifying the account and start date parameters + * @return the list of async jobs that match the criteria + */ + List searchForAsyncJobs(ListAsyncJobsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException; /** * Assign a security group to a VM diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 49e5f1c601c..5cc490e75cb 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -71,6 +71,7 @@ import com.cloud.api.commands.EnableAccountCmd; import com.cloud.api.commands.EnableUserCmd; import com.cloud.api.commands.GetCloudIdentifierCmd; import com.cloud.api.commands.ListAlertsCmd; +import com.cloud.api.commands.ListAsyncJobsCmd; import com.cloud.api.commands.LockAccountCmd; import com.cloud.api.commands.LockUserCmd; import com.cloud.api.commands.PrepareForMaintenanceCmd; @@ -7643,32 +7644,75 @@ public class ManagementServerImpl implements ManagementServer { } @Override - public List searchForAsyncJobs(Criteria c) { - Filter searchFilter = new Filter(AsyncJobVO.class, c.getOrderBy(), c - .getAscending(), c.getOffset(), c.getLimit()); + public List searchForAsyncJobs(ListAsyncJobsCmd cmd) throws InvalidParameterValueException, PermissionDeniedException { + Integer pageSize = cmd.getPageSize(); + Integer page = cmd.getPage(); + Long startIndex = Long.valueOf(0); + int pageSizeNum = 50; + if (pageSize != null) { + pageSizeNum = pageSize.intValue(); + } + if (page != null) { + int pageNum = page.intValue(); + if (pageNum > 0) { + startIndex = Long.valueOf(pageSizeNum * (pageNum-1)); + } + } + + Filter searchFilter = new Filter(AsyncJobVO.class, "id", true, startIndex, Long.valueOf(pageSizeNum)); + SearchBuilder sb = _jobDao.createSearchBuilder(); + + Object accountId = null; + Long domainId = cmd.getDomainId(); + Account account = (Account)UserContext.current().getAccountObject(); + if ((account == null) || isAdmin(account.getType())) { + String accountName = cmd.getAccountName(); + + if ((accountName != null) && (domainId != null)) { + Account userAccount = _accountDao.findActiveAccount(accountName, domainId); + if (userAccount != null) { + accountId = userAccount.getId(); + } else { + throw new InvalidParameterValueException("Failed to list async jobs for account " + accountName + " in domain " + domainId + "; account not found."); + } + } else if (domainId != null) { + if ((account != null) && !_domainDao.isChildDomain(account.getDomainId(), domainId)) { + throw new PermissionDeniedException("Failed to list async jobs for domain " + domainId + "; permission denied."); + } + + // we can do a domain match for the admin case + SearchBuilder domainSearch = _domainDao.createSearchBuilder(); + domainSearch.and("path", domainSearch.entity().getPath(), SearchCriteria.Op.LIKE); + + SearchBuilder accountSearch = _accountDao.createSearchBuilder(); + accountSearch.join("domainSearch", domainSearch, accountSearch.entity().getDomainId(), domainSearch.entity().getId()); + + sb.join("accountSearch", accountSearch, sb.entity().getAccountId(), accountSearch.entity().getId()); + } + } else { + accountId = account.getId(); + } + + Object keyword = cmd.getKeyword(); + Object startDate = cmd.getStartDate(); + + SearchCriteria sc = _jobDao.createSearchCriteria(); - - Object accountId = c.getCriteria(Criteria.ACCOUNTID); - Object status = c.getCriteria(Criteria.STATUS); - Object keyword = c.getCriteria(Criteria.KEYWORD); - Object startDate = c.getCriteria(Criteria.STARTDATE); - if (keyword != null) { - sc.addAnd("cmd", SearchCriteria.Op.LIKE, "%" + keyword+ "%"); + sc.addAnd("cmd", SearchCriteria.Op.LIKE, "%" + keyword + "%"); } if (accountId != null) { sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId); + } else if (domainId != null) { + DomainVO domain = _domainDao.findById(domainId); + sc.setJoinParameters("domainSearch", "path", domain.getPath() + "%"); } - if(status != null) { - sc.addAnd("status", SearchCriteria.Op.EQ, status); - } - - if(startDate != null) { + if (startDate != null) { sc.addAnd("created", SearchCriteria.Op.GTEQ, startDate); } - + return _jobDao.search(sc, searchFilter); }