quota: Adding pagination for quotaSummary and quotaTariffList (#4186)

Adds pagination and keyword search support to quotaSummary and quotaTariffList
Fixes: #4181
This commit is contained in:
davidjumani 2020-07-06 14:54:04 +05:30 committed by GitHub
parent 26f4edff34
commit b64d0b2d92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 118 additions and 45 deletions

View File

@ -31,6 +31,8 @@ public interface AccountDao extends GenericDao<AccountVO, Long> {
List<AccountVO> findAccountsLike(String accountName);
Pair<List<AccountVO>, Integer> findAccountsLike(String accountName, Filter filter);
List<AccountVO> findActiveAccounts(Long maxAccountId, Filter filter);
List<AccountVO> findRecentlyDeletedAccounts(Long maxAccountId, Date earliestRemovedDate, Filter filter);

View File

@ -29,6 +29,7 @@ import com.cloud.utils.db.GenericSearchBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.google.common.base.Strings;
import com.cloud.utils.db.TransactionLegacy;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -157,9 +158,16 @@ public class AccountDaoImpl extends GenericDaoBase<AccountVO, Long> implements A
@Override
public List<AccountVO> findAccountsLike(String accountName) {
return findAccountsLike(accountName, null).first();
}
@Override
public Pair<List<AccountVO>, Integer> findAccountsLike(String accountName, Filter filter) {
SearchCriteria<AccountVO> sc = createSearchCriteria();
sc.addAnd("accountName", SearchCriteria.Op.LIKE, "%" + accountName + "%");
return listBy(sc);
if (!Strings.isNullOrEmpty(accountName)) {
sc.addAnd("accountName", SearchCriteria.Op.LIKE, "%" + accountName + "%");
}
return searchAndCount(sc, filter);
}
@Override

View File

@ -20,12 +20,15 @@ import java.util.List;
import org.apache.cloudstack.quota.vo.QuotaAccountVO;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
public interface QuotaAccountDao extends GenericDao<QuotaAccountVO, Long> {
List<QuotaAccountVO> listAllQuotaAccount();
Pair<List<QuotaAccountVO>,Integer> listAllQuotaAccount(Long startIndex, Long pageSize);
QuotaAccountVO findByIdQuotaAccount(Long id);
QuotaAccountVO persistQuotaAccount(QuotaAccountVO entity);

View File

@ -22,6 +22,8 @@ import org.apache.cloudstack.quota.vo.QuotaAccountVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
@ -34,10 +36,16 @@ public class QuotaAccountDaoImpl extends GenericDaoBase<QuotaAccountVO, Long> im
@Override
public List<QuotaAccountVO> listAllQuotaAccount() {
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<List<QuotaAccountVO>>() {
return listAllQuotaAccount(null, null).first();
}
@Override
public Pair<List<QuotaAccountVO>,Integer> listAllQuotaAccount(final Long startIndex, final Long pageSize) {
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Pair<List<QuotaAccountVO>,Integer>>() {
@Override
public List<QuotaAccountVO> doInTransaction(final TransactionStatus status) {
return listAll();
public Pair<List<QuotaAccountVO>,Integer> doInTransaction(final TransactionStatus status) {
Filter filter = new Filter(QuotaAccountVO.class, "accountId", true, startIndex, pageSize);
return searchAndCount(null, filter);
}
});
}

View File

@ -16,6 +16,7 @@
//under the License.
package org.apache.cloudstack.quota.dao;
import com.cloud.utils.Pair;
import com.cloud.utils.db.GenericDao;
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
@ -27,9 +28,13 @@ public interface QuotaTariffDao extends GenericDao<QuotaTariffVO, Long> {
QuotaTariffVO findTariffPlanByUsageType(int quotaType, Date onOrBefore);
List<QuotaTariffVO> listAllTariffPlans();
Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans();
List<QuotaTariffVO> listAllTariffPlans(Date onOrBefore);
Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans(final Long startIndex, final Long pageSize);
Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans(Date onOrBefore);
Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans(Date onOrBefore, Long startIndex, Long pageSize);
Boolean updateQuotaTariff(QuotaTariffVO plan);

View File

@ -17,6 +17,7 @@
package org.apache.cloudstack.quota.dao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
@ -25,6 +26,7 @@ import org.apache.cloudstack.quota.vo.QuotaTariffVO;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
@ -77,20 +79,41 @@ public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> impl
}
@Override
public List<QuotaTariffVO> listAllTariffPlans() {
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<List<QuotaTariffVO>>() {
public Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans() {
return listAllTariffPlans(null, null);
}
@Override
public Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans(final Long startIndex, final Long pageSize) {
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Pair<List<QuotaTariffVO>, Integer>>() {
@Override
public List<QuotaTariffVO> doInTransaction(final TransactionStatus status) {
return listAll();
public Pair<List<QuotaTariffVO>, Integer> doInTransaction(final TransactionStatus status) {
return searchAndCount(null, new Filter(QuotaTariffVO.class, "updatedOn", false, startIndex, pageSize));
}
});
}
private <T> List<T> paginateList(final List<T> list, final Long startIndex, final Long pageSize) {
if (startIndex == null || pageSize == null) {
return list;
}
if (list.size() < startIndex){
return Collections.emptyList();
}
return list.subList(startIndex.intValue(), (int) Math.min(startIndex + pageSize, list.size()));
}
@Override
public List<QuotaTariffVO> listAllTariffPlans(final Date effectiveDate) {
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<List<QuotaTariffVO>>() {
public Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans(final Date effectiveDate) {
return listAllTariffPlans(effectiveDate, null, null);
}
@Override
public Pair<List<QuotaTariffVO>, Integer> listAllTariffPlans(final Date effectiveDate, final Long startIndex, final Long pageSize) {
return Transaction.execute(TransactionLegacy.USAGE_DB, new TransactionCallback<Pair<List<QuotaTariffVO>, Integer>>() {
@Override
public List<QuotaTariffVO> doInTransaction(final TransactionStatus status) {
public Pair<List<QuotaTariffVO>, Integer> doInTransaction(final TransactionStatus status) {
List<QuotaTariffVO> tariffs = new ArrayList<QuotaTariffVO>();
final Filter filter = new Filter(QuotaTariffVO.class, "updatedOn", false, 0L, 1L);
final SearchCriteria<QuotaTariffVO> sc = listAllIncludedUsageType.create();
@ -106,7 +129,7 @@ public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> impl
}
}
}
return tariffs;
return new Pair<>(paginateList(tariffs, startIndex, pageSize), tariffs.size());
}
});
}

View File

@ -17,6 +17,7 @@
package org.apache.cloudstack.api.command;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
@ -58,17 +59,17 @@ public class QuotaSummaryCmd extends BaseListCmd {
@Override
public void execute() {
Account caller = CallContext.current().getCallingAccount();
List<QuotaSummaryResponse> responses;
Pair<List<QuotaSummaryResponse>, Integer> responses;
if (caller.getType() == Account.ACCOUNT_TYPE_ADMIN) { //admin account
if (getAccountName() != null && getDomainId() != null)
responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
responses = _responseBuilder.createQuotaSummaryResponse(getAccountName(), getDomainId());
else
responses = _responseBuilder.createQuotaSummaryResponse(isListAll());
responses = _responseBuilder.createQuotaSummaryResponse(isListAll(), getKeyword(), getStartIndex(), getPageSizeVal());
} else {
responses = _responseBuilder.createQuotaSummaryResponse(caller.getAccountName(), caller.getDomainId());
}
final ListResponse<QuotaSummaryResponse> response = new ListResponse<QuotaSummaryResponse>();
response.setResponses(responses);
response.setResponses(responses.first(), responses.second());
response.setResponseName(getCommandName());
setResponseObject(response);
}

View File

@ -17,6 +17,7 @@
package org.apache.cloudstack.api.command;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
@ -54,10 +55,10 @@ public class QuotaTariffListCmd extends BaseListCmd {
@Override
public void execute() {
final List<QuotaTariffVO> result = _responseBuilder.listQuotaTariffPlans(this);
final Pair<List<QuotaTariffVO>, Integer> result = _responseBuilder.listQuotaTariffPlans(this);
final List<QuotaTariffResponse> responses = new ArrayList<QuotaTariffResponse>();
for (final QuotaTariffVO resource : result) {
for (final QuotaTariffVO resource : result.first()) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Result desc=" + resource.getDescription() + " date=" + resource.getEffectiveOn() + " val=" + resource.getCurrencyValue());
}
@ -65,7 +66,7 @@ public class QuotaTariffListCmd extends BaseListCmd {
}
final ListResponse<QuotaTariffResponse> response = new ListResponse<QuotaTariffResponse>();
response.setResponses(responses);
response.setResponses(responses, result.second());
response.setResponseName(getCommandName());
setResponseObject(response);
}

View File

@ -29,11 +29,13 @@ import org.apache.cloudstack.quota.vo.QuotaUsageVO;
import java.util.Date;
import java.util.List;
import com.cloud.utils.Pair;
public interface QuotaResponseBuilder {
QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd);
List<QuotaTariffVO> listQuotaTariffPlans(QuotaTariffListCmd cmd);
Pair<List<QuotaTariffVO>, Integer> listQuotaTariffPlans(QuotaTariffListCmd cmd);
QuotaTariffResponse createQuotaTariffResponse(QuotaTariffVO configuration);
@ -41,9 +43,11 @@ public interface QuotaResponseBuilder {
QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaUsage, Date startDate, Date endDate);
List<QuotaSummaryResponse> createQuotaSummaryResponse(Boolean listAll);
Pair<List<QuotaSummaryResponse>, Integer> createQuotaSummaryResponse(Boolean listAll);
List<QuotaSummaryResponse> createQuotaSummaryResponse(String accountName, Long domainId);
Pair<List<QuotaSummaryResponse>, Integer> createQuotaSummaryResponse(Boolean listAll, String keyword, Long startIndex, Long pageSize);
Pair<List<QuotaSummaryResponse>, Integer> createQuotaSummaryResponse(String accountName, Long domainId);
QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate);

View File

@ -69,6 +69,8 @@ import com.cloud.user.AccountVO;
import com.cloud.user.User;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.Pair;
import com.cloud.utils.db.Filter;
@Component
public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
@ -117,7 +119,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
}
@Override
public List<QuotaSummaryResponse> createQuotaSummaryResponse(final String accountName, final Long domainId) {
public Pair<List<QuotaSummaryResponse>, Integer> createQuotaSummaryResponse(final String accountName, final Long domainId) {
List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>();
if (accountName != null && domainId != null) {
@ -126,20 +128,30 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
result.add(qr);
}
return result;
return new Pair<>(result, result.size());
}
@Override
public List<QuotaSummaryResponse> createQuotaSummaryResponse(Boolean listAll) {
List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>();
public Pair<List<QuotaSummaryResponse>, Integer> createQuotaSummaryResponse(Boolean listAll) {
return createQuotaSummaryResponse(listAll, null, null, null);
}
@Override
public Pair<List<QuotaSummaryResponse>, Integer> createQuotaSummaryResponse(Boolean listAll, final String keyword, final Long startIndex, final Long pageSize) {
List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>();
Integer count = 0;
if (listAll) {
for (final AccountVO account : _accountDao.listAll()) {
Filter filter = new Filter(AccountVO.class, "accountName", true, startIndex, pageSize);
Pair<List<AccountVO>, Integer> data = _accountDao.findAccountsLike(keyword, filter);
count = data.second();
for (final AccountVO account : data.first()) {
QuotaSummaryResponse qr = getQuotaSummaryResponse(account);
result.add(qr);
}
} else {
for (final QuotaAccountVO quotaAccount : _quotaAccountDao.listAllQuotaAccount()) {
Pair<List<QuotaAccountVO>, Integer> data = _quotaAccountDao.listAllQuotaAccount(startIndex, pageSize);
count = data.second();
for (final QuotaAccountVO quotaAccount : data.first()) {
AccountVO account = _accountDao.findById(quotaAccount.getId());
if (account == null) {
continue;
@ -148,7 +160,7 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
result.add(qr);
}
}
return result;
return new Pair<>(result, count);
}
private QuotaSummaryResponse getQuotaSummaryResponse(final Account account) {
@ -160,9 +172,9 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
BigDecimal curBalance = _quotaBalanceDao.lastQuotaBalance(account.getAccountId(), account.getDomainId(), period[1].getTime());
BigDecimal quotaUsage = _quotaUsageDao.findTotalQuotaUsage(account.getAccountId(), account.getDomainId(), null, period[0].getTime(), period[1].getTime());
qr.setAccountId(account.getAccountId());
qr.setAccountId(account.getUuid());
qr.setAccountName(account.getAccountName());
qr.setDomainId(account.getDomainId());
qr.setDomainId(domain.getUuid());
qr.setDomainName(domain.getName());
qr.setBalance(curBalance);
qr.setQuotaUsage(quotaUsage);
@ -341,8 +353,8 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
}
@Override
public List<QuotaTariffVO> listQuotaTariffPlans(final QuotaTariffListCmd cmd) {
List<QuotaTariffVO> result = new ArrayList<QuotaTariffVO>();
public Pair<List<QuotaTariffVO>, Integer> listQuotaTariffPlans(final QuotaTariffListCmd cmd) {
Pair<List<QuotaTariffVO>, Integer> result;
Date effectiveDate = cmd.getEffectiveDate() == null ? new Date() : cmd.getEffectiveDate();
Date adjustedEffectiveDate = _quotaService.computeAdjustedTime(effectiveDate);
if (s_logger.isDebugEnabled()) {
@ -351,10 +363,14 @@ public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
if (cmd.getUsageType() != null) {
QuotaTariffVO tariffPlan = _quotaTariffDao.findTariffPlanByUsageType(cmd.getUsageType(), adjustedEffectiveDate);
if (tariffPlan != null) {
result.add(tariffPlan);
List<QuotaTariffVO> list = new ArrayList<>();
list.add(tariffPlan);
result = new Pair<>(list, list.size());
} else {
result = new Pair<>(new ArrayList<>(), 0);
}
} else {
result = _quotaTariffDao.listAllTariffPlans(adjustedEffectiveDate);
result = _quotaTariffDao.listAllTariffPlans(adjustedEffectiveDate, cmd.getStartIndex(), cmd.getPageSizeVal());
}
return result;
}

View File

@ -31,7 +31,7 @@ public class QuotaSummaryResponse extends BaseResponse {
@SerializedName("accountid")
@Param(description = "account id")
private Long accountId;
private String accountId;
@SerializedName("account")
@Param(description = "account name")
@ -39,7 +39,7 @@ public class QuotaSummaryResponse extends BaseResponse {
@SerializedName("domainid")
@Param(description = "domain id")
private Long domainId;
private String domainId;
@SerializedName("domain")
@Param(description = "domain name")
@ -73,11 +73,11 @@ public class QuotaSummaryResponse extends BaseResponse {
super();
}
public Long getAccountId() {
public String getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
public void setAccountId(String accountId) {
this.accountId = accountId;
}
@ -89,11 +89,11 @@ public class QuotaSummaryResponse extends BaseResponse {
this.accountName = accountName;
}
public Long getDomainId() {
public String getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
public void setDomainId(String domainId) {
this.domainId = domainId;
}

View File

@ -33,6 +33,8 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import com.cloud.utils.Pair;
@RunWith(MockitoJUnitRunner.class)
public class QuotaTariffListCmdTest extends TestCase {
@Mock
@ -53,7 +55,7 @@ public class QuotaTariffListCmdTest extends TestCase {
tariff.setUsageType(QuotaTypes.MEMORY);
quotaTariffVOList.add(new QuotaTariffVO());
Mockito.when(responseBuilder.listQuotaTariffPlans(Mockito.eq(cmd))).thenReturn(quotaTariffVOList);
Mockito.when(responseBuilder.listQuotaTariffPlans(Mockito.eq(cmd))).thenReturn(new Pair<>(quotaTariffVOList, quotaTariffVOList.size()));
Mockito.when(responseBuilder.createQuotaTariffResponse(Mockito.any(QuotaTariffVO.class))).thenReturn(new QuotaTariffResponse());
cmd.execute();