Skip to content

Commit eb4b9e3

Browse files
committed
Track volume usage data at vm granularity as well.
1 parent 25f93b1 commit eb4b9e3

File tree

19 files changed

+321
-153
lines changed

19 files changed

+321
-153
lines changed

engine/components-api/src/main/java/com/cloud/event/UsageEventUtils.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ public static void publishUsageEvent(String usageType, long accountId, long zone
9292

9393
}
9494

95+
public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId,
96+
Long size, String entityType, String entityUUID, Long vmId, boolean displayResource) {
97+
if (displayResource) {
98+
saveUsageEvent(usageType, accountId, zoneId, resourceId, offeringId, templateId, size, vmId, resourceName);
99+
}
100+
publishUsageEvent(usageType, accountId, zoneId, entityType, entityUUID);
101+
}
102+
95103
public static void publishUsageEvent(String usageType, long accountId, long zoneId, long resourceId, String resourceName, Long offeringId, Long templateId,
96104
Long size, Long virtualSize, String entityType, String entityUUID, Map<String, String> details) {
97105
saveUsageEvent(usageType, accountId, zoneId, resourceId, resourceName, offeringId, templateId, size, virtualSize, details);
@@ -200,6 +208,10 @@ public static void saveUsageEvent(String usageType, long accountId, long zoneId,
200208
s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, vmId, securityGroupId));
201209
}
202210

211+
public static void saveUsageEvent(String usageType, long accountId, long zoneId, long resourceId, Long offeringId, Long templateId, Long size, Long vmId, String resourceName) {
212+
s_usageEventDao.persist(new UsageEventVO(usageType, accountId, zoneId, resourceId, offeringId, templateId, size, vmId, resourceName));
213+
}
214+
203215
private static void publishUsageEvent(String usageEventType, Long accountId, Long zoneId, String resourceType, String resourceUUID) {
204216
String configKey = "publish.usage.events";
205217
String value = s_configDao.getValue(configKey);

engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/VolumeOrchestrator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ public DiskProfile allocateRawVolume(Type type, String name, DiskOffering offeri
867867
// Save usage event and update resource count for user vm volumes
868868
if (vm.getType() == VirtualMachine.Type.User) {
869869
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offering.getId(), null, size,
870-
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
870+
Volume.class.getName(), vol.getUuid(), vol.getInstanceId(), vol.isDisplayVolume());
871871

872872
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
873873
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));
@@ -939,7 +939,7 @@ private DiskProfile allocateTemplatedVolume(Type type, String name, DiskOffering
939939
}
940940

941941
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, vol.getAccountId(), vol.getDataCenterId(), vol.getId(), vol.getName(), offeringId, vol.getTemplateId(), size,
942-
Volume.class.getName(), vol.getUuid(), vol.isDisplayVolume());
942+
Volume.class.getName(), vol.getUuid(), vol.getInstanceId(), vol.isDisplayVolume());
943943

944944
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, vol.isDisplayVolume());
945945
_resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.primary_storage, vol.isDisplayVolume(), new Long(vol.getSize()));

engine/schema/src/main/java/com/cloud/event/UsageEventVO.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ public enum DynamicParameters {
7575
@Column(name = "virtual_size")
7676
private Long virtualSize;
7777

78+
@Column(name = "vm_id")
79+
private Long vmId;
80+
7881
public UsageEventVO() {
7982
}
8083

@@ -143,6 +146,18 @@ public UsageEventVO(String usageType, long accountId, long zoneId, long vmId, lo
143146
this.offeringId = securityGroupId;
144147
}
145148

149+
public UsageEventVO(String usageType, long accountId, long zoneId, long resourceId, Long offeringId, Long templateId, Long size, Long vmId, String resourceName) {
150+
this.type = usageType;
151+
this.accountId = accountId;
152+
this.zoneId = zoneId;
153+
this.resourceId = resourceId;
154+
this.offeringId = offeringId;
155+
this.templateId = templateId;
156+
this.size = size;
157+
this.vmId = vmId;
158+
this.resourceName = resourceName;
159+
}
160+
146161
@Override
147162
public long getId() {
148163
return id;
@@ -248,4 +263,11 @@ public void setVirtualSize(Long virtualSize) {
248263
this.virtualSize = virtualSize;
249264
}
250265

266+
public Long getVmId() {
267+
return vmId;
268+
}
269+
270+
public void setVmId(Long vmId) {
271+
this.vmId = vmId;
272+
}
251273
}

engine/schema/src/main/java/com/cloud/event/dao/UsageEventDaoImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,11 @@ public class UsageEventDaoImpl extends GenericDaoBase<UsageEventVO, Long> implem
4747
private final SearchBuilder<UsageEventVO> latestEventsSearch;
4848
private final SearchBuilder<UsageEventVO> IpeventsSearch;
4949
private static final String COPY_EVENTS =
50-
"INSERT INTO cloud_usage.usage_event (id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size) "
51-
+ "SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size FROM cloud.usage_event vmevt WHERE vmevt.id > ? and vmevt.id <= ? ";
50+
"INSERT INTO cloud_usage.usage_event (id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size, vm_id) "
51+
+ "SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size, vm_id FROM cloud.usage_event vmevt WHERE vmevt.id > ? and vmevt.id <= ? ";
5252
private static final String COPY_ALL_EVENTS =
53-
"INSERT INTO cloud_usage.usage_event (id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size) "
54-
+ "SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size FROM cloud.usage_event vmevt WHERE vmevt.id <= ?";
53+
"INSERT INTO cloud_usage.usage_event (id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size, vm_id) "
54+
+ "SELECT id, type, account_id, created, zone_id, resource_id, resource_name, offering_id, template_id, size, resource_type, virtual_size, vm_id FROM cloud.usage_event vmevt WHERE vmevt.id <= ?";
5555
private static final String COPY_EVENT_DETAILS = "INSERT INTO cloud_usage.usage_event_details (id, usage_event_id, name, value) "
5656
+ "SELECT id, usage_event_id, name, value FROM cloud.usage_event_details vmevtDetails WHERE vmevtDetails.usage_event_id > ? and vmevtDetails.usage_event_id <= ? ";
5757
private static final String COPY_ALL_EVENT_DETAILS = "INSERT INTO cloud_usage.usage_event_details (id, usage_event_id, name, value) "

engine/schema/src/main/java/com/cloud/upgrade/DatabaseUpgradeChecker.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
import com.cloud.upgrade.dao.Upgrade41800to41810;
8888
import com.cloud.upgrade.dao.Upgrade41810to41900;
8989
import com.cloud.upgrade.dao.Upgrade41900to41910;
90+
import com.cloud.upgrade.dao.Upgrade41930to41940;
9091
import com.cloud.upgrade.dao.Upgrade420to421;
9192
import com.cloud.upgrade.dao.Upgrade421to430;
9293
import com.cloud.upgrade.dao.Upgrade430to440;
@@ -229,6 +230,7 @@ public DatabaseUpgradeChecker() {
229230
.next("4.18.1.0", new Upgrade41810to41900())
230231
.next("4.19.0.0", new Upgrade41900to41910())
231232
.next("4.19.1.0", new Upgrade41910to41920())
233+
.next("4.19.3.0", new Upgrade41930to41940())
232234
.build();
233235
}
234236

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
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 com.cloud.upgrade.dao;
18+
19+
import java.io.InputStream;
20+
import java.sql.Connection;
21+
22+
import com.cloud.utils.exception.CloudRuntimeException;
23+
24+
public class Upgrade41930to41940 implements DbUpgrade {
25+
26+
@Override
27+
public String[] getUpgradableVersionRange() {
28+
return new String[]{"4.19.3.0", "4.19.4.0"};
29+
}
30+
31+
@Override
32+
public String getUpgradedVersion() {
33+
return "4.19.4.0";
34+
}
35+
36+
@Override
37+
public boolean supportsRollingUpgrade() {
38+
return false;
39+
}
40+
41+
@Override
42+
public InputStream[] getPrepareScripts() {
43+
final String scriptFile = "META-INF/db/schema-41930to41940.sql";
44+
final InputStream script = Thread.currentThread().getContextClassLoader().getResourceAsStream(scriptFile);
45+
if (script == null) {
46+
throw new CloudRuntimeException("Unable to find " + scriptFile);
47+
}
48+
49+
return new InputStream[]{script};
50+
}
51+
52+
@Override
53+
public void performDataMigration(Connection conn) {
54+
}
55+
56+
@Override
57+
public InputStream[] getCleanupScripts() {
58+
return new InputStream[0];
59+
}
60+
}

engine/schema/src/main/java/com/cloud/usage/UsageVolumeVO.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ public class UsageVolumeVO implements InternalIdentity {
5959
@Column(name = "size")
6060
private long size;
6161

62+
@Column(name = "vm_id")
63+
private Long vmId;
64+
6265
@Column(name = "created")
6366
@Temporal(value = TemporalType.TIMESTAMP)
6467
private Date created = null;
@@ -70,13 +73,14 @@ public class UsageVolumeVO implements InternalIdentity {
7073
protected UsageVolumeVO() {
7174
}
7275

73-
public UsageVolumeVO(long id, long zoneId, long accountId, long domainId, Long diskOfferingId, Long templateId, long size, Date created, Date deleted) {
76+
public UsageVolumeVO(long id, long zoneId, long accountId, long domainId, Long diskOfferingId, Long templateId, Long vmId, long size, Date created, Date deleted) {
7477
this.volumeId = id;
7578
this.zoneId = zoneId;
7679
this.accountId = accountId;
7780
this.domainId = domainId;
7881
this.diskOfferingId = diskOfferingId;
7982
this.templateId = templateId;
83+
this.vmId = vmId;
8084
this.size = size;
8185
this.created = created;
8286
this.deleted = deleted;
@@ -126,4 +130,12 @@ public void setDeleted(Date deleted) {
126130
public long getVolumeId() {
127131
return volumeId;
128132
}
133+
134+
public Long getVmId() {
135+
return vmId;
136+
}
137+
138+
public void setVmId(Long vmId) {
139+
this.vmId = vmId;
140+
}
129141
}

engine/schema/src/main/java/com/cloud/usage/dao/UsageStorageDaoImpl.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public UsageStorageDaoImpl() {
5959
IdSearch.and("accountId", IdSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
6060
IdSearch.and("id", IdSearch.entity().getEntityId(), SearchCriteria.Op.EQ);
6161
IdSearch.and("type", IdSearch.entity().getStorageType(), SearchCriteria.Op.EQ);
62+
IdSearch.and("deleted", IdSearch.entity().getDeleted(), SearchCriteria.Op.NULL);
6263
IdSearch.done();
6364

6465
IdZoneSearch = createSearchBuilder();
@@ -76,6 +77,7 @@ public List<UsageStorageVO> listById(long accountId, long id, int type) {
7677
sc.setParameters("accountId", accountId);
7778
sc.setParameters("id", id);
7879
sc.setParameters("type", type);
80+
sc.setParameters("deleted", null);
7981
return listBy(sc, null);
8082
}
8183

engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDao.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
import com.cloud.utils.db.GenericDao;
2424

2525
public interface UsageVolumeDao extends GenericDao<UsageVolumeVO, Long> {
26-
public void removeBy(long userId, long id);
27-
28-
public void update(UsageVolumeVO usage);
29-
3026
public List<UsageVolumeVO> getUsageRecords(Long accountId, Long domainId, Date startDate, Date endDate, boolean limit, int page);
27+
28+
List<UsageVolumeVO> listByVolumeId(long volumeId, long accountId);
3129
}

engine/schema/src/main/java/com/cloud/usage/dao/UsageVolumeDaoImpl.java

Lines changed: 32 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,83 +18,48 @@
1818

1919
import java.sql.PreparedStatement;
2020
import java.sql.ResultSet;
21-
import java.sql.SQLException;
2221
import java.util.ArrayList;
2322
import java.util.Date;
2423
import java.util.List;
2524
import java.util.TimeZone;
2625

2726

28-
import com.cloud.exception.CloudException;
27+
import javax.annotation.PostConstruct;
28+
2929
import org.apache.log4j.Logger;
3030
import org.springframework.stereotype.Component;
3131

3232
import com.cloud.usage.UsageVolumeVO;
3333
import com.cloud.utils.DateUtil;
3434
import com.cloud.utils.db.GenericDaoBase;
35+
import com.cloud.utils.db.SearchBuilder;
36+
import com.cloud.utils.db.SearchCriteria;
3537
import com.cloud.utils.db.TransactionLegacy;
3638

3739
@Component
3840
public class UsageVolumeDaoImpl extends GenericDaoBase<UsageVolumeVO, Long> implements UsageVolumeDao {
3941
public static final Logger s_logger = Logger.getLogger(UsageVolumeDaoImpl.class.getName());
4042

41-
protected static final String REMOVE_BY_USERID_VOLID = "DELETE FROM usage_volume WHERE account_id = ? AND volume_id = ?";
42-
protected static final String UPDATE_DELETED = "UPDATE usage_volume SET deleted = ? WHERE account_id = ? AND volume_id = ? and deleted IS NULL";
43-
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT volume_id, zone_id, account_id, domain_id, disk_offering_id, template_id, size, created, deleted "
43+
protected static final String GET_USAGE_RECORDS_BY_ACCOUNT = "SELECT volume_id, zone_id, account_id, domain_id, disk_offering_id, template_id, vm_id, size, created, deleted "
4444
+ "FROM usage_volume " + "WHERE account_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR "
4545
+ " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))";
46-
protected static final String GET_USAGE_RECORDS_BY_DOMAIN = "SELECT volume_id, zone_id, account_id, domain_id, disk_offering_id, template_id, size, created, deleted "
46+
protected static final String GET_USAGE_RECORDS_BY_DOMAIN = "SELECT volume_id, zone_id, account_id, domain_id, disk_offering_id, template_id, vm_id, size, created, deleted "
4747
+ "FROM usage_volume " + "WHERE domain_id = ? AND ((deleted IS NULL) OR (created BETWEEN ? AND ?) OR "
4848
+ " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?)))";
49-
protected static final String GET_ALL_USAGE_RECORDS = "SELECT volume_id, zone_id, account_id, domain_id, disk_offering_id, template_id, size, created, deleted "
49+
protected static final String GET_ALL_USAGE_RECORDS = "SELECT volume_id, zone_id, account_id, domain_id, disk_offering_id, template_id, vm_id, size, created, deleted "
5050
+ "FROM usage_volume " + "WHERE (deleted IS NULL) OR (created BETWEEN ? AND ?) OR " + " (deleted BETWEEN ? AND ?) OR ((created <= ?) AND (deleted >= ?))";
51+
private SearchBuilder<UsageVolumeVO> volumeSearch;
5152

5253
public UsageVolumeDaoImpl() {
5354
}
5455

55-
@Override
56-
public void removeBy(long accountId, long volId) {
57-
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
58-
try {
59-
txn.start();
60-
try(PreparedStatement pstmt = txn.prepareStatement(REMOVE_BY_USERID_VOLID);) {
61-
if (pstmt != null) {
62-
pstmt.setLong(1, accountId);
63-
pstmt.setLong(2, volId);
64-
pstmt.executeUpdate();
65-
}
66-
}catch (SQLException e) {
67-
throw new CloudException("Error removing usageVolumeVO:"+e.getMessage(), e);
68-
}
69-
txn.commit();
70-
} catch (Exception e) {
71-
txn.rollback();
72-
s_logger.warn("Error removing usageVolumeVO:"+e.getMessage(), e);
73-
} finally {
74-
txn.close();
75-
}
76-
}
77-
78-
@Override
79-
public void update(UsageVolumeVO usage) {
80-
TransactionLegacy txn = TransactionLegacy.open(TransactionLegacy.USAGE_DB);
81-
PreparedStatement pstmt = null;
82-
try {
83-
txn.start();
84-
if (usage.getDeleted() != null) {
85-
pstmt = txn.prepareAutoCloseStatement(UPDATE_DELETED);
86-
pstmt.setString(1, DateUtil.getDateDisplayString(TimeZone.getTimeZone("GMT"), usage.getDeleted()));
87-
pstmt.setLong(2, usage.getAccountId());
88-
pstmt.setLong(3, usage.getVolumeId());
89-
pstmt.executeUpdate();
90-
}
91-
txn.commit();
92-
} catch (Exception e) {
93-
txn.rollback();
94-
s_logger.warn("Error updating UsageVolumeVO", e);
95-
} finally {
96-
txn.close();
97-
}
56+
@PostConstruct
57+
protected void init() {
58+
volumeSearch = createSearchBuilder();
59+
volumeSearch.and("accountId", volumeSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
60+
volumeSearch.and("volumeId", volumeSearch.entity().getVolumeId(), SearchCriteria.Op.EQ);
61+
volumeSearch.and("deleted", volumeSearch.entity().getDeleted(), SearchCriteria.Op.NULL);
62+
volumeSearch.done();
9863
}
9964

10065
@Override
@@ -152,11 +117,15 @@ public List<UsageVolumeVO> getUsageRecords(Long accountId, Long domainId, Date s
152117
if (tId == 0) {
153118
tId = null;
154119
}
155-
long size = Long.valueOf(rs.getLong(7));
120+
Long vmId = Long.valueOf(rs.getLong(7));
121+
if (vmId == 0) {
122+
vmId = null;
123+
}
124+
long size = Long.valueOf(rs.getLong(8));
156125
Date createdDate = null;
157126
Date deletedDate = null;
158-
String createdTS = rs.getString(8);
159-
String deletedTS = rs.getString(9);
127+
String createdTS = rs.getString(9);
128+
String deletedTS = rs.getString(10);
160129

161130
if (createdTS != null) {
162131
createdDate = DateUtil.parseDateString(s_gmtTimeZone, createdTS);
@@ -165,7 +134,7 @@ public List<UsageVolumeVO> getUsageRecords(Long accountId, Long domainId, Date s
165134
deletedDate = DateUtil.parseDateString(s_gmtTimeZone, deletedTS);
166135
}
167136

168-
usageRecords.add(new UsageVolumeVO(vId, zoneId, acctId, dId, doId, tId, size, createdDate, deletedDate));
137+
usageRecords.add(new UsageVolumeVO(vId, zoneId, acctId, dId, doId, tId, vmId, size, createdDate, deletedDate));
169138
}
170139
} catch (Exception e) {
171140
txn.rollback();
@@ -176,4 +145,13 @@ public List<UsageVolumeVO> getUsageRecords(Long accountId, Long domainId, Date s
176145

177146
return usageRecords;
178147
}
148+
149+
@Override
150+
public List<UsageVolumeVO> listByVolumeId(long volumeId, long accountId) {
151+
SearchCriteria<UsageVolumeVO> sc = volumeSearch.create();
152+
sc.setParameters("accountId", accountId);
153+
sc.setParameters("volumeId", volumeId);
154+
sc.setParameters("deleted", null);
155+
return listBy(sc);
156+
}
179157
}

0 commit comments

Comments
 (0)