Return-Path: X-Original-To: apmail-cloudstack-commits-archive@www.apache.org Delivered-To: apmail-cloudstack-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 61DF51881C for ; Mon, 7 Dec 2015 18:25:44 +0000 (UTC) Received: (qmail 13517 invoked by uid 500); 7 Dec 2015 18:25:31 -0000 Delivered-To: apmail-cloudstack-commits-archive@cloudstack.apache.org Received: (qmail 13283 invoked by uid 500); 7 Dec 2015 18:25:31 -0000 Mailing-List: contact commits-help@cloudstack.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cloudstack.apache.org Delivered-To: mailing list commits@cloudstack.apache.org Received: (qmail 13016 invoked by uid 99); 7 Dec 2015 18:25:31 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 07 Dec 2015 18:25:31 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 2E932E08BE; Mon, 7 Dec 2015 18:25:31 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: remi@apache.org To: commits@cloudstack.apache.org Date: Mon, 07 Dec 2015 18:25:33 -0000 Message-Id: In-Reply-To: <2833ac85d716401bbf34007c6400a88a@git.apache.org> References: <2833ac85d716401bbf34007c6400a88a@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [3/8] git commit: updated refs/heads/master to 24d0609 http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java new file mode 100644 index 0000000..23b1363 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaResponseBuilderImpl.java @@ -0,0 +1,516 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.domain.DomainVO; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.User; +import com.cloud.user.dao.AccountDao; +import com.cloud.user.dao.UserDao; + +import org.apache.cloudstack.api.command.QuotaBalanceCmd; +import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd; +import org.apache.cloudstack.api.command.QuotaEmailTemplateUpdateCmd; +import org.apache.cloudstack.api.command.QuotaStatementCmd; +import org.apache.cloudstack.api.command.QuotaTariffListCmd; +import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd; +import org.apache.cloudstack.quota.QuotaService; +import org.apache.cloudstack.quota.QuotaStatement; +import org.apache.cloudstack.quota.constant.QuotaConfig; +import org.apache.cloudstack.quota.constant.QuotaTypes; +import org.apache.cloudstack.quota.dao.QuotaAccountDao; +import org.apache.cloudstack.quota.dao.QuotaBalanceDao; +import org.apache.cloudstack.quota.dao.QuotaCreditsDao; +import org.apache.cloudstack.quota.dao.QuotaEmailTemplatesDao; +import org.apache.cloudstack.quota.dao.QuotaTariffDao; +import org.apache.cloudstack.quota.dao.QuotaUsageDao; +import org.apache.cloudstack.quota.vo.QuotaAccountVO; +import org.apache.cloudstack.quota.vo.QuotaBalanceVO; +import org.apache.cloudstack.quota.vo.QuotaCreditsVO; +import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO; +import org.apache.cloudstack.quota.vo.QuotaTariffVO; +import org.apache.cloudstack.quota.vo.QuotaUsageVO; +import org.apache.cloudstack.region.RegionManager; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +@Component +@Local(value = QuotaResponseBuilderImpl.class) +public class QuotaResponseBuilderImpl implements QuotaResponseBuilder { + private static final Logger s_logger = Logger.getLogger(QuotaResponseBuilderImpl.class); + + @Inject + private QuotaTariffDao _quotaTariffDao; + @Inject + private QuotaBalanceDao _quotaBalanceDao; + @Inject + private QuotaCreditsDao _quotaCreditsDao; + @Inject + private QuotaUsageDao _quotaUsageDao; + @Inject + private QuotaEmailTemplatesDao _quotaEmailTemplateDao; + + @Inject + private UserDao _userDao; + @Inject + private QuotaService _quotaService; + @Inject + private AccountDao _accountDao; + @Inject + private QuotaAccountDao _quotaAccountDao; + @Inject + private DomainDao _domainDao; + @Inject + private RegionManager _regionMgr; + @Inject + private QuotaStatement _statement; + + @Override + public QuotaTariffResponse createQuotaTariffResponse(QuotaTariffVO tariff) { + final QuotaTariffResponse response = new QuotaTariffResponse(); + response.setUsageType(tariff.getUsageType()); + response.setUsageName(tariff.getUsageName()); + response.setUsageUnit(tariff.getUsageUnit()); + response.setUsageDiscriminator(tariff.getUsageDiscriminator()); + response.setTariffValue(tariff.getCurrencyValue()); + response.setEffectiveOn(tariff.getEffectiveOn()); + response.setDescription(tariff.getDescription()); + response.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); + return response; + } + + @Override + public List createQuotaSummaryResponse(final String accountName, final Long domainId) { + List result = new ArrayList(); + + if (accountName != null && domainId != null) { + Account account = _accountDao.findActiveAccount(accountName, domainId); + QuotaSummaryResponse qr = getQuotaSummaryResponse(account); + result.add(qr); + } + + return result; + } + + @Override + public List createQuotaSummaryResponse(Boolean listAll) { + List result = new ArrayList(); + + if (listAll) { + for (final AccountVO account : _accountDao.listAll()) { + QuotaSummaryResponse qr = getQuotaSummaryResponse(account); + result.add(qr); + } + } else { + for (final QuotaAccountVO quotaAccount : _quotaAccountDao.listAllQuotaAccount()) { + AccountVO account = _accountDao.findById(quotaAccount.getId()); + QuotaSummaryResponse qr = getQuotaSummaryResponse(account); + result.add(qr); + } + } + return result; + } + + private QuotaSummaryResponse getQuotaSummaryResponse(final Account account) { + Calendar[] period = _statement.getCurrentStatementTime(); + + if (account != null) { + QuotaSummaryResponse qr = new QuotaSummaryResponse(); + DomainVO domain = _domainDao.findById(account.getDomainId()); + 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.setAccountName(account.getAccountName()); + qr.setDomainId(account.getDomainId()); + qr.setDomainName(domain.getName()); + qr.setBalance(curBalance); + qr.setQuotaUsage(quotaUsage); + qr.setState(account.getState()); + qr.setStartDate(period[0].getTime()); + qr.setEndDate(period[1].getTime()); + qr.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); + qr.setObjectName("summary"); + return qr; + } else { + throw new InvalidParameterValueException("Quota summary response for an account requires a valid account."); + } + } + + @Override + public QuotaBalanceResponse createQuotaBalanceResponse(List quotaBalance, Date startDate, Date endDate) { + if (quotaBalance == null || quotaBalance.isEmpty()) { + new InvalidParameterValueException("The request period does not contain balance entries."); + } + Collections.sort(quotaBalance, new Comparator() { + public int compare(QuotaBalanceVO o1, QuotaBalanceVO o2) { + return o2.getUpdatedOn().compareTo(o1.getUpdatedOn()); // desc + } + }); + + boolean have_balance_entries = false; + //check that there is at least one balance entry + for (Iterator it = quotaBalance.iterator(); it.hasNext();) { + QuotaBalanceVO entry = it.next(); + if (entry.getCreditsId() > 0) { + have_balance_entries = true; + break; + } + } + //if last entry is a credit deposit then remove that as that is already + //accounted for in the starting balance after that entry, note the sort is desc + if (have_balance_entries) { + ListIterator li = quotaBalance.listIterator(quotaBalance.size()); + // Iterate in reverse. + while (li.hasPrevious()) { + QuotaBalanceVO entry = li.previous(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("createQuotaBalanceResponse: Entry=" + entry); + } + if (entry.getCreditsId() > 0) { + li.remove(); + } else { + break; + } + } + } + + int quota_activity = quotaBalance.size(); + QuotaBalanceResponse resp = new QuotaBalanceResponse(); + BigDecimal lastCredits = new BigDecimal(0); + boolean consecutive = true; + for (Iterator it = quotaBalance.iterator(); it.hasNext();) { + QuotaBalanceVO entry = it.next(); + if (s_logger.isDebugEnabled()) { + s_logger.debug("createQuotaBalanceResponse: All Credit Entry=" + entry); + } + if (entry.getCreditsId() > 0) { + if (consecutive) { + lastCredits = lastCredits.add(entry.getCreditBalance()); + } + resp.addCredits(entry); + it.remove(); + } else { + consecutive = false; + } + } + + if (quota_activity > 0 && quotaBalance.size() > 0) { + // order is desc last item is the start item + QuotaBalanceVO startItem = quotaBalance.get(quotaBalance.size() - 1); + QuotaBalanceVO endItem = quotaBalance.get(0); + resp.setStartDate(startItem.getUpdatedOn()); + resp.setStartQuota(startItem.getCreditBalance()); + resp.setEndDate(endItem.getUpdatedOn()); + if (s_logger.isDebugEnabled()) { + s_logger.debug("createQuotaBalanceResponse: Start Entry=" + startItem); + s_logger.debug("createQuotaBalanceResponse: End Entry=" + endItem); + } + resp.setEndQuota(endItem.getCreditBalance().add(lastCredits)); + } else if (quota_activity > 0) { + // order is desc last item is the start item + resp.setStartDate(startDate); + resp.setStartQuota(new BigDecimal(0)); + resp.setEndDate(endDate); + resp.setEndQuota(new BigDecimal(0).add(lastCredits)); + } else { + resp.setStartDate(startDate); + resp.setEndDate(endDate); + resp.setStartQuota(new BigDecimal(0)); + resp.setEndQuota(new BigDecimal(0)); + } + resp.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); + resp.setObjectName("balance"); + return resp; + } + + @Override + public QuotaStatementResponse createQuotaStatementResponse(final List quotaUsage) { + if (quotaUsage == null || quotaUsage.isEmpty()) { + throw new InvalidParameterValueException("There is no usage data found for period mentioned."); + } + + QuotaStatementResponse statement = new QuotaStatementResponse(); + + HashMap quotaTariffMap = new HashMap(); + Collection result = QuotaTypes.listQuotaTypes().values(); + + for (QuotaTypes quotaTariff : result) { + quotaTariffMap.put(quotaTariff.getQuotaType(), quotaTariff); + // add dummy record for each usage type + QuotaUsageVO dummy = new QuotaUsageVO(quotaUsage.get(0)); + dummy.setUsageType(quotaTariff.getQuotaType()); + dummy.setQuotaUsed(new BigDecimal(0)); + quotaUsage.add(dummy); + } + + if (s_logger.isDebugEnabled()) { + s_logger.debug( + "createQuotaStatementResponse Type=" + quotaUsage.get(0).getUsageType() + " usage=" + quotaUsage.get(0).getQuotaUsed().setScale(2, RoundingMode.HALF_EVEN) + + " rec.id=" + quotaUsage.get(0).getUsageItemId() + " SD=" + quotaUsage.get(0).getStartDate() + " ED=" + quotaUsage.get(0).getEndDate()); + } + + Collections.sort(quotaUsage, new Comparator() { + public int compare(QuotaUsageVO o1, QuotaUsageVO o2) { + if (o1.getUsageType() == o2.getUsageType()) + return 0; + return o1.getUsageType() < o2.getUsageType() ? -1 : 1; + } + }); + + List items = new ArrayList(); + QuotaStatementItemResponse lineitem; + int type = -1; + BigDecimal usage = new BigDecimal(0); + BigDecimal totalUsage = new BigDecimal(0); + quotaUsage.add(new QuotaUsageVO());// boundary + QuotaUsageVO prev = quotaUsage.get(0); + if (s_logger.isDebugEnabled()) { + s_logger.debug("createQuotaStatementResponse record count=" + quotaUsage.size()); + } + for (final QuotaUsageVO quotaRecord : quotaUsage) { + if (type != quotaRecord.getUsageType()) { + if (type != -1) { + lineitem = new QuotaStatementItemResponse(type); + lineitem.setQuotaUsed(usage); + lineitem.setAccountId(prev.getAccountId()); + lineitem.setDomainId(prev.getDomainId()); + lineitem.setUsageUnit(quotaTariffMap.get(type).getQuotaUnit()); + lineitem.setUsageName(quotaTariffMap.get(type).getQuotaName()); + lineitem.setObjectName("quotausage"); + items.add(lineitem); + totalUsage = totalUsage.add(usage); + usage = new BigDecimal(0); + } + type = quotaRecord.getUsageType(); + } + prev = quotaRecord; + usage = usage.add(quotaRecord.getQuotaUsed()); + } + + statement.setLineItem(items); + statement.setTotalQuota(totalUsage); + statement.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); + statement.setObjectName("statement"); + return statement; + } + + @Override + public List listQuotaTariffPlans(final QuotaTariffListCmd cmd) { + List result = new ArrayList(); + Date effectiveDate = cmd.getEffectiveDate() == null ? new Date() : cmd.getEffectiveDate(); + Date adjustedEffectiveDate = _quotaService.computeAdjustedTime(effectiveDate); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Effective datec=" + effectiveDate + " quotatype=" + cmd.getUsageType() + " Adjusted date=" + adjustedEffectiveDate); + } + if (cmd.getUsageType() != null) { + QuotaTariffVO tariffPlan = _quotaTariffDao.findTariffPlanByUsageType(cmd.getUsageType(), adjustedEffectiveDate); + if (tariffPlan != null) { + result.add(tariffPlan); + } + } else { + result = _quotaTariffDao.listAllTariffPlans(adjustedEffectiveDate); + } + return result; + } + + @Override + public QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd) { + final int quotaType = cmd.getUsageType(); + final BigDecimal quotaCost = new BigDecimal(cmd.getValue()); + final Date effectiveDate = _quotaService.computeAdjustedTime(cmd.getStartDate()); + final Date now = _quotaService.computeAdjustedTime(new Date()); + // if effective date is in the past return error + if (effectiveDate.compareTo(now) < 0) { + throw new InvalidParameterValueException("Incorrect effective date for tariff " + effectiveDate + " is less than now " + now); + } + QuotaTypes quotaConstant = QuotaTypes.listQuotaTypes().get(quotaType); + if (quotaConstant == null) { + throw new InvalidParameterValueException("Quota type does not exists " + quotaType); + } + + QuotaTariffVO result = null; + result = new QuotaTariffVO(quotaType); + result.setUsageName(quotaConstant.getQuotaName()); + result.setUsageUnit(quotaConstant.getQuotaUnit()); + result.setUsageDiscriminator(quotaConstant.getDiscriminator()); + result.setCurrencyValue(quotaCost); + result.setEffectiveOn(effectiveDate); + result.setUpdatedOn(now); + result.setUpdatedBy(cmd.getEntityOwnerId()); + + if (s_logger.isDebugEnabled()) { + s_logger.debug(String.format("Updating Quota Tariff Plan: New value=%s for resource type=%d effective on date=%s", quotaCost, quotaType, effectiveDate)); + } + _quotaTariffDao.addQuotaTariff(result); + + return result; + } + + @Override + public QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy) { + Date depositDate = new Date(); + Date adjustedStartDate = _quotaService.computeAdjustedTime(depositDate); + QuotaBalanceVO qb = _quotaBalanceDao.findLaterBalanceEntry(accountId, domainId, adjustedStartDate); + + if (qb != null) { + throw new InvalidParameterValueException("Incorrect deposit date: " + adjustedStartDate + " there are balance entries after this date"); + } + + return addQuotaCredits(accountId, domainId, amount, updatedBy, adjustedStartDate); + } + + @Override + public QuotaCreditsResponse addQuotaCredits(final Long accountId, final Long domainId, final Double amount, final Long updatedBy, final Date despositedOn) { + + QuotaCreditsVO credits = new QuotaCreditsVO(accountId, domainId, new BigDecimal(amount), updatedBy); + s_logger.debug("AddQuotaCredits: Depositing " + amount + " on adjusted date " + despositedOn); + credits.setUpdatedOn(despositedOn); + QuotaCreditsVO result = _quotaCreditsDao.saveCredits(credits); + + final AccountVO account = _accountDao.findById(accountId); + final boolean lockAccountEnforcement = "true".equalsIgnoreCase(QuotaConfig.QuotaEnableEnforcement.value()); + final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, startOfNextDay(despositedOn)); + if (lockAccountEnforcement && (currentAccountBalance.compareTo(new BigDecimal(0)) >= 0)) { + if (account.getState() == Account.State.locked) { + _regionMgr.enableAccount(account.getAccountName(), domainId, accountId); + } + } + + String creditor = String.valueOf(Account.ACCOUNT_ID_SYSTEM); + User creditorUser = _userDao.getUser(updatedBy); + if (creditorUser != null) { + creditor = creditorUser.getUsername(); + } + QuotaCreditsResponse response = new QuotaCreditsResponse(result, creditor); + response.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); + return response; + } + + private QuotaEmailTemplateResponse createQuotaEmailResponse(QuotaEmailTemplatesVO template) { + QuotaEmailTemplateResponse response = new QuotaEmailTemplateResponse(); + response.setTemplateType(template.getTemplateName()); + response.setTemplateSubject(template.getTemplateSubject()); + response.setTemplateText(template.getTemplateBody()); + response.setLocale(template.getLocale()); + response.setLastUpdatedOn(template.getLastUpdated()); + return response; + } + + @Override + public List listQuotaEmailTemplates(QuotaEmailTemplateListCmd cmd) { + final String templateName = cmd.getTemplateName(); + List templates = _quotaEmailTemplateDao.listAllQuotaEmailTemplates(templateName); + final List responses = new ArrayList(); + for (final QuotaEmailTemplatesVO template : templates) { + responses.add(createQuotaEmailResponse(template)); + } + return responses; + } + + @Override + public boolean updateQuotaEmailTemplate(QuotaEmailTemplateUpdateCmd cmd) { + final String templateName = cmd.getTemplateName(); + final String templateSubject = StringEscapeUtils.escapeJavaScript(cmd.getTemplateSubject()); + final String templateBody = StringEscapeUtils.escapeJavaScript(cmd.getTemplateBody()); + final String locale = cmd.getLocale(); + + final List templates = _quotaEmailTemplateDao.listAllQuotaEmailTemplates(templateName); + if (templates.size() == 1) { + final QuotaEmailTemplatesVO template = templates.get(0); + template.setTemplateSubject(templateSubject); + template.setTemplateBody(templateBody); + if (locale != null) { + template.setLocale(locale); + } + return _quotaEmailTemplateDao.updateQuotaEmailTemplate(template); + } + return false; + } + + @Override + public QuotaBalanceResponse createQuotaLastBalanceResponse(List quotaBalance, Date startDate) { + if (quotaBalance == null) { + throw new InvalidParameterValueException("There are no balance entries on or before the requested date."); + } + if (startDate == null) { + startDate = new Date(); + } + QuotaBalanceResponse resp = new QuotaBalanceResponse(); + BigDecimal lastCredits = new BigDecimal(0); + for (QuotaBalanceVO entry : quotaBalance) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("createQuotaLastBalanceResponse Date=" + entry.getUpdatedOn() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId()); + } + lastCredits = lastCredits.add(entry.getCreditBalance()); + } + resp.setStartQuota(lastCredits); + resp.setStartDate(_quotaService.computeAdjustedTime(startDate)); + resp.setCurrency(QuotaConfig.QuotaCurrencySymbol.value()); + resp.setObjectName("balance"); + return resp; + } + + @Override + public List getQuotaUsage(QuotaStatementCmd cmd) { + return _quotaService.getQuotaUsage(cmd.getAccountId(), cmd.getAccountName(), cmd.getDomainId(), cmd.getUsageType(), cmd.getStartDate(), cmd.getEndDate()); + } + + @Override + public List getQuotaBalance(QuotaBalanceCmd cmd) { + return _quotaService.findQuotaBalanceVO(cmd.getAccountId(), cmd.getAccountName(), cmd.getDomainId(), cmd.getStartDate(), cmd.getEndDate()); + } + + @Override + public Date startOfNextDay(Date dt) { + Calendar c = Calendar.getInstance(); + c.setTime(dt); + c.add(Calendar.DATE, 1); + dt = c.getTime(); + return dt; + } + + @Override + public Date startOfNextDay() { + Calendar c = Calendar.getInstance(); + c.setTime(new Date()); + c.add(Calendar.DATE, 1); + Date dt = c.getTime(); + return dt; + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java new file mode 100644 index 0000000..dec6760 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementItemResponse.java @@ -0,0 +1,118 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.response; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; + +public class QuotaStatementItemResponse extends BaseResponse { + + @SerializedName("type") + @Param(description = "usage type") + private int usageType; + + @SerializedName("accountid") + @Param(description = "account id") + private Long accountId; + + @SerializedName("account") + @Param(description = "account name") + private String accountName; + + @SerializedName("domain") + @Param(description = "domain id") + private Long domainId; + + @SerializedName("name") + @Param(description = "usage type name") + private String usageName; + + @SerializedName("unit") + @Param(description = "usage unit") + private String usageUnit; + + @SerializedName("quota") + @Param(description = "quota consumed") + private BigDecimal quotaUsed; + + public QuotaStatementItemResponse(final int usageType) { + this.usageType = usageType; + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public Long getDomainId() { + return domainId; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + public String getUsageName() { + return usageName; + } + + public void setUsageName(String usageName) { + this.usageName = usageName; + } + + public int getUsageType() { + return usageType; + } + + public void setUsageType(int usageType) { + this.usageType = usageType; + } + + public String getUsageUnit() { + return usageUnit; + } + + public void setUsageUnit(String usageUnit) { + this.usageUnit = usageUnit; + } + + public BigDecimal getQuotaUsed() { + return quotaUsed; + } + + public void setQuotaUsed(BigDecimal quotaUsed) { + this.quotaUsed = quotaUsed.setScale(2, RoundingMode.HALF_EVEN); + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java new file mode 100644 index 0000000..efe8e8e --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaStatementResponse.java @@ -0,0 +1,130 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; +import org.apache.cloudstack.api.BaseResponse; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Date; +import java.util.List; + +public class QuotaStatementResponse extends BaseResponse { + + @SerializedName("accountid") + @Param(description = "account id") + private Long accountId; + + @SerializedName("account") + @Param(description = "account name") + private String accountName; + + @SerializedName("domain") + @Param(description = "domain id") + private Long domainId; + + @SerializedName("quotausage") + @Param(description = "list of quota usage under various types", responseObject = QuotaStatementItemResponse.class) + private List lineItem; + + @SerializedName("totalquota") + @Param(description = "total quota used during this period") + private BigDecimal totalQuota; + + @SerializedName("startdate") + @Param(description = "start date") + private Date startDate = null; + + @SerializedName("enddate") + @Param(description = "end date") + private Date endDate = null; + + @SerializedName("currency") + @Param(description = "currency") + private String currency; + + public QuotaStatementResponse() { + super(); + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public Long getDomainId() { + return domainId; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + public List getLineItem() { + return lineItem; + } + + public void setLineItem(List lineItem) { + this.lineItem = lineItem; + } + + public Date getStartDate() { + return startDate == null ? null : new Date(startDate.getTime()); + } + + public void setStartDate(Date startDate) { + this.startDate = startDate == null ? null : new Date(startDate.getTime()); + } + + public Date getEndDate() { + return endDate == null ? null : new Date(endDate.getTime()); + } + + public void setEndDate(Date endDate) { + this.endDate = endDate == null ? null : new Date(endDate.getTime()); + } + + + public BigDecimal getTotalQuota() { + return totalQuota; + } + + public void setTotalQuota(BigDecimal totalQuota) { + this.totalQuota = totalQuota.setScale(2, RoundingMode.HALF_EVEN); + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaSummaryResponse.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaSummaryResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaSummaryResponse.java new file mode 100644 index 0000000..4e6f684 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaSummaryResponse.java @@ -0,0 +1,155 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.response; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Date; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; +import com.cloud.user.Account.State; + +public class QuotaSummaryResponse extends BaseResponse { + + @SerializedName("accountid") + @Param(description = "account id") + private Long accountId; + + @SerializedName("account") + @Param(description = "account name") + private String accountName; + + @SerializedName("domainid") + @Param(description = "domain id") + private Long domainId; + + @SerializedName("domain") + @Param(description = "domain name") + private String domainName; + + @SerializedName("balance") + @Param(description = "account balance") + private BigDecimal balance; + + @SerializedName("state") + @Param(description = "account state") + private State state; + + @SerializedName("quota") + @Param(description = "quota usage of this period") + private BigDecimal quotaUsage; + + @SerializedName("startdate") + @Param(description = "start date") + private Date startDate = null; + + @SerializedName("enddate") + @Param(description = "end date") + private Date endDate = null; + + @SerializedName("currency") + @Param(description = "currency") + private String currency; + + public QuotaSummaryResponse() { + super(); + } + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public Long getDomainId() { + return domainId; + } + + public void setDomainId(Long domainId) { + this.domainId = domainId; + } + + public String getDomainName() { + return domainName; + } + + public void setDomainName(String domainName) { + this.domainName = domainName; + } + + public BigDecimal getQuotaUsage() { + return quotaUsage; + } + + public State getState() { + return state; + } + + public void setState(State state) { + this.state = state; + } + + public void setQuotaUsage(BigDecimal startQuota) { + this.quotaUsage = startQuota.setScale(2, RoundingMode.HALF_EVEN); + } + + public BigDecimal getBalance() { + return balance; + } + + public void setBalance(BigDecimal balance) { + this.balance = balance.setScale(2, RoundingMode.HALF_EVEN); + } + + public Date getStartDate() { + return startDate == null ? null : new Date(startDate.getTime()); + } + + public void setStartDate(Date startDate) { + this.startDate = startDate == null ? null : new Date(startDate.getTime()); + } + + public Date getEndDate() { + return endDate == null ? null : new Date(endDate.getTime()); + } + + public void setEndDate(Date endDate) { + this.endDate = endDate == null ? null : new Date(endDate.getTime()); + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTariffResponse.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTariffResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTariffResponse.java new file mode 100644 index 0000000..48697fd --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTariffResponse.java @@ -0,0 +1,134 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +import java.math.BigDecimal; +import java.util.Date; + +public class QuotaTariffResponse extends BaseResponse { + + @SerializedName("usageType") + @Param(description = "usageType") + private int usageType; + + @SerializedName("usageName") + @Param(description = "usageName") + private String usageName; + + @SerializedName("usageUnit") + @Param(description = "usageUnit") + private String usageUnit; + + @SerializedName("usageDiscriminator") + @Param(description = "usageDiscriminator") + private String usageDiscriminator; + + @SerializedName("tariffValue") + @Param(description = "tariffValue") + private BigDecimal tariffValue; + + @SerializedName("effectiveDate") + @Param(description = "the date on/after which this quota value will be effective") + private Date effectiveOn = null; + + @SerializedName("description") + @Param(description = "description") + private String description; + + @SerializedName("currency") + @Param(description = "currency") + private String currency; + + public QuotaTariffResponse() { + super(); + this.setObjectName("quotatariff"); + } + + public QuotaTariffResponse(final int usageType) { + super(); + this.usageType = usageType; + } + + public String getUsageName() { + return usageName; + } + + public void setUsageName(String usageName) { + this.usageName = usageName; + } + + public int getUsageType() { + return usageType; + } + + public void setUsageType(int usageType) { + this.usageType = usageType; + } + + public String getUsageUnit() { + return usageUnit; + } + + public void setUsageUnit(String usageUnit) { + this.usageUnit = usageUnit; + } + + public String getUsageDiscriminator() { + return usageDiscriminator; + } + + public void setUsageDiscriminator(String usageDiscriminator) { + this.usageDiscriminator = usageDiscriminator; + } + + public BigDecimal getTariffValue() { + return tariffValue; + } + + public void setTariffValue(BigDecimal tariffValue) { + this.tariffValue = tariffValue; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Date getEffectiveOn() { + return effectiveOn; + } + + public void setEffectiveOn(Date effectiveOn) { + this.effectiveOn = effectiveOn; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTypeResponse.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTypeResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTypeResponse.java new file mode 100644 index 0000000..989fba5 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaTypeResponse.java @@ -0,0 +1,58 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.response; + +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.ApiConstants; +import org.apache.cloudstack.api.BaseResponse; + +import com.cloud.serializer.Param; + +public class QuotaTypeResponse extends BaseResponse { + + @SerializedName("quotatypeid") + @Param(description = "quota type") + private Integer quotaType; + + @SerializedName(ApiConstants.DESCRIPTION) + @Param(description = "description of usage type") + private String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Integer getQuotaType() { + return quotaType; + } + + public void setQuotaType(Integer quotaType) { + this.quotaType = quotaType; + } + + public QuotaTypeResponse(Integer quotaType, String description) { + this.quotaType = quotaType; + this.description = description; + setObjectName(ApiConstants.USAGE_TYPE); + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaUpdateResponse.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaUpdateResponse.java b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaUpdateResponse.java new file mode 100644 index 0000000..e98da9b --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/api/response/QuotaUpdateResponse.java @@ -0,0 +1,38 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.api.response; + +import com.cloud.serializer.Param; +import com.google.gson.annotations.SerializedName; + +import org.apache.cloudstack.api.BaseResponse; + +import java.util.Calendar; +import java.util.Date; + +public class QuotaUpdateResponse extends BaseResponse { + + @SerializedName("updated_on") + @Param(description = "timestamp when the run got over") + private Date updatedOn; + + public QuotaUpdateResponse(Calendar now) { + super(); + updatedOn=now.getTime(); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java new file mode 100644 index 0000000..8ee39b8 --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaService.java @@ -0,0 +1,39 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.quota; + +import com.cloud.utils.component.PluggableService; + +import org.apache.cloudstack.quota.vo.QuotaBalanceVO; +import org.apache.cloudstack.quota.vo.QuotaUsageVO; + +import java.util.Date; +import java.util.List; + +public interface QuotaService extends PluggableService { + + List getQuotaUsage(Long accountId, String accountName, Long domainId, Integer usageType, Date startDate, Date endDate); + + List findQuotaBalanceVO(Long accountId, String accountName, Long domainId, Date startDate, Date endDate); + + Date computeAdjustedTime(Date date); + + void setLockAccount(Long accountId, Boolean state); + + void setMinBalance(Long accountId, Double balance); + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java new file mode 100644 index 0000000..1b4c98f --- /dev/null +++ b/plugins/database/quota/src/org/apache/cloudstack/quota/QuotaServiceImpl.java @@ -0,0 +1,299 @@ +//Licensed to the Apache Software Foundation (ASF) under one +//or more contributor license agreements. See the NOTICE file +//distributed with this work for additional information +//regarding copyright ownership. The ASF licenses this file +//to you under the Apache License, Version 2.0 (the +//"License"); you may not use this file except in compliance +//with the License. You may obtain a copy of the License at +// +//http://www.apache.org/licenses/LICENSE-2.0 +// +//Unless required by applicable law or agreed to in writing, +//software distributed under the License is distributed on an +//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +//KIND, either express or implied. See the License for the +//specific language governing permissions and limitations +//under the License. +package org.apache.cloudstack.quota; + +import com.cloud.configuration.Config; +import com.cloud.domain.dao.DomainDao; +import com.cloud.exception.InvalidParameterValueException; +import com.cloud.exception.PermissionDeniedException; +import com.cloud.user.Account; +import com.cloud.user.AccountVO; +import com.cloud.user.dao.AccountDao; +import com.cloud.utils.component.ManagerBase; +import com.cloud.utils.db.Filter; + +import org.apache.cloudstack.api.command.QuotaBalanceCmd; +import org.apache.cloudstack.api.command.QuotaCreditsCmd; +import org.apache.cloudstack.api.command.QuotaEmailTemplateUpdateCmd; +import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd; +import org.apache.cloudstack.api.command.QuotaStatementCmd; +import org.apache.cloudstack.api.command.QuotaSummaryCmd; +import org.apache.cloudstack.api.command.QuotaTariffListCmd; +import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd; +import org.apache.cloudstack.api.command.QuotaUpdateCmd; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.context.CallContext; +import org.apache.cloudstack.framework.config.ConfigKey; +import org.apache.cloudstack.framework.config.Configurable; +import org.apache.cloudstack.framework.config.dao.ConfigurationDao; +import org.apache.cloudstack.quota.constant.QuotaConfig; +import org.apache.cloudstack.quota.dao.QuotaAccountDao; +import org.apache.cloudstack.quota.dao.QuotaBalanceDao; +import org.apache.cloudstack.quota.dao.QuotaUsageDao; +import org.apache.cloudstack.quota.vo.QuotaAccountVO; +import org.apache.cloudstack.quota.vo.QuotaBalanceVO; +import org.apache.cloudstack.quota.vo.QuotaUsageVO; +import org.apache.cloudstack.utils.usage.UsageUtils; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.ejb.Local; +import javax.inject.Inject; +import javax.naming.ConfigurationException; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; + +@Component +@Local(value = QuotaService.class) +public class QuotaServiceImpl extends ManagerBase implements QuotaService, Configurable, QuotaConfig { + private static final Logger s_logger = Logger.getLogger(QuotaServiceImpl.class); + + @Inject + private AccountDao _accountDao; + @Inject + private QuotaAccountDao _quotaAcc; + @Inject + private QuotaUsageDao _quotaUsageDao; + @Inject + private DomainDao _domainDao; + @Inject + private ConfigurationDao _configDao; + @Inject + private QuotaBalanceDao _quotaBalanceDao; + @Inject + private QuotaResponseBuilder _respBldr; + + private TimeZone _usageTimezone; + private int _aggregationDuration = 0; + + public QuotaServiceImpl() { + super(); + } + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + super.configure(name, params); + String timeZoneStr = _configDao.getValue(Config.UsageAggregationTimezone.toString()); + String aggregationRange = _configDao.getValue(Config.UsageStatsJobAggregationRange.toString()); + if (timeZoneStr == null) { + timeZoneStr = "GMT"; + } + _usageTimezone = TimeZone.getTimeZone(timeZoneStr); + + _aggregationDuration = Integer.parseInt(aggregationRange); + if (_aggregationDuration < UsageUtils.USAGE_AGGREGATION_RANGE_MIN) { + s_logger.warn("Usage stats job aggregation range is to small, using the minimum value of " + UsageUtils.USAGE_AGGREGATION_RANGE_MIN); + _aggregationDuration = UsageUtils.USAGE_AGGREGATION_RANGE_MIN; + } + if (s_logger.isDebugEnabled()) { + s_logger.debug("Usage timezone = " + _usageTimezone + " AggregationDuration=" + _aggregationDuration); + } + return true; + } + + @Override + public List> getCommands() { + final List> cmdList = new ArrayList>(); + if (!isQuotaServiceEnabled()) { + return cmdList; + } + cmdList.add(QuotaStatementCmd.class); + cmdList.add(QuotaBalanceCmd.class); + cmdList.add(QuotaSummaryCmd.class); + cmdList.add(QuotaUpdateCmd.class); + cmdList.add(QuotaTariffListCmd.class); + cmdList.add(QuotaTariffUpdateCmd.class); + cmdList.add(QuotaCreditsCmd.class); + cmdList.add(QuotaEmailTemplateListCmd.class); + cmdList.add(QuotaEmailTemplateUpdateCmd.class); + return cmdList; + } + + @Override + public String getConfigComponentName() { + return "QUOTA-PLUGIN"; + } + + @Override + public ConfigKey[] getConfigKeys() { + return new ConfigKey[] { QuotaPluginEnabled, QuotaEnableEnforcement, QuotaCurrencySymbol, QuotaStatementPeriod, QuotaSmtpHost, QuotaSmtpPort, QuotaSmtpTimeout, QuotaSmtpUser, QuotaSmtpPassword, + QuotaSmtpAuthType, QuotaSmtpSender }; + } + + public Boolean isQuotaServiceEnabled() { + return QuotaPluginEnabled.value(); + } + + @Override + public List findQuotaBalanceVO(Long accountId, String accountName, Long domainId, Date startDate, Date endDate) { + if ((accountId == null) && (accountName != null) && (domainId != null)) { + Account userAccount = null; + Account caller = CallContext.current().getCallingAccount(); + if (_domainDao.isChildDomain(caller.getDomainId(), domainId)) { + Filter filter = new Filter(AccountVO.class, "id", Boolean.FALSE, null, null); + List accounts = _accountDao.listAccounts(accountName, domainId, filter); + if (!accounts.isEmpty()) { + userAccount = accounts.get(0); + } + if (userAccount != null) { + accountId = userAccount.getId(); + } else { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + } else { + throw new PermissionDeniedException("Invalid Domain Id or Account"); + } + } + + startDate = startDate == null ? new Date() : startDate; + + if (endDate == null) { + // adjust start date to end of day as there is no end date + Date adjustedStartDate = computeAdjustedTime(_respBldr.startOfNextDay(startDate)); + if (s_logger.isDebugEnabled()) { + s_logger.debug("getQuotaBalance1: Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + adjustedStartDate); + } + List qbrecords = _quotaBalanceDao.lastQuotaBalanceVO(accountId, domainId, adjustedStartDate); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Found records size=" + qbrecords.size()); + } + if (qbrecords.isEmpty()) { + s_logger.info("Incorrect Date there are no quota records before this date " + adjustedStartDate); + return qbrecords; + } else { + return qbrecords; + } + } else { + Date adjustedStartDate = computeAdjustedTime(startDate); + if (endDate.after(_respBldr.startOfNextDay())) { + throw new InvalidParameterValueException("Incorrect Date Range. End date:" + endDate + " should not be in future. "); + } else if (startDate.before(endDate)) { + Date adjustedEndDate = computeAdjustedTime(endDate); + if (s_logger.isDebugEnabled()) { + s_logger.debug("getQuotaBalance2: Getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + + adjustedEndDate); + } + List qbrecords = _quotaBalanceDao.findQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate); + if (s_logger.isDebugEnabled()) { + s_logger.debug("getQuotaBalance3: Found records size=" + qbrecords.size()); + } + if (qbrecords.isEmpty()) { + s_logger.info("There are no quota records between these dates start date " + adjustedStartDate + " and end date:" + endDate); + return qbrecords; + } else { + return qbrecords; + } + } else { + throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate); + } + } + } + + @Override + public List getQuotaUsage(Long accountId, String accountName, Long domainId, Integer usageType, Date startDate, Date endDate) { + // if accountId is not specified, use accountName and domainId + if ((accountId == null) && (accountName != null) && (domainId != null)) { + Account userAccount = null; + Account caller = CallContext.current().getCallingAccount(); + if (_domainDao.isChildDomain(caller.getDomainId(), domainId)) { + Filter filter = new Filter(AccountVO.class, "id", Boolean.FALSE, null, null); + List accounts = _accountDao.listAccounts(accountName, domainId, filter); + if (!accounts.isEmpty()) { + userAccount = accounts.get(0); + } + if (userAccount != null) { + accountId = userAccount.getId(); + } else { + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); + } + } else { + throw new PermissionDeniedException("Invalid Domain Id or Account"); + } + } + + if (startDate.after(endDate)) { + throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate); + } + if (endDate.after(_respBldr.startOfNextDay())) { + throw new InvalidParameterValueException("Incorrect Date Range. End date:" + endDate + " should not be in future. "); + } + Date adjustedEndDate = computeAdjustedTime(endDate); + Date adjustedStartDate = computeAdjustedTime(startDate); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Getting quota records for account: " + accountId + ", domainId: " + domainId + ", between " + startDate + " and " + endDate); + } + return _quotaUsageDao.findQuotaUsage(accountId, domainId, usageType, adjustedStartDate, adjustedEndDate); + } + + @Override + public Date computeAdjustedTime(final Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + TimeZone localTZ = cal.getTimeZone(); + int timezoneOffset = cal.get(Calendar.ZONE_OFFSET); + if (localTZ.inDaylightTime(date)) { + timezoneOffset += (60 * 60 * 1000); + } + cal.add(Calendar.MILLISECOND, timezoneOffset); + + Date newTime = cal.getTime(); + + Calendar calTS = Calendar.getInstance(_usageTimezone); + calTS.setTime(newTime); + timezoneOffset = calTS.get(Calendar.ZONE_OFFSET); + if (_usageTimezone.inDaylightTime(date)) { + timezoneOffset += (60 * 60 * 1000); + } + + calTS.add(Calendar.MILLISECOND, -1 * timezoneOffset); + + return calTS.getTime(); + } + + @Override + public void setLockAccount(Long accountId, Boolean state) { + QuotaAccountVO acc = _quotaAcc.findByIdQuotaAccount(accountId); + if (acc == null) { + acc = new QuotaAccountVO(accountId); + acc.setQuotaEnforce(state ? 1 : 0); + _quotaAcc.persistQuotaAccount(acc); + } else { + acc.setQuotaEnforce(state ? 1 : 0); + _quotaAcc.updateQuotaAccount(accountId, acc); + } + } + + @Override + public void setMinBalance(Long accountId, Double balance) { + QuotaAccountVO acc = _quotaAcc.findByIdQuotaAccount(accountId); + if (acc == null) { + acc = new QuotaAccountVO(accountId); + acc.setQuotaMinBalance(new BigDecimal(balance)); + _quotaAcc.persistQuotaAccount(acc); + } else { + acc.setQuotaMinBalance(new BigDecimal(balance)); + _quotaAcc.updateQuotaAccount(accountId, acc); + } + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java new file mode 100644 index 0000000..4369a8c --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaBalanceCmdTest.java @@ -0,0 +1,65 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.response.QuotaBalanceResponse; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.quota.vo.QuotaBalanceVO; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaBalanceCmdTest extends TestCase { + + @Mock + QuotaResponseBuilder responseBuilder; + + @Test + public void testQuotaBalanceCmd() throws NoSuchFieldException, IllegalAccessException { + QuotaBalanceCmd cmd = new QuotaBalanceCmd(); + Field rbField = QuotaBalanceCmd.class.getDeclaredField("_responseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + List quotaBalanceVOList = new ArrayList(); + Mockito.when(responseBuilder.getQuotaBalance(Mockito.any(cmd.getClass()))).thenReturn(quotaBalanceVOList); + Mockito.when(responseBuilder.createQuotaLastBalanceResponse(Mockito.eq(quotaBalanceVOList), Mockito.any(Date.class))).thenReturn(new QuotaBalanceResponse()); + Mockito.when(responseBuilder.createQuotaBalanceResponse(Mockito.eq(quotaBalanceVOList), Mockito.any(Date.class), Mockito.any(Date.class))).thenReturn(new QuotaBalanceResponse()); + Mockito.when(responseBuilder.startOfNextDay(Mockito.any(Date.class))).thenReturn(new Date()); + + // end date not specified + cmd.setStartDate(new Date()); + cmd.setEndDate(null); + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).createQuotaLastBalanceResponse(Mockito.eq(quotaBalanceVOList), Mockito.any(Date.class)); + Mockito.verify(responseBuilder, Mockito.times(0)).createQuotaBalanceResponse(Mockito.eq(quotaBalanceVOList), Mockito.any(Date.class), Mockito.any(Date.class)); + + // end date specified + cmd.setEndDate(new Date()); + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).createQuotaBalanceResponse(Mockito.eq(quotaBalanceVOList), Mockito.any(Date.class), Mockito.any(Date.class)); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java new file mode 100644 index 0000000..f4d16b7 --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaCreditsCmdTest.java @@ -0,0 +1,87 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import com.cloud.user.AccountService; +import com.cloud.user.AccountVO; + +import junit.framework.TestCase; + +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.BaseCmd; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.QuotaCreditsResponse; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.quota.QuotaService; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaCreditsCmdTest extends TestCase { + @Mock + QuotaResponseBuilder responseBuilder; + @Mock + QuotaService quotaService; + @Mock + AccountService accountService; + + @Test + public void testQuotaCreditsCmd() throws NoSuchFieldException, IllegalAccessException { + QuotaCreditsCmd cmd = new QuotaCreditsCmd(); + cmd.setAccountName("admin"); + cmd.setMinBalance(200.0); + + Field rbField = QuotaCreditsCmd.class.getDeclaredField("_responseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + Field qsbField = QuotaCreditsCmd.class.getDeclaredField("_quotaService"); + qsbField.setAccessible(true); + qsbField.set(cmd, quotaService); + + Field asField = BaseCmd.class.getDeclaredField("_accountService"); + asField.setAccessible(true); + asField.set(cmd, accountService); + + AccountVO acc = new AccountVO(); + acc.setId(2L); + Mockito.when(accountService.getActiveAccountByName(Mockito.anyString(), Mockito.anyLong())).thenReturn(acc); + Mockito.when(responseBuilder.addQuotaCredits(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyDouble(), Mockito.anyLong())).thenReturn(new QuotaCreditsResponse()); + + // No value provided test + try { + cmd.execute(); + } catch (ServerApiException e) { + assertTrue(e.getErrorCode().equals(ApiErrorCode.PARAM_ERROR)); + } + + // With value provided test + cmd.setValue(11.80); + cmd.execute(); + Mockito.verify(quotaService, Mockito.times(0)).setLockAccount(Mockito.anyLong(), Mockito.anyBoolean()); + Mockito.verify(quotaService, Mockito.times(1)).setMinBalance(Mockito.anyLong(), Mockito.anyDouble()); + Mockito.verify(responseBuilder, Mockito.times(1)).addQuotaCredits(Mockito.anyLong(), Mockito.anyLong(), Mockito.anyDouble(), Mockito.anyLong()); + + + } + +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java new file mode 100644 index 0000000..aecee6b --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateListCmdTest.java @@ -0,0 +1,50 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.response.QuotaEmailTemplateResponse; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaEmailTemplateListCmdTest extends TestCase { + + @Mock + QuotaResponseBuilder responseBuilder; + + @Test + public void testQuotaEmailTemplateListCmd() throws NoSuchFieldException, IllegalAccessException { + QuotaEmailTemplateListCmd cmd = new QuotaEmailTemplateListCmd(); + Field rbField = QuotaEmailTemplateListCmd.class.getDeclaredField("_quotaResponseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + List responses = new ArrayList(); + Mockito.when(responseBuilder.listQuotaEmailTemplates(Mockito.eq(cmd))).thenReturn(responses); + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).listQuotaEmailTemplates(cmd); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java new file mode 100644 index 0000000..a357a18 --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaEmailTemplateUpdateCmdTest.java @@ -0,0 +1,68 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.quota.constant.QuotaConfig; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaEmailTemplateUpdateCmdTest extends TestCase { + @Mock + QuotaResponseBuilder responseBuilder; + + @Test + public void testQuotaEmailTemplateUpdateCmd () throws NoSuchFieldException, IllegalAccessException { + QuotaEmailTemplateUpdateCmd cmd = new QuotaEmailTemplateUpdateCmd(); + + Field rbField = QuotaEmailTemplateUpdateCmd.class.getDeclaredField("_quotaResponseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + // templatename parameter check + try { + cmd.execute(); + } catch (ServerApiException e) { + assertTrue(e.getErrorCode().equals(ApiErrorCode.PARAM_ERROR)); + } + + // invalid template name test + cmd.setTemplateName("randomTemplate"); + cmd.setTemplateBody("some body"); + cmd.setTemplateSubject("some subject"); + try { + cmd.execute(); + } catch (ServerApiException e) { + assertTrue(e.getErrorCode().equals(ApiErrorCode.PARAM_ERROR)); + } + + // valid template test + cmd.setTemplateName(QuotaConfig.QuotaEmailTemplateTypes.QUOTA_EMPTY.toString()); + Mockito.when(responseBuilder.updateQuotaEmailTemplate(Mockito.eq(cmd))).thenReturn(true); + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).updateQuotaEmailTemplate(Mockito.eq(cmd)); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java new file mode 100644 index 0000000..0492ae8 --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaStatementCmdTest.java @@ -0,0 +1,53 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.api.response.QuotaStatementResponse; +import org.apache.cloudstack.quota.vo.QuotaUsageVO; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaStatementCmdTest extends TestCase { + @Mock + QuotaResponseBuilder responseBuilder; + + @Test + public void testQuotaStatementCmd() throws NoSuchFieldException, IllegalAccessException { + QuotaStatementCmd cmd = new QuotaStatementCmd(); + cmd.setAccountName("admin"); + + Field rbField = QuotaStatementCmd.class.getDeclaredField("_responseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + List quotaUsageVOList = new ArrayList(); + Mockito.when(responseBuilder.getQuotaUsage(Mockito.eq(cmd))).thenReturn(quotaUsageVOList); + Mockito.when(responseBuilder.createQuotaStatementResponse(Mockito.eq(quotaUsageVOList))).thenReturn(new QuotaStatementResponse()); + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).getQuotaUsage(Mockito.eq(cmd)); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java new file mode 100644 index 0000000..5781103 --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffListCmdTest.java @@ -0,0 +1,62 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.api.response.QuotaTariffResponse; +import org.apache.cloudstack.quota.constant.QuotaTypes; +import org.apache.cloudstack.quota.vo.QuotaTariffVO; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaTariffListCmdTest extends TestCase { + @Mock + QuotaResponseBuilder responseBuilder; + + @Test + public void testQuotaTariffListCmd() throws NoSuchFieldException, IllegalAccessException { + QuotaTariffListCmd cmd = new QuotaTariffListCmd(); + + Field rbField = QuotaTariffListCmd.class.getDeclaredField("_responseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + List quotaTariffVOList = new ArrayList(); + QuotaTariffVO tariff = new QuotaTariffVO(); + tariff.setEffectiveOn(new Date()); + tariff.setCurrencyValue(new BigDecimal(100)); + tariff.setUsageType(QuotaTypes.MEMORY); + + quotaTariffVOList.add(new QuotaTariffVO()); + Mockito.when(responseBuilder.listQuotaTariffPlans(Mockito.eq(cmd))).thenReturn(quotaTariffVOList); + Mockito.when(responseBuilder.createQuotaTariffResponse(Mockito.any(QuotaTariffVO.class))).thenReturn(new QuotaTariffResponse()); + + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).createQuotaTariffResponse(Mockito.any(QuotaTariffVO.class)); + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/987fcbd4/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java ---------------------------------------------------------------------- diff --git a/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java new file mode 100644 index 0000000..dc50af1 --- /dev/null +++ b/plugins/database/quota/test/org/apache/cloudstack/api/command/QuotaTariffUpdateCmdTest.java @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. +package org.apache.cloudstack.api.command; + +import junit.framework.TestCase; +import org.apache.cloudstack.api.ApiErrorCode; +import org.apache.cloudstack.api.ServerApiException; +import org.apache.cloudstack.api.response.QuotaResponseBuilder; +import org.apache.cloudstack.api.response.QuotaTariffResponse; +import org.apache.cloudstack.quota.constant.QuotaTypes; +import org.apache.cloudstack.quota.vo.QuotaTariffVO; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.runners.MockitoJUnitRunner; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.Date; + +@RunWith(MockitoJUnitRunner.class) +public class QuotaTariffUpdateCmdTest extends TestCase { + + @Mock + QuotaResponseBuilder responseBuilder; + + @Test + public void testQuotaTariffUpdateCmd() throws NoSuchFieldException, IllegalAccessException { + QuotaTariffUpdateCmd cmd = new QuotaTariffUpdateCmd(); + + Field rbField = QuotaTariffUpdateCmd.class.getDeclaredField("_responseBuilder"); + rbField.setAccessible(true); + rbField.set(cmd, responseBuilder); + + QuotaTariffVO tariff = new QuotaTariffVO(); + tariff.setEffectiveOn(new Date()); + tariff.setCurrencyValue(new BigDecimal(100)); + tariff.setUsageType(QuotaTypes.MEMORY); + + Mockito.when(responseBuilder.updateQuotaTariffPlan(Mockito.eq(cmd))).thenReturn(null); + try { + cmd.execute(); + } catch (ServerApiException e) { + assertTrue(e.getErrorCode().equals(ApiErrorCode.INTERNAL_ERROR)); + } + + Mockito.when(responseBuilder.updateQuotaTariffPlan(Mockito.eq(cmd))).thenReturn(tariff); + Mockito.when(responseBuilder.createQuotaTariffResponse(Mockito.eq(tariff))).thenReturn(new QuotaTariffResponse()); + cmd.execute(); + Mockito.verify(responseBuilder, Mockito.times(1)).createQuotaTariffResponse(Mockito.eq(tariff)); + } +}