Skip to content

Commit a73cc9a

Browse files
julien-vazJulien Hervot de Mattos Vazwinterhazel
authored
Improve Quota Statement (#10506)
* Improve Quota Statement * Removes unused import * Fix QuotaUsageJoinDao, QuotaResponseBuilderImpl, QuotaServiceImpl e QuotaServiceImplTest * Reorganize imports * Updates QuotaStatementCmd responseBuilder scope to default * Fix log4j syntax * Address reviews + other improvements * Add missing SQL scripts and injections * Change accountid and domainid logic + add unit tests * Rename QuotaUsageDetail to QuotaTariffUsage * Fix out of bounds exception --------- Co-authored-by: Julien Hervot de Mattos Vaz <julien.vaz@scclouds.com.br> Co-authored-by: Fabricio Duarte <fabricio.duarte.jr@gmail.com>
1 parent 089eb36 commit a73cc9a

23 files changed

Lines changed: 1212 additions & 248 deletions

File tree

api/src/main/java/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ public class ApiConstants {
157157
public static final String CUSTOM_ID = "customid";
158158
public static final String CUSTOM_ACTION_ID = "customactionid";
159159
public static final String CUSTOM_JOB_ID = "customjobid";
160+
public static final String CURRENCY = "currency";
160161
public static final String CURRENT_START_IP = "currentstartip";
161162
public static final String CURRENT_END_IP = "currentendip";
162163
public static final String ENCRYPT = "encrypt";
@@ -541,6 +542,7 @@ public class ApiConstants {
541542
public static final String SESSIONKEY = "sessionkey";
542543
public static final String SHOW_CAPACITIES = "showcapacities";
543544
public static final String SHOW_REMOVED = "showremoved";
545+
public static final String SHOW_RESOURCES = "showresources";
544546
public static final String SHOW_RESOURCE_ICON = "showicon";
545547
public static final String SHOW_INACTIVE = "showinactive";
546548
public static final String SHOW_UNIQUE = "showunique";
@@ -606,9 +608,11 @@ public class ApiConstants {
606608
public static final String TENANT_NAME = "tenantname";
607609
public static final String TOTAL = "total";
608610
public static final String TOTAL_SUBNETS = "totalsubnets";
611+
public static final String TOTAL_QUOTA = "totalquota";
609612
public static final String TYPE = "type";
610613
public static final String TRUST_STORE = "truststore";
611614
public static final String TRUST_STORE_PASSWORD = "truststorepass";
615+
public static final String UNIT = "unit";
612616
public static final String URL = "url";
613617
public static final String USAGE_INTERFACE = "usageinterface";
614618
public static final String USED = "used";
@@ -1300,6 +1304,8 @@ public class ApiConstants {
13001304
public static final String OBJECT_LOCKING = "objectlocking";
13011305
public static final String ENCRYPTION = "encryption";
13021306
public static final String QUOTA = "quota";
1307+
public static final String QUOTA_CONSUMED = "quotaconsumed";
1308+
public static final String QUOTA_USAGE = "quotausage";
13031309
public static final String ACCESS_KEY = "accesskey";
13041310

13051311
public static final String SOURCE_NAT_IP = "sourcenatipaddress";

engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,13 @@ CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tin
117117

118118
--- Disable/enable NICs
119119
CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.nics','enabled', 'TINYINT(1) NOT NULL DEFAULT 1 COMMENT ''Indicates whether the NIC is enabled or not'' ');
120+
121+
--- Quota tariff/usage mapping
122+
CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_tariff_usage` (
123+
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
124+
`tariff_id` bigint(20) unsigned NOT NULL COMMENT 'ID of the tariff of the Quota usage detail calculated, foreign key to quota_tariff table',
125+
`quota_usage_id` bigint(20) unsigned NOT NULL COMMENT 'ID of the aggregation of Quota usage details, foreign key to quota_usage table',
126+
`quota_used` decimal(20,8) NOT NULL COMMENT 'Amount of quota used',
127+
PRIMARY KEY (`id`),
128+
CONSTRAINT `fk_quota_tariff_usage__tariff_id` FOREIGN KEY (`tariff_id`) REFERENCES `cloud_usage`.`quota_tariff` (`id`),
129+
CONSTRAINT `fk_quota_tariff_usage__quota_usage_id` FOREIGN KEY (`quota_usage_id`) REFERENCES `cloud_usage`.`quota_usage` (`id`));
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
-- Licensed to the Apache Software Foundation (ASF) under one
2+
-- or more contributor license agreements. See the NOTICE file
3+
-- distributed with this work for additional information
4+
-- regarding copyright ownership. The ASF licenses this file
5+
-- to you under the Apache License, Version 2.0 (the
6+
-- "License"); you may not use this file except in compliance
7+
-- with the License. You may obtain a copy of the License at
8+
--
9+
-- http://www.apache.org/licenses/LICENSE-2.0
10+
--
11+
-- Unless required by applicable law or agreed to in writing,
12+
-- software distributed under the License is distributed on an
13+
-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
-- KIND, either express or implied. See the License for the
15+
-- specific language governing permissions and limitations
16+
-- under the License.
17+
18+
-- VIEW `cloud_usage`.`quota_usage_view`;
19+
20+
DROP VIEW IF EXISTS `cloud_usage`.`quota_usage_view`;
21+
CREATE VIEW `cloud_usage`.`quota_usage_view` AS
22+
SELECT qu.id,
23+
qu.usage_item_id,
24+
qu.zone_id,
25+
qu.account_id,
26+
qu.domain_id,
27+
qu.usage_type,
28+
qu.quota_used,
29+
qu.start_date,
30+
qu.end_date,
31+
cu.usage_id AS resource_id,
32+
cu.network_id as network_id,
33+
cu.offering_id as offering_id
34+
FROM `cloud_usage`.`quota_usage` qu
35+
INNER JOIN `cloud_usage`.`cloud_usage` cu ON (cu.id = qu.usage_item_id);

framework/db/src/main/java/com/cloud/utils/db/SearchCriteria.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ public void setJoinParameters(String joinName, String conditionName, Object... p
205205

206206
}
207207

208+
public void setJoinParametersIfNotNull(String joinName, String conditionName, Object... params) {
209+
if (ArrayUtils.isNotEmpty(params) && (params.length > 1 || params[0] != null)) {
210+
setJoinParameters(joinName, conditionName, params);
211+
}
212+
}
213+
208214
public SearchCriteria<?> getJoin(String joinName) {
209215
return _joins.get(joinName).getT();
210216
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//Licensed to the Apache Software Foundation (ASF) under one
2+
//or more contributor license agreements. See the NOTICE file
3+
//distributed with this work for additional information
4+
//regarding copyright ownership. The ASF licenses this file
5+
//to you under the Apache License, Version 2.0 (the
6+
//"License"); you may not use this file except in compliance
7+
//with the License. You may obtain a copy of the License at
8+
//
9+
//http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
//Unless required by applicable law or agreed to in writing,
12+
//software distributed under the License is distributed on an
13+
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
//KIND, either express or implied. See the License for the
15+
//specific language governing permissions and limitations
16+
//under the License.
17+
package org.apache.cloudstack.quota.dao;
18+
19+
import com.cloud.utils.db.GenericDao;
20+
import org.apache.cloudstack.quota.vo.QuotaTariffUsageVO;
21+
import java.util.List;
22+
23+
public interface QuotaTariffUsageDao extends GenericDao<QuotaTariffUsageVO, Long> {
24+
25+
void persistQuotaTariffUsage(QuotaTariffUsageVO quotaTariffUsage);
26+
27+
List<QuotaTariffUsageVO> listQuotaTariffUsages(Long quotaUsageId);
28+
29+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
//Licensed to the Apache Software Foundation (ASF) under one
2+
//or more contributor license agreements. See the NOTICE file
3+
//distributed with this work for additional information
4+
//regarding copyright ownership. The ASF licenses this file
5+
//to you under the Apache License, Version 2.0 (the
6+
//"License"); you may not use this file except in compliance
7+
//with the License. You may obtain a copy of the License at
8+
//
9+
//http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
//Unless required by applicable law or agreed to in writing,
12+
//software distributed under the License is distributed on an
13+
//"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
//KIND, either express or implied. See the License for the
15+
//specific language governing permissions and limitations
16+
//under the License.
17+
package org.apache.cloudstack.quota.dao;
18+
19+
import com.cloud.utils.db.SearchBuilder;
20+
import com.cloud.utils.db.SearchCriteria;
21+
import org.apache.cloudstack.quota.vo.QuotaTariffUsageVO;
22+
import org.springframework.stereotype.Component;
23+
24+
import com.cloud.utils.db.GenericDaoBase;
25+
import com.cloud.utils.db.Transaction;
26+
import com.cloud.utils.db.TransactionCallback;
27+
import com.cloud.utils.db.TransactionLegacy;
28+
29+
import javax.annotation.PostConstruct;
30+
import java.util.List;
31+
32+
@Component
33+
public class QuotaTariffUsageDaoImpl extends GenericDaoBase<QuotaTariffUsageVO, Long> implements QuotaTariffUsageDao {
34+
private SearchBuilder<QuotaTariffUsageVO> searchQuotaTariffUsages;
35+
36+
@PostConstruct
37+
public void init() {
38+
searchQuotaTariffUsages = createSearchBuilder();
39+
searchQuotaTariffUsages.and("quotaUsageId", searchQuotaTariffUsages.entity().getQuotaUsageId(), SearchCriteria.Op.EQ);
40+
searchQuotaTariffUsages.done();
41+
}
42+
43+
@Override
44+
public void persistQuotaTariffUsage(final QuotaTariffUsageVO quotaTariffUsage) {
45+
logger.trace("Persisting quota tariff usage [{}].", quotaTariffUsage);
46+
Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback<QuotaTariffUsageVO>) status -> persist(quotaTariffUsage));
47+
}
48+
49+
@Override
50+
public List<QuotaTariffUsageVO> listQuotaTariffUsages(Long quotaUsageId) {
51+
SearchCriteria<QuotaTariffUsageVO> sc = searchQuotaTariffUsages.create();
52+
sc.setParameters("quotaUsageId", quotaUsageId);
53+
return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback<List<QuotaTariffUsageVO>>) status -> listBy(sc));
54+
}
55+
56+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
//
18+
19+
package org.apache.cloudstack.quota.dao;
20+
21+
import com.cloud.utils.db.GenericDao;
22+
import org.apache.cloudstack.quota.vo.QuotaUsageJoinVO;
23+
24+
import java.util.Date;
25+
import java.util.List;
26+
27+
public interface QuotaUsageJoinDao extends GenericDao<QuotaUsageJoinVO, Long> {
28+
29+
List<QuotaUsageJoinVO> findQuotaUsage(Long accountId, Long domainId, Integer usageType, Long resourceId, Long networkId, Long offeringId, Date startDate, Date endDate, Long tariffId);
30+
31+
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
//
18+
package org.apache.cloudstack.quota.dao;
19+
20+
import com.cloud.utils.db.GenericDaoBase;
21+
import com.cloud.utils.db.JoinBuilder;
22+
import com.cloud.utils.db.SearchBuilder;
23+
import com.cloud.utils.db.SearchCriteria;
24+
import com.cloud.utils.db.Transaction;
25+
import com.cloud.utils.db.TransactionCallback;
26+
import com.cloud.utils.db.TransactionLegacy;
27+
import org.apache.cloudstack.quota.vo.QuotaTariffUsageVO;
28+
import org.apache.cloudstack.quota.vo.QuotaUsageJoinVO;
29+
import org.apache.commons.lang3.ObjectUtils;
30+
import org.springframework.stereotype.Component;
31+
32+
import javax.annotation.PostConstruct;
33+
import javax.inject.Inject;
34+
import java.util.Date;
35+
import java.util.List;
36+
37+
@Component
38+
public class QuotaUsageJoinDaoImpl extends GenericDaoBase<QuotaUsageJoinVO, Long> implements QuotaUsageJoinDao {
39+
40+
private SearchBuilder<QuotaUsageJoinVO> searchQuotaUsages;
41+
42+
private SearchBuilder<QuotaUsageJoinVO> searchQuotaUsagesJoinTariffUsages;
43+
44+
@Inject
45+
private QuotaTariffUsageDao quotaTariffUsageDao;
46+
47+
@PostConstruct
48+
public void init() {
49+
searchQuotaUsages = createSearchBuilder();
50+
prepareQuotaUsageSearchBuilder(searchQuotaUsages);
51+
searchQuotaUsages.done();
52+
53+
SearchBuilder<QuotaTariffUsageVO> searchQuotaTariffUsages = quotaTariffUsageDao.createSearchBuilder();
54+
searchQuotaTariffUsages.and("tariffId", searchQuotaTariffUsages.entity().getTariffId(), SearchCriteria.Op.EQ);
55+
searchQuotaUsagesJoinTariffUsages = createSearchBuilder();
56+
prepareQuotaUsageSearchBuilder(searchQuotaUsagesJoinTariffUsages);
57+
searchQuotaUsagesJoinTariffUsages.join("searchQuotaTariffUsages", searchQuotaTariffUsages, searchQuotaUsagesJoinTariffUsages.entity().getId(),
58+
searchQuotaTariffUsages.entity().getQuotaUsageId(), JoinBuilder.JoinType.INNER);
59+
searchQuotaUsagesJoinTariffUsages.done();
60+
}
61+
62+
private void prepareQuotaUsageSearchBuilder(SearchBuilder<QuotaUsageJoinVO> searchBuilder) {
63+
searchBuilder.and("accountId", searchBuilder.entity().getAccountId(), SearchCriteria.Op.EQ);
64+
searchBuilder.and("domainId", searchBuilder.entity().getDomainId(), SearchCriteria.Op.EQ);
65+
searchBuilder.and("usageType", searchBuilder.entity().getUsageType(), SearchCriteria.Op.EQ);
66+
searchBuilder.and("resourceId", searchBuilder.entity().getResourceId(), SearchCriteria.Op.EQ);
67+
searchBuilder.and("networkId", searchBuilder.entity().getNetworkId(), SearchCriteria.Op.EQ);
68+
searchBuilder.and("offeringId", searchBuilder.entity().getOfferingId(), SearchCriteria.Op.EQ);
69+
searchBuilder.and("startDate", searchBuilder.entity().getStartDate(), SearchCriteria.Op.BETWEEN);
70+
searchBuilder.and("endDate", searchBuilder.entity().getEndDate(), SearchCriteria.Op.BETWEEN);
71+
}
72+
73+
@Override
74+
public List<QuotaUsageJoinVO> findQuotaUsage(Long accountId, Long domainId, Integer usageType, Long resourceId, Long networkId, Long offeringId, Date startDate, Date endDate, Long tariffId) {
75+
SearchCriteria<QuotaUsageJoinVO> sc = tariffId == null ? searchQuotaUsages.create() : searchQuotaUsagesJoinTariffUsages.create();
76+
77+
sc.setParametersIfNotNull("accountId", accountId);
78+
sc.setParametersIfNotNull("domainId", domainId);
79+
sc.setParametersIfNotNull("usageType", usageType);
80+
sc.setParametersIfNotNull("resourceId", resourceId);
81+
sc.setParametersIfNotNull("networkId", networkId);
82+
sc.setParametersIfNotNull("offeringId", offeringId);
83+
84+
if (ObjectUtils.allNotNull(startDate, endDate)) {
85+
sc.setParameters("startDate", startDate, endDate);
86+
sc.setParameters("endDate", startDate, endDate);
87+
}
88+
89+
sc.setJoinParametersIfNotNull("searchQuotaTariffUsages", "tariffId", tariffId);
90+
91+
return Transaction.execute(TransactionLegacy.USAGE_DB, (TransactionCallback<List<QuotaUsageJoinVO>>) status -> listBy(sc));
92+
}
93+
94+
}

0 commit comments

Comments
 (0)