mirror of https://github.com/apache/cloudstack.git
quota service
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
This commit is contained in:
parent
873dba477b
commit
d0852ef87c
|
|
@ -269,6 +269,7 @@ public class ApiConstants {
|
|||
public static final String VIRTUAL_MACHINE_IDS = "virtualmachineids";
|
||||
public static final String VIRTUAL_MACHINE_ID_IP = "vmidipmap";
|
||||
public static final String USAGE_ID = "usageid";
|
||||
public static final String USAGE_TYPE = "usagetype";
|
||||
|
||||
public static final String VLAN = "vlan";
|
||||
public static final String VLAN_RANGE = "vlanrange";
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ public abstract class BaseCmd {
|
|||
GET, POST, PUT, DELETE
|
||||
}
|
||||
public static enum CommandType {
|
||||
BOOLEAN, DATE, FLOAT, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE, UUID
|
||||
BOOLEAN, DATE, FLOAT, DOUBLE, INTEGER, SHORT, LIST, LONG, OBJECT, MAP, STRING, TZDATE, UUID
|
||||
}
|
||||
|
||||
private Object _responseObject;
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@ import com.cloud.utils.Pair;
|
|||
@APICommand(name = "listUsageRecords", description = "Lists usage records for accounts", responseObject = UsageRecordResponse.class,
|
||||
requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class GetUsageRecordsCmd extends BaseListCmd {
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(GetUsageRecordsCmd.class.getName());
|
||||
|
||||
private static final String s_name = "listusagerecordsresponse";
|
||||
|
|
@ -111,6 +112,30 @@ public class GetUsageRecordsCmd extends BaseListCmd {
|
|||
public String getUsageId() {
|
||||
return usageId;
|
||||
}
|
||||
public void setAccountName(String accountName) {
|
||||
this.accountName = accountName;
|
||||
}
|
||||
|
||||
public void setDomainId(Long domainId) {
|
||||
this.domainId = domainId;
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public void setAccountId(Long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public void setUsageId(String usageId) {
|
||||
this.usageId = usageId;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////// API Implementation///////////////////
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ import java.util.List;
|
|||
import org.apache.cloudstack.api.response.UsageTypeResponse;
|
||||
|
||||
public class UsageTypes {
|
||||
|
||||
/* Any changes here should also reflect in cloud_usage.quota_mapping table */
|
||||
public static final int RUNNING_VM = 1;
|
||||
public static final int ALLOCATED_VM = 2; // used for tracking how long storage has been allocated for a VM
|
||||
public static final int IP_ADDRESS = 3;
|
||||
|
|
|
|||
|
|
@ -1356,6 +1356,13 @@ label.show.advanced.settings=Show advanced settings
|
|||
label.delete.OpenDaylight.device=Delete OpenDaylight Controller
|
||||
label.polling.interval.sec=Polling Interval (in sec)
|
||||
label.quiet.time.sec=Quiet Time (in sec)
|
||||
label.usage.type=Usage Type
|
||||
label.usage.unit=Unit
|
||||
label.quota.value=Quota Value
|
||||
label.quota.description=Quota Description
|
||||
label.quota.configuration=Quota Configuration
|
||||
label.quota.configure=Configure Quota
|
||||
label.quota.remove=Remove Quota
|
||||
label.destroy.vm.graceperiod=Destroy VM Grace Period
|
||||
label.SNMP.community=SNMP Community
|
||||
label.SNMP.port=SNMP Port
|
||||
|
|
|
|||
|
|
@ -246,6 +246,11 @@
|
|||
<artifactId>cloud-framework-ipc</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-quota</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-rest</artifactId>
|
||||
|
|
@ -356,6 +361,11 @@
|
|||
<artifactId>cloud-plugin-network-globodns</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-plugin-database-quota</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
|||
|
|
@ -782,3 +782,14 @@ listOpenDaylightControllers=1
|
|||
|
||||
### GloboDNS commands
|
||||
addGloboDnsHost=1
|
||||
|
||||
### Quota Service
|
||||
quotaRefresh=1
|
||||
quotaStatement=15
|
||||
quotaBalance=15
|
||||
quotaTariffList=15
|
||||
quotaTariffUpdate=1
|
||||
quotaCredits=1
|
||||
quotaEmailTemplateList=1
|
||||
quotaEmailTemplateUpdate=1
|
||||
|
||||
|
|
|
|||
|
|
@ -103,6 +103,17 @@ public class UsageVO implements Usage, InternalIdentity {
|
|||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date endDate = null;
|
||||
|
||||
@Column(name = "quota_calculated")
|
||||
private Integer quotaCalculated = null;
|
||||
|
||||
public Integer getQuotaCalculated() {
|
||||
return quotaCalculated;
|
||||
}
|
||||
|
||||
public void setQuotaCalculated(Integer quotaCalculated) {
|
||||
this.quotaCalculated = quotaCalculated;
|
||||
}
|
||||
|
||||
public UsageVO() {
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -53,4 +53,6 @@ public interface UsageDao extends GenericDao<UsageVO, Long> {
|
|||
void saveVmDiskStats(List<VmDiskStatisticsVO> vmDiskStats);
|
||||
|
||||
void saveUsageRecords(List<UsageVO> usageRecords);
|
||||
|
||||
Pair<List<? extends UsageVO>, Integer> getUsageRecordsPendingQuotaAggregation(long accountId, long domainId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,35 +42,30 @@ import com.cloud.utils.db.TransactionLegacy;
|
|||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
@Local(value = {UsageDao.class})
|
||||
@Local(value = { UsageDao.class })
|
||||
public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements UsageDao {
|
||||
public static final Logger s_logger = Logger.getLogger(UsageDaoImpl.class.getName());
|
||||
private static final String DELETE_ALL = "DELETE FROM cloud_usage";
|
||||
private static final String DELETE_ALL_BY_ACCOUNTID = "DELETE FROM cloud_usage WHERE account_id = ?";
|
||||
private static final String INSERT_ACCOUNT = "INSERT INTO cloud_usage.account (id, account_name, type, domain_id, removed, cleanup_needed) VALUES (?,?,?,?,?,?)";
|
||||
private static final String INSERT_USER_STATS =
|
||||
"INSERT INTO cloud_usage.user_statistics (id, data_center_id, account_id, public_ip_address, device_id, device_type, network_id, net_bytes_received,"
|
||||
+ " net_bytes_sent, current_bytes_received, current_bytes_sent, agg_bytes_received, agg_bytes_sent) VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?)";
|
||||
private static final String INSERT_USER_STATS = "INSERT INTO cloud_usage.user_statistics (id, data_center_id, account_id, public_ip_address, device_id, device_type, network_id, net_bytes_received,"
|
||||
+ " net_bytes_sent, current_bytes_received, current_bytes_sent, agg_bytes_received, agg_bytes_sent) VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?)";
|
||||
|
||||
private static final String UPDATE_ACCOUNT = "UPDATE cloud_usage.account SET account_name=?, removed=? WHERE id=?";
|
||||
private static final String UPDATE_USER_STATS =
|
||||
"UPDATE cloud_usage.user_statistics SET net_bytes_received=?, net_bytes_sent=?, current_bytes_received=?, current_bytes_sent=?, agg_bytes_received=?, agg_bytes_sent=? WHERE id=?";
|
||||
private static final String UPDATE_USER_STATS = "UPDATE cloud_usage.user_statistics SET net_bytes_received=?, net_bytes_sent=?, current_bytes_received=?, current_bytes_sent=?, agg_bytes_received=?, agg_bytes_sent=? WHERE id=?";
|
||||
|
||||
private static final String GET_LAST_ACCOUNT = "SELECT id FROM cloud_usage.account ORDER BY id DESC LIMIT 1";
|
||||
private static final String GET_LAST_USER_STATS = "SELECT id FROM cloud_usage.user_statistics ORDER BY id DESC LIMIT 1";
|
||||
private static final String GET_PUBLIC_TEMPLATES_BY_ACCOUNTID = "SELECT id FROM cloud.vm_template WHERE account_id = ? AND public = '1' AND removed IS NULL";
|
||||
|
||||
private static final String GET_LAST_VM_DISK_STATS = "SELECT id FROM cloud_usage.vm_disk_statistics ORDER BY id DESC LIMIT 1";
|
||||
private static final String INSERT_VM_DISK_STATS =
|
||||
"INSERT INTO cloud_usage.vm_disk_statistics (id, data_center_id, account_id, vm_id, volume_id, net_io_read, net_io_write, current_io_read, "
|
||||
+ "current_io_write, agg_io_read, agg_io_write, net_bytes_read, net_bytes_write, current_bytes_read, current_bytes_write, agg_bytes_read, agg_bytes_write) "
|
||||
+ " VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?, ?,?, ?, ?)";
|
||||
private static final String UPDATE_VM_DISK_STATS =
|
||||
"UPDATE cloud_usage.vm_disk_statistics SET net_io_read=?, net_io_write=?, current_io_read=?, current_io_write=?, agg_io_read=?, agg_io_write=?, "
|
||||
+ "net_bytes_read=?, net_bytes_write=?, current_bytes_read=?, current_bytes_write=?, agg_bytes_read=?, agg_bytes_write=? WHERE id=?";
|
||||
private static final String INSERT_VM_DISK_STATS = "INSERT INTO cloud_usage.vm_disk_statistics (id, data_center_id, account_id, vm_id, volume_id, net_io_read, net_io_write, current_io_read, "
|
||||
+ "current_io_write, agg_io_read, agg_io_write, net_bytes_read, net_bytes_write, current_bytes_read, current_bytes_write, agg_bytes_read, agg_bytes_write) "
|
||||
+ " VALUES (?,?,?,?,?,?,?,?,?,?, ?, ?, ?, ?,?, ?, ?)";
|
||||
private static final String UPDATE_VM_DISK_STATS = "UPDATE cloud_usage.vm_disk_statistics SET net_io_read=?, net_io_write=?, current_io_read=?, current_io_write=?, agg_io_read=?, agg_io_write=?, "
|
||||
+ "net_bytes_read=?, net_bytes_write=?, current_bytes_read=?, current_bytes_write=?, agg_bytes_read=?, agg_bytes_write=? WHERE id=?";
|
||||
private static final String INSERT_USAGE_RECORDS = "INSERT INTO cloud_usage.cloud_usage (zone_id, account_id, domain_id, description, usage_display, "
|
||||
+
|
||||
"usage_type, raw_usage, vm_instance_id, vm_name, offering_id, template_id, "
|
||||
+ "usage_type, raw_usage, vm_instance_id, vm_name, offering_id, template_id, "
|
||||
+ "usage_id, type, size, network_id, start_date, end_date, virtual_size) VALUES (?,?,?,?,?,?,?,?,?, ?, ?, ?,?,?,?,?,?,?)";
|
||||
|
||||
protected final static TimeZone s_gmtTimeZone = TimeZone.getTimeZone("GMT");
|
||||
|
|
@ -111,7 +106,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = INSERT_ACCOUNT;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (AccountVO acct : accounts) {
|
||||
pstmt.setLong(1, acct.getId());
|
||||
pstmt.setString(2, acct.getAccountName());
|
||||
|
|
@ -145,7 +142,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = UPDATE_ACCOUNT;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (AccountVO acct : accounts) {
|
||||
pstmt.setString(1, acct.getAccountName());
|
||||
|
||||
|
|
@ -175,7 +174,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = INSERT_USER_STATS;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (UserStatisticsVO userStat : userStats) {
|
||||
pstmt.setLong(1, userStat.getId());
|
||||
pstmt.setLong(2, userStat.getDataCenterId());
|
||||
|
|
@ -216,7 +217,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = UPDATE_USER_STATS;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (UserStatisticsVO userStat : userStats) {
|
||||
pstmt.setLong(1, userStat.getNetBytesReceived());
|
||||
pstmt.setLong(2, userStat.getNetBytesSent());
|
||||
|
|
@ -313,7 +316,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = UPDATE_VM_DISK_STATS;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (VmDiskStatisticsVO vmDiskStat : vmDiskStats) {
|
||||
pstmt.setLong(1, vmDiskStat.getNetIORead());
|
||||
pstmt.setLong(2, vmDiskStat.getNetIOWrite());
|
||||
|
|
@ -347,7 +352,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = INSERT_VM_DISK_STATS;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (VmDiskStatisticsVO vmDiskStat : vmDiskStats) {
|
||||
pstmt.setLong(1, vmDiskStat.getId());
|
||||
pstmt.setLong(2, vmDiskStat.getDataCenterId());
|
||||
|
|
@ -393,7 +400,9 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
txn.start();
|
||||
String sql = INSERT_USAGE_RECORDS;
|
||||
PreparedStatement pstmt = null;
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just want CLOUD_USAGE dataSource connection
|
||||
pstmt = txn.prepareAutoCloseStatement(sql); // in reality I just
|
||||
// want CLOUD_USAGE
|
||||
// dataSource connection
|
||||
for (UsageVO usageRecord : usageRecords) {
|
||||
pstmt.setLong(1, usageRecord.getZoneId());
|
||||
pstmt.setLong(2, usageRecord.getAccountId());
|
||||
|
|
@ -451,4 +460,25 @@ public class UsageDaoImpl extends GenericDaoBase<UsageVO, Long> implements Usage
|
|||
throw new CloudRuntimeException(ex.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public Pair<List<? extends UsageVO>, Integer> getUsageRecordsPendingQuotaAggregation(final long accountId, final long domainId) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
s_logger.debug("getting usage records for account: " + accountId + ", domainId: " + domainId);
|
||||
Filter usageFilter = new Filter(UsageVO.class, "startDate", true, 0L, 10000L);
|
||||
SearchCriteria<UsageVO> sc = createSearchCriteria();
|
||||
if (accountId != -1) {
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
}
|
||||
if (domainId != -1) {
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
}
|
||||
sc.addAnd("quotaCalculated", SearchCriteria.Op.EQ, 0);
|
||||
s_logger.debug("Getting usage records" + usageFilter.getOrderBy());
|
||||
Pair<List<UsageVO>, Integer> usageRecords = searchAndCountAllRecords(sc, usageFilter);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return new Pair<List<? extends UsageVO>, Integer>(usageRecords.first(), usageRecords.second());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
<module>rest</module>
|
||||
<module>events</module>
|
||||
<module>jobs</module>
|
||||
<module>quota</module>
|
||||
<module>cluster</module>
|
||||
<module>db</module>
|
||||
<module>config</module>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-framework-quota</artifactId>
|
||||
<name>Apache CloudStack Framework - Quota</name>
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloudstack-framework</artifactId>
|
||||
<version>4.5.2</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-schema</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<!-- 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. -->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<bean id="QuotaTariffDao" class="org.apache.cloudstack.quota.dao.QuotaTariffDaoImpl" />
|
||||
<bean id="QuotaAccountDao" class="org.apache.cloudstack.quota.dao.QuotaAccountDaoImpl" />
|
||||
<bean id="QuotaBalanceDao" class="org.apache.cloudstack.quota.dao.QuotaBalanceDaoImpl" />
|
||||
<bean id="QuotaCreditsDao" class="org.apache.cloudstack.quota.dao.QuotaCreditsDaoImpl" />
|
||||
<bean id="QuotaEmailTemplatesDao"
|
||||
class="org.apache.cloudstack.quota.dao.QuotaEmailTemplatesDaoImpl" />
|
||||
<bean id="QuotaUsageDao" class="org.apache.cloudstack.quota.dao.QuotaUsageDaoImpl" />
|
||||
<bean id="ServiceOfferingDao" class="org.apache.cloudstack.quota.dao.ServiceOfferingDaoImpl" />
|
||||
<bean id="UserVmDetailsDao" class="org.apache.cloudstack.quota.dao.UserVmDetailsDaoImpl" />
|
||||
|
||||
</beans>
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
//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.constant;
|
||||
import org.apache.cloudstack.framework.config.ConfigKey;
|
||||
|
||||
public interface QuotaConfig {
|
||||
|
||||
public static final ConfigKey<Boolean> QuotaPluginEnabled = new ConfigKey<Boolean>("Advanced", Boolean.class, "quota.enable.service", "false",
|
||||
"Indicates whether Quota plugin is enabled or not", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaEnableEnforcement = new ConfigKey<String>("Advanced", String.class, "quota.enable.enforcement", "true",
|
||||
"Enable the usage quota enforcement, i.e. on true when exceeding quota the respective account will be locked.", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaCurrencySymbol = new ConfigKey<String>("Advanced", String.class, "quota.currency.symbol", "R",
|
||||
"The symbol for the currency in use to measure usage.", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpHost = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.host", "",
|
||||
"Quota SMTP host for quota related emails", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpTimeout = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.connection.timeout", "60",
|
||||
"Quota SMTP server connection timeout duration", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpUser = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.user", "",
|
||||
"Quota SMTP server username", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpPassword = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.password", "",
|
||||
"Quota SMTP server password", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpPort = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.port", "",
|
||||
"Quota SMTP port", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpAuthType = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.useAuth", "",
|
||||
"If true, use secure SMTP authentication when sending emails.", true);
|
||||
|
||||
public static final ConfigKey<String> QuotaSmtpSender = new ConfigKey<String>("Advanced", String.class, "quota.usage.smtp.sender", "",
|
||||
"Sender of quota alert email (will be in the From header of the email)", true);
|
||||
|
||||
enum QuotaEmailTemplateTypes {
|
||||
QUOTA_LOW, QUOTA_EMPTY, QUOTA_UNLOCK_ACCOUNT, QUOTA_STATEMENT
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
// 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.constant;
|
||||
|
||||
import org.apache.cloudstack.usage.UsageTypes;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class QuotaTypes extends UsageTypes {
|
||||
public static final int CPU_CLOCK_RATE = 15;
|
||||
public static final int CPU_NUMBER = 16;
|
||||
public static final int MEMORY = 17;
|
||||
|
||||
private Integer quotaType;
|
||||
private String quotaName;
|
||||
private String quotaUnit;
|
||||
private String description;
|
||||
private String discriminator;
|
||||
|
||||
public QuotaTypes(Integer quotaType, String name, String unit, String description) {
|
||||
this.quotaType = quotaType;
|
||||
this.description = description;
|
||||
this.quotaName = name;
|
||||
this.quotaUnit = unit;
|
||||
this.discriminator = "None";
|
||||
}
|
||||
|
||||
public static HashMap<Integer, QuotaTypes> listQuotaTypes() {
|
||||
final HashMap<Integer, QuotaTypes> quotaTypeList = new HashMap<Integer, QuotaTypes>();
|
||||
quotaTypeList.put(new Integer(RUNNING_VM), new QuotaTypes(new Integer(RUNNING_VM), "RUNNING_VM", "Compute-Month", "Running Vm Usage"));
|
||||
quotaTypeList.put(new Integer(ALLOCATED_VM), new QuotaTypes(new Integer(ALLOCATED_VM), "ALLOCATED_VM", "Compute-Month", "Allocated Vm Usage"));
|
||||
quotaTypeList.put(new Integer(IP_ADDRESS), new QuotaTypes(new Integer(IP_ADDRESS), "IP_ADDRESS", "IP-Month", "IP Address Usage"));
|
||||
quotaTypeList.put(new Integer(NETWORK_BYTES_SENT), new QuotaTypes(new Integer(NETWORK_BYTES_SENT), "NETWORK_BYTES_SENT", "GB", "Network Usage (Bytes Sent)"));
|
||||
quotaTypeList.put(new Integer(NETWORK_BYTES_RECEIVED), new QuotaTypes(new Integer(NETWORK_BYTES_RECEIVED), "NETWORK_BYTES_RECEIVED", "GB", "Network Usage (Bytes Received)"));
|
||||
quotaTypeList.put(new Integer(VOLUME), new QuotaTypes(new Integer(VOLUME), "VOLUME", "GB-Month", "Volume Usage"));
|
||||
quotaTypeList.put(new Integer(TEMPLATE), new QuotaTypes(new Integer(TEMPLATE), "TEMPLATE", "GB-Month", "Template Usage"));
|
||||
quotaTypeList.put(new Integer(ISO), new QuotaTypes(new Integer(ISO), "ISO", "GB-Month", "ISO Usage"));
|
||||
quotaTypeList.put(new Integer(SNAPSHOT), new QuotaTypes(new Integer(SNAPSHOT), "SNAPSHOT", "GB-Month", "Snapshot Usage"));
|
||||
quotaTypeList.put(new Integer(SECURITY_GROUP), new QuotaTypes(new Integer(SECURITY_GROUP), "SECURITY_GROUP", "Policy-Month", "Security Group Usage"));
|
||||
quotaTypeList.put(new Integer(LOAD_BALANCER_POLICY), new QuotaTypes(new Integer(LOAD_BALANCER_POLICY), "LOAD_BALANCER_POLICY", "Policy-Month", "Load Balancer Usage"));
|
||||
quotaTypeList.put(new Integer(PORT_FORWARDING_RULE), new QuotaTypes(new Integer(PORT_FORWARDING_RULE), "PORT_FORWARDING_RULE", "Policy-Month", "Port Forwarding Usage"));
|
||||
quotaTypeList.put(new Integer(NETWORK_OFFERING), new QuotaTypes(new Integer(NETWORK_OFFERING), "NETWORK_OFFERING", "Policy-Month", "Network Offering Usage"));
|
||||
quotaTypeList.put(new Integer(VPN_USERS), new QuotaTypes(new Integer(VPN_USERS), "VPN_USERS", "Policy-Month", "VPN users usage"));
|
||||
quotaTypeList.put(new Integer(VM_DISK_IO_READ), new QuotaTypes(new Integer(VM_DISK_IO_READ), "VM_DISK_IO_READ", "GB", "VM Disk usage(I/O Read)"));
|
||||
quotaTypeList.put(new Integer(VM_DISK_IO_WRITE), new QuotaTypes(new Integer(VM_DISK_IO_WRITE), "VM_DISK_IO_WRITE", "GB", "VM Disk usage(I/O Write)"));
|
||||
quotaTypeList.put(new Integer(VM_DISK_BYTES_READ), new QuotaTypes(new Integer(VM_DISK_BYTES_READ), "VM_DISK_BYTES_READ", "GB", "VM Disk usage(Bytes Read)"));
|
||||
quotaTypeList.put(new Integer(VM_DISK_BYTES_WRITE), new QuotaTypes(new Integer(VM_DISK_BYTES_WRITE), "VPN_USERS", "GB", "VM Disk usage(Bytes Write)"));
|
||||
quotaTypeList.put(new Integer(VM_SNAPSHOT), new QuotaTypes(new Integer(VM_SNAPSHOT), "VM_SNAPSHOT", "GB-Month", "VM Snapshot storage usage"));
|
||||
quotaTypeList.put(new Integer(CPU_CLOCK_RATE), new QuotaTypes(new Integer(CPU_CLOCK_RATE), "CPU_CLOCK_RATE", "Compute-Month", "Quota tariff for using 1 CPU of clock rate 100MHz"));
|
||||
quotaTypeList.put(new Integer(CPU_NUMBER), new QuotaTypes(new Integer(CPU_NUMBER), "CPU_NUMBER", "Compute-Month", "Quota tariff for running VM that has 1vCPU"));
|
||||
quotaTypeList.put(new Integer(MEMORY), new QuotaTypes(new Integer(MEMORY), "MEMORY", "Compute-Month", "Quota tariff for using 1MB or RAM for 1 hour"));
|
||||
return quotaTypeList;
|
||||
}
|
||||
|
||||
public String getDiscriminator() {
|
||||
return discriminator;
|
||||
}
|
||||
|
||||
public String getQuotaName() {
|
||||
return quotaName;
|
||||
}
|
||||
|
||||
public String getQuotaUnit() {
|
||||
return quotaUnit;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public Integer getQuotaType() {
|
||||
return quotaType;
|
||||
}
|
||||
|
||||
static public String getDescription(int quotaType) {
|
||||
return listQuotaTypes().get(quotaType).getDescription();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
//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.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.QuotaAccountVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface QuotaAccountDao extends GenericDao<QuotaAccountVO, Long> {
|
||||
|
||||
List<QuotaAccountVO> listAll();
|
||||
|
||||
QuotaAccountVO findById(Long id);
|
||||
|
||||
QuotaAccountVO persist(QuotaAccountVO entity);
|
||||
|
||||
boolean update(Long id, QuotaAccountVO entity);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
//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.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.QuotaAccountVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
@Component
|
||||
@Local(value = { QuotaAccountDao.class })
|
||||
public class QuotaAccountDaoImpl extends GenericDaoBase<QuotaAccountVO, Long> implements QuotaAccountDao {
|
||||
|
||||
@Override
|
||||
public List<QuotaAccountVO> listAll() {
|
||||
List<QuotaAccountVO> result = null;
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
result = super.listAll();
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaAccountVO findById(Long id) {
|
||||
QuotaAccountVO result = null;
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
result = super.findById(id);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaAccountVO persist(QuotaAccountVO entity) {
|
||||
QuotaAccountVO result = null;
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
result = super.persist(entity);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(Long id, QuotaAccountVO entity) {
|
||||
boolean result = false;
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
result = super.update(id, entity);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
//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.dao;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface QuotaBalanceDao extends GenericDao<QuotaBalanceVO, Long> {
|
||||
|
||||
void saveQuotaBalance(List<QuotaBalanceVO> credits);
|
||||
|
||||
List<QuotaBalanceVO> findCreditBalance(long accountId, long domainId, Date startDate, Date endDate);
|
||||
|
||||
QuotaBalanceVO findLastBalanceEntry(long accountId, long domainId, Date beforeThis);
|
||||
|
||||
QuotaBalanceVO findLaterBalanceEntry(long accountId, long domainId, Date afterThis);
|
||||
|
||||
List<QuotaBalanceVO> findQuotaBalance(Long accountId, Long domainId, Date startDate, Date endDate);
|
||||
|
||||
List<QuotaBalanceVO> lastQuotaBalanceVO(Long accountId, Long domainId, Date startDate);
|
||||
|
||||
BigDecimal lastQuotaBalance(Long accountId, Long domainId, Date startDate);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,201 @@
|
|||
//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.dao;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
@Component
|
||||
@Local(value = { QuotaBalanceDao.class })
|
||||
public class QuotaBalanceDaoImpl extends GenericDaoBase<QuotaBalanceVO, Long> implements QuotaBalanceDao {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaBalanceDaoImpl.class.getName());
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public QuotaBalanceVO findLastBalanceEntry(final long accountId, final long domainId, final Date beforeThis) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
Filter filter = new Filter(QuotaBalanceVO.class, "updatedOn", false, 0L, 1L);
|
||||
SearchCriteria<QuotaBalanceVO> sc = createSearchCriteria();
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
sc.addAnd("creditsId", SearchCriteria.Op.EQ, 0);
|
||||
sc.addAnd("updatedOn", SearchCriteria.Op.LT, beforeThis);
|
||||
List<QuotaBalanceVO> quotab = this.search(sc, filter);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return quotab.size() > 0 ? quotab.get(0) : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public QuotaBalanceVO findLaterBalanceEntry(final long accountId, final long domainId, final Date afterThis) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
Filter filter = new Filter(QuotaBalanceVO.class, "updatedOn", true, 0L, 1L);
|
||||
SearchCriteria<QuotaBalanceVO> sc = createSearchCriteria();
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
sc.addAnd("creditsId", SearchCriteria.Op.EQ, 0);
|
||||
sc.addAnd("updatedOn", SearchCriteria.Op.GT, afterThis);
|
||||
List<QuotaBalanceVO> quotab = this.search(sc, filter);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return quotab.size() > 0 ? quotab.get(0) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveQuotaBalance(final List<QuotaBalanceVO> credits) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
for (QuotaBalanceVO credit : credits) {
|
||||
persist(credit);
|
||||
}
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public List<QuotaBalanceVO> findCreditBalance(final long accountId, final long domainId, final Date lastbalancedate, final Date beforeThis) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
Filter filter = new Filter(QuotaBalanceVO.class, "updatedOn", true, 0L, Long.MAX_VALUE);
|
||||
SearchCriteria<QuotaBalanceVO> sc = createSearchCriteria();
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
sc.addAnd("creditsId", SearchCriteria.Op.GT, 0);
|
||||
if ((lastbalancedate != null) && (beforeThis != null) && lastbalancedate.before(beforeThis)) {
|
||||
sc.addAnd("updatedOn", SearchCriteria.Op.BETWEEN, lastbalancedate, beforeThis);
|
||||
} else {
|
||||
return new ArrayList<QuotaBalanceVO>();
|
||||
}
|
||||
List<QuotaBalanceVO> qb = search(sc, filter);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return qb;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public List<QuotaBalanceVO> findQuotaBalance(final Long accountId, final Long domainId, final Date startDate, final Date endDate) {
|
||||
// TODO account for series of credits around boundaries
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
List<QuotaBalanceVO> quotaUsageRecords = null;
|
||||
try {
|
||||
SearchCriteria<QuotaBalanceVO> sc = createSearchCriteria();
|
||||
if (accountId != null) {
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
}
|
||||
if (domainId != null) {
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
}
|
||||
if ((startDate != null) && (endDate != null) && startDate.before(endDate)) {
|
||||
sc.addAnd("updatedOn", SearchCriteria.Op.BETWEEN, startDate, endDate);
|
||||
} else {
|
||||
return new ArrayList<QuotaBalanceVO>();
|
||||
}
|
||||
quotaUsageRecords = listBy(sc);
|
||||
if (quotaUsageRecords.size() == 0) {
|
||||
quotaUsageRecords.addAll(lastQuotaBalanceVO(accountId, domainId, startDate));
|
||||
}
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return quotaUsageRecords;
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public List<QuotaBalanceVO> lastQuotaBalanceVO(final Long accountId, final Long domainId, final Date pivotDate) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
List<QuotaBalanceVO> quotaUsageRecords = null;
|
||||
List<QuotaBalanceVO> trimmedRecords = new ArrayList<QuotaBalanceVO>();
|
||||
try {
|
||||
Filter filter = new Filter(QuotaBalanceVO.class, "updatedOn", false, 0L, 100L);
|
||||
// ASSUMPTION there will be less than 100 continuous credit
|
||||
// transactions
|
||||
SearchCriteria<QuotaBalanceVO> sc = createSearchCriteria();
|
||||
if (accountId != null) {
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
}
|
||||
if (domainId != null) {
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
}
|
||||
if ((pivotDate != null)) {
|
||||
sc.addAnd("updatedOn", SearchCriteria.Op.LTEQ, pivotDate);
|
||||
}
|
||||
quotaUsageRecords = search(sc, filter);
|
||||
|
||||
// get records before startDate to find start balance
|
||||
for (Iterator<QuotaBalanceVO> it = quotaUsageRecords.iterator(); it.hasNext();) {
|
||||
QuotaBalanceVO entry = it.next();
|
||||
s_logger.info("findQuotaBalance Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId());
|
||||
if (entry.getCreditsId() > 0) {
|
||||
trimmedRecords.add(entry);
|
||||
} else {
|
||||
trimmedRecords.add(entry);
|
||||
break; // add only consecutive credit entries and last balance entry
|
||||
}
|
||||
}
|
||||
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return trimmedRecords;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal lastQuotaBalance(final Long accountId, final Long domainId, Date startDate) {
|
||||
List<QuotaBalanceVO> quotaBalance = lastQuotaBalanceVO(accountId, domainId, startDate);
|
||||
if (quotaBalance.size() == 0) {
|
||||
new InvalidParameterValueException("There are no balance entries on or before the requested date.");
|
||||
}
|
||||
BigDecimal finalBalance = new BigDecimal(0);
|
||||
for (Iterator<QuotaBalanceVO> it = quotaBalance.iterator(); it.hasNext();) {
|
||||
QuotaBalanceVO entry = it.next();
|
||||
s_logger.info("lastQuotaBalance Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId());
|
||||
finalBalance.add(entry.getCreditBalance());
|
||||
}
|
||||
return finalBalance;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.QuotaCreditsVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface QuotaCreditsDao extends GenericDao<QuotaCreditsVO, Long> {
|
||||
|
||||
List<QuotaCreditsVO> findCredits(long accountId, long domainId, Date startDate, Date endDate);
|
||||
|
||||
QuotaCreditsVO saveCredits(QuotaCreditsVO credits);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
//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.dao;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
|
||||
import org.apache.cloudstack.quota.vo.QuotaCreditsVO;
|
||||
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
@Component
|
||||
@Local(value = { QuotaCreditsDao.class })
|
||||
public class QuotaCreditsDaoImpl extends GenericDaoBase<QuotaCreditsVO, Long> implements QuotaCreditsDao {
|
||||
@Inject
|
||||
QuotaBalanceDao _quotaBalanceDao;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public List<QuotaCreditsVO> findCredits(final long accountId, final long domainId, final Date startDate, final Date endDate) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
Filter filter = new Filter(QuotaCreditsVO.class, "updatedOn", true, 0L, Long.MAX_VALUE);
|
||||
SearchCriteria<QuotaCreditsVO> sc = createSearchCriteria();
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, accountId);
|
||||
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
|
||||
if ((startDate != null) && (endDate != null) && startDate.before(endDate)) {
|
||||
sc.addAnd("updatedOn", SearchCriteria.Op.BETWEEN, startDate, endDate);
|
||||
} else {
|
||||
return new ArrayList<QuotaCreditsVO>();
|
||||
}
|
||||
List<QuotaCreditsVO> qc = search(sc, filter);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return qc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaCreditsVO saveCredits(final QuotaCreditsVO credits) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
persist(credits);
|
||||
// make an entry in the balance table
|
||||
QuotaBalanceVO bal = new QuotaBalanceVO(credits);
|
||||
_quotaBalanceDao.persist(bal);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return credits;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
//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.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface QuotaEmailTemplatesDao extends GenericDao<QuotaEmailTemplatesVO, Long> {
|
||||
List<QuotaEmailTemplatesVO> listAllQuotaEmailTemplates(String templateName);
|
||||
boolean updateQuotaEmailTemplate(QuotaEmailTemplatesVO template);
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
//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.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Local(value = { QuotaEmailTemplatesDao.class })
|
||||
public class QuotaEmailTemplatesDaoImpl extends GenericDaoBase<QuotaEmailTemplatesVO, Long> implements QuotaEmailTemplatesDao {
|
||||
|
||||
protected SearchBuilder<QuotaEmailTemplatesVO> QuotaEmailTemplateSearch;
|
||||
|
||||
public QuotaEmailTemplatesDaoImpl() {
|
||||
super();
|
||||
|
||||
QuotaEmailTemplateSearch = createSearchBuilder();
|
||||
QuotaEmailTemplateSearch.and("template_name", QuotaEmailTemplateSearch.entity().getTemplateName(), SearchCriteria.Op.EQ);
|
||||
QuotaEmailTemplateSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaEmailTemplatesVO> listAllQuotaEmailTemplates(String templateName) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
SearchCriteria<QuotaEmailTemplatesVO> sc = QuotaEmailTemplateSearch.create();
|
||||
if (templateName != null) {
|
||||
sc.setParameters("template_name", templateName);
|
||||
}
|
||||
List<QuotaEmailTemplatesVO> result = this.listBy(sc);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuotaEmailTemplate(QuotaEmailTemplatesVO template) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
final boolean result = this.update(template.getId(), template);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
//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.dao;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface QuotaTariffDao extends GenericDao<QuotaTariffVO, Long> {
|
||||
|
||||
QuotaTariffVO findTariffPlanByUsageType(int quotaType, Date onOrBefore);
|
||||
|
||||
List<QuotaTariffVO> listAllTariffPlans(Date onOrBefore);
|
||||
|
||||
boolean updateQuotaTariff(QuotaTariffVO plan);
|
||||
|
||||
QuotaTariffVO addQuotaTariff(QuotaTariffVO plan);
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
//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.dao;
|
||||
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
import org.apache.cloudstack.quota.constant.QuotaTypes;
|
||||
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Local(value = { QuotaTariffDao.class })
|
||||
public class QuotaTariffDaoImpl extends GenericDaoBase<QuotaTariffVO, Long> implements QuotaTariffDao {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaTariffDaoImpl.class.getName());
|
||||
|
||||
private final SearchBuilder<QuotaTariffVO> searchUsageType;
|
||||
private final SearchBuilder<QuotaTariffVO> listAllIncludedUsageType;
|
||||
|
||||
public QuotaTariffDaoImpl() {
|
||||
super();
|
||||
searchUsageType = createSearchBuilder();
|
||||
searchUsageType.and("usage_type", searchUsageType.entity().getUsageType(), SearchCriteria.Op.EQ);
|
||||
searchUsageType.done();
|
||||
|
||||
listAllIncludedUsageType = createSearchBuilder();
|
||||
listAllIncludedUsageType.and("onorbefore", listAllIncludedUsageType.entity().getEffectiveOn(), SearchCriteria.Op.LTEQ);
|
||||
listAllIncludedUsageType.and("quotatype", listAllIncludedUsageType.entity().getUsageType(), SearchCriteria.Op.EQ);
|
||||
listAllIncludedUsageType.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaTariffVO findTariffPlanByUsageType(final int quotaType, final Date effectiveDate) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
List<QuotaTariffVO> result = null;
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
final Filter filter = new Filter(QuotaTariffVO.class, "effectiveOn", false, 0L, 1L);
|
||||
final SearchCriteria<QuotaTariffVO> sc = listAllIncludedUsageType.create();
|
||||
sc.setParameters("onorbefore", effectiveDate);
|
||||
sc.setParameters("quotatype", quotaType);
|
||||
result = search(sc, filter);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
// Switch back
|
||||
TransactionLegacy.open(opendb).close();
|
||||
if (result.size() > 0) {
|
||||
//s_logger.info("findTariffPlanByUsageType: " + effectiveDate + "quota type " + quotaType + " val=" + result.get(0).getCurrencyValue());
|
||||
return result.get(0);
|
||||
} else {
|
||||
//s_logger.info("Missing quota type " + quotaType);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<QuotaTariffVO> listAllTariffPlans(final Date effectiveDate) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
List<QuotaTariffVO> tariffs = new ArrayList<QuotaTariffVO>();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
final Filter filter = new Filter(QuotaTariffVO.class, "effectiveOn", false, 0L, 1L);
|
||||
final SearchCriteria<QuotaTariffVO> sc = listAllIncludedUsageType.create();
|
||||
sc.setParameters("onorbefore", effectiveDate);
|
||||
for (Integer quotaType : QuotaTypes.listQuotaTypes().keySet()) {
|
||||
sc.setParameters("quotatype", quotaType);
|
||||
List<QuotaTariffVO> result = search(sc, filter);
|
||||
if (result.size() > 0) {
|
||||
tariffs.add(result.get(0));
|
||||
s_logger.info("listAllTariffPlans onorbefore" + effectiveDate + "quota type " + result.get(0).getDescription() + " , effective Date=" + result.get(0).getEffectiveOn() + " val=" + result.get(0).getCurrencyValue());
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
// Switch back
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return tariffs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateQuotaTariff(QuotaTariffVO plan) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); // Switch
|
||||
// to
|
||||
boolean result = false;
|
||||
try {
|
||||
// Usage DB
|
||||
result = this.update(plan.getId(), plan);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
TransactionLegacy.open(opendb).close(); // Switch back
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public QuotaTariffVO addQuotaTariff(QuotaTariffVO plan) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB); // Switch
|
||||
// to
|
||||
QuotaTariffVO result = null;
|
||||
try {
|
||||
// Usage DB
|
||||
plan.setId(null);
|
||||
result = this.persist(plan);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
TransactionLegacy.open(opendb).close(); // Switch back
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
//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.dao;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.QuotaUsageVO;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
public interface QuotaUsageDao extends GenericDao<QuotaUsageVO, Long> {
|
||||
|
||||
List<QuotaUsageVO> findQuotaUsage(Long accountId, Long domainId, Integer usageType, Date startDate, Date endDate);
|
||||
|
||||
Pair<List<QuotaUsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<QuotaUsageVO> sc, Filter filter);
|
||||
|
||||
void saveQuotaUsage(List<QuotaUsageVO> credits);
|
||||
|
||||
BigDecimal findTotalQuotaUsage(Long accountId, Long domainId, Integer usageType, Date startDate, Date endDate);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
//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.dao;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.quota.vo.QuotaUsageVO;
|
||||
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
@Component
|
||||
@Local(value = { QuotaUsageDao.class })
|
||||
public class QuotaUsageDaoImpl extends GenericDaoBase<QuotaUsageVO, Long> implements QuotaUsageDao {
|
||||
|
||||
@Override
|
||||
public Pair<List<QuotaUsageVO>, Integer> searchAndCountAllRecords(SearchCriteria<QuotaUsageVO> sc, Filter filter) {
|
||||
return listAndCountIncludingRemovedBy(sc, filter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveQuotaUsage(List<QuotaUsageVO> records) {
|
||||
for (QuotaUsageVO usageRecord : records) {
|
||||
persist(usageRecord);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public BigDecimal findTotalQuotaUsage(final Long accountId, final Long domainId, final Integer usageType, final Date startDate, final Date endDate) {
|
||||
List<QuotaUsageVO> quotaUsage = findQuotaUsage(accountId, domainId, null, startDate, endDate);
|
||||
BigDecimal total = new BigDecimal(0);
|
||||
for (final QuotaUsageVO quotaRecord : quotaUsage) {
|
||||
total = total.add(quotaRecord.getQuotaUsed());
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public List<QuotaUsageVO> findQuotaUsage(final Long accountId, final Long domainId, final Integer usageType, final Date startDate, final Date endDate) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
List<QuotaUsageVO> quotaUsageRecords = null;
|
||||
try {
|
||||
// TODO instead of max value query with reasonable number and
|
||||
// iterate
|
||||
SearchCriteria<QuotaUsageVO> sc = createSearchCriteria();
|
||||
if (accountId != null) {
|
||||
sc.addAnd("accountId", SearchCriteria.Op.EQ, 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);
|
||||
}
|
||||
if (usageType != null) {
|
||||
sc.addAnd("usageType", SearchCriteria.Op.EQ, usageType);
|
||||
}
|
||||
if ((startDate != null) && (endDate != null) && startDate.before(endDate)) {
|
||||
sc.addAnd("startDate", SearchCriteria.Op.BETWEEN, startDate, endDate);
|
||||
sc.addAnd("endDate", SearchCriteria.Op.BETWEEN, startDate, endDate);
|
||||
} else {
|
||||
return new ArrayList<QuotaUsageVO>();
|
||||
}
|
||||
quotaUsageRecords = listBy(sc);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return quotaUsageRecords;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
// 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.dao;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.ServiceOfferingVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface ServiceOfferingDao extends GenericDao<ServiceOfferingVO, Long> {
|
||||
|
||||
ServiceOfferingVO findServiceOffering(Long vmId, long serviceOfferingId);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
// 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.dao;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.quota.vo.ServiceOfferingVO;
|
||||
|
||||
import com.cloud.event.UsageEventVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
|
||||
@Component
|
||||
@Local(value = { ServiceOfferingDao.class })
|
||||
@DB()
|
||||
public class ServiceOfferingDaoImpl extends GenericDaoBase<ServiceOfferingVO, Long> implements ServiceOfferingDao {
|
||||
protected static final Logger s_logger = Logger.getLogger(ServiceOfferingDaoImpl.class);
|
||||
|
||||
@Inject
|
||||
UserVmDetailsDao userVmDetailsDao;
|
||||
|
||||
@Override
|
||||
public ServiceOfferingVO findServiceOffering(final Long vmId, final long serviceOfferingId) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.CLOUD_DB);
|
||||
ServiceOfferingVO result;
|
||||
try {
|
||||
result = findById(vmId, serviceOfferingId);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return result;
|
||||
}
|
||||
|
||||
public ServiceOfferingVO findById(Long vmId, long serviceOfferingId) {
|
||||
ServiceOfferingVO offering = super.findById(serviceOfferingId);
|
||||
if (offering.isDynamic()) {
|
||||
offering.setDynamicFlag(true);
|
||||
if (vmId == null) {
|
||||
throw new CloudRuntimeException("missing argument vmId");
|
||||
}
|
||||
Map<String, String> dynamicOffering = userVmDetailsDao.listDetailsKeyPairs(vmId);
|
||||
return getcomputeOffering(offering, dynamicOffering);
|
||||
}
|
||||
return offering;
|
||||
}
|
||||
|
||||
public ServiceOfferingVO getcomputeOffering(ServiceOfferingVO serviceOffering, Map<String, String> customParameters) {
|
||||
ServiceOfferingVO dummyoffering = new ServiceOfferingVO(serviceOffering);
|
||||
dummyoffering.setDynamicFlag(true);
|
||||
if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuNumber.name())) {
|
||||
dummyoffering.setCpu(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuNumber.name())));
|
||||
}
|
||||
if (customParameters.containsKey(UsageEventVO.DynamicParameters.cpuSpeed.name())) {
|
||||
dummyoffering.setSpeed(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.cpuSpeed.name())));
|
||||
}
|
||||
if (customParameters.containsKey(UsageEventVO.DynamicParameters.memory.name())) {
|
||||
dummyoffering.setRamSize(Integer.parseInt(customParameters.get(UsageEventVO.DynamicParameters.memory.name())));
|
||||
}
|
||||
return dummyoffering;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 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.dao;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
import org.apache.cloudstack.quota.vo.UserVmDetailVO;
|
||||
|
||||
public interface UserVmDetailsDao extends GenericDao<UserVmDetailVO, Long> {
|
||||
|
||||
Map<String, String> listDetailsKeyPairs(long resourceId);
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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.quota.dao;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.apache.cloudstack.quota.vo.UserVmDetailVO;
|
||||
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
|
||||
@Component
|
||||
@Local(value = UserVmDetailsDao.class)
|
||||
public class UserVmDetailsDaoImpl extends GenericDaoBase<UserVmDetailVO, Long> implements UserVmDetailsDao {
|
||||
private SearchBuilder<UserVmDetailVO> AllFieldsSearch;
|
||||
|
||||
public UserVmDetailsDaoImpl() {
|
||||
AllFieldsSearch = createSearchBuilder();
|
||||
AllFieldsSearch.and("resourceId", AllFieldsSearch.entity().getResourceId(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ);
|
||||
AllFieldsSearch.and("value", AllFieldsSearch.entity().getValue(), SearchCriteria.Op.EQ);
|
||||
// FIXME SnapshotDetailsVO doesn't have a display field
|
||||
if (_allAttributes.containsKey("display")) {
|
||||
AllFieldsSearch.and("display", AllFieldsSearch.entity().isDisplay(), SearchCriteria.Op.EQ);
|
||||
}
|
||||
AllFieldsSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> listDetailsKeyPairs(long resourceId) {
|
||||
SearchCriteria<UserVmDetailVO> sc = AllFieldsSearch.create();
|
||||
sc.setParameters("resourceId", resourceId);
|
||||
|
||||
List<UserVmDetailVO> results = search(sc, null);
|
||||
Map<String, String> details = new HashMap<String, String>(results.size());
|
||||
for (UserVmDetailVO result : results) {
|
||||
details.put(result.getName(), result.getValue());
|
||||
}
|
||||
return details;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
//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.vo;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_account")
|
||||
public class QuotaAccountVO implements InternalIdentity {
|
||||
|
||||
private static final long serialVersionUID = -7112846845287653210L;
|
||||
|
||||
@Id
|
||||
@Column(name = "account_id")
|
||||
private Long accountId = null;
|
||||
|
||||
@Column(name = "quota_enforce")
|
||||
private Integer quotaEnforce = null;
|
||||
|
||||
@Column(name = "quota_balance")
|
||||
private BigDecimal quotaBalance;
|
||||
|
||||
@Column(name = "quota_balance_date")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date quotaBalanceDate = null;
|
||||
|
||||
@Column(name = "quota_min_balance")
|
||||
private BigDecimal quotaMinBalance;
|
||||
|
||||
@Column(name = "quota_alert_type")
|
||||
private Integer quotaAlertType = null;
|
||||
|
||||
@Column(name = "quota_alert_date")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date quotaAlertDate = null;
|
||||
|
||||
@Column(name = "last_statement_date")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date lastStatementDate = null;
|
||||
|
||||
public QuotaAccountVO() {
|
||||
}
|
||||
|
||||
public QuotaAccountVO(Long accountId) {
|
||||
super();
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public Long getAccountId() {
|
||||
return accountId;
|
||||
}
|
||||
|
||||
public void setAccountId(Long accountId) {
|
||||
this.accountId = accountId;
|
||||
}
|
||||
|
||||
public Integer getQuotaEnforce() {
|
||||
return quotaEnforce == null ? 0 : quotaEnforce;
|
||||
}
|
||||
|
||||
public void setQuotaEnforce(Integer quotaEnforce) {
|
||||
this.quotaEnforce = quotaEnforce;
|
||||
}
|
||||
|
||||
public BigDecimal getQuotaBalance() {
|
||||
return quotaBalance;
|
||||
}
|
||||
|
||||
public void setQuotaBalance(BigDecimal quotaBalance) {
|
||||
this.quotaBalance = quotaBalance;
|
||||
}
|
||||
|
||||
public BigDecimal getQuotaMinBalance() {
|
||||
return quotaMinBalance == null ? new BigDecimal(0) : quotaMinBalance;
|
||||
}
|
||||
|
||||
public void setQuotaMinBalance(BigDecimal quotaMinBalance) {
|
||||
this.quotaMinBalance = quotaMinBalance;
|
||||
}
|
||||
|
||||
public Integer getQuotaAlertType() {
|
||||
return quotaAlertType;
|
||||
}
|
||||
|
||||
public void setQuotaAlertType(Integer quotaAlertType) {
|
||||
this.quotaAlertType = quotaAlertType;
|
||||
}
|
||||
|
||||
public Date getQuotaAlertDate() {
|
||||
return quotaAlertDate;
|
||||
}
|
||||
|
||||
public void setQuotaAlertDate(Date quotaAlertDate) {
|
||||
this.quotaAlertDate = quotaAlertDate;
|
||||
}
|
||||
|
||||
public Date getQuotaBalanceDate() {
|
||||
return quotaBalanceDate;
|
||||
}
|
||||
|
||||
public void setQuotaBalanceDate(Date quotaBalanceDate) {
|
||||
this.quotaBalanceDate = quotaBalanceDate;
|
||||
}
|
||||
|
||||
public Date getLastStatementDate() {
|
||||
return lastStatementDate;
|
||||
}
|
||||
|
||||
public void setLastStatementDate(Date lastStatementDate) {
|
||||
this.lastStatementDate = lastStatementDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
//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.vo;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_balance")
|
||||
public class QuotaBalanceVO implements InternalIdentity {
|
||||
|
||||
private static final long serialVersionUID = -7112846845287653210L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private Long accountId = null;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private Long domainId = null;
|
||||
|
||||
@Column(name = "credit_balance")
|
||||
private BigDecimal creditBalance;
|
||||
|
||||
@Column(name = "credits_id")
|
||||
private Long creditsId;
|
||||
|
||||
@Column(name = "updated_on")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date updatedOn = null;
|
||||
|
||||
public QuotaBalanceVO() {
|
||||
super();
|
||||
}
|
||||
|
||||
public QuotaBalanceVO(QuotaCreditsVO credit) {
|
||||
super();
|
||||
this.accountId = credit.getAccountId();
|
||||
this.domainId = credit.getDomainId();
|
||||
this.creditBalance = credit.getCredit();
|
||||
this.updatedOn = credit.getUpdatedOn();
|
||||
this.creditsId = credit.getId();
|
||||
}
|
||||
|
||||
public QuotaBalanceVO(Long accountId, Long domainId, BigDecimal creditBalance, Date updatedOn) {
|
||||
super();
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.creditBalance = creditBalance;
|
||||
this.creditsId=0L;
|
||||
this.updatedOn = updatedOn;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Long getCreditsId() {
|
||||
return creditsId;
|
||||
}
|
||||
|
||||
public void setCreditsId(Long creditsId) {
|
||||
this.creditsId = creditsId;
|
||||
}
|
||||
|
||||
public BigDecimal getCreditBalance() {
|
||||
return creditBalance;
|
||||
}
|
||||
|
||||
public void setCreditBalance(BigDecimal creditBalance) {
|
||||
this.creditBalance = creditBalance;
|
||||
}
|
||||
|
||||
public Date getUpdatedOn() {
|
||||
return updatedOn;
|
||||
}
|
||||
|
||||
public void setUpdatedOn(Date updatedOn) {
|
||||
this.updatedOn = updatedOn;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
//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.vo;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_credits")
|
||||
public class QuotaCreditsVO implements InternalIdentity {
|
||||
|
||||
private static final long serialVersionUID = -3576833845287653210L;
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "account_id")
|
||||
private Long accountId = null;
|
||||
|
||||
@Column(name = "domain_id")
|
||||
private Long domainId = null;
|
||||
|
||||
@Column(name = "credit")
|
||||
private BigDecimal credit;
|
||||
|
||||
@Column(name = "updated_on")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date updatedOn = null;
|
||||
|
||||
public QuotaCreditsVO() {
|
||||
}
|
||||
|
||||
public QuotaCreditsVO(long accountId, long domainId, BigDecimal credit, long updatedBy) {
|
||||
super();
|
||||
this.accountId = accountId;
|
||||
this.domainId = domainId;
|
||||
this.credit = credit;
|
||||
this.updatedBy = updatedBy;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public BigDecimal getCredit() {
|
||||
return credit;
|
||||
}
|
||||
|
||||
public void setCredit(BigDecimal credit) {
|
||||
this.credit = credit;
|
||||
}
|
||||
|
||||
public Date getUpdatedOn() {
|
||||
return updatedOn;
|
||||
}
|
||||
|
||||
public void setUpdatedOn(Date updatedOn) {
|
||||
this.updatedOn = updatedOn;
|
||||
}
|
||||
|
||||
public Long getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
public void setUpdatedBy(Long updatedBy) {
|
||||
this.updatedBy = updatedBy;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// User ID of the creditor
|
||||
@Column(name = "updated_by")
|
||||
private Long updatedBy = null;
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
// TODO Auto-generated method stub
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
//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.vo;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_email_templates")
|
||||
public class QuotaEmailTemplatesVO implements InternalIdentity {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "template_name")
|
||||
private String templateName;
|
||||
|
||||
@Column(name = "template_subject")
|
||||
private String templateSubject;
|
||||
|
||||
@Column(name = "template_body")
|
||||
private String templateBody;
|
||||
|
||||
@Column(name = "locale")
|
||||
private String locale;
|
||||
|
||||
@Column(name = "updated")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date lastUpdated = null;
|
||||
|
||||
public QuotaEmailTemplatesVO() {
|
||||
}
|
||||
|
||||
public QuotaEmailTemplatesVO(String templateName, String templateSubject, String templateBody) {
|
||||
super();
|
||||
this.templateName = templateName;
|
||||
this.templateSubject = templateSubject;
|
||||
this.templateBody = templateBody;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTemplateName() {
|
||||
return templateName;
|
||||
}
|
||||
|
||||
public void setTemplateName(String templateName) {
|
||||
this.templateName = templateName;
|
||||
}
|
||||
|
||||
public String getTemplateSubject() {
|
||||
return templateSubject;
|
||||
}
|
||||
|
||||
public void setTemplateSubject(String templateSubject) {
|
||||
this.templateSubject = templateSubject;
|
||||
}
|
||||
|
||||
public String getTemplateBody() {
|
||||
return templateBody;
|
||||
}
|
||||
|
||||
public void setTemplateBody(String templateBody) {
|
||||
this.templateBody = templateBody;
|
||||
}
|
||||
|
||||
public Date getLastUpdated() {
|
||||
return lastUpdated;
|
||||
}
|
||||
|
||||
public void setLastUpdated(Date lastUpdated) {
|
||||
this.lastUpdated = lastUpdated;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
//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.vo;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
import org.apache.cloudstack.quota.constant.QuotaTypes;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_tariff")
|
||||
public class QuotaTariffVO implements InternalIdentity {
|
||||
private static final long serialVersionUID = -7117933766387653203L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "usage_type")
|
||||
private int usageType;
|
||||
|
||||
@Column(name = "usage_name")
|
||||
private String usageName;
|
||||
|
||||
@Column(name = "usage_unit")
|
||||
private String usageUnit;
|
||||
|
||||
@Column(name = "usage_discriminator")
|
||||
private String usageDiscriminator;
|
||||
|
||||
@Column(name = "currency_value")
|
||||
private BigDecimal currencyValue;
|
||||
|
||||
@Column(name = "effective_on")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date effectiveOn = null;
|
||||
|
||||
@Column(name = "updated_on")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date updatedOn = null;
|
||||
|
||||
@Column(name = "updated_by")
|
||||
private Long updatedBy = null;
|
||||
|
||||
public QuotaTariffVO() {
|
||||
}
|
||||
|
||||
public QuotaTariffVO(final int usagetype, final String usagename, final String usageunit, final String usagediscriminator, final BigDecimal currencyvalue,
|
||||
final Date effectiveOn, final Date updatedOn, final long updatedBy) {
|
||||
this.usageType = usagetype;
|
||||
this.usageName = usagename;
|
||||
this.usageUnit = usageunit;
|
||||
this.usageDiscriminator = usagediscriminator;
|
||||
this.currencyValue = currencyvalue;
|
||||
this.effectiveOn = effectiveOn;
|
||||
this.updatedOn = updatedOn;
|
||||
this.updatedBy = updatedBy;
|
||||
}
|
||||
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Date getEffectiveOn() {
|
||||
return effectiveOn;
|
||||
}
|
||||
|
||||
public void setEffectiveOn(Date effectiveOn) {
|
||||
this.effectiveOn = effectiveOn;
|
||||
}
|
||||
|
||||
public Date getUpdatedOn() {
|
||||
return updatedOn;
|
||||
}
|
||||
|
||||
public void setUpdatedOn(Date updatedOn) {
|
||||
this.updatedOn = updatedOn;
|
||||
}
|
||||
|
||||
public Long getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
public void setUpdatedBy(Long updatedBy) {
|
||||
this.updatedBy = updatedBy;
|
||||
}
|
||||
|
||||
public int getUsageType() {
|
||||
return usageType;
|
||||
}
|
||||
|
||||
public void setUsageType(int usageType) {
|
||||
this.usageType = usageType;
|
||||
}
|
||||
|
||||
public String getUsageName() {
|
||||
return usageName;
|
||||
}
|
||||
|
||||
public void setUsageName(String usageName) {
|
||||
this.usageName = usageName;
|
||||
}
|
||||
|
||||
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 getCurrencyValue() {
|
||||
return currencyValue;
|
||||
}
|
||||
|
||||
public void setCurrencyValue(BigDecimal currencyValue) {
|
||||
this.currencyValue = currencyValue;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return QuotaTypes.getDescription(usageType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
//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.vo;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import org.apache.cloudstack.api.InternalIdentity;
|
||||
|
||||
@Entity
|
||||
@Table(name = "quota_usage")
|
||||
public class QuotaUsageVO implements InternalIdentity {
|
||||
|
||||
private static final long serialVersionUID = -7117933845287204781L;
|
||||
|
||||
@Id
|
||||
@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;
|
||||
|
||||
@Column(name = "usage_type")
|
||||
private int usageType;
|
||||
|
||||
@Column(name = "quota_used")
|
||||
private BigDecimal quotaUsed;
|
||||
|
||||
@Column(name = "start_date")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date startDate = null;
|
||||
|
||||
@Column(name = "end_date")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date endDate = null;
|
||||
|
||||
public QuotaUsageVO() {
|
||||
usageType=-1;
|
||||
quotaUsed = new BigDecimal(0);
|
||||
endDate = new Date();
|
||||
startDate = new Date();
|
||||
}
|
||||
|
||||
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 QuotaUsageVO(QuotaUsageVO toclone) {
|
||||
super();
|
||||
this.usageItemId = toclone.usageItemId;
|
||||
this.zoneId = toclone.zoneId;
|
||||
this.accountId = toclone.accountId;
|
||||
this.domainId = toclone.domainId;
|
||||
this.usageType = toclone.usageType;
|
||||
this.quotaUsed = toclone.quotaUsed;
|
||||
this.startDate = toclone.startDate;
|
||||
this.endDate = toclone.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
|
||||
return id;
|
||||
}
|
||||
|
||||
public Long getUsageItemId() {
|
||||
return usageItemId;
|
||||
}
|
||||
|
||||
public void setUsageItemId(Long usageItemId) {
|
||||
this.usageItemId = usageItemId;
|
||||
}
|
||||
|
||||
public int getUsageType() {
|
||||
return usageType;
|
||||
}
|
||||
|
||||
public void setUsageType(int usageType) {
|
||||
this.usageType = usageType;
|
||||
}
|
||||
|
||||
public BigDecimal getQuotaUsed() {
|
||||
return quotaUsed;
|
||||
}
|
||||
|
||||
public void setQuotaUsed(BigDecimal quotaUsed) {
|
||||
this.quotaUsed = quotaUsed;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,337 @@
|
|||
//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.vo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.DiscriminatorValue;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.PrimaryKeyJoinColumn;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Transient;
|
||||
|
||||
import com.cloud.offering.ServiceOffering;
|
||||
import com.cloud.storage.DiskOfferingVO;
|
||||
import com.cloud.storage.Storage.ProvisioningType;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
|
||||
@Entity
|
||||
@Table(name = "service_offering")
|
||||
@DiscriminatorValue(value = "Service")
|
||||
@PrimaryKeyJoinColumn(name = "id")
|
||||
public class ServiceOfferingVO extends DiskOfferingVO implements ServiceOffering {
|
||||
@Column(name = "cpu")
|
||||
private Integer cpu;
|
||||
|
||||
@Column(name = "speed")
|
||||
private Integer speed;
|
||||
|
||||
@Column(name = "ram_size")
|
||||
private Integer ramSize;
|
||||
|
||||
@Column(name = "nw_rate")
|
||||
private Integer rateMbps;
|
||||
|
||||
@Column(name = "mc_rate")
|
||||
private Integer multicastRateMbps;
|
||||
|
||||
@Column(name = "ha_enabled")
|
||||
private boolean offerHA;
|
||||
|
||||
@Column(name = "limit_cpu_use")
|
||||
private boolean limitCpuUse;
|
||||
|
||||
@Column(name = "is_volatile")
|
||||
private boolean volatileVm;
|
||||
|
||||
@Column(name = "host_tag")
|
||||
private String hostTag;
|
||||
|
||||
@Column(name = "default_use")
|
||||
private boolean defaultUse;
|
||||
|
||||
@Column(name = "vm_type")
|
||||
private String vmType;
|
||||
|
||||
@Column(name = "sort_key")
|
||||
int sortKey;
|
||||
|
||||
@Column(name = "deployment_planner")
|
||||
private String deploymentPlanner = null;
|
||||
|
||||
// This is a delayed load value. If the value is null,
|
||||
// then this field has not been loaded yet.
|
||||
// Call service offering dao to load it.
|
||||
@Transient
|
||||
Map<String, String> details;
|
||||
|
||||
// This flag is required to tell if the offering is dynamic once the cpu, memory and speed are set.
|
||||
// In some cases cpu, memory and speed are set to non-null values even if the offering is dynamic.
|
||||
@Transient
|
||||
boolean isDynamic;
|
||||
|
||||
protected ServiceOfferingVO() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, String displayText,
|
||||
ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, boolean defaultUse) {
|
||||
super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true);
|
||||
this.cpu = cpu;
|
||||
this.ramSize = ramSize;
|
||||
this.speed = speed;
|
||||
this.rateMbps = rateMbps;
|
||||
this.multicastRateMbps = multicastRateMbps;
|
||||
this.offerHA = offerHA;
|
||||
limitCpuUse = false;
|
||||
volatileVm = false;
|
||||
this.defaultUse = defaultUse;
|
||||
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
||||
}
|
||||
|
||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA, boolean limitCpuUse,
|
||||
boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse, VirtualMachine.Type vmType, Long domainId) {
|
||||
super(name, displayText, provisioningType, false, tags, recreatable, useLocalStorage, systemUse, true, domainId);
|
||||
this.cpu = cpu;
|
||||
this.ramSize = ramSize;
|
||||
this.speed = speed;
|
||||
this.rateMbps = rateMbps;
|
||||
this.multicastRateMbps = multicastRateMbps;
|
||||
this.offerHA = offerHA;
|
||||
this.limitCpuUse = limitCpuUse;
|
||||
this.volatileVm = volatileVm;
|
||||
this.vmType = vmType == null ? null : vmType.toString().toLowerCase();
|
||||
}
|
||||
|
||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
|
||||
boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
|
||||
VirtualMachine.Type vmType, Long domainId, String hostTag) {
|
||||
this(name,
|
||||
cpu,
|
||||
ramSize,
|
||||
speed,
|
||||
rateMbps,
|
||||
multicastRateMbps,
|
||||
offerHA,
|
||||
limitResourceUse,
|
||||
volatileVm,
|
||||
displayText,
|
||||
provisioningType,
|
||||
useLocalStorage,
|
||||
recreatable,
|
||||
tags,
|
||||
systemUse,
|
||||
vmType,
|
||||
domainId);
|
||||
this.hostTag = hostTag;
|
||||
}
|
||||
|
||||
public ServiceOfferingVO(String name, Integer cpu, Integer ramSize, Integer speed, Integer rateMbps, Integer multicastRateMbps, boolean offerHA,
|
||||
boolean limitResourceUse, boolean volatileVm, String displayText, ProvisioningType provisioningType, boolean useLocalStorage, boolean recreatable, String tags, boolean systemUse,
|
||||
VirtualMachine.Type vmType, Long domainId, String hostTag, String deploymentPlanner) {
|
||||
this(name,
|
||||
cpu,
|
||||
ramSize,
|
||||
speed,
|
||||
rateMbps,
|
||||
multicastRateMbps,
|
||||
offerHA,
|
||||
limitResourceUse,
|
||||
volatileVm,
|
||||
displayText,
|
||||
provisioningType,
|
||||
useLocalStorage,
|
||||
recreatable,
|
||||
tags,
|
||||
systemUse,
|
||||
vmType,
|
||||
domainId,
|
||||
hostTag);
|
||||
this.deploymentPlanner = deploymentPlanner;
|
||||
}
|
||||
|
||||
public ServiceOfferingVO(ServiceOfferingVO offering) {
|
||||
super(offering.getId(),
|
||||
offering.getName(),
|
||||
offering.getDisplayText(),
|
||||
offering.getProvisioningType(),
|
||||
false,
|
||||
offering.getTags(),
|
||||
offering.isRecreatable(),
|
||||
offering.getUseLocalStorage(),
|
||||
offering.getSystemUse(),
|
||||
true,
|
||||
offering.isCustomizedIops()== null ? false:offering.isCustomizedIops(),
|
||||
offering.getDomainId(),
|
||||
offering.getMinIops(),
|
||||
offering.getMaxIops());
|
||||
cpu = offering.getCpu();
|
||||
ramSize = offering.getRamSize();
|
||||
speed = offering.getSpeed();
|
||||
rateMbps = offering.getRateMbps();
|
||||
multicastRateMbps = offering.getMulticastRateMbps();
|
||||
offerHA = offering.getOfferHA();
|
||||
limitCpuUse = offering.getLimitCpuUse();
|
||||
volatileVm = offering.getVolatileVm();
|
||||
hostTag = offering.getHostTag();
|
||||
vmType = offering.getSystemVmType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getOfferHA() {
|
||||
return offerHA;
|
||||
}
|
||||
|
||||
public void setOfferHA(boolean offerHA) {
|
||||
this.offerHA = offerHA;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getLimitCpuUse() {
|
||||
return limitCpuUse;
|
||||
}
|
||||
|
||||
public void setLimitResourceUse(boolean limitCpuUse) {
|
||||
this.limitCpuUse = limitCpuUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getDefaultUse() {
|
||||
return defaultUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transient
|
||||
public String[] getTagsArray() {
|
||||
String tags = getTags();
|
||||
if (tags == null || tags.length() == 0) {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
return tags.split(",");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getCpu() {
|
||||
return cpu;
|
||||
}
|
||||
|
||||
public void setCpu(int cpu) {
|
||||
this.cpu = cpu;
|
||||
}
|
||||
|
||||
public void setSpeed(int speed) {
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public void setRamSize(int ramSize) {
|
||||
this.ramSize = ramSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSpeed() {
|
||||
return speed;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getRamSize() {
|
||||
return ramSize;
|
||||
}
|
||||
|
||||
public void setRateMbps(Integer rateMbps) {
|
||||
this.rateMbps = rateMbps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getRateMbps() {
|
||||
return rateMbps;
|
||||
}
|
||||
|
||||
public void setMulticastRateMbps(Integer multicastRateMbps) {
|
||||
this.multicastRateMbps = multicastRateMbps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getMulticastRateMbps() {
|
||||
return multicastRateMbps;
|
||||
}
|
||||
|
||||
public void setHostTag(String hostTag) {
|
||||
this.hostTag = hostTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHostTag() {
|
||||
return hostTag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSystemVmType() {
|
||||
return vmType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSortKey(int key) {
|
||||
sortKey = key;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSortKey() {
|
||||
return sortKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getVolatileVm() {
|
||||
return volatileVm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDeploymentPlanner() {
|
||||
return deploymentPlanner;
|
||||
}
|
||||
|
||||
public Map<String, String> getDetails() {
|
||||
return details;
|
||||
}
|
||||
|
||||
public String getDetail(String name) {
|
||||
assert (details != null) : "Did you forget to load the details?";
|
||||
|
||||
return details != null ? details.get(name) : null;
|
||||
}
|
||||
|
||||
public void setDetail(String name, String value) {
|
||||
assert (details != null) : "Did you forget to load the details?";
|
||||
|
||||
details.put(name, value);
|
||||
}
|
||||
|
||||
public void setDetails(Map<String, String> details) {
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDynamic() {
|
||||
return cpu == null || speed == null || ramSize == null || isDynamic;
|
||||
}
|
||||
|
||||
public void setDynamicFlag(boolean isdynamic) {
|
||||
isDynamic = isdynamic;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
//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.vo;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.apache.cloudstack.api.ResourceDetail;
|
||||
|
||||
@Entity
|
||||
@Table(name = "user_vm_details")
|
||||
public class UserVmDetailVO implements ResourceDetail {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "vm_id")
|
||||
private long resourceId;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "value", length = 5120)
|
||||
private String value;
|
||||
|
||||
@Column(name = "display")
|
||||
private boolean display = true;
|
||||
|
||||
public UserVmDetailVO() {
|
||||
}
|
||||
|
||||
public UserVmDetailVO(long vmId, String name, String value, boolean display) {
|
||||
this.resourceId = vmId;
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.display = display;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getResourceId() {
|
||||
return resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisplay() {
|
||||
return display;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -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. -->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>cloud-plugin-database-quota</artifactId>
|
||||
<name>Apache CloudStack Plugin - Quota Service</name>
|
||||
<parent>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloudstack-plugins</artifactId>
|
||||
<version>4.5.2</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-engine-schema</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-utils</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-quota</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${cs.commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>${cs.joda-time.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# 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.
|
||||
name=quota
|
||||
parent=api
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<!--
|
||||
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.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<bean id="QuotaService" class="org.apache.cloudstack.quota.QuotaServiceImpl" />
|
||||
<bean id="QuotaResponseBuilder" class="org.apache.cloudstack.api.response.QuotaResponseBuilderImpl"/>
|
||||
|
||||
</beans>
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
//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 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.BaseCmd;
|
||||
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.QuotaBalanceResponse;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
|
||||
import org.apache.cloudstack.api.response.QuotaStatementItemResponse;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "quotaBalance", responseObject = QuotaStatementItemResponse.class, description = "Create a quota balance statement", since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaBalanceCmd extends BaseCmd {
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaBalanceCmd.class.getName());
|
||||
|
||||
private static final String s_name = "quotabalanceresponse";
|
||||
|
||||
@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.")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.END_DATE, type = CommandType.DATE, 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, 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.ACCOUNT_ID, type = CommandType.UUID, entityType = AccountResponse.class, description = "List usage records for the specified account")
|
||||
private Long accountId;
|
||||
|
||||
@Inject
|
||||
QuotaResponseBuilder _responseBuilder;
|
||||
|
||||
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 Date getEndDate() {
|
||||
return endDate == null ? null : _responseBuilder.startOfNextDay(endDate);
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public QuotaBalanceCmd() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Long accountId = _accountService.getActiveAccountByName(accountName, domainId).getAccountId();
|
||||
if (accountId == null) {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<QuotaBalanceVO> quotaUsage = _responseBuilder.getQuotaBalance(this);
|
||||
|
||||
QuotaBalanceResponse response;
|
||||
if (getEndDate() == null) {
|
||||
response = _responseBuilder.createQuotaLastBalanceResponse(quotaUsage, startDate);
|
||||
} else {
|
||||
response = _responseBuilder.createQuotaBalanceResponse(quotaUsage, startDate, endDate);
|
||||
}
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
//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.Account;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.DomainResponse;
|
||||
import org.apache.cloudstack.api.response.QuotaCreditsResponse;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.QuotaService;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "quotaCredits", responseObject = QuotaCreditsResponse.class, description = "Add +-credits to an account", since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaCreditsCmd extends BaseCmd {
|
||||
|
||||
@Inject
|
||||
QuotaResponseBuilder _responseBuilder;
|
||||
|
||||
@Inject
|
||||
QuotaService _quotaService;
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaStatementCmd.class.getName());
|
||||
|
||||
private static final String s_name = "quotacreditsresponse";
|
||||
|
||||
@Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, required = true, description = "Account Id for which quota credits need to be added")
|
||||
private String accountName;
|
||||
|
||||
@Parameter(name = ApiConstants.DOMAIN_ID, type = CommandType.UUID, required = true, entityType = DomainResponse.class, description = "Domain for which quota credits need to be added")
|
||||
private Long domainId;
|
||||
|
||||
@Parameter(name = ApiConstants.VALUE, type = CommandType.DOUBLE, required = true, description = "Value of the credits to be added+, subtracted-")
|
||||
private Double value;
|
||||
|
||||
@Parameter(name = "min_balance", type = CommandType.DOUBLE, required = false, description = "Minimum balance threshold of the account")
|
||||
private Double minBalance;
|
||||
|
||||
@Parameter(name = "quota_enforce", type = CommandType.BOOLEAN, required = false, description = "Account for which quota enforce is set to false will not be locked when there is no credit balance")
|
||||
private Boolean quotaEnforce;
|
||||
|
||||
public Double getMinBalance() {
|
||||
return minBalance;
|
||||
}
|
||||
|
||||
public void setMinBalance(Double minBalance) {
|
||||
this.minBalance = minBalance;
|
||||
}
|
||||
|
||||
public Boolean getQuotaEnforce() {
|
||||
return quotaEnforce;
|
||||
}
|
||||
|
||||
public void setQuotaEnforce(Boolean quotaEnforce) {
|
||||
this.quotaEnforce = quotaEnforce;
|
||||
}
|
||||
|
||||
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 Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public QuotaCreditsCmd() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
Long accountId = _accountService.getActiveAccountByName(accountName, domainId).getAccountId();
|
||||
if (accountId == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "The account does not exists or has been removed/disabled");
|
||||
}
|
||||
if (value == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Please send a valid non-empty quota value");
|
||||
}
|
||||
if (getQuotaEnforce() != null) {
|
||||
_quotaService.setLockAccount(accountId, getQuotaEnforce());
|
||||
}
|
||||
if (getMinBalance() != null) {
|
||||
_quotaService.setMinBalance(accountId, getMinBalance());
|
||||
}
|
||||
else {
|
||||
_quotaService.setMinBalance(accountId, 0.2 * value);
|
||||
}
|
||||
|
||||
final QuotaCreditsResponse response = _responseBuilder.addQuotaCredits(accountId, domainId, value, CallContext.current().getCallingUserId());
|
||||
response.setResponseName(getCommandName());
|
||||
response.setObjectName("quotacredits");
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
//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 org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.BaseListCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.response.ListResponse;
|
||||
import org.apache.cloudstack.api.response.QuotaEmailTemplateResponse;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@APICommand(name = "quotaEmailTemplateList", responseObject = QuotaEmailTemplateResponse.class, description = "Lists all quota email templates", since = "4.6.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaEmailTemplateListCmd extends BaseListCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaEmailTemplateListCmd.class.getName());
|
||||
private static final String s_name = "quotaemailtemplatelistresponse";
|
||||
|
||||
@Inject
|
||||
QuotaResponseBuilder _quotaResponseBuilder;
|
||||
|
||||
@Parameter(name = "templatetype", type = CommandType.STRING, description = "List by type of the quota email template, allowed types: QUOTA_LOW, QUOTA_EMPTY")
|
||||
private String templateName;
|
||||
|
||||
public String getTemplateName() {
|
||||
return templateName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final ListResponse<QuotaEmailTemplateResponse> response = new ListResponse<QuotaEmailTemplateResponse>();
|
||||
response.setResponses(_quotaResponseBuilder.listQuotaEmailTemplates(this));
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
//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.Account;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
import org.apache.cloudstack.api.ServerApiException;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.api.response.SuccessResponse;
|
||||
import org.apache.cloudstack.quota.constant.QuotaConfig;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Arrays;
|
||||
|
||||
@APICommand(name = "quotaEmailTemplateUpdate", responseObject = SuccessResponse.class, description = "Updates existing email templates for quota alerts", since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaEmailTemplateUpdateCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaEmailTemplateUpdateCmd.class.getName());
|
||||
private static final String s_name = "quotaemailtemplateupdateresponse";
|
||||
|
||||
@Inject
|
||||
QuotaResponseBuilder _quotaResponseBuilder;
|
||||
|
||||
@Parameter(name = "templatetype", type = CommandType.STRING, required=true, description = "Type of the quota email template, allowed types: QUOTA_LOW, QUOTA_EMPTY")
|
||||
private String templateName;
|
||||
|
||||
@Parameter(name = "templatesubject", type = CommandType.STRING, required=true, description = "The quota email template subject, max: 77 characters", length = 77)
|
||||
private String templateSubject;
|
||||
|
||||
@Parameter(name = "templatebody", type = CommandType.STRING, required=true, description = "The quota email template body, max: 500k characters", length = 512000)
|
||||
private String templateBody;
|
||||
|
||||
@Parameter(name = "locale", type = CommandType.STRING, description = "The locale of the email text")
|
||||
private String locale;
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final String templateName = getTemplateName();
|
||||
if (templateName == null || getTemplateSubject() == null || getTemplateBody() == null) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Failed to update quota email template due to empty or invalid template name or text");
|
||||
}
|
||||
|
||||
boolean isValidTemplateName = false;
|
||||
for (QuotaConfig.QuotaEmailTemplateTypes e: QuotaConfig.QuotaEmailTemplateTypes.values()) {
|
||||
if (e.toString().equalsIgnoreCase(templateName)) {
|
||||
isValidTemplateName = true;
|
||||
setTemplateName(e.toString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isValidTemplateName) {
|
||||
throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Invalid quota email template type, allowed values are: " + Arrays.toString(QuotaConfig.QuotaEmailTemplateTypes.values()));
|
||||
}
|
||||
|
||||
if (!_quotaResponseBuilder.updateQuotaEmailTemplate(this)) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Unable to update quota email template due to an internal error");
|
||||
}
|
||||
final SuccessResponse response = new SuccessResponse();
|
||||
response.setResponseName(getCommandName());
|
||||
response.setSuccess(true);
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
private void setTemplateName(String templateName) {
|
||||
this.templateName = templateName;
|
||||
}
|
||||
|
||||
public String getTemplateName() {
|
||||
return templateName;
|
||||
}
|
||||
|
||||
public String getTemplateSubject() {
|
||||
return templateSubject;
|
||||
}
|
||||
|
||||
public String getTemplateBody() {
|
||||
return templateBody;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
//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 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.BaseCmd;
|
||||
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.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.api.response.QuotaStatementResponse;
|
||||
import org.apache.cloudstack.context.CallContext;
|
||||
import org.apache.cloudstack.quota.vo.QuotaUsageVO;
|
||||
import org.apache.cloudstack.api.response.QuotaStatementItemResponse;
|
||||
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@APICommand(name = "quotaStatement", responseObject = QuotaStatementItemResponse.class, description = "Create a quota statement", since = "4.2.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaStatementCmd extends BaseCmd {
|
||||
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaStatementCmd.class.getName());
|
||||
|
||||
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")
|
||||
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.")
|
||||
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
|
||||
QuotaResponseBuilder _responseBuilder;
|
||||
|
||||
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 _responseBuilder.startOfNextDay(endDate == null ? new Date() : 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();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Long accountId = _accountService.getActiveAccountByName(accountName, domainId).getAccountId();
|
||||
if (accountId == null) {
|
||||
return CallContext.current().getCallingAccount().getId();
|
||||
}
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
List<QuotaUsageVO> quotaUsage = _responseBuilder.getQuotaUsage(this);
|
||||
|
||||
QuotaStatementResponse response = _responseBuilder.createQuotaStatementResponse(quotaUsage);
|
||||
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
//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.Account;
|
||||
|
||||
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.ListResponse;
|
||||
import org.apache.cloudstack.api.response.QuotaResponseBuilder;
|
||||
import org.apache.cloudstack.api.response.QuotaTariffResponse;
|
||||
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
@APICommand(name = "quotaTariffList", responseObject = QuotaTariffResponse.class, description = "Lists all quota tariff plans", since = "4.6.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaTariffListCmd extends BaseListCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaTariffListCmd.class.getName());
|
||||
private static final String s_name = "quotatarifflistresponse";
|
||||
|
||||
@Inject
|
||||
QuotaResponseBuilder _responseBuilder;
|
||||
|
||||
@Parameter(name = ApiConstants.USAGE_TYPE, type = CommandType.INTEGER, required = false, description = "Usage type of the resource")
|
||||
private Integer usageType;
|
||||
|
||||
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = false, description = "The effective start date on/after which the quota tariff is effective and older tariffs are no longer used for the usage type. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.")
|
||||
private Date effectiveDate;
|
||||
|
||||
public QuotaTariffListCmd() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final List<QuotaTariffVO> result = _responseBuilder.listQuotaTariffPlans(this);
|
||||
|
||||
final List<QuotaTariffResponse> responses = new ArrayList<QuotaTariffResponse>();
|
||||
for (final QuotaTariffVO resource : result) {
|
||||
s_logger.info("Result desc=" + resource.getDescription() + " date=" + resource.getEffectiveOn() + " val=" + resource.getCurrencyValue());
|
||||
responses.add(_responseBuilder.createQuotaTariffResponse(resource));
|
||||
}
|
||||
|
||||
final ListResponse<QuotaTariffResponse> response = new ListResponse<QuotaTariffResponse>();
|
||||
response.setResponses(responses);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
public Date getEffectiveDate() {
|
||||
return effectiveDate;
|
||||
}
|
||||
|
||||
public Integer getUsageType() {
|
||||
return usageType;
|
||||
}
|
||||
|
||||
public void setUsageType(Integer usageType) {
|
||||
this.usageType = usageType;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
//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.Account;
|
||||
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.ApiErrorCode;
|
||||
import org.apache.cloudstack.api.BaseCmd;
|
||||
import org.apache.cloudstack.api.Parameter;
|
||||
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.vo.QuotaTariffVO;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@APICommand(name = "quotaTariffUpdate", responseObject = QuotaTariffResponse.class, description = "Update the tariff plan for a resource", since = "4.6.0", requestHasSensitiveInfo = false, responseHasSensitiveInfo = false)
|
||||
public class QuotaTariffUpdateCmd extends BaseCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(QuotaTariffUpdateCmd.class.getName());
|
||||
private static final String s_name = "quotatariffupdateresponse";
|
||||
|
||||
@Inject
|
||||
QuotaResponseBuilder _responseBuilder;
|
||||
|
||||
@Parameter(name = ApiConstants.USAGE_TYPE, type = CommandType.INTEGER, required = true, description = "Integer value for the usage type of the resource")
|
||||
private Integer usageType;
|
||||
|
||||
@Parameter(name = "value", type = CommandType.DOUBLE, required = true, description = "The quota tariff value of the resource as per the default unit")
|
||||
private Double value;
|
||||
|
||||
@Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, required = true, description = "The effective start date on/after which the quota tariff is effective and older tariffs are no longer used for the usage type. Use yyyy-MM-dd as the date format, e.g. startDate=2009-06-03.")
|
||||
private Date startDate;
|
||||
|
||||
public int getUsageType() {
|
||||
return usageType;
|
||||
}
|
||||
|
||||
public void setUsageType(int usageType) {
|
||||
this.usageType = usageType;
|
||||
}
|
||||
|
||||
public Double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public QuotaTariffUpdateCmd() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
final QuotaTariffVO result = _responseBuilder.updateQuotaTariffPlan(this);
|
||||
if (result == null) {
|
||||
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to update quota tariff plan");
|
||||
}
|
||||
final QuotaTariffResponse response = _responseBuilder.createQuotaTariffResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
setResponseObject(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
//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.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import org.apache.cloudstack.api.BaseResponse;
|
||||
import org.apache.cloudstack.quota.vo.QuotaBalanceVO;
|
||||
|
||||
import com.cloud.serializer.Param;
|
||||
|
||||
public class QuotaBalanceResponse 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("startquota")
|
||||
@Param(description = "quota started with")
|
||||
private BigDecimal startQuota;
|
||||
|
||||
@SerializedName("endquota")
|
||||
@Param(description = "quota by end of this period")
|
||||
private BigDecimal endQuota;
|
||||
|
||||
@SerializedName("credits")
|
||||
@Param(description = "list of credits made during this period")
|
||||
private List<QuotaCreditsResponse> credits = null;
|
||||
|
||||
@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 QuotaBalanceResponse() {
|
||||
super();
|
||||
credits = new ArrayList<QuotaCreditsResponse>();
|
||||
}
|
||||
|
||||
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 BigDecimal getStartQuota() {
|
||||
return startQuota;
|
||||
}
|
||||
|
||||
public void setStartQuota(BigDecimal startQuota) {
|
||||
this.startQuota = startQuota.setScale(2, RoundingMode.HALF_EVEN);
|
||||
}
|
||||
|
||||
public BigDecimal getEndQuota() {
|
||||
return endQuota;
|
||||
}
|
||||
|
||||
public void setEndQuota(BigDecimal endQuota) {
|
||||
this.endQuota = endQuota.setScale(2, RoundingMode.HALF_EVEN);
|
||||
}
|
||||
|
||||
public List<QuotaCreditsResponse> getCredits() {
|
||||
return credits;
|
||||
}
|
||||
|
||||
public void setCredits(List<QuotaCreditsResponse> credits) {
|
||||
this.credits = credits;
|
||||
}
|
||||
|
||||
public void addCredits(QuotaBalanceVO credit) {
|
||||
QuotaCreditsResponse cr = new QuotaCreditsResponse();
|
||||
cr.setCredits(credit.getCreditBalance());
|
||||
cr.setUpdatedOn(credit.getUpdatedOn());
|
||||
credits.add(0, cr);
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
//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 org.apache.cloudstack.quota.vo.QuotaCreditsVO;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Date;
|
||||
|
||||
public class QuotaCreditsResponse extends BaseResponse {
|
||||
|
||||
@SerializedName("credits")
|
||||
@Param(description = "the credit deposited")
|
||||
private BigDecimal credits;
|
||||
|
||||
@SerializedName("updated_by")
|
||||
@Param(description = "the user name of the admin who updated the credits")
|
||||
private String updatedBy;
|
||||
|
||||
@SerializedName("updated_on")
|
||||
@Param(description = "the account name of the admin who updated the credits")
|
||||
private Date updatedOn;
|
||||
|
||||
@SerializedName("currency")
|
||||
@Param(description = "currency")
|
||||
private String currency;
|
||||
|
||||
public QuotaCreditsResponse() {
|
||||
super();
|
||||
}
|
||||
|
||||
public QuotaCreditsResponse(QuotaCreditsVO result, String updatedBy) {
|
||||
super();
|
||||
if (result != null) {
|
||||
setCredits(result.getCredit());
|
||||
setUpdatedBy(updatedBy);
|
||||
setUpdatedOn(new Date());
|
||||
}
|
||||
}
|
||||
|
||||
public BigDecimal getCredits() {
|
||||
return credits;
|
||||
}
|
||||
|
||||
public void setCredits(BigDecimal credits) {
|
||||
this.credits = credits.setScale(2, RoundingMode.HALF_EVEN);
|
||||
}
|
||||
|
||||
public String getUpdatedBy() {
|
||||
return updatedBy;
|
||||
}
|
||||
|
||||
public void setUpdatedBy(String updatedBy) {
|
||||
this.updatedBy = updatedBy;
|
||||
}
|
||||
|
||||
public Date getUpdatedOn() {
|
||||
return updatedOn;
|
||||
}
|
||||
|
||||
public void setUpdatedOn(Date updatedOn) {
|
||||
this.updatedOn = updatedOn;
|
||||
}
|
||||
|
||||
public String getCurrency() {
|
||||
return currency;
|
||||
}
|
||||
|
||||
public void setCurrency(String currency) {
|
||||
this.currency = currency;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
//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.Date;
|
||||
|
||||
public class QuotaEmailTemplateResponse extends BaseResponse {
|
||||
@SerializedName("templatetype")
|
||||
@Param(description = "Template type")
|
||||
private String templateType;
|
||||
|
||||
@SerializedName("templatesubject")
|
||||
@Param(description = "The quota email template subject")
|
||||
private String templateSubject;
|
||||
|
||||
@SerializedName("templatebody")
|
||||
@Param(description = "The quota email template content")
|
||||
private String templateText;
|
||||
|
||||
@SerializedName("locale")
|
||||
@Param(description = "The quota email template locale")
|
||||
private String locale;
|
||||
|
||||
@SerializedName("last_updated")
|
||||
@Param(description = "Last date/time when template was updated")
|
||||
private Date lastUpdatedOn;
|
||||
|
||||
public QuotaEmailTemplateResponse() {
|
||||
super();
|
||||
this.setObjectName("quotaemailtemplate");
|
||||
}
|
||||
|
||||
public String getTemplateType() {
|
||||
return templateType;
|
||||
}
|
||||
|
||||
public void setTemplateType(String templateType) {
|
||||
this.templateType = templateType;
|
||||
}
|
||||
|
||||
public String getTemplateSubject() {
|
||||
return templateSubject;
|
||||
}
|
||||
|
||||
public void setTemplateSubject(String templateSubject) {
|
||||
this.templateSubject = templateSubject;
|
||||
}
|
||||
|
||||
public String getTemplateText() {
|
||||
return templateText;
|
||||
}
|
||||
|
||||
public void setTemplateText(String templateText) {
|
||||
this.templateText = templateText;
|
||||
}
|
||||
|
||||
public String getLocale() {
|
||||
return locale;
|
||||
}
|
||||
|
||||
public void setLocale(String locale) {
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
public Date getLastUpdatedOn() {
|
||||
return lastUpdatedOn;
|
||||
}
|
||||
|
||||
public void setLastUpdatedOn(Date lastUpdatedOn) {
|
||||
this.lastUpdatedOn = lastUpdatedOn;
|
||||
}
|
||||
}
|
||||
|
|
@ -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.response;
|
||||
|
||||
|
||||
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.vo.QuotaBalanceVO;
|
||||
import org.apache.cloudstack.quota.vo.QuotaTariffVO;
|
||||
import org.apache.cloudstack.quota.vo.QuotaUsageVO;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
public interface QuotaResponseBuilder {
|
||||
|
||||
QuotaTariffVO updateQuotaTariffPlan(QuotaTariffUpdateCmd cmd);
|
||||
|
||||
List<QuotaTariffVO> listQuotaTariffPlans(QuotaTariffListCmd cmd);
|
||||
|
||||
QuotaTariffResponse createQuotaTariffResponse(QuotaTariffVO configuration);
|
||||
|
||||
QuotaStatementResponse createQuotaStatementResponse(List<QuotaUsageVO> quotaUsage);
|
||||
|
||||
QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaUsage, Date startDate, Date endDate);
|
||||
|
||||
QuotaBalanceResponse createQuotaLastBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate);
|
||||
|
||||
QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy, Date despositedOn);
|
||||
|
||||
public List<QuotaUsageVO> getQuotaUsage(QuotaStatementCmd cmd);
|
||||
|
||||
List<QuotaBalanceVO> getQuotaBalance(QuotaBalanceCmd cmd);
|
||||
|
||||
QuotaCreditsResponse addQuotaCredits(Long accountId, Long domainId, Double amount, Long updatedBy);
|
||||
|
||||
List<QuotaEmailTemplateResponse> listQuotaEmailTemplates(QuotaEmailTemplateListCmd cmd);
|
||||
|
||||
boolean updateQuotaEmailTemplate(QuotaEmailTemplateUpdateCmd cmd);
|
||||
|
||||
Date startOfNextDay(Date dt);
|
||||
|
||||
Date startOfNextDay();
|
||||
}
|
||||
|
|
@ -0,0 +1,412 @@
|
|||
//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.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 com.cloud.utils.db.TransactionLegacy;
|
||||
|
||||
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.constant.QuotaConfig;
|
||||
import org.apache.cloudstack.quota.constant.QuotaTypes;
|
||||
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.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.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
@Component
|
||||
@Local(value = QuotaResponseBuilderImpl.class)
|
||||
public class QuotaResponseBuilderImpl implements QuotaResponseBuilder {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaResponseBuilderImpl.class.getName());
|
||||
|
||||
@Inject
|
||||
private QuotaTariffDao _quotaTariffDao;
|
||||
@Inject
|
||||
private QuotaBalanceDao _quotaBalanceDao;
|
||||
@Inject
|
||||
private QuotaCreditsDao _quotaCreditsDao;
|
||||
@Inject
|
||||
private QuotaEmailTemplatesDao _quotaEmailTemplateDao;
|
||||
|
||||
@Inject
|
||||
private UserDao _userDao;
|
||||
@Inject
|
||||
private QuotaService _quotaService;
|
||||
@Inject
|
||||
AccountDao _accountDao;
|
||||
@Inject
|
||||
private RegionManager _regionMgr;
|
||||
|
||||
@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 QuotaBalanceResponse createQuotaBalanceResponse(List<QuotaBalanceVO> quotaBalance, Date startDate, Date endDate) {
|
||||
if (quotaBalance.size() == 0) {
|
||||
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
|
||||
}
|
||||
});
|
||||
|
||||
QuotaBalanceResponse resp = new QuotaBalanceResponse();
|
||||
BigDecimal lastCredits = new BigDecimal(0);
|
||||
boolean consecutive = true;
|
||||
for (Iterator<QuotaBalanceVO> it = quotaBalance.iterator(); it.hasNext();) {
|
||||
QuotaBalanceVO entry = it.next();
|
||||
s_logger.info("createQuotaBalanceResponse: Date=" + entry.getUpdatedOn().toGMTString() + " balance=" + entry.getCreditBalance() + " credit=" + entry.getCreditsId());
|
||||
if (entry.getCreditsId() > 0) {
|
||||
if (consecutive) {
|
||||
lastCredits = lastCredits.add(entry.getCreditBalance());
|
||||
}
|
||||
resp.addCredits(entry);
|
||||
it.remove();
|
||||
} else {
|
||||
consecutive = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (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(startDate);
|
||||
resp.setStartQuota(startItem.getCreditBalance());
|
||||
resp.setEndDate(endDate);
|
||||
resp.setEndQuota(endItem.getCreditBalance().add(lastCredits));
|
||||
} else {
|
||||
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.size() == 0) {
|
||||
throw new InvalidParameterValueException("There is no usage data found for period mentioned.");
|
||||
}
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
QuotaStatementResponse statement = new QuotaStatementResponse();
|
||||
|
||||
HashMap<Integer, QuotaTariffVO> quotaTariffMap = new HashMap<Integer, QuotaTariffVO>();
|
||||
List<QuotaTariffVO> result = _quotaTariffDao.listAll();
|
||||
|
||||
for (QuotaTariffVO quotaTariff : result) {
|
||||
quotaTariffMap.put(quotaTariff.getUsageType(), quotaTariff);
|
||||
// add dummy record for each usage type
|
||||
QuotaUsageVO dummy = new QuotaUsageVO(quotaUsage.get(0));
|
||||
dummy.setUsageType(quotaTariff.getUsageType());
|
||||
dummy.setQuotaUsed(new BigDecimal(0));
|
||||
quotaUsage.add(dummy);
|
||||
}
|
||||
|
||||
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);
|
||||
//s_logger.info("createQuotaStatementResponse record count=" + quotaUsage.size());
|
||||
for (final QuotaUsageVO quotaRecord : quotaUsage) {
|
||||
//s_logger.info("createQuotaStatementResponse Type=" + quotaRecord.getUsageType() + " usage=" + usage + " name" + quotaRecord.getUsageItemId());
|
||||
if (type != quotaRecord.getUsageType()) {
|
||||
if (type != -1) {
|
||||
lineitem = new QuotaStatementItemResponse();
|
||||
lineitem.setUsageType(type);
|
||||
lineitem.setQuotaUsed(usage);
|
||||
lineitem.setAccountId(prev.getAccountId());
|
||||
lineitem.setDomainId(prev.getDomainId());
|
||||
lineitem.setStartDate(prev.getStartDate());
|
||||
lineitem.setEndDate(prev.getEndDate());
|
||||
lineitem.setUsageUnit(quotaTariffMap.get(type).getUsageUnit());
|
||||
lineitem.setUsageName(quotaTariffMap.get(type).getUsageName());
|
||||
lineitem.setObjectName("quotausage");
|
||||
items.add(lineitem);
|
||||
totalUsage = totalUsage.add(usage);
|
||||
usage = new BigDecimal(0);
|
||||
}
|
||||
type = quotaRecord.getUsageType();
|
||||
}
|
||||
prev = quotaRecord;
|
||||
usage = usage.add(quotaRecord.getQuotaUsed());
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
|
||||
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);
|
||||
s_logger.info("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);
|
||||
}
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.USAGE_DB).close();
|
||||
QuotaTariffVO result = null;
|
||||
try {
|
||||
result = new QuotaTariffVO();
|
||||
result.setUsageType(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());
|
||||
|
||||
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);
|
||||
} catch (Exception pokemon) {
|
||||
s_logger.error("Error in update quota tariff plan: " + pokemon);
|
||||
} finally {
|
||||
TransactionLegacy.open(opendb).close();
|
||||
}
|
||||
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) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
QuotaCreditsVO result = null;
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
QuotaCreditsVO credits = new QuotaCreditsVO(accountId, domainId, new BigDecimal(amount), updatedBy);
|
||||
s_logger.info("addQuotaCredits: Depositing " + amount + " on adjusted date " + despositedOn);
|
||||
credits.setUpdatedOn(despositedOn);
|
||||
result = _quotaCreditsDao.saveCredits(credits);
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
final AccountVO account = _accountDao.findById(accountId);
|
||||
final boolean lockAccountEnforcement = QuotaConfig.QuotaEnableEnforcement.value().equalsIgnoreCase("true");
|
||||
final BigDecimal currentAccountBalance = _quotaBalanceDao.lastQuotaBalance(accountId, domainId, startOfNextDay(despositedOn));
|
||||
if (lockAccountEnforcement && (currentAccountBalance.compareTo(new BigDecimal(0)) >= 0)) {
|
||||
if (account.getState() == Account.State.locked) {
|
||||
try {
|
||||
_regionMgr.enableAccount(account.getAccountName(), domainId, accountId);
|
||||
//_quotaMgr.sendQuotaAlert(account, currentAccountBalance, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_UNLOCK_ACCOUNT);
|
||||
} catch (Exception e) {
|
||||
s_logger.error(String.format("Unable to unlock account %s after getting enough quota credits", account.getAccountName()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String creditor = String.valueOf(Account.ACCOUNT_ID_SYSTEM);
|
||||
User creditorUser = _userDao.getUser(updatedBy);
|
||||
if (creditorUser != null) {
|
||||
creditor = creditorUser.getUsername();
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
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.size() == 0) {
|
||||
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 (Iterator<QuotaBalanceVO> it = quotaBalance.iterator(); it.hasNext();) {
|
||||
QuotaBalanceVO entry = it.next();
|
||||
s_logger.info("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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
//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;
|
||||
|
||||
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;
|
||||
|
||||
@SerializedName("startdate")
|
||||
@Param(description = "start date")
|
||||
private Date startDate = null;
|
||||
|
||||
@SerializedName("enddate")
|
||||
@Param(description = "end date")
|
||||
private Date endDate = null;
|
||||
|
||||
public QuotaStatementItemResponse() {
|
||||
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 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);
|
||||
}
|
||||
|
||||
public Date getStartDate() {
|
||||
return startDate;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
public void setStartDate(Date startDate) {
|
||||
this.startDate = startDate;
|
||||
}
|
||||
|
||||
public Date getEndDate() {
|
||||
return endDate;
|
||||
}
|
||||
|
||||
public void setEndDate(Date endDate) {
|
||||
this.endDate = endDate;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,296 @@
|
|||
//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.QuotaEmailTemplateUpdateCmd;
|
||||
import org.apache.cloudstack.api.command.QuotaEmailTemplateListCmd;
|
||||
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.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.getName());
|
||||
|
||||
@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;
|
||||
|
||||
final static BigDecimal s_hoursInMonth = new BigDecimal(30 * 24);
|
||||
final static BigDecimal s_minutesInMonth = new BigDecimal(30 * 24 * 60);
|
||||
final 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<?>>();
|
||||
if (!isQuotaServiceEnabled()) {
|
||||
return cmdList;
|
||||
}
|
||||
cmdList.add(QuotaStatementCmd.class);
|
||||
cmdList.add(QuotaBalanceCmd.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, 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) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
|
||||
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();
|
||||
|
||||
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));
|
||||
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);
|
||||
s_logger.info("Found records size=" + qbrecords.size());
|
||||
if (qbrecords.size() == 0) {
|
||||
throw new InvalidParameterValueException("Incorrect Date there are no quota records before this date " + adjustedStartDate);
|
||||
} 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);
|
||||
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);
|
||||
s_logger.info("getQuotaBalance3: Found records size=" + qbrecords.size());
|
||||
if (qbrecords.size() == 0) {
|
||||
throw new InvalidParameterValueException("Incorrect Date range there are no quota records between these dates start date " + adjustedStartDate + " and end date:" + endDate);
|
||||
} 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) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
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();
|
||||
|
||||
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);
|
||||
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.findById(accountId);
|
||||
if (acc == null) {
|
||||
acc = new QuotaAccountVO(accountId);
|
||||
acc.setQuotaEnforce(state ? 1 : 0);
|
||||
_quotaAcc.persist(acc);
|
||||
} else {
|
||||
acc.setQuotaEnforce(state ? 1 : 0);
|
||||
_quotaAcc.update(accountId, acc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMinBalance(Long accountId, Double balance) {
|
||||
QuotaAccountVO acc = _quotaAcc.findById(accountId);
|
||||
if (acc == null) {
|
||||
acc = new QuotaAccountVO(accountId);
|
||||
acc.setQuotaMinBalance(new BigDecimal(balance));
|
||||
_quotaAcc.persist(acc);
|
||||
} else {
|
||||
acc.setQuotaMinBalance(new BigDecimal(balance));
|
||||
_quotaAcc.update(accountId, acc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -90,6 +90,7 @@
|
|||
<module>network-elements/internal-loadbalancer</module>
|
||||
<module>network-elements/vxlan</module>
|
||||
<module>network-elements/globodns</module>
|
||||
<module>database/quota</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
|||
2
pom.xml
2
pom.xml
|
|
@ -83,6 +83,7 @@
|
|||
<cs.aws.sdk.version>1.3.22</cs.aws.sdk.version>
|
||||
<cs.lang.version>2.6</cs.lang.version>
|
||||
<cs.commons-io.version>1.4</cs.commons-io.version>
|
||||
<cs.commons-lang3.version>3.4</cs.commons-lang3.version>
|
||||
<cs.reflections.version>0.9.8</cs.reflections.version>
|
||||
<cs.java-ipv6.version>0.10</cs.java-ipv6.version>
|
||||
<cs.replace.properties>build/replace.properties</cs.replace.properties>
|
||||
|
|
@ -96,6 +97,7 @@
|
|||
<cs.findbugs.version>2.5.3</cs.findbugs.version>
|
||||
<cs.javadoc.version>2.9.1</cs.javadoc.version>
|
||||
<cs.opensaml.version>2.6.1</cs.opensaml.version>
|
||||
<cs.joda-time.version>2.8.1</cs.joda-time.version>
|
||||
</properties>
|
||||
|
||||
<distributionManagement>
|
||||
|
|
|
|||
|
|
@ -291,6 +291,14 @@ public class ParamProcessWorker implements DispatchWorker {
|
|||
field.set(cmdObj, Float.valueOf(paramObj.toString()));
|
||||
}
|
||||
break;
|
||||
case DOUBLE:
|
||||
// Assuming that the parameters have been checked for required before now,
|
||||
// we ignore blank or null values and defer to the command to set a default
|
||||
// value for optional parameters ...
|
||||
if (paramObj != null && isNotBlank(paramObj.toString())) {
|
||||
field.set(cmdObj, Double.valueOf(paramObj.toString()));
|
||||
}
|
||||
break;
|
||||
case INTEGER:
|
||||
// Assuming that the parameters have been checked for required before now,
|
||||
// we ignore blank or null values and defer to the command to set a default
|
||||
|
|
|
|||
|
|
@ -2179,8 +2179,7 @@ public class AccountManagerImpl extends ManagerBase implements AccountManager, M
|
|||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)");
|
||||
}
|
||||
throw new CloudAuthenticationException("User " + username + " in domain " + domainName + " is disabled/locked (or account is disabled/locked)");
|
||||
// return null;
|
||||
throw new CloudAuthenticationException("User " + username + " (or their account) in domain " + domainName + " is disabled/locked. Please contact the administrator.");
|
||||
}
|
||||
// Whenever the user is able to log in successfully, reset the login attempts to zero
|
||||
if (!isInternalAccount(userAccount.getId()))
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@
|
|||
-- Schema upgrade from 4.5.1 to 4.5.2;
|
||||
--;
|
||||
|
||||
DELETE FROM `cloud`.`configuration` WHERE name like 'saml%';
|
||||
-- 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";
|
||||
|
||||
|
|
@ -33,3 +35,117 @@ CREATE TABLE `cloud`.`saml_token` (
|
|||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_saml_token__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- Quota
|
||||
|
||||
ALTER TABLE `cloud_usage`.`cloud_usage` ADD COLUMN `quota_calculated` tinyint(1) DEFAULT 0 COMMENT "quota calculation status";
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_account` (
|
||||
`account_id` int(11) NOT NULL,
|
||||
`quota_balance` decimal(15,2) NULL,
|
||||
`quota_balance_date` datetime NULL,
|
||||
`quota_enforce` int(1) DEFAULT NULL,
|
||||
`quota_min_balance` decimal(15,2) DEFAULT NULL,
|
||||
`quota_alert_date` datetime DEFAULT NULL,
|
||||
`quota_alert_type` int(11) DEFAULT NULL,
|
||||
`last_statement_date` datetime DEFAULT NULL,
|
||||
PRIMARY KEY (`account_id`),
|
||||
CONSTRAINT `account_id` FOREIGN KEY (`account_id`) REFERENCES `cloud_usage`.`account` (`quota_enforce`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE NO ACTION
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_tariff` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
|
||||
`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',
|
||||
`usage_discriminator` varchar(255) NOT NULL COMMENT 'usage type',
|
||||
`currency_value` decimal(15,2) NOT NULL COMMENT 'usage type',
|
||||
`effective_on` datetime NOT NULL COMMENT 'date time on which this quota values will become effective',
|
||||
`updated_on` datetime NOT NULL COMMENT 'date this entry was updated on',
|
||||
`updated_by` bigint unsigned NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
LOCK TABLES `cloud_usage`.`quota_tariff` WRITE;
|
||||
INSERT IGNORE INTO `cloud_usage`.`quota_tariff` (`usage_type`, `usage_name`, `usage_unit`, `usage_discriminator`, `currency_value`, `effective_on`, `updated_on`, `updated_by`) VALUES
|
||||
(1,'RUNNING_VM','Compute-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(2,'ALLOCATED_VM','Compute-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(3,'IP_ADDRESS','IP-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(4,'NETWORK_BYTES_SENT','GB','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(5,'NETWORK_BYTES_RECEIVED','GB','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(6,'VOLUME','GB-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(7,'TEMPLATE','GB-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(8,'ISO','GB-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(9,'SNAPSHOT','GB-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(10,'SECURITY_GROUP','Policy-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(11,'LOAD_BALANCER_POLICY','Policy-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(12,'PORT_FORWARDING_RULE','Policy-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(13,'NETWORK_OFFERING','Policy-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(14,'VPN_USERS','Policy-Month','',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(15,'CPU_SPEED','Compute-Month','100MHz',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(16,'vCPU','Compute-Month','1VCPU',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(17,'MEMORY','Compute-Month','1MB',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(21,'VM_DISK_IO_READ','GB','1',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(22,'VM_DISK_IO_WRITE','GB','1',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(23,'VM_DISK_BYTES_READ','GB','1',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(24,'VM_DISK_BYTES_WRITE','GB','1',0.00,'2010-05-04', '2010-05-04',1),
|
||||
(25,'VM_SNAPSHOT','GB-Month','',0.00,'2010-05-04', '2010-05-04',1);
|
||||
UNLOCK TABLES;
|
||||
|
||||
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,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(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` decimal(15,8) 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 AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_balance` (
|
||||
`id` bigint unsigned NOT NULL auto_increment COMMENT 'id',
|
||||
`account_id` bigint unsigned NOT NULL,
|
||||
`domain_id` bigint(20) unsigned NOT NULL,
|
||||
`credit_balance` decimal(15,8) COMMENT 'amount of credits remaining',
|
||||
`credits_id` bigint unsigned COMMENT 'if not null then this entry corresponds to credit change quota_credits',
|
||||
`updated_on` datetime NOT NULL COMMENT 'date updated on',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_email_templates` (
|
||||
`id` bigint(20) NOT NULL AUTO_INCREMENT,
|
||||
`template_name` varchar(64) NOT NULL UNIQUE,
|
||||
`template_subject` longtext,
|
||||
`template_body` longtext,
|
||||
`locale` varchar(25) DEFAULT 'en_US',
|
||||
`updated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
LOCK TABLES `cloud_usage`.`quota_email_templates` WRITE;
|
||||
INSERT IGNORE INTO `cloud_usage`.`quota_email_templates` (`template_name`, `template_subject`, `template_body`) VALUES
|
||||
('QUOTA_LOW', 'Quota Usage Threshold crossed by your account ${accountName}', 'Your account ${accountName} in the domain ${domainName} has reached quota usage threshold, your current quota balance is ${quotaBalance}.'),
|
||||
('QUOTA_EMPTY', 'Quota Exhausted, account ${accountName} is locked now', 'Your account ${accountName} in the domain ${domainName} has exhausted allocated quota and has been locked now, please contact the administrator.'),
|
||||
('QUOTA_UNLOCK_ACCOUNT', 'Quota credits added, account ${accountName} is unlocked now', 'Your account ${accountName} in the domain ${domainName} has enough quota credits now with the current balance of ${quotaBalance}. Your account has been unlocked now.'),
|
||||
('QUOTA_STATEMENT', 'Quota Statement for your account ${accountName}', 'Monthly quota statement of your account ${accountName} in the domain ${domainName}:<br>Balance = ${quotaBalance}<br>Total Usage = ${quotaUsage}.');
|
||||
UNLOCK TABLES;
|
||||
|
||||
|
|
|
|||
|
|
@ -118,6 +118,8 @@ known_categories = {
|
|||
'listIdps': 'Authentication',
|
||||
'authorizeSamlSso': 'Authentication',
|
||||
'listSamlAuthorization': 'Authentication',
|
||||
'quota': 'Quota',
|
||||
'emailTemplate': 'Quota',
|
||||
'Capacity': 'System Capacity',
|
||||
'NetworkDevice': 'Network Device',
|
||||
'ExternalLoadBalancer': 'Ext Load Balancer',
|
||||
|
|
|
|||
|
|
@ -982,6 +982,13 @@ dictionary = {
|
|||
'label.purpose': '<fmt:message key="label.purpose" />',
|
||||
'label.Pxe.server.type': '<fmt:message key="label.Pxe.server.type" />',
|
||||
'label.quickview': '<fmt:message key="label.quickview" />',
|
||||
'label.usage.type': '<fmt:message key="label.usage.type" />',
|
||||
'label.usage.unit': '<fmt:message key="label.usage.unit" />',
|
||||
'label.quota.value': '<fmt:message key="label.quota.value" />',
|
||||
'label.quota.description': '<fmt:message key="label.quota.description" />',
|
||||
'label.quota.configuration': '<fmt:message key="label.quota.configuration" />',
|
||||
'label.quota.configure': '<fmt:message key="label.quota.configure" />',
|
||||
'label.quota.remove': '<fmt:message key="label.quota.remove" />',
|
||||
'label.rbd': '<fmt:message key="label.rbd" />',
|
||||
'label.rbd.monitor': '<fmt:message key="label.rbd.monitor" />',
|
||||
'label.rbd.pool': '<fmt:message key="label.rbd.pool" />',
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
// under the License.
|
||||
(function($, cloudStack) {
|
||||
cloudStack.plugins = [
|
||||
// 'testPlugin'
|
||||
//'quota',
|
||||
//'testPlugin'
|
||||
];
|
||||
}(jQuery, cloudStack));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
// 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.
|
||||
(function (cloudStack) {
|
||||
cloudStack.plugins.quota.config = {
|
||||
title: 'Quota',
|
||||
desc: 'CloudStack Quota',
|
||||
externalLink: 'http://www.cloudstack.org/',
|
||||
authorName: 'Apache CloudStack',
|
||||
authorEmail: 'dev@cloudstack.apache.org'
|
||||
};
|
||||
}(cloudStack));
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.8 KiB |
|
|
@ -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.
|
||||
*/
|
||||
|
||||
.quota-tariff-edit {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.quota-bold {
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
color: #6D6D6D;
|
||||
}
|
||||
|
||||
.quota-text {
|
||||
font-size: 11px;
|
||||
color: #282828;
|
||||
}
|
||||
|
||||
.quota-element {
|
||||
margin: 5px;
|
||||
margin-left: 13px;
|
||||
}
|
||||
|
||||
.quota-input {
|
||||
background: #F6F6F6;
|
||||
border: 1px solid #AFAFAF;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.quota-button {
|
||||
border:1px solid #0077c7; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px;
|
||||
font-size:11px;
|
||||
padding: 8px;
|
||||
margin-top: 12px;
|
||||
text-shadow: -1px -1px 0 rgba(0,0,0,0.3);font-weight:bold; color: #FFFFFF;
|
||||
background-color: #0099FF; background-image: -webkit-gradient(linear, left top, left bottom, from(#0099FF), to(#004FF7));
|
||||
background-image: -webkit-linear-gradient(top, #0099FF, #004FF7);
|
||||
background-image: -moz-linear-gradient(top, #0099FF, #004FF7);
|
||||
background-image: -ms-linear-gradient(top, #0099FF, #004FF7);
|
||||
background-image: -o-linear-gradient(top, #0099FF, #004FF7);
|
||||
background-image: linear-gradient(to bottom, #0099FF, #004FF7);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#0099FF, endColorstr=#004FF7);
|
||||
}
|
||||
|
||||
.quota-button:hover {
|
||||
border:1px solid #005c99;
|
||||
background-color: #0039B3; background-image: -webkit-gradient(linear, left top, left bottom, from(#0039B3), to(#004FF7));
|
||||
background-image: -webkit-linear-gradient(top, #0039B3, #004FF7);
|
||||
background-image: -moz-linear-gradient(top, #0039B3, #004FF7);
|
||||
background-image: -ms-linear-gradient(top, #0039B3, #004FF7);
|
||||
background-image: -o-linear-gradient(top, #0039B3, #004FF7);
|
||||
background-image: linear-gradient(to bottom, #0039B3, #004FF7);filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr=#0039B3, endColorstr=#004FF7);
|
||||
}
|
||||
|
|
@ -0,0 +1,726 @@
|
|||
// 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.
|
||||
|
||||
var g_quotaCurrency = '';
|
||||
(function (cloudStack) {
|
||||
cloudStack.plugins.quota = function(plugin) {
|
||||
plugin.ui.addSection({
|
||||
id: 'quota',
|
||||
title: 'Quota',
|
||||
showOnNavigation: true,
|
||||
preFilter: function(args) {
|
||||
return true;
|
||||
},
|
||||
show: function() {
|
||||
var $quotaView = $('<div class="quota-container detail-view ui-tabs ui-widget ui-widget-content ui-corner-all">');
|
||||
var $toolbar = $('<div class="toolbar"><div class="section-switcher reduced-hide"><div class="section-select"><label>Quota Management</label></div></div></div>');
|
||||
var $tabs = $('<ul class="ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all">');
|
||||
var $tabViews = [];
|
||||
|
||||
var sections = [{'id': 'quota-statement',
|
||||
'name': 'Statement',
|
||||
'render': function ($node) {
|
||||
var statementView = $('<div class="details quota-text" style="padding: 10px">');
|
||||
var generatedStatement = $('<div class="quota-generated-statement">');
|
||||
var generatedBalanceStatement = $('<div class="quota-generated-balance-statement">');
|
||||
|
||||
var statementForm = $('<div class="quota-statement select-container">');
|
||||
var domainDropdown = $('<div class="quota-domain-dropdown quota-element">');
|
||||
var accountDropdown = $('<div class="quota-account-dropdown quota-element">');
|
||||
var startDateInput = $('<input type="text" class="quota-input" id="quota-statement-start-date" style="margin-left: 13px">');
|
||||
var endDateInput = $('<input type="text" class="quota-input" id="quota-statement-end-date" style="margin-left: 13px">');
|
||||
var generateStatementButton = $('<button class="quota-element quota-button" id="quota-get-statement-button">').html("Generate Statement");
|
||||
|
||||
startDateInput.datepicker({
|
||||
defaultDate: new Date(),
|
||||
changeMonth: true,
|
||||
dateFormat: "yy-mm-dd",
|
||||
onClose: function (selectedDate) {
|
||||
endDateInput.datepicker("option", "minDate", selectedDate);
|
||||
}
|
||||
});
|
||||
|
||||
endDateInput.datepicker({
|
||||
defaultDate: new Date(),
|
||||
changeMonth: true,
|
||||
dateFormat: "yy-mm-dd",
|
||||
onClose: function (selectedDate) {
|
||||
startDateInput.datepicker("option", "maxDate", selectedDate);
|
||||
}
|
||||
});
|
||||
|
||||
generateStatementButton.click(function() {
|
||||
var domainId = g_domainid;
|
||||
if (isAdmin() || isDomainAdmin()) {
|
||||
domainId = domainDropdown.find("select :selected").val();
|
||||
}
|
||||
var accountId = accountDropdown.find("select :selected").val();
|
||||
var account = accountDropdown.find("select :selected").html();
|
||||
var startDate = startDateInput.val();
|
||||
var endDate = endDateInput.val();
|
||||
|
||||
if (!domainId || !account) {
|
||||
generatedStatement.empty();
|
||||
$("<br><hr>").appendTo(generatedStatement);
|
||||
$("<p class='quota-text'>").html("Error: Please select valid domain and account").appendTo(generatedStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!startDate || !endDate) {
|
||||
generatedStatement.empty();
|
||||
$("<br><hr>").appendTo(generatedStatement);
|
||||
$("<p class='quota-text'>").html("Error: Please select start and end dates").appendTo(generatedStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL('quotaStatement'),
|
||||
data: {
|
||||
domainid: domainId,
|
||||
accountid: accountId,
|
||||
account: account,
|
||||
startdate: startDate,
|
||||
enddate: endDate
|
||||
},
|
||||
success: function(json) {
|
||||
var statement = json.quotastatementresponse.statement;
|
||||
var totalQuota = statement.totalquota;
|
||||
var quotaUsage = statement.quotausage;
|
||||
if (statement.currency) {
|
||||
g_quotaCurrency = statement.currency.trim() + ' ';
|
||||
}
|
||||
|
||||
generatedStatement.empty();
|
||||
$("<hr>").appendTo(generatedStatement);
|
||||
|
||||
if (quotaUsage.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$('<h1 class="quota-bold">').html("<br>Usage Statement").appendTo(generatedStatement);
|
||||
var statementTable = $('<table>');
|
||||
statementTable.appendTo($('<div class="data-table">').appendTo(generatedStatement));
|
||||
|
||||
var statementTableHead = $('<tr>');
|
||||
$('<th>').html('Usage Description').appendTo(statementTableHead);
|
||||
$('<th>').html('Usage Unit').appendTo(statementTableHead);
|
||||
$('<th>').html('Amount').appendTo(statementTableHead);
|
||||
statementTableHead.appendTo($('<thead>').appendTo(statementTable));
|
||||
|
||||
// Add total usage
|
||||
quotaUsage.push({type: '', unit: '', name: '<span class="quota-bold">Total Quota Usage</span>', quota: totalQuota, });
|
||||
|
||||
var statementTableBody = $('<tbody>');
|
||||
for (var i = 0; i < quotaUsage.length; i++) {
|
||||
var statementTableBodyRow = $('<tr>');
|
||||
if (i % 2 == 0) {
|
||||
statementTableBodyRow.addClass('even');
|
||||
} else {
|
||||
statementTableBodyRow.addClass('odd');
|
||||
}
|
||||
$('<td>').html(quotaUsage[i].name).appendTo(statementTableBodyRow);
|
||||
$('<td>').html(quotaUsage[i].unit).appendTo(statementTableBodyRow);
|
||||
$('<td>').html(g_quotaCurrency + quotaUsage[i].quota).appendTo(statementTableBodyRow);
|
||||
statementTableBodyRow.appendTo(statementTableBody);
|
||||
}
|
||||
statementTableBody.appendTo(statementTable);
|
||||
},
|
||||
error: function(data) {
|
||||
generatedStatement.empty();
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(data)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: createURL('quotaBalance'),
|
||||
data: {
|
||||
domainid: domainId,
|
||||
account: account,
|
||||
startdate: startDate,
|
||||
enddate: endDate
|
||||
},
|
||||
success: function(json) {
|
||||
var statement = json.quotabalanceresponse.balance;
|
||||
var credits = statement.credits;
|
||||
var startBalance = statement.startquota;
|
||||
var startBalanceDate = statement.startdate;
|
||||
var endBalance = statement.endquota;
|
||||
var endBalanceDate = statement.enddate;
|
||||
if (statement.currency) {
|
||||
g_quotaCurrency = statement.currency.trim() + ' ';
|
||||
}
|
||||
|
||||
generatedBalanceStatement.empty();
|
||||
$("<br>").appendTo(generatedBalanceStatement);
|
||||
|
||||
$('<p class="quota-bold">').html("<br>Quota Balance Statement").appendTo(generatedBalanceStatement);
|
||||
var statementTable = $('<table>');
|
||||
statementTable.appendTo($('<div class="data-table">').appendTo(generatedBalanceStatement));
|
||||
|
||||
var statementTableHead = $('<tr>');
|
||||
$('<th>').html('Description').appendTo(statementTableHead);
|
||||
$('<th>').html("Date").appendTo(statementTableHead);
|
||||
$('<th>').html('Amount').appendTo(statementTableHead);
|
||||
statementTableHead.appendTo($('<thead>').appendTo(statementTable));
|
||||
|
||||
var statementTableBody = $('<tbody>');
|
||||
if (typeof startBalance !== 'undefined') {
|
||||
var statementTableBodyRow = $('<tr>');
|
||||
$('<td>').html("Start Quota Balance").appendTo(statementTableBodyRow);
|
||||
$('<td>').html(startBalanceDate).appendTo(statementTableBodyRow);
|
||||
$('<td>').html(g_quotaCurrency + startBalance).appendTo(statementTableBodyRow);
|
||||
statementTableBodyRow.appendTo(statementTableBody);
|
||||
}
|
||||
|
||||
for (var i = 0; i < credits.length; i++) {
|
||||
var statementTableBodyRow = $('<tr>');
|
||||
if (i % 2 == 0) {
|
||||
statementTableBodyRow.addClass('even');
|
||||
} else {
|
||||
statementTableBodyRow.addClass('odd');
|
||||
}
|
||||
$('<td>').html("Credit").appendTo(statementTableBodyRow);
|
||||
$('<td>').html(credits[i].updated_on).appendTo(statementTableBodyRow);
|
||||
$('<td>').html(g_quotaCurrency + credits[i].credits).appendTo(statementTableBodyRow);
|
||||
statementTableBodyRow.appendTo(statementTableBody);
|
||||
}
|
||||
|
||||
if (typeof endBalance !== 'undefined') {
|
||||
var statementTableBodyRow = $('<tr>');
|
||||
$('<td class="quota-bold">').html("Final Quota Balance").appendTo(statementTableBodyRow);
|
||||
$('<td>').html(endBalanceDate).appendTo(statementTableBodyRow);
|
||||
$('<td>').html(g_quotaCurrency + endBalance).appendTo(statementTableBodyRow);
|
||||
statementTableBodyRow.appendTo(statementTableBody);
|
||||
}
|
||||
|
||||
statementTableBody.appendTo(statementTable);
|
||||
},
|
||||
error: function(data) {
|
||||
generatedBalanceStatement.empty();
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(data)
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
domainDropdown.appendTo(statementForm);
|
||||
accountDropdown.appendTo(statementForm);
|
||||
$('<p class="quota-bold quota-element">').html('Start Date').appendTo(statementForm);
|
||||
startDateInput.appendTo(statementForm);
|
||||
$('<p class="quota-bold quota-element">').html('End Date').appendTo(statementForm);
|
||||
endDateInput.appendTo(statementForm);
|
||||
$('<br>').appendTo(statementForm);
|
||||
|
||||
generateStatementButton.appendTo(statementForm);
|
||||
|
||||
var accountLister = function(selectedDomainId) {
|
||||
var data = {listall: true};
|
||||
if (selectedDomainId) {
|
||||
data.domainid = selectedDomainId;
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL('listAccounts'),
|
||||
data : data,
|
||||
success: function(json) {
|
||||
accountDropdown.empty();
|
||||
$('<p class="quota-bold" style="margin-bottom: 5px">').html('Account').appendTo(accountDropdown);
|
||||
if (json.hasOwnProperty('listaccountsresponse') && json.listaccountsresponse.hasOwnProperty('account')) {
|
||||
var accounts = json.listaccountsresponse.account;
|
||||
var dropdown = $('<select class="quota-input">');
|
||||
for (var i = 0; i < accounts.length; i++) {
|
||||
$('<option value="' + accounts[i].id + '">' + accounts[i].name + '</option>').appendTo(dropdown);
|
||||
}
|
||||
dropdown.appendTo(accountDropdown);
|
||||
} else {
|
||||
$('<span class="quota-text">No accounts found in the selected domain</span>').appendTo(accountDropdown);
|
||||
}
|
||||
},
|
||||
error: function(data) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var domainLister = function() {
|
||||
$.ajax({
|
||||
url: createURL('listDomains'),
|
||||
data: {
|
||||
listall: true
|
||||
},
|
||||
success: function(json) {
|
||||
var domains = json.listdomainsresponse.domain;
|
||||
$('<p class="quota-bold" style="margin-bottom: 5px">').html('Domain').appendTo(domainDropdown);
|
||||
var dropdown = $('<select class="quota-input">');
|
||||
if (domains.length > 1) {
|
||||
$('<option value="">--- Select Domain ---</option>').appendTo(dropdown);
|
||||
}
|
||||
for (var i = 0; i < domains.length; i++) {
|
||||
$('<option value="' + domains[i].id + '">' + domains[i].name + '</option>').appendTo(dropdown);
|
||||
}
|
||||
dropdown.appendTo(domainDropdown);
|
||||
|
||||
dropdown.change(function() {
|
||||
var selectedDomainId = $(this).find(':selected').val();
|
||||
if (!selectedDomainId) {
|
||||
accountDropdown.empty();
|
||||
return;
|
||||
}
|
||||
accountLister(selectedDomainId);
|
||||
});
|
||||
dropdown.change();
|
||||
},
|
||||
error: function(data) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (isAdmin() || isDomainAdmin()) {
|
||||
domainLister();
|
||||
} else {
|
||||
accountLister(g_domainid);
|
||||
}
|
||||
|
||||
statementForm.appendTo(statementView);
|
||||
generatedStatement.appendTo(statementView);
|
||||
generatedBalanceStatement.appendTo(statementView);
|
||||
statementView.appendTo($node);
|
||||
}
|
||||
},
|
||||
{
|
||||
'id': 'quota-tariff',
|
||||
'name' : 'Tariff Plan',
|
||||
'render': function($node) {
|
||||
var tariffView = $('<div class="details quota-text" style="margin-top: -30px">');
|
||||
var tariffViewList = $('<div class="view list-view">');
|
||||
tariffViewList.appendTo(tariffView);
|
||||
|
||||
var renderDateForm = function(lastDate) {
|
||||
var startDateInput = $('<input type="text" class="quota-input" id="quota-tariff-startdate">');
|
||||
if (lastDate) {
|
||||
startDateInput.val(lastDate);
|
||||
}
|
||||
|
||||
startDateInput.datepicker({
|
||||
defaultDate: new Date(),
|
||||
changeMonth: true,
|
||||
dateFormat: "yy-mm-dd",
|
||||
onClose: function (selectedDate) {
|
||||
if (!selectedDate) {
|
||||
return;
|
||||
}
|
||||
tariffViewList.empty();
|
||||
renderDateForm(selectedDate);
|
||||
renderTariffTable(selectedDate);
|
||||
}
|
||||
});
|
||||
startDateInput.appendTo($('<br><span class="quota-element quota-bold">').html('Effective Date ').appendTo(tariffViewList));
|
||||
};
|
||||
|
||||
var renderTariffTable = function(startDate) {
|
||||
var tariffTable = $('<table style="margin-top: 15px">');
|
||||
tariffTable.appendTo(tariffViewList);
|
||||
|
||||
var tariffTableHead = $('<tr>');
|
||||
$('<th>').html(_l('label.usage.type')).appendTo(tariffTableHead);
|
||||
$('<th>').html(_l('label.usage.unit')).appendTo(tariffTableHead);
|
||||
$('<th>').html(_l('label.quota.value')).appendTo(tariffTableHead);
|
||||
$('<th>').html(_l('label.quota.description')).appendTo(tariffTableHead);
|
||||
tariffTableHead.appendTo($('<thead>').appendTo(tariffTable));
|
||||
|
||||
$.ajax({
|
||||
url: createURL('quotaTariffList'),
|
||||
data: {startdate: startDate },
|
||||
success: function(json) {
|
||||
var items = json.quotatarifflistresponse.quotatariff;
|
||||
if (items.constructor === Array && items[0].currency) {
|
||||
g_quotaCurrency = items[0].currency.trim() + ' ';
|
||||
}
|
||||
|
||||
var tariffTableBody = $('<tbody>');
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var tariffTableBodyRow = $('<tr>');
|
||||
if (i % 2 == 0) {
|
||||
tariffTableBodyRow.addClass('even');
|
||||
} else {
|
||||
tariffTableBodyRow.addClass('odd');
|
||||
}
|
||||
$('<td>').html(items[i].usageName).appendTo(tariffTableBodyRow);
|
||||
$('<td>').html(items[i].usageUnit).appendTo(tariffTableBodyRow);
|
||||
|
||||
if (isAdmin()) {
|
||||
var valueCell = $('<td class="value actions">');
|
||||
var value = $('<span class="quota-element">').html(g_quotaCurrency + items[i].tariffValue);
|
||||
value.appendTo(valueCell);
|
||||
valueCell.appendTo(tariffTableBodyRow);
|
||||
|
||||
var usageType = items[i].usageType;
|
||||
var editButton = $('<div class="action edit quota-tariff-edit" alt="Change value" title="Change value"><span class="icon"> </span></div>');
|
||||
editButton.appendTo(valueCell);
|
||||
editButton.attr('id', 'quota-tariff-edit-' + items[i].usageType);
|
||||
editButton.click(function() {
|
||||
var usageTypeId = $(this).context.id.replace('quota-tariff-edit-', '');
|
||||
var updateTariffForm = cloudStack.dialog.createForm({
|
||||
form: {
|
||||
title: 'label.quota.configuration',
|
||||
fields: {
|
||||
quotaValue: {
|
||||
label: 'label.quota.value',
|
||||
validation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
effectiveDate: {
|
||||
label: 'Effective Date',
|
||||
validation: {
|
||||
required: true
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
after: function(args) {
|
||||
$.ajax({
|
||||
url: createURL('quotaTariffUpdate'),
|
||||
data: {
|
||||
usagetype: usageTypeId,
|
||||
value: args.data.quotaValue,
|
||||
startDate: args.data.effectiveDate
|
||||
},
|
||||
type: "POST",
|
||||
success: function(json) {
|
||||
$('#quota-tariff').click();
|
||||
},
|
||||
error: function(data) {
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(data)
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
updateTariffForm.find('input[name=effectiveDate]').datepicker({
|
||||
defaultDate: new Date(),
|
||||
changeMonth: true,
|
||||
dateFormat: "yy-mm-dd",
|
||||
});
|
||||
});
|
||||
} else {
|
||||
$('<td>').html(g_quotaCurrency + items[i].tariffValue).appendTo(tariffTableBodyRow);
|
||||
}
|
||||
$('<td>').html(items[i].description).appendTo(tariffTableBodyRow);
|
||||
tariffTableBodyRow.appendTo(tariffTableBody);
|
||||
}
|
||||
tariffTableBody.appendTo(tariffTable);
|
||||
},
|
||||
error: function(data) {
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(data)
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
renderDateForm();
|
||||
renderTariffTable();
|
||||
tariffView.appendTo($node);
|
||||
}
|
||||
},
|
||||
{'id': 'quota-credit',
|
||||
'name': 'Manage Credits',
|
||||
'render': function($node) {
|
||||
var manageCreditView = $('<div class="details quota-text" style="padding: 10px">');
|
||||
var creditStatement = $('<div class="quota-credit-statement">');
|
||||
|
||||
var creditForm = $('<div class="quota-credit">');
|
||||
var domainDropdown = $('<div class="quota-domain-dropdown quota-element">');
|
||||
var accountDropdown = $('<div class="quota-account-dropdown quota-element">');
|
||||
var quotaValueInput = $('<input class="quota-input" type="text" style="margin-left: 12px">');
|
||||
var quotaThresholdInput = $('<input class="quota-input" type="text" style="margin-left: 12px">');
|
||||
var quotaThresholdLockCheckbox = $('<input class="quota-input quota-element" type="checkbox" style="margin-left: 12px" checked>');
|
||||
var addCreditButton = $('<button class="quota-element quota-button" id="quota-add-credit-button">').html("Add Credit");
|
||||
|
||||
addCreditButton.click(function() {
|
||||
if (isAdmin() || isDomainAdmin()) {
|
||||
domainId = domainDropdown.find("select :selected").val();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
var account = accountDropdown.find("select :selected").val();
|
||||
var quotaValue = quotaValueInput.val();
|
||||
var quotaThreshold = quotaThresholdInput.val();
|
||||
var isLockedOptionSelected = quotaThresholdLockCheckbox.is(':checked');
|
||||
|
||||
if (!quotaValue || !account) {
|
||||
creditStatement.empty();
|
||||
$('<br>').appendTo(creditStatement);
|
||||
$('<p class="quota-element">').html('Please select domain/account and enter valid credit/debit value').appendTo(creditStatement);
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: createURL('quotaCredits'),
|
||||
data: {
|
||||
account: account,
|
||||
domainid: domainId,
|
||||
value: quotaValue,
|
||||
quota_enforce: isLockedOptionSelected,
|
||||
min_balance: quotaThreshold
|
||||
},
|
||||
success: function(json) {
|
||||
quotaValueInput.val('');
|
||||
creditStatement.empty();
|
||||
if (json.quotacreditsresponse.quotacredits.currency) {
|
||||
g_quotaCurrency = json.quotacreditsresponse.quotacredits.currency.trim() + ' ';
|
||||
}
|
||||
$('<hr>').appendTo(creditStatement);
|
||||
$('<p class="quota-bold">').html('Credit amount ' + g_quotaCurrency + json.quotacreditsresponse.quotacredits.credits + ' added to the account ' + account).appendTo(creditStatement);
|
||||
$.ajax({
|
||||
url: createURL('quotaBalance'),
|
||||
data: {
|
||||
account: account,
|
||||
domainid: domainId,
|
||||
},
|
||||
success: function(json) {
|
||||
if (json.hasOwnProperty('quotabalanceresponse') && json.quotabalanceresponse.hasOwnProperty('balance')) {
|
||||
$('<p class="quota-bold">').html('Current Quota Balance of "' + account + '": ' + g_quotaCurrency + json.quotabalanceresponse.balance.startquota).appendTo(creditStatement);
|
||||
}
|
||||
},
|
||||
error: function(json) {
|
||||
}
|
||||
});
|
||||
},
|
||||
error: function(json) {
|
||||
cloudStack.dialog.notice({
|
||||
message: parseXMLHttpResponse(json)
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
domainDropdown.appendTo(creditForm);
|
||||
accountDropdown.appendTo(creditForm);
|
||||
$('<p class="quota-bold quota-element">').html('Credit Value').appendTo(creditForm);
|
||||
quotaValueInput.appendTo(creditForm);
|
||||
$('<p class="quota-bold quota-element">').html('Account Minimum Threshold').appendTo(creditForm);
|
||||
quotaThresholdInput.appendTo(creditForm);
|
||||
$('<br>').appendTo(creditForm);
|
||||
quotaThresholdLockCheckbox.appendTo(creditForm);
|
||||
$('<span class="quota-bold">').html('Lock account when quota balance is less than minimum threshold').appendTo(creditForm);
|
||||
$('<br>').appendTo(creditForm);
|
||||
addCreditButton.appendTo(creditForm);
|
||||
|
||||
var accountLister = function(selectedDomainId) {
|
||||
var data = {listall: true};
|
||||
if (selectedDomainId) {
|
||||
data.domainid = selectedDomainId;
|
||||
}
|
||||
$.ajax({
|
||||
url: createURL('listAccounts'),
|
||||
data : data,
|
||||
success: function(json) {
|
||||
accountDropdown.empty();
|
||||
$('<p class="quota-bold">').html('Account').appendTo(accountDropdown);
|
||||
if (json.hasOwnProperty('listaccountsresponse') && json.listaccountsresponse.hasOwnProperty('account')) {
|
||||
var accounts = json.listaccountsresponse.account;
|
||||
var dropdown = $('<select class="quota-input">');
|
||||
for (var i = 0; i < accounts.length; i++) {
|
||||
$('<option value="' + accounts[i].name + '">' + accounts[i].name + '</option>').appendTo(dropdown);
|
||||
}
|
||||
dropdown.appendTo(accountDropdown);
|
||||
} else {
|
||||
$('<span>No accounts found in the selected domain</span>').appendTo(accountDropdown);
|
||||
}
|
||||
},
|
||||
error: function(data) {
|
||||
// TODO: Add error dialog?
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var domainLister = function() {
|
||||
$.ajax({
|
||||
url: createURL('listDomains'),
|
||||
data: {
|
||||
listall: true
|
||||
},
|
||||
success: function(json) {
|
||||
$('<p class="quota-bold">').html('Domain').appendTo(domainDropdown);
|
||||
var domains = json.listdomainsresponse.domain;
|
||||
var dropdown = $('<select class="quota-input">');
|
||||
if (domains.length > 1) {
|
||||
$('<option value="">--- Select Domain ---</option>').appendTo(dropdown);
|
||||
}
|
||||
for (var i = 0; i < domains.length; i++) {
|
||||
$('<option value="' + domains[i].id + '">' + domains[i].name + '</option>').appendTo(dropdown);
|
||||
}
|
||||
dropdown.appendTo(domainDropdown);
|
||||
|
||||
dropdown.change(function() {
|
||||
var selectedDomainId = $(this).find(':selected').val();
|
||||
if (!selectedDomainId) {
|
||||
accountDropdown.empty();
|
||||
return;
|
||||
}
|
||||
accountLister(selectedDomainId);
|
||||
});
|
||||
dropdown.change();
|
||||
},
|
||||
error: function(data) {
|
||||
// FIXME: what to do on error?
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
domainLister();
|
||||
|
||||
creditForm.appendTo(manageCreditView);
|
||||
creditStatement.appendTo(manageCreditView);
|
||||
manageCreditView.appendTo($node);
|
||||
}
|
||||
},
|
||||
{'id': 'quota-email',
|
||||
'name': 'Email Templates',
|
||||
'render': function($node) {
|
||||
var manageTemplatesView = $('<div class="details quota-text" style="padding: 10px">');
|
||||
|
||||
var emailTemplateForm = $('<div class="quota-email-form">');
|
||||
var templateDropdown = $('<div class="quota-template-dropdown">');
|
||||
var templateOptions = $('<select class="quota-input" style="margin: 0px 0px 5px 11px"><option value="QUOTA_LOW">Template for accounts with low quota balance</option><option value="QUOTA_EMPTY">Template for accounts with no quota balance that will be locked</option><option value="QUOTA_UNLOCK_ACCOUNT">Template for accounts with enough credits getting unlocked</option><option value="QUOTA_STATEMENT">Template for quota statement</option><</select>');
|
||||
$('<p class="quota-bold quota-element">').html('Email Template').appendTo(templateDropdown);
|
||||
templateOptions.appendTo(templateDropdown);
|
||||
//templateOptions.appendTo($('<p class="quota-bold quota-element">Email Template</p>').appendTo(templateDropdown));
|
||||
|
||||
var templateSubjectTextArea = $('<textarea id="quota-template-subjectarea" class="quota-input" style="margin: 0px 0px 10px 12px; font-size: 12px">');
|
||||
var templateBodyTextArea = $('<textarea id="quota-template-bodyarea" class="quota-input" style="height: 250px; margin: 0px 0px 10px 12px; font-size: 12px"></textarea>');
|
||||
var saveTemplateButton = $('<button class="quota-button quota-element" id="quota-save-template-button">').html("Save Template");
|
||||
|
||||
templateOptions.change(function() {
|
||||
var templateName = $(this).find(':selected').val();
|
||||
templateSubjectTextArea.val('');
|
||||
templateBodyTextArea.val('');
|
||||
$.ajax({
|
||||
url: createURL('quotaEmailTemplateList'),
|
||||
data: {
|
||||
templatetype: templateName
|
||||
},
|
||||
success: function(json) {
|
||||
if (!json.hasOwnProperty('quotaemailtemplatelistresponse') || !json.quotaemailtemplatelistresponse.hasOwnProperty('quotaemailtemplate')) {
|
||||
return;
|
||||
}
|
||||
var template = json.quotaemailtemplatelistresponse.quotaemailtemplate[0];
|
||||
templateSubjectTextArea.val(template.templatesubject.replace(/\\n/g, '\n').replace(/\\"/g, '"').replace(/<br>/g, '\n'));
|
||||
templateBodyTextArea.val(template.templatebody.replace(/\\n/g, '\n').replace(/\\"/g, '"').replace(/<br>/g, '\n'));
|
||||
},
|
||||
error: function(data) {
|
||||
}
|
||||
});
|
||||
});
|
||||
templateOptions.change();
|
||||
|
||||
saveTemplateButton.click(function() {
|
||||
var templateName = templateOptions.find(':selected').val();
|
||||
var templateSubject = templateSubjectTextArea.val().replace(/\n/g, '<br>');
|
||||
var templateBody = templateBodyTextArea.val().replace(/\n/g, '<br>');
|
||||
|
||||
$.ajax({
|
||||
url: createURL('quotaEmailTemplateUpdate'),
|
||||
type: "POST",
|
||||
data: {
|
||||
templatetype: templateName,
|
||||
templatesubject: templateSubject,
|
||||
templatebody: unescape(templateBody),
|
||||
},
|
||||
success: function(json) {
|
||||
templateOptions.change();
|
||||
},
|
||||
error: function(data) {
|
||||
//handle error here
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
templateDropdown.appendTo(emailTemplateForm);
|
||||
$('<p class="quota-bold quota-element">').html('Email Template Subject').appendTo(emailTemplateForm);
|
||||
templateSubjectTextArea.appendTo(emailTemplateForm);
|
||||
$('<p class="quota-bold quota-element">').html('Email Template Body').appendTo(emailTemplateForm);
|
||||
templateBodyTextArea.appendTo(emailTemplateForm);
|
||||
saveTemplateButton.appendTo(emailTemplateForm);
|
||||
$('<hr>').appendTo(emailTemplateForm);
|
||||
$('<p>').html("These options can be used in template as ${variable}: quotaBalance, quotaUsage, accountName, accountID, accountUsers, domainName, domainID").appendTo(emailTemplateForm);
|
||||
|
||||
emailTemplateForm.appendTo(manageTemplatesView);
|
||||
manageTemplatesView.appendTo($node);
|
||||
}
|
||||
}];
|
||||
|
||||
if (isAdmin()) {
|
||||
} else if (isDomainAdmin()) {
|
||||
sections = $.grep(sections, function(item) {
|
||||
return ['quota-credit', 'quota-email'].indexOf(item.id) < 0;
|
||||
});
|
||||
} else {
|
||||
sections = $.grep(sections, function(item) {
|
||||
return ['quota-credit', 'quota-email'].indexOf(item.id) < 0;
|
||||
});
|
||||
}
|
||||
|
||||
for (idx in sections) {
|
||||
var tabLi = $('<li detail-view-tab="true" class="first ui-state-default ui-corner-top"><a href="#">' + sections[idx].name+ '</a></li>');
|
||||
var tabView = $('<div class="detail-group ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide">');
|
||||
|
||||
tabLi.attr('id', sections[idx].id);
|
||||
tabView.attr('id', 'details-tab-' + sections[idx].id);
|
||||
|
||||
tabLi.click(function() {
|
||||
var tabIdx = 0;
|
||||
for (sidx in sections) {
|
||||
$('#' + sections[sidx].id).removeClass('ui-tabs-selected ui-state-active');
|
||||
$('#details-tab-' + sections[sidx].id).addClass('ui-tabs-hide');
|
||||
$('#details-tab-' + sections[sidx].id).empty();
|
||||
if (sections[sidx].id === $(this).context.id) {
|
||||
tabIdx = sidx;
|
||||
}
|
||||
}
|
||||
$(this).addClass('ui-tabs-selected ui-state-active');
|
||||
var tabDetails = $('#details-tab-' + $(this).context.id);
|
||||
tabDetails.removeClass('ui-tabs-hide');
|
||||
sections[tabIdx].render(tabDetails);
|
||||
});
|
||||
|
||||
if (idx == 0) {
|
||||
tabLi.addClass('ui-tabs-selected ui-state-active');
|
||||
tabView.removeClass('ui-tabs-hide');
|
||||
sections[idx].render(tabView);
|
||||
}
|
||||
|
||||
tabLi.appendTo($tabs);
|
||||
$tabViews.push(tabView);
|
||||
}
|
||||
|
||||
$toolbar.appendTo($quotaView);
|
||||
$tabs.appendTo($quotaView);
|
||||
for (idx in $tabViews) {
|
||||
$tabViews[idx].appendTo($quotaView);
|
||||
}
|
||||
return $quotaView;
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
}(cloudStack));
|
||||
|
|
@ -19,6 +19,7 @@
|
|||
plugin.ui.addSection({
|
||||
id: 'testPlugin',
|
||||
title: 'TestPlugin',
|
||||
showOnNavigation: true,
|
||||
preFilter: function(args) {
|
||||
return isAdmin();
|
||||
},
|
||||
|
|
|
|||
|
|
@ -31,9 +31,12 @@
|
|||
sections = ["dashboard", "instances", "storage", "network", "templates", "accounts", "events", "regions", "affinityGroups"];
|
||||
}
|
||||
|
||||
if (cloudStack.plugins.length) {
|
||||
sections.push('plugins');
|
||||
}
|
||||
$.each(cloudStack.plugins, function(idx, plugin) {
|
||||
if (cloudStack.sections.hasOwnProperty(plugin) && !cloudStack.sections[plugin].showOnNavigation) {
|
||||
sections.push('plugins');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return sections;
|
||||
},
|
||||
|
|
@ -304,10 +307,11 @@
|
|||
},
|
||||
error: function(XMLHttpRequest) {
|
||||
var errorMsg = parseXMLHttpResponse(XMLHttpRequest);
|
||||
if (errorMsg.length == 0 && XMLHttpRequest.status == 0)
|
||||
if (errorMsg.length == 0 && XMLHttpRequest.status == 0) {
|
||||
errorMsg = dictionary['error.unable.to.reach.management.server'];
|
||||
else
|
||||
} else if (errorMsg.indexOf('Failed to authenticate') === 0) {
|
||||
errorMsg = _l('error.invalid.username.password'); //override error message
|
||||
}
|
||||
args.response.error(errorMsg);
|
||||
},
|
||||
beforeSend: function(XMLHttpResponse) {
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@
|
|||
);
|
||||
}
|
||||
|
||||
if (args.isPlugin) {
|
||||
if (args.isPlugin && !args.showOnNavigation) {
|
||||
$li.hide();
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +88,7 @@
|
|||
return $(this).hasClass(sectionID);
|
||||
});
|
||||
var data = args.sections[sectionID];
|
||||
var isPlugin = data.isPlugin;
|
||||
var isPlugin = data.isPlugin && !data.showOnNavigation;
|
||||
|
||||
data.$browser = $browser;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,10 +35,26 @@
|
|||
<artifactId>cloud-engine-components-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.cloudstack</groupId>
|
||||
<artifactId>cloud-framework-quota</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-daemon</groupId>
|
||||
<artifactId>commons-daemon</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>${cs.mysql.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.mail</groupId>
|
||||
<artifactId>mail</artifactId>
|
||||
|
|
@ -49,6 +65,11 @@
|
|||
<version>2.4.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${cs.commons-lang3.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<resources>
|
||||
|
|
|
|||
|
|
@ -17,36 +17,38 @@
|
|||
under the License.
|
||||
-->
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/tx
|
||||
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
|
||||
http://www.springframework.org/schema/aop
|
||||
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
|
||||
|
||||
<context:annotation-config />
|
||||
<context:component-scan base-package="com.cloud.usage, com.cloud.event.dao, com.cloud.user.dao, com.cloud.configuration.dao, com.cloud.alert.dao, com.cloud.domain.dao, org.apache.cloudstack.framework.config.dao">
|
||||
</context:component-scan>
|
||||
|
||||
<!--
|
||||
@DB support
|
||||
-->
|
||||
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
|
||||
<context:annotation-config />
|
||||
<context:component-scan
|
||||
base-package="com.cloud.usage, com.cloud.event.dao, com.cloud.user.dao, com.cloud.configuration.dao, com.cloud.alert.dao, com.cloud.domain.dao, org.apache.cloudstack.framework.config.dao,
|
||||
org.apache.cloudstack.quota.constant, org.apache.cloudstack.quota.dao, org.apache.cloudstack.quota.vo">
|
||||
</context:component-scan>
|
||||
|
||||
<bean id="QuotaManager" class="org.apache.cloudstack.quota.QuotaManagerImpl" />
|
||||
<bean id="QuotaAlertManager" class="org.apache.cloudstack.quota.QuotaAlertManagerImpl" />
|
||||
|
||||
<!-- @DB support -->
|
||||
<bean id="transactionContextBuilder" class="com.cloud.utils.db.TransactionContextBuilder" />
|
||||
|
||||
<bean id="instantiatePostProcessor"
|
||||
class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
|
||||
<property name="Interceptors">
|
||||
<list>
|
||||
<ref bean="transactionContextBuilder" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="ComponentContext" class="com.cloud.utils.component.ComponentContext" />
|
||||
|
||||
<bean id="instantiatePostProcessor" class="com.cloud.utils.component.ComponentInstantiationPostProcessor">
|
||||
<property name="Interceptors">
|
||||
<list>
|
||||
<ref bean="transactionContextBuilder" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="ComponentContext" class="com.cloud.utils.component.ComponentContext" />
|
||||
|
||||
</beans>
|
||||
|
|
|
|||
|
|
@ -34,10 +34,11 @@ import javax.ejb.Local;
|
|||
import javax.inject.Inject;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.cloudstack.quota.QuotaAlertManager;
|
||||
import org.apache.cloudstack.quota.QuotaManager;
|
||||
import org.apache.cloudstack.utils.usage.UsageUtils;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
|
||||
import org.apache.cloudstack.usage.UsageTypes;
|
||||
|
|
@ -144,11 +145,16 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
|
|||
ConfigurationDao _configDao;
|
||||
@Inject
|
||||
private UsageVMSnapshotDao _usageVMSnapshotDao;
|
||||
@Inject
|
||||
private QuotaManager _quotaManager;
|
||||
@Inject
|
||||
private QuotaAlertManager _alertManager;
|
||||
|
||||
private String _version = null;
|
||||
private final Calendar _jobExecTime = Calendar.getInstance();
|
||||
private int _aggregationDuration = 0;
|
||||
private int _sanityCheckInterval = 0;
|
||||
private boolean _runQuota=false;
|
||||
String _hostname = null;
|
||||
int _pid = 0;
|
||||
TimeZone _usageTimezone = TimeZone.getTimeZone("GMT");;
|
||||
|
|
@ -202,6 +208,8 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
|
|||
String execTimeZone = configs.get("usage.execution.timezone");
|
||||
String aggreagationTimeZone = configs.get("usage.aggregation.timezone");
|
||||
String sanityCheckInterval = configs.get("usage.sanity.check.interval");
|
||||
String quotaEnable = configs.get("quota.enable.service");
|
||||
_runQuota = Boolean.valueOf(quotaEnable == null ? "false" : quotaEnable );
|
||||
if (sanityCheckInterval != null) {
|
||||
_sanityCheckInterval = Integer.parseInt(sanityCheckInterval);
|
||||
}
|
||||
|
|
@ -376,6 +384,26 @@ public class UsageManagerImpl extends ManagerBase implements UsageManager, Runna
|
|||
}
|
||||
|
||||
parse(job, startDate, endDate);
|
||||
if (_runQuota){
|
||||
try {
|
||||
_quotaManager.calculateQuotaUsage();
|
||||
}
|
||||
catch (Exception e){
|
||||
s_logger.fatal("Exception received while calculating quota " + e.getMessage());
|
||||
if (s_logger.isDebugEnabled()){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
_alertManager.checkAndSendQuotaAlertEmails();
|
||||
_alertManager.sendMonthlyStatement();
|
||||
} catch (Exception e) {
|
||||
s_logger.fatal("Exception received while sending alerts " + e.getMessage());
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (s_logger.isDebugEnabled()) {
|
||||
s_logger.debug("Not owner of usage job, skipping...");
|
||||
|
|
|
|||
|
|
@ -0,0 +1,27 @@
|
|||
//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
|
||||
//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.Manager;
|
||||
|
||||
public interface QuotaAlertManager extends Manager {
|
||||
|
||||
public void checkAndSendQuotaAlertEmails();
|
||||
|
||||
void sendMonthlyStatement();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
//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.domain.DomainVO;
|
||||
import com.cloud.domain.dao.DomainDao;
|
||||
import com.cloud.user.Account;
|
||||
//import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.UserVO;
|
||||
import com.cloud.user.Account.State;
|
||||
import com.cloud.user.dao.AccountDao;
|
||||
import com.cloud.user.dao.UserDao;
|
||||
import com.cloud.utils.DateUtil;
|
||||
import com.cloud.utils.NumbersUtil;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.db.TransactionLegacy;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.sun.mail.smtp.SMTPMessage;
|
||||
import com.sun.mail.smtp.SMTPSSLTransport;
|
||||
import com.sun.mail.smtp.SMTPTransport;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
import org.apache.cloudstack.quota.constant.QuotaConfig;
|
||||
import org.apache.cloudstack.quota.constant.QuotaConfig.QuotaEmailTemplateTypes;
|
||||
import org.apache.cloudstack.quota.dao.QuotaAccountDao;
|
||||
import org.apache.cloudstack.quota.dao.QuotaEmailTemplatesDao;
|
||||
import org.apache.cloudstack.quota.dao.QuotaUsageDao;
|
||||
import org.apache.cloudstack.quota.vo.QuotaAccountVO;
|
||||
import org.apache.cloudstack.quota.vo.QuotaEmailTemplatesVO;
|
||||
import org.apache.commons.lang3.text.StrSubstitutor;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.inject.Inject;
|
||||
import javax.mail.Authenticator;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.PasswordAuthentication;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.URLName;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigDecimal;
|
||||
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.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Component
|
||||
@Local(value = QuotaAlertManager.class)
|
||||
public class QuotaAlertManagerImpl extends ManagerBase implements QuotaAlertManager {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaAlertManagerImpl.class.getName());
|
||||
|
||||
@Inject
|
||||
private AccountDao _accountDao;
|
||||
@Inject
|
||||
private QuotaAccountDao _quotaAcc;
|
||||
@Inject
|
||||
private UserDao _userDao;
|
||||
@Inject
|
||||
private DomainDao _domainDao;
|
||||
@Inject
|
||||
private QuotaEmailTemplatesDao _quotaEmailTemplateDao;
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
@Inject
|
||||
private QuotaUsageDao _quotaUsage;
|
||||
|
||||
private EmailQuotaAlert _emailQuotaAlert;
|
||||
private boolean _lockAccountEnforcement = false;
|
||||
|
||||
final static BigDecimal s_hoursInMonth = new BigDecimal(30 * 24);
|
||||
final static BigDecimal s_minutesInMonth = new BigDecimal(30 * 24 * 60);
|
||||
final static BigDecimal s_gb = new BigDecimal(1024 * 1024 * 1024);
|
||||
|
||||
boolean _smtpDebug = false;
|
||||
|
||||
int _pid = 0;
|
||||
|
||||
public QuotaAlertManagerImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
private void mergeConfigs(Map<String, String> dbParams, Map<String, Object> xmlParams) {
|
||||
for (Map.Entry<String, Object> param : xmlParams.entrySet()) {
|
||||
dbParams.put(param.getKey(), (String) param.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
Map<String, String> configs = _configDao.getConfiguration(params);
|
||||
|
||||
if (params != null) {
|
||||
mergeConfigs(configs, params);
|
||||
}
|
||||
|
||||
final String smtpHost = configs.get(QuotaConfig.QuotaSmtpHost.key());
|
||||
int smtpPort = NumbersUtil.parseInt(configs.get(QuotaConfig.QuotaSmtpPort.key()), 25);
|
||||
String useAuthStr = configs.get(QuotaConfig.QuotaSmtpAuthType.key());
|
||||
boolean useAuth = ((useAuthStr != null) && Boolean.parseBoolean(useAuthStr));
|
||||
String smtpUsername = configs.get(QuotaConfig.QuotaSmtpUser.key());
|
||||
String smtpPassword = configs.get(QuotaConfig.QuotaSmtpPassword.key());
|
||||
String emailSender = configs.get(QuotaConfig.QuotaSmtpSender.key());
|
||||
_lockAccountEnforcement = configs.get(QuotaConfig.QuotaEnableEnforcement.key()).equalsIgnoreCase("true");
|
||||
_emailQuotaAlert = new EmailQuotaAlert(smtpHost, smtpPort, useAuth, smtpUsername, smtpPassword, emailSender, _smtpDebug);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Starting Alert Manager");
|
||||
}
|
||||
_pid = Integer.parseInt(System.getProperty("pid"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Stopping Alert Manager");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void sendMonthlyStatement() {
|
||||
Date now = new Date();
|
||||
Calendar aCalendar = Calendar.getInstance();
|
||||
aCalendar.add(Calendar.MONTH, -1);
|
||||
aCalendar.set(Calendar.DATE, 1);
|
||||
aCalendar.set(Calendar.HOUR, 0);
|
||||
aCalendar.set(Calendar.MINUTE, 0);
|
||||
aCalendar.set(Calendar.SECOND, 0);
|
||||
Date firstDateOfPreviousMonth = aCalendar.getTime();
|
||||
aCalendar.set(Calendar.DATE, aCalendar.getActualMaximum(Calendar.DAY_OF_MONTH) + 1);
|
||||
Date lastDateOfPreviousMonth = aCalendar.getTime(); // actually the first day of this month
|
||||
//s_logger.info("firstDateOfPreviousMonth" + firstDateOfPreviousMonth + " lastDateOfPreviousMonth" + lastDateOfPreviousMonth);
|
||||
|
||||
List<DeferredQuotaEmail> deferredQuotaEmailList = new ArrayList<DeferredQuotaEmail>();
|
||||
for (final QuotaAccountVO quotaAccount : _quotaAcc.listAll()) {
|
||||
if (quotaAccount.getQuotaBalance() == null) continue; // no quota usage for this account ever, ignore
|
||||
Date lastStatementDate = quotaAccount.getLastStatementDate();
|
||||
if (now.getDate() < 6) {
|
||||
AccountVO account = _accountDao.findById(quotaAccount.getId());
|
||||
if (lastStatementDate == null) {
|
||||
BigDecimal quotaUsage = _quotaUsage.findTotalQuotaUsage(account.getAccountId(), account.getDomainId(), null, firstDateOfPreviousMonth, lastDateOfPreviousMonth);
|
||||
s_logger.info("For account=" + quotaAccount.getId() + ", quota used = " + quotaUsage);
|
||||
// send statement
|
||||
deferredQuotaEmailList.add(new DeferredQuotaEmail(account, quotaAccount, quotaUsage, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_STATEMENT));
|
||||
} else if (getDifferenceDays(lastStatementDate, new Date()) < 7) {
|
||||
s_logger.debug("For " + quotaAccount.getId() + " the statement has been sent recently");
|
||||
} else {
|
||||
BigDecimal quotaUsage = _quotaUsage.findTotalQuotaUsage(account.getAccountId(), account.getDomainId(), null, firstDateOfPreviousMonth, lastDateOfPreviousMonth);
|
||||
s_logger.info("For account=" + quotaAccount.getId() + ", quota used = " + quotaUsage);
|
||||
deferredQuotaEmailList.add(new DeferredQuotaEmail(account, quotaAccount, quotaUsage, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_STATEMENT));
|
||||
}
|
||||
} else {
|
||||
s_logger.info("For " + quotaAccount.getId() + " it is already more than " + getDifferenceDays(lastStatementDate, new Date()) + " days, will send statement in next cycle");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (DeferredQuotaEmail emailToBeSent : deferredQuotaEmailList) {
|
||||
s_logger.debug("Attempting to send quota STATEMENT email to users of account: " + emailToBeSent.getAccount().getAccountName());
|
||||
sendQuotaAlert(emailToBeSent);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkAndSendQuotaAlertEmails() {
|
||||
s_logger.info("Running checkAndSendQuotaAlertEmails");
|
||||
List<DeferredQuotaEmail> deferredQuotaEmailList = new ArrayList<DeferredQuotaEmail>();
|
||||
final BigDecimal zeroBalance = new BigDecimal(0);
|
||||
for (final QuotaAccountVO quotaAccount : _quotaAcc.listAll()) {
|
||||
s_logger.info("checkAndSendQuotaAlertEmails accId=" + quotaAccount.getId());
|
||||
BigDecimal accountBalance = quotaAccount.getQuotaBalance();
|
||||
Date balanceDate = quotaAccount.getQuotaBalanceDate();
|
||||
Date alertDate = quotaAccount.getQuotaAlertDate();
|
||||
int lockable = quotaAccount.getQuotaEnforce();
|
||||
BigDecimal thresholdBalance = quotaAccount.getQuotaMinBalance();
|
||||
if (accountBalance != null) {
|
||||
AccountVO account = _accountDao.findById(quotaAccount.getId());
|
||||
// s_logger.info("Check id " + account.getId() + " bal="+ accountBalance + " alertDate"+ alertDate + " diff" + getDifferenceDays(alertDate, new Date()));
|
||||
if (accountBalance.compareTo(zeroBalance) <= 0) {
|
||||
if (_lockAccountEnforcement && (lockable == 1)) {
|
||||
if (account.getType() == Account.ACCOUNT_TYPE_NORMAL) {
|
||||
lockAccount(account.getId());
|
||||
}
|
||||
}
|
||||
if (alertDate == null || (balanceDate.after(alertDate) && getDifferenceDays(alertDate, new Date()) > 1)) {
|
||||
deferredQuotaEmailList.add(new DeferredQuotaEmail(account, quotaAccount, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_EMPTY));
|
||||
}
|
||||
} else if (accountBalance.compareTo(thresholdBalance) <= 0) {
|
||||
if (alertDate == null || (balanceDate.after(alertDate) && getDifferenceDays(alertDate, new Date()) > 1)) {
|
||||
deferredQuotaEmailList.add(new DeferredQuotaEmail(account, quotaAccount, QuotaConfig.QuotaEmailTemplateTypes.QUOTA_LOW));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (DeferredQuotaEmail emailToBeSent : deferredQuotaEmailList) {
|
||||
s_logger.debug("Attempting to send quota alert email to users of account: " + emailToBeSent.getAccount().getAccountName());
|
||||
sendQuotaAlert(emailToBeSent);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendQuotaAlert(DeferredQuotaEmail emailToBeSent) {
|
||||
final AccountVO account = emailToBeSent.getAccount();
|
||||
final BigDecimal balance = emailToBeSent.getQuotaBalance();
|
||||
final BigDecimal usage = emailToBeSent.getQuotaUsage();
|
||||
final QuotaConfig.QuotaEmailTemplateTypes emailType = emailToBeSent.getEmailTemplateType();
|
||||
|
||||
final List<QuotaEmailTemplatesVO> emailTemplates = _quotaEmailTemplateDao.listAllQuotaEmailTemplates(emailType.toString());
|
||||
if (emailTemplates != null && emailTemplates.get(0) != null) {
|
||||
final QuotaEmailTemplatesVO emailTemplate = emailTemplates.get(0);
|
||||
|
||||
final DomainVO accountDomain = _domainDao.findByIdIncludingRemoved(account.getDomainId());
|
||||
final List<UserVO> usersInAccount = _userDao.listByAccount(account.getId());
|
||||
|
||||
String userNames = "";
|
||||
final List<String> emailRecipients = new ArrayList<String>();
|
||||
for (UserVO user : usersInAccount) {
|
||||
userNames += String.format("%s <%s>,", user.getUsername(), user.getEmail());
|
||||
emailRecipients.add(user.getEmail());
|
||||
}
|
||||
if (userNames.endsWith(",")) {
|
||||
userNames = userNames.substring(0, userNames.length() - 1);
|
||||
}
|
||||
|
||||
final Map<String, String> optionMap = new HashMap<String, String>();
|
||||
optionMap.put("accountName", account.getAccountName());
|
||||
optionMap.put("accountID", account.getUuid());
|
||||
optionMap.put("accountUsers", userNames);
|
||||
optionMap.put("domainName", accountDomain.getName());
|
||||
optionMap.put("domainID", accountDomain.getUuid());
|
||||
optionMap.put("quotaBalance", QuotaConfig.QuotaCurrencySymbol.value() + " " + balance.toString());
|
||||
if (emailType == QuotaEmailTemplateTypes.QUOTA_STATEMENT) {
|
||||
optionMap.put("quotaUsage", QuotaConfig.QuotaCurrencySymbol.value() + " " + usage.toString());
|
||||
}
|
||||
|
||||
// s_logger.info("accountName" + account.getAccountName() + "accountID" + account.getUuid() + "accountUsers" + userNames + "domainName" + accountDomain.getName() + "domainID"
|
||||
// + accountDomain.getUuid());
|
||||
|
||||
final StrSubstitutor templateEngine = new StrSubstitutor(optionMap);
|
||||
final String subject = templateEngine.replace(emailTemplate.getTemplateSubject());
|
||||
final String body = templateEngine.replace(emailTemplate.getTemplateBody());
|
||||
try {
|
||||
_emailQuotaAlert.sendQuotaAlert(emailRecipients, subject, body);
|
||||
emailToBeSent.sentSuccessfully();
|
||||
} catch (Exception e) {
|
||||
s_logger.error(String.format("Unable to send quota alert email (subject=%s; body=%s) to account %s (%s) recipients (%s) due to error (%s)", subject, body, account.getAccountName(),
|
||||
account.getUuid(), emailRecipients, e));
|
||||
}
|
||||
} else {
|
||||
s_logger.error(String.format("No quota email template found for type %s, cannot send quota alert email to account %s(%s)", emailType, account.getAccountName(), account.getUuid()));
|
||||
}
|
||||
}
|
||||
|
||||
class DeferredQuotaEmail {
|
||||
AccountVO account;
|
||||
QuotaAccountVO quotaAccount;
|
||||
QuotaConfig.QuotaEmailTemplateTypes emailTemplateType;
|
||||
BigDecimal quotaUsage;
|
||||
|
||||
public DeferredQuotaEmail(AccountVO account, QuotaAccountVO quotaAccount, BigDecimal quotaUsage, QuotaConfig.QuotaEmailTemplateTypes emailTemplateType) {
|
||||
this.account = account;
|
||||
this.quotaAccount = quotaAccount;
|
||||
this.emailTemplateType = emailTemplateType;
|
||||
this.quotaUsage = quotaUsage;
|
||||
}
|
||||
|
||||
public DeferredQuotaEmail(AccountVO account, QuotaAccountVO quotaAccount, QuotaConfig.QuotaEmailTemplateTypes emailTemplateType) {
|
||||
this.account = account;
|
||||
this.quotaAccount = quotaAccount;
|
||||
this.emailTemplateType = emailTemplateType;
|
||||
this.quotaUsage = new BigDecimal(-1);
|
||||
}
|
||||
|
||||
public AccountVO getAccount() {
|
||||
return account;
|
||||
}
|
||||
|
||||
public BigDecimal getQuotaBalance() {
|
||||
return quotaAccount.getQuotaBalance();
|
||||
}
|
||||
|
||||
public BigDecimal getQuotaUsage() {
|
||||
return quotaUsage;
|
||||
}
|
||||
|
||||
public QuotaConfig.QuotaEmailTemplateTypes getEmailTemplateType() {
|
||||
return emailTemplateType;
|
||||
}
|
||||
|
||||
public void sentSuccessfully() {
|
||||
if (emailTemplateType == QuotaEmailTemplateTypes.QUOTA_STATEMENT) {
|
||||
quotaAccount.setLastStatementDate(new Date());
|
||||
_quotaAcc.update(quotaAccount.getAccountId(), quotaAccount);
|
||||
}
|
||||
else {
|
||||
quotaAccount.setQuotaAlertDate(new Date());
|
||||
quotaAccount.setQuotaAlertType(emailTemplateType.ordinal());
|
||||
_quotaAcc.update(quotaAccount.getAccountId(), quotaAccount);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class EmailQuotaAlert {
|
||||
private Session _smtpSession;
|
||||
private final String _smtpHost;
|
||||
private int _smtpPort = -1;
|
||||
private boolean _smtpUseAuth = false;
|
||||
private final String _smtpUsername;
|
||||
private final String _smtpPassword;
|
||||
private final String _emailSender;
|
||||
|
||||
public EmailQuotaAlert(String smtpHost, int smtpPort, boolean smtpUseAuth, final String smtpUsername, final String smtpPassword, String emailSender, boolean smtpDebug) {
|
||||
_smtpHost = smtpHost;
|
||||
_smtpPort = smtpPort;
|
||||
_smtpUseAuth = smtpUseAuth;
|
||||
_smtpUsername = smtpUsername;
|
||||
_smtpPassword = smtpPassword;
|
||||
_emailSender = emailSender;
|
||||
|
||||
if (_smtpHost != null) {
|
||||
Properties smtpProps = new Properties();
|
||||
smtpProps.put("mail.smtp.host", smtpHost);
|
||||
smtpProps.put("mail.smtp.port", smtpPort);
|
||||
smtpProps.put("mail.smtp.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtp.user", smtpUsername);
|
||||
}
|
||||
|
||||
smtpProps.put("mail.smtps.host", smtpHost);
|
||||
smtpProps.put("mail.smtps.port", smtpPort);
|
||||
smtpProps.put("mail.smtps.auth", "" + smtpUseAuth);
|
||||
if (smtpUsername != null) {
|
||||
smtpProps.put("mail.smtps.user", smtpUsername);
|
||||
}
|
||||
|
||||
if ((smtpUsername != null) && (smtpPassword != null)) {
|
||||
_smtpSession = Session.getInstance(smtpProps, new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(smtpUsername, smtpPassword);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
_smtpSession = Session.getInstance(smtpProps);
|
||||
}
|
||||
_smtpSession.setDebug(smtpDebug);
|
||||
} else {
|
||||
_smtpSession = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void sendQuotaAlert(List<String> emails, String subject, String body) throws MessagingException, UnsupportedEncodingException {
|
||||
if (_smtpSession != null) {
|
||||
SMTPMessage msg = new SMTPMessage(_smtpSession);
|
||||
msg.setSender(new InternetAddress(_emailSender, _emailSender));
|
||||
msg.setFrom(new InternetAddress(_emailSender, _emailSender));
|
||||
|
||||
for (String email : emails) {
|
||||
if (email != null && !email.isEmpty()) {
|
||||
try {
|
||||
InternetAddress address = new InternetAddress(email, email);
|
||||
msg.addRecipient(Message.RecipientType.TO, address);
|
||||
} catch (Exception pokemon) {
|
||||
s_logger.error("Exception in creating address for:" + email, pokemon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
msg.setSubject(subject);
|
||||
msg.setSentDate(new Date(DateUtil.currentGMTTime().getTime() >> 10));
|
||||
msg.setContent(body, "text/html; charset=utf-8");
|
||||
msg.saveChanges();
|
||||
|
||||
SMTPTransport smtpTrans = null;
|
||||
if (_smtpUseAuth) {
|
||||
smtpTrans = new SMTPSSLTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
} else {
|
||||
smtpTrans = new SMTPTransport(_smtpSession, new URLName("smtp", _smtpHost, _smtpPort, null, _smtpUsername, _smtpPassword));
|
||||
}
|
||||
smtpTrans.connect();
|
||||
smtpTrans.sendMessage(msg, msg.getAllRecipients());
|
||||
smtpTrans.close();
|
||||
} else {
|
||||
throw new CloudRuntimeException("Unable to create smtp session.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Date startOfNextDay() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(new Date());
|
||||
c.add(Calendar.DATE, 1);
|
||||
Date dt = c.getTime();
|
||||
return dt;
|
||||
}
|
||||
|
||||
public static long getDifferenceDays(Date d1, Date d2) {
|
||||
long diff = d2.getTime() - d1.getTime();
|
||||
return TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
protected boolean lockAccount(long accountId) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
boolean success = false;
|
||||
Account account = _accountDao.findById(accountId);
|
||||
if (account != null) {
|
||||
if (account.getState().equals(State.locked)) {
|
||||
return true; // already locked, no-op
|
||||
} else if (account.getState().equals(State.enabled)) {
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.locked);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
} else {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Attempting to lock a non-enabled account, current state is " + account.getState() + " (accountId: " + accountId + "), locking failed.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Failed to lock account " + accountId + ", account not found.");
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean enableAccount(long accountId) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
boolean success = false;
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.enabled);
|
||||
acctForUpdate.setNeedsCleanup(false);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
//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
|
||||
//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.Manager;
|
||||
|
||||
public interface QuotaManager extends Manager {
|
||||
|
||||
boolean calculateQuotaUsage();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,465 @@
|
|||
//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.usage.UsageVO;
|
||||
import com.cloud.usage.dao.UsageDao;
|
||||
import com.cloud.user.Account;
|
||||
//import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.AccountVO;
|
||||
import com.cloud.user.Account.State;
|
||||
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.TransactionLegacy;
|
||||
|
||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||
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.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.QuotaTariffVO;
|
||||
import org.apache.cloudstack.quota.vo.QuotaUsageVO;
|
||||
import org.apache.cloudstack.quota.vo.ServiceOfferingVO;
|
||||
import org.apache.cloudstack.quota.dao.ServiceOfferingDao;
|
||||
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.List;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
@Component
|
||||
@Local(value = QuotaManager.class)
|
||||
public class QuotaManagerImpl extends ManagerBase implements QuotaManager {
|
||||
private static final Logger s_logger = Logger.getLogger(QuotaManagerImpl.class.getName());
|
||||
|
||||
@Inject
|
||||
private AccountDao _accountDao;
|
||||
@Inject
|
||||
private QuotaAccountDao _quotaAcc;
|
||||
@Inject
|
||||
private UsageDao _usageDao;
|
||||
@Inject
|
||||
private QuotaTariffDao _quotaTariffDao;
|
||||
@Inject
|
||||
private QuotaUsageDao _quotaUsageDao;
|
||||
@Inject
|
||||
private ServiceOfferingDao _serviceOfferingDao;
|
||||
@Inject
|
||||
private QuotaBalanceDao _quotaBalanceDao;
|
||||
@Inject
|
||||
private ConfigurationDao _configDao;
|
||||
|
||||
private TimeZone _usageTimezone;
|
||||
private int _aggregationDuration = 0;
|
||||
|
||||
final static BigDecimal s_hoursInMonth = new BigDecimal(30 * 24);
|
||||
final static BigDecimal s_minutesInMonth = new BigDecimal(30 * 24 * 60);
|
||||
final static BigDecimal s_gb = new BigDecimal(1024 * 1024 * 1024);
|
||||
|
||||
int _pid = 0;
|
||||
|
||||
public QuotaManagerImpl() {
|
||||
super();
|
||||
}
|
||||
|
||||
private void mergeConfigs(Map<String, String> dbParams, Map<String, Object> xmlParams) {
|
||||
for (Map.Entry<String, Object> param : xmlParams.entrySet()) {
|
||||
dbParams.put(param.getKey(), (String) param.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
super.configure(name, params);
|
||||
|
||||
Map<String, String> configs = _configDao.getConfiguration(params);
|
||||
|
||||
if (params != null) {
|
||||
mergeConfigs(configs, params);
|
||||
}
|
||||
|
||||
String aggregationRange = configs.get("usage.stats.job.aggregation.range");
|
||||
String timeZoneStr = configs.get("usage.aggregation.timezone");
|
||||
|
||||
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 boolean start() {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Starting Quota Manager");
|
||||
}
|
||||
_pid = Integer.parseInt(System.getProperty("pid"));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Stopping Quota Manager");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean calculateQuotaUsage() {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
boolean jobResult = false;
|
||||
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
|
||||
try {
|
||||
// get all the active accounts for which there is usage
|
||||
List<AccountVO> accounts = _accountDao.listAll();
|
||||
for (AccountVO account : accounts) { // START ACCOUNT
|
||||
Pair<List<? extends UsageVO>, Integer> usageRecords = null;
|
||||
List<QuotaUsageVO> quotalistforaccount = new ArrayList<QuotaUsageVO>();
|
||||
do {
|
||||
s_logger.info("Account =" + account.getAccountName());
|
||||
usageRecords = _usageDao.getUsageRecordsPendingQuotaAggregation(account.getAccountId(), account.getDomainId());
|
||||
s_logger.debug("Usage records found " + usageRecords.second());
|
||||
for (UsageVO usageRecord : usageRecords.first()) {
|
||||
BigDecimal aggregationRatio = new BigDecimal(_aggregationDuration).divide(s_minutesInMonth, 8, RoundingMode.HALF_EVEN);
|
||||
switch (usageRecord.getUsageType()) {
|
||||
case QuotaTypes.RUNNING_VM:
|
||||
quotalistforaccount.addAll(updateQuotaRunningVMUsage(usageRecord, aggregationRatio));
|
||||
break;
|
||||
case QuotaTypes.ALLOCATED_VM:
|
||||
quotalistforaccount.add(updateQuotaAllocatedVMUsage(usageRecord, aggregationRatio));
|
||||
break;
|
||||
case QuotaTypes.SNAPSHOT:
|
||||
quotalistforaccount.add(updateQuotaDiskUsage(usageRecord, aggregationRatio, QuotaTypes.SNAPSHOT));
|
||||
break;
|
||||
case QuotaTypes.TEMPLATE:
|
||||
quotalistforaccount.add(updateQuotaDiskUsage(usageRecord, aggregationRatio, QuotaTypes.TEMPLATE));
|
||||
break;
|
||||
case QuotaTypes.ISO:
|
||||
quotalistforaccount.add(updateQuotaDiskUsage(usageRecord, aggregationRatio, QuotaTypes.ISO));
|
||||
break;
|
||||
case QuotaTypes.VOLUME:
|
||||
quotalistforaccount.add(updateQuotaDiskUsage(usageRecord, aggregationRatio, QuotaTypes.VOLUME));
|
||||
break;
|
||||
case QuotaTypes.VM_SNAPSHOT:
|
||||
quotalistforaccount.add(updateQuotaDiskUsage(usageRecord, aggregationRatio, QuotaTypes.VM_SNAPSHOT));
|
||||
break;
|
||||
case QuotaTypes.LOAD_BALANCER_POLICY:
|
||||
quotalistforaccount.add(updateQuotaRaw(usageRecord, aggregationRatio, QuotaTypes.LOAD_BALANCER_POLICY));
|
||||
break;
|
||||
case QuotaTypes.PORT_FORWARDING_RULE:
|
||||
quotalistforaccount.add(updateQuotaRaw(usageRecord, aggregationRatio, QuotaTypes.PORT_FORWARDING_RULE));
|
||||
break;
|
||||
case QuotaTypes.IP_ADDRESS:
|
||||
quotalistforaccount.add(updateQuotaRaw(usageRecord, aggregationRatio, QuotaTypes.IP_ADDRESS));
|
||||
break;
|
||||
case QuotaTypes.NETWORK_OFFERING:
|
||||
quotalistforaccount.add(updateQuotaRaw(usageRecord, aggregationRatio, QuotaTypes.NETWORK_OFFERING));
|
||||
break;
|
||||
case QuotaTypes.SECURITY_GROUP:
|
||||
quotalistforaccount.add(updateQuotaRaw(usageRecord, aggregationRatio, QuotaTypes.SECURITY_GROUP));
|
||||
break;
|
||||
case QuotaTypes.VPN_USERS:
|
||||
quotalistforaccount.add(updateQuotaRaw(usageRecord, aggregationRatio, QuotaTypes.VPN_USERS));
|
||||
break;
|
||||
case QuotaTypes.NETWORK_BYTES_RECEIVED:
|
||||
quotalistforaccount.add(updateQuotaNetwork(usageRecord, QuotaTypes.NETWORK_BYTES_RECEIVED));
|
||||
break;
|
||||
case QuotaTypes.NETWORK_BYTES_SENT:
|
||||
quotalistforaccount.add(updateQuotaNetwork(usageRecord, QuotaTypes.NETWORK_BYTES_SENT));
|
||||
break;
|
||||
case QuotaTypes.VM_DISK_IO_READ:
|
||||
case QuotaTypes.VM_DISK_IO_WRITE:
|
||||
case QuotaTypes.VM_DISK_BYTES_READ:
|
||||
case QuotaTypes.VM_DISK_BYTES_WRITE:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while ((usageRecords != null) && !usageRecords.first().isEmpty());
|
||||
// list of quotas for this account
|
||||
s_logger.info("Quota entries size = " + quotalistforaccount.size() + ", accId" + account.getAccountId() + ", domId" + account.getDomainId());
|
||||
if (quotalistforaccount.size() > 0) { // balance to be processed
|
||||
quotalistforaccount.add(new QuotaUsageVO());
|
||||
Date startDate = quotalistforaccount.get(0).getStartDate();
|
||||
Date endDate = quotalistforaccount.get(0).getEndDate();
|
||||
BigDecimal aggrUsage = new BigDecimal(0);
|
||||
for (QuotaUsageVO entry : quotalistforaccount) {
|
||||
if (startDate.compareTo(entry.getStartDate()) != 0) {
|
||||
QuotaBalanceVO lastrealbalanceentry = _quotaBalanceDao.findLastBalanceEntry(account.getAccountId(), account.getDomainId(), startDate);
|
||||
Date lastbalancedate;
|
||||
if (lastrealbalanceentry != null) {
|
||||
lastbalancedate = lastrealbalanceentry.getUpdatedOn();
|
||||
aggrUsage = aggrUsage.add(lastrealbalanceentry.getCreditBalance());
|
||||
} else {
|
||||
lastbalancedate = new Date(0);
|
||||
}
|
||||
|
||||
List<QuotaBalanceVO> creditsrcvd = _quotaBalanceDao.findCreditBalance(account.getAccountId(), account.getDomainId(), lastbalancedate, endDate);
|
||||
for (QuotaBalanceVO credit : creditsrcvd) {
|
||||
aggrUsage = aggrUsage.add(credit.getCreditBalance());
|
||||
}
|
||||
|
||||
QuotaBalanceVO newbalance = new QuotaBalanceVO(account.getAccountId(), account.getDomainId(), aggrUsage, endDate);
|
||||
// s_logger.info("Balance entry=" + aggrUsage + " on Date=" + endDate);
|
||||
_quotaBalanceDao.persist(newbalance);
|
||||
aggrUsage = new BigDecimal(0);
|
||||
}
|
||||
startDate = entry.getStartDate();
|
||||
endDate = entry.getEndDate();
|
||||
aggrUsage = aggrUsage.subtract(entry.getQuotaUsed());
|
||||
}
|
||||
// update is quota_accounts
|
||||
QuotaAccountVO quota_account = _quotaAcc.findById(account.getAccountId());
|
||||
s_logger.info("Updating quota account bal=" + aggrUsage + " date=" + endDate);
|
||||
if (quota_account == null) {
|
||||
quota_account = new QuotaAccountVO(account.getAccountId());
|
||||
quota_account.setQuotaBalance(aggrUsage);
|
||||
quota_account.setQuotaBalanceDate(endDate);
|
||||
_quotaAcc.persist(quota_account);
|
||||
} else {
|
||||
quota_account.setQuotaBalance(aggrUsage);
|
||||
quota_account.setQuotaBalanceDate(endDate);
|
||||
_quotaAcc.update(account.getAccountId(), quota_account);
|
||||
}
|
||||
}// balance processed
|
||||
} // END ACCOUNT
|
||||
jobResult = true;
|
||||
} catch (Exception e) {
|
||||
s_logger.error("Quota Manager error", e);
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
txn.close();
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return jobResult;
|
||||
}
|
||||
|
||||
|
||||
@DB
|
||||
private QuotaUsageVO updateQuotaDiskUsage(UsageVO usageRecord, final BigDecimal aggregationRatio, final int quotaType) {
|
||||
QuotaUsageVO quota_usage = null;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(quotaType, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal quotaUsgage;
|
||||
BigDecimal onehourcostpergb;
|
||||
BigDecimal noofgbinuse;
|
||||
onehourcostpergb = tariff.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.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), usageRecord.getUsageType(), quotaUsgage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
_quotaUsageDao.persist(quota_usage);
|
||||
}
|
||||
usageRecord.setQuotaCalculated(1);
|
||||
_usageDao.persist(usageRecord);
|
||||
return quota_usage;
|
||||
}
|
||||
|
||||
@DB
|
||||
private List<QuotaUsageVO> updateQuotaRunningVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) {
|
||||
List<QuotaUsageVO> quotalist = new ArrayList<QuotaUsageVO>();
|
||||
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()
|
||||
// + ", aggrR=" + aggregationRatio);
|
||||
// get service offering details
|
||||
ServiceOfferingVO serviceoffering = _serviceOfferingDao.findServiceOffering(usageRecord.getVmInstanceId(), usageRecord.getOfferingId());
|
||||
rawusage = new BigDecimal(usageRecord.getRawUsage());
|
||||
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_NUMBER, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal cpu = new BigDecimal(serviceoffering.getCpu());
|
||||
onehourcostpercpu = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
cpuquotausgage = rawusage.multiply(onehourcostpercpu).multiply(cpu);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.CPU_NUMBER, cpuquotausgage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
_quotaUsageDao.persist(quota_usage);
|
||||
quotalist.add(quota_usage);
|
||||
}
|
||||
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.CPU_CLOCK_RATE, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal speed = new BigDecimal(serviceoffering.getSpeed() / 100.00);
|
||||
onehourcostper100mhz = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
speedquotausage = rawusage.multiply(onehourcostper100mhz).multiply(speed);
|
||||
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);
|
||||
quotalist.add(quota_usage);
|
||||
}
|
||||
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.MEMORY, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal memory = new BigDecimal(serviceoffering.getRamSize());
|
||||
onehourcostper1mb = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
memoryquotausage = rawusage.multiply(onehourcostper1mb).multiply(memory);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.MEMORY, memoryquotausage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
_quotaUsageDao.persist(quota_usage);
|
||||
quotalist.add(quota_usage);
|
||||
}
|
||||
tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.RUNNING_VM, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
vmusage = rawusage.multiply(onehourcostforvmusage);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.RUNNING_VM, vmusage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
_quotaUsageDao.persist(quota_usage);
|
||||
quotalist.add(quota_usage);
|
||||
}
|
||||
|
||||
usageRecord.setQuotaCalculated(1);
|
||||
_usageDao.persist(usageRecord);
|
||||
return quotalist;
|
||||
}
|
||||
|
||||
@DB
|
||||
private QuotaUsageVO updateQuotaAllocatedVMUsage(UsageVO usageRecord, final BigDecimal aggregationRatio) {
|
||||
QuotaUsageVO quota_usage = null;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(QuotaTypes.ALLOCATED_VM, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal vmusage;
|
||||
BigDecimal onehourcostforvmusage;
|
||||
onehourcostforvmusage = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
// s_logger.info("Quotatariff onehourcostforvmusage=" +
|
||||
// onehourcostforvmusage);
|
||||
vmusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcostforvmusage);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), QuotaTypes.ALLOCATED_VM, vmusage,
|
||||
usageRecord.getStartDate(), usageRecord.getEndDate());
|
||||
_quotaUsageDao.persist(quota_usage);
|
||||
}
|
||||
|
||||
usageRecord.setQuotaCalculated(1);
|
||||
_usageDao.persist(usageRecord);
|
||||
return quota_usage;
|
||||
}
|
||||
|
||||
@DB
|
||||
private QuotaUsageVO updateQuotaRaw(UsageVO usageRecord, final BigDecimal aggregationRatio, final int ruleType) {
|
||||
QuotaUsageVO quota_usage = null;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(ruleType, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal ruleusage;
|
||||
BigDecimal onehourcost;
|
||||
onehourcost = tariff.getCurrencyValue().multiply(aggregationRatio);
|
||||
// s_logger.info("Quotatariff onehourcost=" + onehourcost);
|
||||
ruleusage = new BigDecimal(usageRecord.getRawUsage()).multiply(onehourcost);
|
||||
quota_usage = new QuotaUsageVO(usageRecord.getId(), usageRecord.getZoneId(), usageRecord.getAccountId(), usageRecord.getDomainId(), ruleType, ruleusage, usageRecord.getStartDate(),
|
||||
usageRecord.getEndDate());
|
||||
_quotaUsageDao.persist(quota_usage);
|
||||
}
|
||||
|
||||
usageRecord.setQuotaCalculated(1);
|
||||
_usageDao.persist(usageRecord);
|
||||
return quota_usage;
|
||||
}
|
||||
|
||||
@DB
|
||||
private QuotaUsageVO updateQuotaNetwork(UsageVO usageRecord, final int transferType) {
|
||||
QuotaUsageVO quota_usage = null;
|
||||
QuotaTariffVO tariff = _quotaTariffDao.findTariffPlanByUsageType(transferType, usageRecord.getEndDate());
|
||||
if (tariff != null && !tariff.getCurrencyValue().equals(0)) {
|
||||
BigDecimal onegbcost;
|
||||
BigDecimal rawusageingb;
|
||||
BigDecimal networkusage;
|
||||
onegbcost = tariff.getCurrencyValue();
|
||||
// s_logger.info("Quotatariff onegbcost=" + onegbcost);
|
||||
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);
|
||||
}
|
||||
|
||||
usageRecord.setQuotaCalculated(1);
|
||||
_usageDao.persist(usageRecord);
|
||||
return quota_usage;
|
||||
}
|
||||
|
||||
public Date startOfNextDay() {
|
||||
Calendar c = Calendar.getInstance();
|
||||
c.setTime(new Date());
|
||||
c.add(Calendar.DATE, 1);
|
||||
Date dt = c.getTime();
|
||||
return dt;
|
||||
}
|
||||
|
||||
protected boolean lockAccount(long accountId) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
boolean success = false;
|
||||
Account account = _accountDao.findById(accountId);
|
||||
if (account != null) {
|
||||
if (account.getState().equals(State.locked)) {
|
||||
return true; // already locked, no-op
|
||||
} else if (account.getState().equals(State.enabled)) {
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.locked);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
} else {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
s_logger.info("Attempting to lock a non-enabled account, current state is " + account.getState() + " (accountId: " + accountId + "), locking failed.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s_logger.warn("Failed to lock account " + accountId + ", account not found.");
|
||||
}
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return success;
|
||||
}
|
||||
|
||||
public boolean enableAccount(long accountId) {
|
||||
final short opendb = TransactionLegacy.currentTxn().getDatabaseId();
|
||||
TransactionLegacy.open(TransactionLegacy.CLOUD_DB).close();
|
||||
boolean success = false;
|
||||
AccountVO acctForUpdate = _accountDao.createForUpdate();
|
||||
acctForUpdate.setState(State.enabled);
|
||||
acctForUpdate.setNeedsCleanup(false);
|
||||
success = _accountDao.update(Long.valueOf(accountId), acctForUpdate);
|
||||
TransactionLegacy.open(opendb).close();
|
||||
return success;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue