mirror of https://github.com/apache/cloudstack.git
CLOUDSTACK-8592: splitting out quotamanager into quotamanager and quotaservice
This commit is contained in:
parent
02234778d7
commit
ccde3cfca9
|
|
@ -26,6 +26,7 @@
|
|||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<bean id="QuotaManager" class="org.apache.cloudstack.quota.QuotaManagerImpl" />
|
||||
<bean id="QuotaService" class="org.apache.cloudstack.quota.QuotaServiceImpl" />
|
||||
<bean id="QuotaDBUtils" class="org.apache.cloudstack.quota.QuotaDBUtilsImpl" />
|
||||
<bean id="QuotaTariffDao" class="org.apache.cloudstack.quota.dao.QuotaTariffDaoImpl" />
|
||||
<bean id="QuotaBalanceDao" class="org.apache.cloudstack.quota.dao.QuotaBalanceDaoImpl"/>
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import org.apache.cloudstack.api.response.QuotaBalanceResponse;
|
|||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.QuotaBalanceVO;
|
||||
import org.apache.cloudstack.quota.QuotaDBUtils;
|
||||
import org.apache.cloudstack.quota.QuotaManager;
|
||||
import org.apache.cloudstack.quota.QuotaService;
|
||||
import org.apache.cloudstack.api.response.QuotaStatementItemResponse;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
|
@ -60,7 +60,7 @@ public class QuotaBalanceCmd extends BaseCmd {
|
|||
private Long accountId;
|
||||
|
||||
@Inject
|
||||
QuotaManager _quotaManager;
|
||||
QuotaService _quotaManager;
|
||||
@Inject
|
||||
QuotaDBUtils _quotaDBUtils;
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.cloudstack.api.command;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import org.apache.cloudstack.api.response.DomainResponse;
|
|||
import org.apache.cloudstack.api.response.QuotaStatementResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.QuotaDBUtils;
|
||||
import org.apache.cloudstack.quota.QuotaManager;
|
||||
import org.apache.cloudstack.quota.QuotaService;
|
||||
import org.apache.cloudstack.quota.QuotaUsageVO;
|
||||
import org.apache.cloudstack.api.response.QuotaStatementItemResponse;
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ public class QuotaStatementCmd extends BaseCmd {
|
|||
private Long accountId;
|
||||
|
||||
@Inject
|
||||
QuotaManager _quotaManager;
|
||||
QuotaService _quotaManager;
|
||||
@Inject
|
||||
QuotaDBUtils _quotaDBUtils;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ package org.apache.cloudstack.quota;
|
|||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.usage.UsageVO;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.service.ServiceOfferingVO;
|
||||
|
||||
import org.apache.cloudstack.api.command.QuotaTariffListCmd;
|
||||
|
|
@ -48,10 +47,6 @@ public interface QuotaDBUtils {
|
|||
|
||||
QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy);
|
||||
|
||||
boolean accountLockNoCredit(AccountVO account);
|
||||
|
||||
boolean accountUnlockCredit(AccountVO account);
|
||||
|
||||
QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,16 +17,11 @@
|
|||
package org.apache.cloudstack.quota;
|
||||
|
||||
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.Account.State;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.User;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
|
|
@ -72,8 +67,6 @@ public class QuotaDBUtilsImpl implements QuotaDBUtils {
|
|||
private UserDao _userDao;
|
||||
@Inject
|
||||
private UsageDao _usageDao;
|
||||
@Inject
|
||||
private AccountDao _accountDao;
|
||||
|
||||
static Long s_recordtofetch = 1000L;
|
||||
|
||||
|
|
@ -291,74 +284,4 @@ public class QuotaDBUtilsImpl implements QuotaDBUtils {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accountLockNoCredit(AccountVO account) {
|
||||
short opendb=TransactionLegacy.currentTxn().getDatabaseId();
|
||||
boolean success = false;
|
||||
|
||||
if (account == null) {
|
||||
s_logger.warn("The account parameter is null");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (account.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
throw new InvalidParameterValueException("Project accounts cannot be locked " + account.getAccountName());
|
||||
}
|
||||
|
||||
if (account.getId() == Account.ACCOUNT_ID_SYSTEM) {
|
||||
throw new PermissionDeniedException("Account name : " + account.getAccountName() + " is a system account, lock is not allowed");
|
||||
}
|
||||
|
||||
if (account.getState().equals(State.locked)) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.warn("The account is locked cannot put it in nocredit state (accountId: " + account.getId() + "), locking failed.");
|
||||
}
|
||||
} else if (account.getState().equals(State.enabled)) {
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
|
||||
try {
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.nocredit);
|
||||
success = _accountDao.update(Long.valueOf(account.getId()), acctForUpdate);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Attempting to lock a non-enabled account, current state is " + account.getState() + " (accountId: " + account.getId() + "), locking failed.");
|
||||
}
|
||||
}
|
||||
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean accountUnlockCredit(AccountVO account) {
|
||||
short opendb=TransactionLegacy.currentTxn().getDatabaseId();
|
||||
boolean success = false;
|
||||
|
||||
if (account == null) {
|
||||
s_logger.warn("The account parameter is null");
|
||||
return success;
|
||||
}
|
||||
|
||||
if (account.getState().equals(State.nocredit)) {
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
|
||||
try {
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.enabled);
|
||||
success = _accountDao.update(Long.valueOf(account.getId()), acctForUpdate);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Attempting to unlock a account that is not locked due to no credits, current state is " + account.getState() + " (accountId: " + account.getId()
|
||||
+ "), unlocking failed.");
|
||||
}
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
//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
|
||||
//the License. You may obtain a copy of the License at
|
||||
//
|
||||
//http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
|
@ -16,19 +16,10 @@
|
|||
//under the License.
|
||||
package org.apache.cloudstack.quota;
|
||||
|
||||
import com.cloud.utils.component.PluggableService;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
import org.apache.cloudstack.api.command.QuotaBalanceCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaStatementCmd;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface QuotaManager extends PluggableService {
|
||||
public interface QuotaManager extends Manager {
|
||||
|
||||
public boolean calculateQuotaUsage();
|
||||
|
||||
public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd);
|
||||
|
||||
List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,57 +16,36 @@
|
|||
//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.service.ServiceOfferingVO;
|
||||
import com.cloud.usage.UsageVO;
|
||||
import com.cloud.usage.dao.UsageDao;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
import org.apache.cloudstack.api.command.QuotaBalanceCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaCreditsCmd;
|
||||
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.api.command.QuotaTariffListCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd;
|
||||
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.dao.QuotaTariffDao;
|
||||
import org.apache.cloudstack.quota.dao.QuotaBalanceDao;
|
||||
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 javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
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;
|
||||
|
||||
@Component
|
||||
@Local(value = QuotaManager.class)
|
||||
public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Configurable, QuotaConfig {
|
||||
public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaManagerImpl.class.getName());
|
||||
|
||||
@Inject
|
||||
|
|
@ -78,10 +57,6 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
|
|||
@Inject
|
||||
private QuotaUsageDao _quotaUsageDao;
|
||||
@Inject
|
||||
private DomainDao _domainDao;
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
@Inject
|
||||
private QuotaDBUtils _quotaDBUtils;
|
||||
@Inject
|
||||
private QuotaBalanceDao _quotaBalanceDao;
|
||||
|
|
@ -97,49 +72,6 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
|
|||
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<?>>();
|
||||
cmdList.add(QuotaTariffListCmd.class);
|
||||
cmdList.add(QuotaTariffUpdateCmd.class);
|
||||
cmdList.add(QuotaCreditsCmd.class);
|
||||
cmdList.add(QuotaEmailTemplateAddCmd.class);
|
||||
cmdList.add(QuotaRefreshCmd.class);
|
||||
cmdList.add(QuotaStatementCmd.class);
|
||||
cmdList.add(QuotaBalanceCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return "QUOTA-PLUGIN";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] { QuotaPluginEnabled, QuotaPeriodType, QuotaPeriod, QuotaGenerateActivity, QuotaEmailRecordOutgoing, QuotaEnableEnforcement, QuotaCurrencySymbol, QuotaLimitCritical,
|
||||
QuotaLimitIncremental, QuotaSmtpHost, QuotaSmtpTimeout, QuotaSmtpUser, QuotaSmtpPassword, QuotaSmtpPort, QuotaSmtpAuthType };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean calculateQuotaUsage() {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
|
|
@ -262,98 +194,6 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
|
|||
return jobResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd) {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
|
||||
Long accountId = cmd.getAccountId();
|
||||
String accountName = cmd.getAccountName();
|
||||
Long domainId = cmd.getDomainId();
|
||||
Account userAccount = null;
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
|
||||
Date startDate = cmd.getStartDate();
|
||||
Date endDate = cmd.getEndDate();
|
||||
startDate = startDate == null ? new Date() : startDate;
|
||||
|
||||
TimeZone usageTZ = getUsageTimezone();
|
||||
Date adjustedStartDate = computeAdjustedTime(startDate, usageTZ);
|
||||
|
||||
if (endDate == null) {
|
||||
s_logger.debug("getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + adjustedStartDate);
|
||||
return _quotaBalanceDao.getQuotaBalance(accountId, domainId, adjustedStartDate);
|
||||
} else if (startDate.before(endDate)) {
|
||||
Date adjustedEndDate = computeAdjustedTime(endDate, usageTZ);
|
||||
s_logger.debug("getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate);
|
||||
return _quotaBalanceDao.getQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate);
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd) {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
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");
|
||||
}
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
|
||||
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);
|
||||
return _quotaUsageDao.getQuotaUsage(accountId, domainId, usageType, adjustedStartDate, adjustedEndDate);
|
||||
}
|
||||
|
||||
@DB
|
||||
private QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, HashMap<Integer, QuotaTariffVO> quotaTariffMap, BigDecimal aggregationRatio, int quotaType) {
|
||||
QuotaUsageVO quota_usage = null;
|
||||
|
|
@ -491,28 +331,4 @@ public class QuotaManagerImpl extends ManagerBase implements QuotaManager, Confi
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
//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.api.command.QuotaBalanceCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaStatementCmd;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface QuotaService extends PluggableService {
|
||||
|
||||
public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd);
|
||||
|
||||
List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,249 @@
|
|||
//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 com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
import org.apache.cloudstack.api.command.QuotaBalanceCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaCreditsCmd;
|
||||
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.api.command.QuotaTariffListCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaTariffUpdateCmd;
|
||||
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.dao.QuotaBalanceDao;
|
||||
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 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.getName());
|
||||
|
||||
@Inject
|
||||
private AccountDao _accountDao;
|
||||
@Inject
|
||||
private QuotaUsageDao _quotaUsageDao;
|
||||
@Inject
|
||||
private DomainDao _domainDao;
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
@Inject
|
||||
private QuotaBalanceDao _quotaBalanceDao;
|
||||
|
||||
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 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;
|
||||
}
|
||||
s_logger.info("Usage timezone = " + _usageTimezone + " AggregationDuration=" + _aggregationDuration);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Class<?>> getCommands() {
|
||||
final List<Class<?>> cmdList = new ArrayList<Class<?>>();
|
||||
cmdList.add(QuotaTariffListCmd.class);
|
||||
cmdList.add(QuotaTariffUpdateCmd.class);
|
||||
cmdList.add(QuotaCreditsCmd.class);
|
||||
cmdList.add(QuotaEmailTemplateAddCmd.class);
|
||||
cmdList.add(QuotaRefreshCmd.class);
|
||||
cmdList.add(QuotaStatementCmd.class);
|
||||
cmdList.add(QuotaBalanceCmd.class);
|
||||
return cmdList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConfigComponentName() {
|
||||
return "QUOTA-PLUGIN";
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] { QuotaPluginEnabled, QuotaPeriodType, QuotaPeriod, QuotaGenerateActivity, QuotaEmailRecordOutgoing, QuotaEnableEnforcement, QuotaCurrencySymbol, QuotaLimitCritical,
|
||||
QuotaLimitIncremental, QuotaSmtpHost, QuotaSmtpTimeout, QuotaSmtpUser, QuotaSmtpPassword, QuotaSmtpPort, QuotaSmtpAuthType };
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd) {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
|
||||
Long accountId = cmd.getAccountId();
|
||||
String accountName = cmd.getAccountName();
|
||||
Long domainId = cmd.getDomainId();
|
||||
Account userAccount = null;
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
|
||||
Date startDate = cmd.getStartDate();
|
||||
Date endDate = cmd.getEndDate();
|
||||
startDate = startDate == null ? new Date() : startDate;
|
||||
|
||||
TimeZone usageTZ = getUsageTimezone();
|
||||
Date adjustedStartDate = computeAdjustedTime(startDate, usageTZ);
|
||||
|
||||
if (endDate == null) {
|
||||
s_logger.debug("getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", on or before " + adjustedStartDate);
|
||||
return _quotaBalanceDao.getQuotaBalance(accountId, domainId, adjustedStartDate);
|
||||
} else if (startDate.before(endDate)) {
|
||||
Date adjustedEndDate = computeAdjustedTime(endDate, usageTZ);
|
||||
s_logger.debug("getting quota balance records for account: " + accountId + ", domainId: " + domainId + ", between " + adjustedStartDate + " and " + adjustedEndDate);
|
||||
return _quotaBalanceDao.getQuotaBalance(accountId, domainId, adjustedStartDate, adjustedEndDate);
|
||||
} else {
|
||||
throw new InvalidParameterValueException("Incorrect Date Range. Start date: " + startDate + " is after end date:" + endDate);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd) {
|
||||
short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
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");
|
||||
}
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
|
||||
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);
|
||||
return _quotaUsageDao.getQuotaUsage(accountId, domainId, usageType, adjustedStartDate, adjustedEndDate);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue