cloudstack-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From r...@apache.org
Subject [3/8] git commit: updated refs/heads/master to 24d0609
Date Mon, 07 Dec 2015 18:25:33 GMT
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<QuotaSummaryResponse> createQuotaSummaryResponse(final String accountName, final Long domainId) {
+        List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>();
+
+        if (accountName != null && domainId != null) {
+            Account account = _accountDao.findActiveAccount(accountName, domainId);
+            QuotaSummaryResponse qr = getQuotaSummaryResponse(account);
+            result.add(qr);
+        }
+
+        return result;
+    }
+
+    @Override
+    public List<QuotaSummaryResponse> createQuotaSummaryResponse(Boolean listAll) {
+        List<QuotaSummaryResponse> result = new ArrayList<QuotaSummaryResponse>();
+
+        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<QuotaBalanceVO> 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<QuotaBalanceVO>() {
+            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<QuotaBalanceVO> 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<QuotaBalanceVO> 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<QuotaBalanceVO> 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<QuotaUsageVO> quotaUsage) {
+        if (quotaUsage == null || quotaUsage.isEmpty()) {
+            throw new InvalidParameterValueException("There is no usage data found for period mentioned.");
+        }
+
+        QuotaStatementResponse statement = new QuotaStatementResponse();
+
+        HashMap<Integer, QuotaTypes> quotaTariffMap = new HashMap<Integer, QuotaTypes>();
+        Collection<QuotaTypes> 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<QuotaUsageVO>() {
+            public int compare(QuotaUsageVO o1, QuotaUsageVO o2) {
+                if (o1.getUsageType() == o2.getUsageType())
+                    return 0;
+                return o1.getUsageType() < o2.getUsageType() ? -1 : 1;
+            }
+        });
+
+        List<QuotaStatementItemResponse> items = new ArrayList<QuotaStatementItemResponse>();
+        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<QuotaTariffVO> listQuotaTariffPlans(final QuotaTariffListCmd cmd) {
+        List<QuotaTariffVO> result = new ArrayList<QuotaTariffVO>();
+        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<QuotaEmailTemplateResponse> listQuotaEmailTemplates(QuotaEmailTemplateListCmd cmd) {
+        final String templateName = cmd.getTemplateName();
+        List<QuotaEmailTemplatesVO> templates = _quotaEmailTemplateDao.listAllQuotaEmailTemplates(templateName);
+        final List<QuotaEmailTemplateResponse> responses = new ArrayList<QuotaEmailTemplateResponse>();
+        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<QuotaEmailTemplatesVO> 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<QuotaBalanceVO> 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<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd) {
+        return _quotaService.getQuotaUsage(cmd.getAccountId(), cmd.getAccountName(), cmd.getDomainId(), cmd.getUsageType(), cmd.getStartDate(), cmd.getEndDate());
+    }
+
+    @Override
+    public List<QuotaBalanceVO> 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<QuotaStatementItemResponse> 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<QuotaStatementItemResponse> getLineItem() {
+        return lineItem;
+    }
+
+    public void setLineItem(List<QuotaStatementItemResponse> 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<QuotaUsageVO> getQuotaUsage(Long accountId, String accountName, Long domainId, Integer usageType, Date startDate, Date endDate);
+
+    List<QuotaBalanceVO> 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<String, Object> 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<Class<?>> getCommands() {
+        final List<Class<?>> cmdList = new ArrayList<Class<?>>();
+        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<QuotaBalanceVO> 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<AccountVO> 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<QuotaBalanceVO> 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<QuotaBalanceVO> 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<QuotaUsageVO> 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<AccountVO> 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<QuotaBalanceVO> quotaBalanceVOList = new ArrayList<QuotaBalanceVO>();
+        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<QuotaEmailTemplateResponse> responses = new ArrayList<QuotaEmailTemplateResponse>();
+        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<QuotaUsageVO> quotaUsageVOList = new ArrayList<QuotaUsageVO>();
+        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<QuotaTariffVO> quotaTariffVOList = new ArrayList<QuotaTariffVO>();
+        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));
+    }
+}


Mime
View raw message