CLOUDSTACK-8592: first cut implementation of quota statement

This commit is contained in:
Abhinandan Prateek 2015-07-14 11:15:55 +05:30
parent 7dd68a1493
commit ae0eb6e334
10 changed files with 500 additions and 166 deletions

View File

@ -16,17 +16,27 @@
//under the License.
package org.apache.cloudstack.api.command;
import java.util.Date;
import java.util.List;
import javax.inject.Inject;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseListCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.response.AccountResponse;
import org.apache.cloudstack.api.response.DomainResponse;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.quota.QuotaDBUtils;
import org.apache.cloudstack.quota.QuotaManager;
import org.apache.cloudstack.quota.QuotaUsageVO;
import org.apache.cloudstack.api.response.QuotaStatementResponse;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
@APICommand(name = "quotaStatement", responseObject = QuotaStatementResponse.class, description = "Create a quota statement", since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
public class QuotaStatementCmd extends BaseListCmd {
@ -35,12 +45,77 @@ public class QuotaStatementCmd extends BaseListCmd {
private static final String s_name = "quotastatementresponse";
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required=true, description = "Optional, Account Id for which statement needs to be generated")
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Optional, Account Id for which statement needs to be generated")
private String accountName;
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required=true, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.")
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Optional, If domain Id is given and the caller is domain admin then the statement is generated for domain.")
private Long domainId;
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, required = true, description = "End date range for quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.")
private Date endDate;
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = true, description = "Start date range quota query. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-01.")
private Date startDate;
@Parameter(name = ApiConstants.TYPE, type = CommandType.INTEGER, description = "List quota usage records for the specified usage type")
private Integer usageType;
@Parameter(name = ApiConstants.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account")
private Long accountId;
@Inject
QuotaManager _quotaManager;
@Inject
QuotaDBUtils _quotaDBUtils;
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public Integer getUsageType() {
return usageType;
}
public void setUsageType(Integer usageType) {
this.usageType = usageType;
}
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 Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public QuotaStatementCmd() {
super();
}
@ -61,21 +136,12 @@ public class QuotaStatementCmd extends BaseListCmd {
@Override
public void execute() {
/**
* final Pair<List<QuotaConfigurationVO>, Integer> result =
* _quotaManager.listConfigurations(this);
*
* final List<QuotaStatementResponse> responses = new
* ArrayList<QuotaStatementResponse>(); for (final QuotaConfigurationVO
* resource : result.first()) { final QuotaStatementResponse
* configurationResponse =
* _quotaManager.createQuotaConfigurationResponse(resource);
* configurationResponse.setObjectName("QuotaConfiguration");
* responses.add(configurationResponse); }
**/
Pair<List<QuotaUsageVO>, Integer> result = _quotaManager.getQuotaUsage(this);
List<QuotaStatementResponse> responses = _quotaDBUtils.createQuotaStatementResponse(result.first());
final ListResponse<QuotaStatementResponse> response = new ListResponse<QuotaStatementResponse>();
// response.setResponses(responses, responses.size());
response.setResponses(responses, responses.size());
response.setResponseName(getCommandName());
setResponseObject(response);
}

View File

@ -16,6 +16,9 @@
//under the License.
package org.apache.cloudstack.api.response;
import java.math.BigDecimal;
import java.util.Date;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.api.BaseResponse;
@ -24,85 +27,80 @@ import com.cloud.serializer.Param;
public class QuotaStatementResponse extends BaseResponse {
@SerializedName("usageType")
@Param(description = "usageType")
private String usageType;
@SerializedName("type")
@Param(description = "usage type")
private int usageType;
@SerializedName("usageUnit")
@Param(description = "usageUnit")
@SerializedName("unit")
@Param(description = "usage unit")
private String usageUnit;
@SerializedName("usageDiscriminator")
@Param(description = "usageDiscriminator")
private String usageDiscriminator;
@SerializedName("quota")
@Param(description = "quota consumed")
private BigDecimal quotaUsed;
@SerializedName("currencyValue")
@Param(description = "currencyValue")
private int currencyValue;
@SerializedName("startdate")
@Param(description = "start date")
private Date startDate = null;
@SerializedName("include")
@Param(description = "include")
private int include;
@SerializedName("enddate")
@Param(description = "end date")
private Date endDate = null;
@SerializedName("description")
@Param(description = "description")
private String description;
public QuotaStatementResponse() {
super();
}
public QuotaStatementResponse(final String usageType) {
super();
this.usageType = usageType;
}
public String getUsageType() {
public int getUsageType() {
return usageType;
}
public void setUsageType(String 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 BigDecimal getQuotaUsed() {
return quotaUsed;
}
public void setUsageDiscriminator(String usageDiscriminator) {
this.usageDiscriminator = usageDiscriminator;
public void setQuotaUsed(BigDecimal quotaUsed) {
this.quotaUsed = quotaUsed;
}
public int getCurrencyValue() {
return currencyValue;
public Date getStartDate() {
return startDate;
}
public void setCurrencyValue(int currencyValue) {
this.currencyValue = currencyValue;
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public int getInclude() {
return include;
public Date getEndDate() {
return endDate;
}
public void setInclude(int include) {
this.include = include;
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}

View File

@ -22,11 +22,11 @@ import org.apache.cloudstack.api.command.QuotaEditMappingCmd;
import org.apache.cloudstack.api.command.QuotaMapping;
import org.apache.cloudstack.api.response.QuotaConfigurationResponse;
import org.apache.cloudstack.api.response.QuotaCreditsResponse;
import org.apache.cloudstack.api.response.QuotaStatementResponse;
import com.cloud.utils.Pair;
import com.cloud.utils.component.PluggableService;
public interface QuotaDBUtils extends PluggableService {
public interface QuotaDBUtils {
Pair<List<QuotaMappingVO>, Integer> editQuotaMapping(QuotaEditMappingCmd cmd);
@ -34,7 +34,8 @@ public interface QuotaDBUtils extends PluggableService {
QuotaConfigurationResponse createQuotaConfigurationResponse(QuotaMappingVO configuration);
List<QuotaStatementResponse> createQuotaStatementResponse(List<QuotaUsageVO> quotaUsage);
QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Integer amount, Long updatedBy);
}

View File

@ -17,7 +17,11 @@
package org.apache.cloudstack.quota;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.ejb.Local;
@ -27,6 +31,7 @@ import org.apache.cloudstack.api.command.QuotaEditMappingCmd;
import org.apache.cloudstack.api.command.QuotaMapping;
import org.apache.cloudstack.api.response.QuotaConfigurationResponse;
import org.apache.cloudstack.api.response.QuotaCreditsResponse;
import org.apache.cloudstack.api.response.QuotaStatementResponse;
import org.apache.cloudstack.quota.dao.QuotaMappingDao;
import org.apache.cloudstack.quota.dao.QuotaCreditsDao;
import org.apache.log4j.Logger;
@ -38,7 +43,7 @@ import com.cloud.utils.db.TransactionLegacy;
@Component
@Local(value = QuotaDBUtilsImpl.class)
public class QuotaDBUtilsImpl {
public class QuotaDBUtilsImpl implements QuotaDBUtils {
private static final Logger s_logger = Logger.getLogger(QuotaDBUtilsImpl.class.getName());
@Inject
@ -47,8 +52,8 @@ public class QuotaDBUtilsImpl {
@Inject
private QuotaCreditsDao _quotaCreditsDao;
public QuotaConfigurationResponse createQuotaConfigurationResponse(final QuotaMappingVO configuration) {
@Override
public QuotaConfigurationResponse createQuotaConfigurationResponse(QuotaMappingVO configuration) {
final QuotaConfigurationResponse response = new QuotaConfigurationResponse();
response.setUsageType(configuration.getUsageType());
response.setUsageName(configuration.getUsageName());
@ -60,12 +65,54 @@ public class QuotaDBUtilsImpl {
return response;
}
@Override
public List<QuotaStatementResponse> createQuotaStatementResponse(List<QuotaUsageVO> quotaUsage) {
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
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;
}
});
HashMap<Integer, String> map = new HashMap<Integer, String>();
List<QuotaMappingVO> result = _quotaMappingDao.listAll();
for (QuotaMappingVO mapping : result) {
map.put(mapping.getUsageType(), mapping.getUsageUnit());
}
List<QuotaStatementResponse> statement = new ArrayList<QuotaStatementResponse>();
QuotaStatementResponse lineitem;
int type = -1;
BigDecimal totalUsage = new BigDecimal(0);
for (final QuotaUsageVO quotaRecord : quotaUsage) {
if (type != quotaRecord.getUsageType()) {
if (type != -1) {
lineitem = new QuotaStatementResponse();
lineitem.setUsageType(type);
lineitem.setQuotaUsed(totalUsage);
lineitem.setUsageUnit(map.get(type));
statement.add(lineitem);
totalUsage = new BigDecimal(0);
}
type = quotaRecord.getUsageType();
}
totalUsage = totalUsage.add(quotaRecord.getQuotaUsed());
}
TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
return statement;
}
@Override
public Pair<List<QuotaMappingVO>, Integer> listConfigurations(final QuotaMapping cmd) {
final Pair<List<QuotaMappingVO>, Integer> result = _quotaMappingDao.listAllMapping();
TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
return result;
}
@Override
public Pair<List<QuotaMappingVO>, Integer> editQuotaMapping(QuotaEditMappingCmd cmd) {
int resourceType = cmd.getUsageType();
BigDecimal quotaCost = new BigDecimal(cmd.getValue());
@ -86,6 +133,7 @@ public class QuotaDBUtilsImpl {
return result;
}
@Override
public QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Integer amount, Long updatedBy) {
QuotaCreditsVO result = null;
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
@ -100,5 +148,4 @@ public class QuotaDBUtilsImpl {
return new QuotaCreditsResponse(result);
}
}

View File

@ -16,10 +16,18 @@
//under the License.
package org.apache.cloudstack.quota;
import java.util.List;
import org.apache.cloudstack.api.command.QuotaStatementCmd;
import com.cloud.utils.Pair;
import com.cloud.utils.component.PluggableService;
public interface QuotaManager extends PluggableService {
public void calculateQuotaUsage();
public Pair<List<QuotaUsageVO>,Integer> getQuotaUsage(QuotaStatementCmd cmd);
}

View File

@ -19,11 +19,16 @@ package org.apache.cloudstack.quota;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.apache.cloudstack.api.command.QuotaMapping;
import org.apache.cloudstack.api.command.QuotaCreditsCmd;
@ -31,18 +36,26 @@ import org.apache.cloudstack.api.command.QuotaEditMappingCmd;
import org.apache.cloudstack.api.command.QuotaEmailTemplateAddCmd;
import org.apache.cloudstack.api.command.QuotaRefreshCmd;
import org.apache.cloudstack.api.command.QuotaStatementCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
import org.apache.cloudstack.quota.dao.QuotaMappingDao;
import org.apache.cloudstack.quota.dao.QuotaUsageDao;
import org.apache.cloudstack.utils.usage.UsageUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import com.cloud.configuration.Config;
import com.cloud.domain.dao.DomainDao;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.usage.UsageVO;
import com.cloud.usage.dao.UsageDao;
import com.cloud.user.Account;
import com.cloud.user.AccountService;
import com.cloud.user.AccountVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.utils.Pair;
@ -54,7 +67,7 @@ import com.cloud.utils.db.TransactionLegacy;
@Component
@Local(value = QuotaManager.class)
public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Configurable, QuotaConfig, Runnable {
public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Configurable, QuotaConfig {
private static final Logger s_logger = Logger.getLogger(QuotaManagerImpl.class.getName());
@Inject
@ -67,14 +80,43 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
private QuotaUsageDao _quotaUsageDao;
@Inject
private ServiceOfferingDao _serviceOfferingDao;
@Inject
private DomainDao _domainDao;
@Inject
private ConfigurationDao _configDao;
@Inject
private AccountService _accountService;
static BigDecimal s_hoursInMonth = new BigDecimal(30.00 * 24.00);
private TimeZone _usageTimezone;
private int _aggregationDuration = 0;
static BigDecimal s_hoursInMonth = new BigDecimal(30 * 24);
static BigDecimal s_minutesInMonth = new BigDecimal(30 * 24 * 60);
static BigDecimal s_gb = new BigDecimal(1024 * 1024 * 1024);
public QuotaManagerImpl() {
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;
}
s_logger.info("Usage timezone = " + _usageTimezone + " AggregationDuration=" + _aggregationDuration);
return true;
}
@Override
public List<Class<?>> getCommands() {
final List<Class<?>> cmdList = new ArrayList<Class<?>>();
@ -116,53 +158,56 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
s_logger.info("Account =" + account.getAccountName());
Pair<List<? extends UsageVO>, Integer> usageRecords = getUsageRecords(account.getAccountId(), account.getDomainId());
s_logger.debug("Usage records found " + usageRecords.second());
for (UsageVO usageRecord : usageRecords.first()) {
s_logger.info("Type=" + usageRecord.getUsageType());
BigDecimal aggregationRatio = new BigDecimal(_aggregationDuration).divide(s_minutesInMonth, 8, RoundingMode.HALF_EVEN);
switch (usageRecord.getUsageType()) {
case QuotaTypes.RUNNING_VM:
updateQuotaRunningVMUsage(usageRecord, mapping);
updateQuotaRunningVMUsage(usageRecord, mapping, aggregationRatio);
break;
case QuotaTypes.ALLOCATED_VM:
updateQuotaAllocatedVMUsage(usageRecord, mapping);
updateQuotaAllocatedVMUsage(usageRecord, mapping, aggregationRatio);
break;
case QuotaTypes.SNAPSHOT:
updateQuotaDiskUsage(usageRecord, mapping, QuotaTypes.SNAPSHOT);
updateQuotaDiskUsage(usageRecord, mapping, aggregationRatio, QuotaTypes.SNAPSHOT);
break;
case QuotaTypes.TEMPLATE:
updateQuotaDiskUsage(usageRecord, mapping, QuotaTypes.TEMPLATE);
updateQuotaDiskUsage(usageRecord, mapping, aggregationRatio, QuotaTypes.TEMPLATE);
break;
case QuotaTypes.ISO:
updateQuotaDiskUsage(usageRecord, mapping, QuotaTypes.ISO);
updateQuotaDiskUsage(usageRecord, mapping, aggregationRatio, QuotaTypes.ISO);
break;
case QuotaTypes.VOLUME:
updateQuotaDiskUsage(usageRecord, mapping, QuotaTypes.VOLUME);
updateQuotaDiskUsage(usageRecord, mapping, aggregationRatio, QuotaTypes.VOLUME);
break;
case QuotaTypes.VM_SNAPSHOT:
updateQuotaDiskUsage(usageRecord, mapping, QuotaTypes.VM_SNAPSHOT);
updateQuotaDiskUsage(usageRecord, mapping, aggregationRatio, QuotaTypes.VM_SNAPSHOT);
break;
case QuotaTypes.LOAD_BALANCER_POLICY:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.LOAD_BALANCER_POLICY);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.LOAD_BALANCER_POLICY);
break;
case QuotaTypes.PORT_FORWARDING_RULE:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.PORT_FORWARDING_RULE);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.PORT_FORWARDING_RULE);
break;
case QuotaTypes.IP_ADDRESS:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.IP_ADDRESS);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.IP_ADDRESS);
break;
case QuotaTypes.NETWORK_OFFERING:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.NETWORK_OFFERING);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.NETWORK_OFFERING);
break;
case QuotaTypes.SECURITY_GROUP:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.SECURITY_GROUP);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.SECURITY_GROUP);
break;
case QuotaTypes.VPN_USERS:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.VPN_USERS);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.VPN_USERS);
break;
case QuotaTypes.NETWORK_BYTES_RECEIVED:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.NETWORK_BYTES_RECEIVED);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.NETWORK_BYTES_RECEIVED);
break;
case QuotaTypes.NETWORK_BYTES_SENT:
updateQuotaRaw(usageRecord, mapping, QuotaTypes.NETWORK_BYTES_SENT);
updateQuotaRaw(usageRecord, mapping, aggregationRatio, QuotaTypes.NETWORK_BYTES_SENT);
break;
case QuotaTypes.VM_DISK_IO_READ:
case QuotaTypes.VM_DISK_IO_WRITE:
@ -182,19 +227,127 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
}
}
@SuppressWarnings("deprecation")
@Override
public Pair<List<QuotaUsageVO>, Integer> getQuotaUsage(QuotaStatementCmd cmd) {
Long accountId = cmd.getAccountId();
String accountName = cmd.getAccountName();
Long domainId = cmd.getDomainId();
Account userAccount = null;
Account caller = CallContext.current().getCallingAccount();
Integer usageType = cmd.getUsageType();
// if accountId is not specified, use accountName and domainId
if ((accountId == null) && (accountName != null) && (domainId != null)) {
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.size() > 0) {
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");
}
}
boolean isAdmin = false;
boolean isDomainAdmin = false;
// If accountId couldn't be found using accountName and domainId, get it
// from userContext
if (accountId == null) {
accountId = caller.getId();
// List records for all the accounts if the caller account is of
// type admin.
// If account_id or account_name is explicitly mentioned, list
// records for the specified account only even if the caller is of
// type admin
if (_accountService.isRootAdmin(caller.getId())) {
isAdmin = true;
} else if (_accountService.isDomainAdmin(caller.getId())) {
isDomainAdmin = true;
}
s_logger.debug("Account details not available. Using userContext accountId: " + accountId);
}
Date startDate = cmd.getStartDate();
Date endDate = cmd.getEndDate();
if (startDate.after(endDate)) {
throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate);
}
TimeZone usageTZ = getUsageTimezone();
Date adjustedStartDate = computeAdjustedTime(startDate, usageTZ);
Date adjustedEndDate = computeAdjustedTime(endDate, usageTZ);
s_logger.debug("getting quota records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate + ", using pageSize: "
+ cmd.getPageSizeVal() + " and startIndex: " + cmd.getStartIndex());
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
Pair<List<QuotaUsageVO>, Integer> quotaUsageRecords = null;
try {
Filter usageFilter = new Filter(QuotaUsageVO.class, "id", true, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchCriteria<QuotaUsageVO> sc = _quotaUsageDao.createSearchCriteria();
if (accountId != null) {
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
s_logger.debug("Account ID=" + accountId);
}
/*
* if (isDomainAdmin) { SearchCriteria<DomainVO> sdc =
* _domainDao.createSearchCriteria(); sdc.addOr("path",
* SearchCriteria.Op.LIKE,
* _domainDao.findById(caller.getDomainId()).getPath() + "%");
* List<DomainVO> domains = _domainDao.search(sdc, null); List<Long>
* domainIds = new ArrayList<Long>(); for (DomainVO domain :
* domains) domainIds.add(domain.getId()); sc.addAnd("domainId",
* SearchCriteria.Op.IN, domainIds.toArray());
* s_logger.debug("Account ID=" + accountId); }
*/
if (domainId != null) {
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
s_logger.debug("Domain ID=" + domainId);
}
if (usageType != null) {
sc.addAnd("usageType", SearchCriteria.Op.EQ, usageType);
s_logger.debug("usageType ID=" + usageType);
}
if ((adjustedStartDate != null) && (adjustedEndDate != null) && adjustedStartDate.before(adjustedEndDate)) {
sc.addAnd("startDate", SearchCriteria.Op.BETWEEN, adjustedStartDate, adjustedEndDate);
sc.addAnd("endDate", SearchCriteria.Op.BETWEEN, adjustedStartDate, adjustedEndDate);
s_logger.debug("start Date=" + adjustedStartDate + ", enddate=" + adjustedEndDate);
} else {
s_logger.debug("Screwed up start Date=" + adjustedStartDate + ", enddate=" + adjustedEndDate);
return new Pair<List<QuotaUsageVO>, Integer>(new ArrayList<QuotaUsageVO>(), new Integer(0));
}
quotaUsageRecords = _quotaUsageDao.searchAndCountAllRecords(sc, usageFilter);
} finally {
txn.close();
}
// switch back to VMOPS_DB
TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
return quotaUsageRecords;
}
@DB
private void updateQuotaDiskUsage(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, int quotaType) {
private void updateQuotaDiskUsage(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, BigDecimal aggregationRatio, int quotaType) {
if (mapping.get(quotaType) != null) {
QuotaUsageVO quota_usage;
BigDecimal quotaUsgage;
BigDecimal onehourcostpergb;
BigDecimal noofgbinuse;
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getTemplateId() + ", " + usageRecord.getUsageDisplay());
onehourcostpergb = mapping.get(quotaType).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
noofgbinuse = new BigDecimal(usageRecord.getSize()).divide(s_gb, 4, RoundingMode.HALF_EVEN);
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getTemplateId() + ", " + usageRecord.getUsageDisplay()
+ ", aggrR=" + aggregationRatio);
onehourcostpergb = mapping.get(quotaType).getCurrencyValue().multiply(aggregationRatio);
noofgbinuse = new BigDecimal(usageRecord.getSize()).divide(s_gb, 8, RoundingMode.HALF_EVEN);
quotaUsgage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostpergb).multiply(noofgbinuse);
s_logger.info(" No of GB In use = " + noofgbinuse + " onehour cost=" + onehourcostpergb);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getUsageType(), quotaUsgage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), usageRecord.getUsageType(), quotaUsgage,
usageRecord.getStartDate(), usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
usageRecord.setQuotaCalculated(1);
@ -202,41 +355,46 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
}
@DB
private void updateQuotaRunningVMUsage(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping) {
private void updateQuotaRunningVMUsage(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, BigDecimal aggregationRatio) {
QuotaUsageVO quota_usage;
BigDecimal cpuquotausgage, speedquotausage, memoryquotausage, vmusage;
BigDecimal onehourcostpercpu, onehourcostper100mhz, onehourcostper1mb, onehourcostforvmusage;
BigDecimal rawusage;
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getVmInstanceId() + ", " + usageRecord.getUsageDisplay());
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getVmInstanceId() + ", " + usageRecord.getUsageDisplay()
+ ", aggrR=" + aggregationRatio);
// get service offering details
ServiceOfferingVO serviceoffering = findServiceOffering(usageRecord.getVmInstanceId(), usageRecord.getOfferingId());
rawusage = new BigDecimal(usageRecord.getRawUsage());
if (mapping.get(QuotaTypes.CPU_NUMBER) == null) {
if (mapping.get(QuotaTypes.CPU_NUMBER) != null) {
BigDecimal cpu = new BigDecimal(serviceoffering.getCpu());
onehourcostpercpu = mapping.get(QuotaTypes.CPU_NUMBER).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
onehourcostpercpu = mapping.get(QuotaTypes.CPU_NUMBER).getCurrencyValue().multiply(aggregationRatio);
cpuquotausgage = rawusage.multiply(onehourcostpercpu).multiply(cpu);
quota_usage = new QuotaUsageVO(usageRecord.getId(), QuotaTypes.CPU_NUMBER, cpuquotausgage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_NUMBER, cpuquotausgage,
usageRecord.getStartDate(), usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
if (mapping.get(QuotaTypes.CPU_CLOCK_RATE) == null) {
if (mapping.get(QuotaTypes.CPU_CLOCK_RATE) != null) {
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed() / 100.00);
onehourcostper100mhz = mapping.get(QuotaTypes.CPU_CLOCK_RATE).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
onehourcostper100mhz = mapping.get(QuotaTypes.CPU_CLOCK_RATE).getCurrencyValue().multiply(aggregationRatio);
speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed);
quota_usage = new QuotaUsageVO(usageRecord.getId(), QuotaTypes.CPU_CLOCK_RATE, speedquotausage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_CLOCK_RATE, speedquotausage,
usageRecord.getStartDate(), usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
if (mapping.get(QuotaTypes.MEMORY) == null) {
if (mapping.get(QuotaTypes.MEMORY) != null) {
BigDecimal memory = new BigDecimal(serviceoffering.getRamSize());
onehourcostper1mb = mapping.get(QuotaTypes.MEMORY).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
onehourcostper1mb = mapping.get(QuotaTypes.MEMORY).getCurrencyValue().multiply(aggregationRatio);
memoryquotausage = rawusage.multiply(onehourcostper1mb).multiply(memory);
quota_usage = new QuotaUsageVO(usageRecord.getId(), QuotaTypes.MEMORY, memoryquotausage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.MEMORY, memoryquotausage,
usageRecord.getStartDate(), usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
if (mapping.get(QuotaTypes.RUNNING_VM) == null) {
onehourcostforvmusage = mapping.get(QuotaTypes.RUNNING_VM).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
if (mapping.get(QuotaTypes.RUNNING_VM) != null) {
onehourcostforvmusage = mapping.get(QuotaTypes.RUNNING_VM).getCurrencyValue().multiply(aggregationRatio);
vmusage = rawusage.multiply(onehourcostforvmusage);
quota_usage = new QuotaUsageVO(usageRecord.getId(), QuotaTypes.RUNNING_VM, vmusage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.RUNNING_VM, vmusage,
usageRecord.getStartDate(), usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
@ -245,17 +403,18 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
}
@DB
private void updateQuotaAllocatedVMUsage(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping) {
private void updateQuotaAllocatedVMUsage(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, BigDecimal aggregationRatio) {
if (mapping.get(QuotaTypes.ALLOCATED_VM) != null) {
QuotaUsageVO quota_usage;
BigDecimal vmusage;
BigDecimal onehourcostforvmusage;
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getVmInstanceId() + ", "
+ usageRecord.getUsageDisplay());
+ usageRecord.getUsageDisplay() + ", aggrR=" + aggregationRatio);
onehourcostforvmusage = mapping.get(QuotaTypes.ALLOCATED_VM).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
onehourcostforvmusage = mapping.get(QuotaTypes.ALLOCATED_VM).getCurrencyValue().multiply(aggregationRatio);
vmusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostforvmusage);
quota_usage = new QuotaUsageVO(usageRecord.getId(), QuotaTypes.ALLOCATED_VM, vmusage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.ALLOCATED_VM, vmusage,
usageRecord.getStartDate(), usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
@ -264,17 +423,18 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
}
@DB
private void updateQuotaRaw(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, int ruleType) {
private void updateQuotaRaw(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, BigDecimal aggregationRatio, int ruleType) {
if (mapping.get(ruleType) != null) {
QuotaUsageVO quota_usage;
BigDecimal ruleusage;
BigDecimal onehourcost;
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getVmInstanceId() + ", "
+ usageRecord.getUsageDisplay());
+ usageRecord.getUsageDisplay() + ", aggrR=" + aggregationRatio);
onehourcost = mapping.get(ruleType).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
onehourcost = mapping.get(ruleType).getCurrencyValue().multiply(aggregationRatio);
ruleusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcost);
quota_usage = new QuotaUsageVO(usageRecord.getId(), ruleType, ruleusage, usageRecord.getStartDate(), usageRecord.getEndDate());
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), ruleType, ruleusage, usageRecord.getStartDate(),
usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
@ -286,16 +446,17 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
private void updateQuotaNetwork(UsageVO usageRecord, HashMap<Integer, QuotaMappingVO> mapping, int transferType) {
if (mapping.get(transferType) != null) {
QuotaUsageVO quota_usage;
BigDecimal onehourcost;
BigDecimal onegbcost;
BigDecimal rawusageingb;
BigDecimal networkusage;
s_logger.info(usageRecord.getDescription() + ", " + usageRecord.getType() + ", " + usageRecord.getOfferingId() + ", " + usageRecord.getVmInstanceId() + ", "
+ usageRecord.getUsageDisplay());
onehourcost = mapping.get(transferType).getCurrencyValue().divide(s_hoursInMonth, 4, RoundingMode.HALF_EVEN);
rawusageingb = new BigDecimal(usageRecord.getRawUsage()).divide(s_gb, 4, RoundingMode.HALF_EVEN);
networkusage = rawusageingb.multiply(onehourcost);
quota_usage = new QuotaUsageVO(usageRecord.getId(), transferType, networkusage, usageRecord.getStartDate(), usageRecord.getEndDate());
onegbcost = mapping.get(transferType).getCurrencyValue();
rawusageingb = new BigDecimal(usageRecord.getRawUsage()).divide(s_gb, 8, RoundingMode.HALF_EVEN);
networkusage = rawusageingb.multiply(onegbcost);
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), transferType, networkusage, usageRecord.getStartDate(),
usageRecord.getEndDate());
_quotaUsageDao.persist(quota_usage);
}
@ -332,14 +493,32 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
return result;
}
@Override
public void run() {
(new ManagedContextRunnable() {
@Override
protected void runInContext() {
calculateQuotaUsage();
}
}).run();
public TimeZone getUsageTimezone() {
return _usageTimezone;
}
private Date computeAdjustedTime(Date initialDate, TimeZone targetTZ) {
Calendar cal = Calendar.getInstance();
cal.setTime(initialDate);
TimeZone localTZ = cal.getTimeZone();
int timezoneOffset = cal.get(Calendar.ZONE_OFFSET);
if (localTZ.inDaylightTime(initialDate)) {
timezoneOffset += (60 * 60 * 1000);
}
cal.add(Calendar.MILLISECOND, timezoneOffset);
Date newTime = cal.getTime();
Calendar calTS = Calendar.getInstance(targetTZ);
calTS.setTime(newTime);
timezoneOffset = calTS.get(Calendar.ZONE_OFFSET);
if (targetTZ.inDaylightTime(initialDate)) {
timezoneOffset += (60 * 60 * 1000);
}
calTS.add(Calendar.MILLISECOND, -1 * timezoneOffset);
return calTS.getTime();
}
}

View File

@ -31,9 +31,6 @@ public class QuotaMappingVO implements InternalIdentity {
private static final long serialVersionUID = -7117933766387653203L;
@Id
@Column(name = "id")
private Long id;
@Column(name = "usage_type")
private int usageType;
@ -127,6 +124,6 @@ public class QuotaMappingVO implements InternalIdentity {
@Override
public long getId() {
// TODO Auto-generated method stub
return this.id;
return this.usageType;
}
}

View File

@ -38,6 +38,15 @@ public class QuotaUsageVO implements InternalIdentity {
@Column(name = "id")
private Long id;
@Column(name = "zone_id")
private Long zoneId = null;
@Column(name = "account_id")
private Long accountId = null;
@Column(name = "domain_id")
private Long domainId = null;
@Column(name = "usage_item_id")
private Long usageItemId;
@ -58,15 +67,42 @@ public class QuotaUsageVO implements InternalIdentity {
public QuotaUsageVO() {
}
public QuotaUsageVO(Long usageItemId, int usageType, BigDecimal quotaUsed, Date startDate, Date endDate) {
public QuotaUsageVO(Long usageItemId, Long zoneId, Long accountId, Long domainId, int usageType, BigDecimal quotaUsed, Date startDate, Date endDate) {
super();
this.usageItemId = usageItemId;
this.zoneId = zoneId;
this.accountId = accountId;
this.domainId = domainId;
this.usageType = usageType;
this.quotaUsed = quotaUsed;
this.startDate = startDate;
this.endDate = endDate;
}
public Long getZoneId() {
return zoneId;
}
public void setZoneId(Long zoneId) {
this.zoneId = zoneId;
}
public Long getAccountId() {
return accountId;
}
public void setAccountId(Long accountId) {
this.accountId = accountId;
}
public Long getDomainId() {
return domainId;
}
public void setDomainId(Long domainId) {
this.domainId = domainId;
}
@Override
public long getId() {
// TODO Auto-generated method stub

View File

@ -34,14 +34,14 @@ public class QuotaUsageDaoImpl extends GenericDaoBase<QuotaUsageVO, Long> implem
@Override
public Pair<List<QuotaUsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<QuotaUsageVO> sc, Filter filter) {
// TODO Auto-generated method stub
return null;
return listAndCountIncludingRemovedBy(sc, filter);
}
@Override
public void saveQuotaUsage(List<QuotaUsageVO> credits) {
// TODO Auto-generated method stub
public void saveQuotaUsage(List<QuotaUsageVO> records) {
for (QuotaUsageVO usageRecord : records) {
persist(usageRecord);
}
}
}

View File

@ -21,6 +21,7 @@
-- SAML
DELETE FROM `cloud`.`configuration` WHERE name like 'saml%' and component='management-server';
ALTER TABLE `cloud`.`user` ADD COLUMN `external_entity` text DEFAULT NULL COMMENT "reference to external federation entity";
@ -37,8 +38,7 @@ CREATE TABLE `cloud`.`saml_token` (
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `quota_mapping` (
`id` bigint(20) unsigned NOT NULL COMMENT 'id',
CREATE TABLE `quota_mapping` (
`usage_type` int(2) unsigned DEFAULT NULL,
`usage_name` varchar(255) NOT NULL COMMENT 'usage type',
`usage_unit` varchar(255) NOT NULL COMMENT 'usage type',
@ -46,34 +46,34 @@ CREATE TABLE IF NOT EXISTS `quota_mapping` (
`currency_value` decimal(15,2) NOT NULL COMMENT 'usage type',
`include` tinyint(1) NOT NULL COMMENT 'usage type',
`description` varchar(255) NOT NULL COMMENT 'usage type',
PRIMARY KEY (`id`)
PRIMARY KEY (`usage_type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
LOCK TABLES `quota_mapping` WRITE;
INSERT INTO `quota_mapping` VALUES
(1,1,'RUNNING_VM','Compute-Month','',5.00,1,'Quota mapping for running VM'),
(2,2,'ALLOCATED_VM','Compute-Month','',10.00,1,'Quota mapping for allocsated VM'),
(3,3,'IP_ADDRESS','IP-Month','',5.12,1,'Quota mapping for IP address in use'),
(4,4,'NETWORK_BYTES_SENT','GB','',1.00,1,'Quota mapping for network bytes sent'),
(5,5,'NETWORK_BYTES_RECEIVED','GB','',1.00,1,'Quota mapping for network bytes received'),
(6,6,'VOLUME','GB-Month','',5.00,1,'Quota mapping for volume usage per month'),
(7,7,'TEMPLATE','GB-Month','',5.00,1,'Quota mapping for template usage per month'),
(8,8,'ISO','GB-Month','',5.00,1,'Quota mapping for ISO storage per month'),
(9,9,'SNAPSHOT','GB-Month','',5.00,1,'Quota mapping for snapshot usage per month'),
(10,10,'SECURITY_GROUP','Policy-Month','',5.00,1,'Quota mapping for Security groups'),
(11,11,'LOAD_BALANCER_POLICY','Policy-Month','',5.00,1,'Quota mapping load balancer policy use per hour'),
(12,12,'PORT_FORWARDING_RULE','Policy-Month','',5.00,1,'Quota mapping port forwarding rule useper hour'),
(13,13,'NETWORK_OFFERING','Policy-Month','',5.00,1,'Quota mapping for network offering usage per hour'),
(14,14,'VPN_USERS','Policy-Month','',5.00,1,'Quota mapping for using VPN'),
(15,15,'CPU_SPEED','Compute-Month','100MHz',5.00,1,'Quota mapping for 100 MHz of CPU running for an hour'),
(16,16,'vCPU','Compute-Month','1VCPU',5.00,1,'Quota mapping for running VM that has 1vCPU'),
(17,17,'MEMORY','Compute-Month','1MB',5.00,1,'Quota mapping for usign 1MB or RAM for 1 hour'),
(18,21,'VM_DISK_IO_READ','GB','1',5.00,1,'Quota mapping for 1GB of disk IO read'),
(19,22,'VM_DISK_IO_WRITE','GB','1',5.00,1,'Quota mapping for 1GB of disk data write'),
(20,23,'VM_DISK_BYTES_READ','GB','1',5.00,1,'Quota mapping for disk bytes read'),
(21,24,'VM_DISK_BYTES_WRITE','GB','1',5.00,1,'Quota mapping for disk bytes write'),
(22,25,'VM_SNAPSHOT','GB-Month','',5.00,1,'Quota mapping for running VM');
(1,'RUNNING_VM','Compute-Month','',5.00,1,'Quota mapping for running VM'),
(2,'ALLOCATED_VM','Compute-Month','',10.00,1,'Quota mapping for allocsated VM'),
(3,'IP_ADDRESS','IP-Month','',5.12,1,'Quota mapping for IP address in use'),
(4,'NETWORK_BYTES_SENT','GB','',1.00,1,'Quota mapping for network bytes sent'),
(5,'NETWORK_BYTES_RECEIVED','GB','',1.00,1,'Quota mapping for network bytes received'),
(6,'VOLUME','GB-Month','',5.00,1,'Quota mapping for volume usage per month'),
(7,'TEMPLATE','GB-Month','',5.00,1,'Quota mapping for template usage per month'),
(8,'ISO','GB-Month','',5.00,1,'Quota mapping for ISO storage per month'),
(9,'SNAPSHOT','GB-Month','',5.00,1,'Quota mapping for snapshot usage per month'),
(10,'SECURITY_GROUP','Policy-Month','',5.00,1,'Quota mapping for Security groups'),
(11,'LOAD_BALANCER_POLICY','Policy-Month','',5.00,1,'Quota mapping load balancer policy use per hour'),
(12,'PORT_FORWARDING_RULE','Policy-Month','',5.00,1,'Quota mapping port forwarding rule useper hour'),
(13,'NETWORK_OFFERING','Policy-Month','',5.00,1,'Quota mapping for network offering usage per hour'),
(14,'VPN_USERS','Policy-Month','',5.00,1,'Quota mapping for using VPN'),
(15,'CPU_SPEED','Compute-Month','100MHz',5.00,1,'Quota mapping for 100 MHz of CPU running for an hour'),
(16,'vCPU','Compute-Month','1VCPU',5.00,1,'Quota mapping for running VM that has 1vCPU'),
(17,'MEMORY','Compute-Month','1MB',5.00,1,'Quota mapping for usign 1MB or RAM for 1 hour'),
(21,'VM_DISK_IO_READ','GB','1',5.00,1,'Quota mapping for 1GB of disk IO read'),
(22,'VM_DISK_IO_WRITE','GB','1',5.00,1,'Quota mapping for 1GB of disk data write'),
(23,'VM_DISK_BYTES_READ','GB','1',5.00,1,'Quota mapping for disk bytes read'),
(24,'VM_DISK_BYTES_WRITE','GB','1',5.00,1,'Quota mapping for disk bytes write'),
(25,'VM_SNAPSHOT','GB-Month','',5.00,1,'Quota mapping for running VM');
UNLOCK TABLES;
@ -81,22 +81,24 @@ CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_credits` (
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
`account_id` bigint unsigned NOT NULL,
`domain_id` bigint(20) unsigned NOT NULL,
`credit` decimal(15,2) COMMENT 'amount credited',
`credit` decimal(15,4) COMMENT 'amount credited',
`updated_on` datetime NOT NULL COMMENT 'date created',
`updated_by` bigint unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_usage` (
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
`usage_item_id` bigint unsigned NOT NULL,
CREATE TABLE IF NOT EXISTS `quota_usage` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`usage_item_id` bigint(20) unsigned NOT NULL,
`zone_id` bigint(20) unsigned NOT NULL,
`account_id` bigint(20) unsigned NOT NULL,
`domain_id` bigint(20) unsigned NOT NULL,
`usage_type` varchar(64) DEFAULT NULL,
`quota_used` int unsigned NOT NULL,
`quota_used` decimal(15,4) unsigned NOT NULL,
`start_date` datetime NOT NULL COMMENT 'start time for this usage item',
`end_date` datetime NOT NULL COMMENT 'end time for this usage item',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_balance` (